/* Simulator for Analog Devices Blackfin processors.
- Copyright (C) 2005-2013 Free Software Foundation, Inc.
+ Copyright (C) 2005-2019 Free Software Foundation, Inc.
Contributed by Analog Devices, Inc.
This file is part of simulators.
for (i = 1; i >= 0; --i)
if (LCREG (i) > 1 && pc == LBREG (i))
{
- TRACE_BRANCH (cpu, pc, LTREG (i), i, "Hardware loop %i", i);
+ BFIN_TRACE_BRANCH (cpu, pc, LTREG (i), i, "Hardware loop %i", i);
return LTREG (i);
}
IFETCH_CHECK (newpc);
if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
illegal_instruction_combination (cpu);
- TRACE_BRANCH (cpu, pc, newpc, -1, "RTS");
+ BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "RTS");
SET_PCREG (newpc);
BFIN_CPU_STATE.did_jump = true;
CYCLE_DELAY = 5;
IFETCH_CHECK (newpc);
if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
illegal_instruction_combination (cpu);
- TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (Preg)");
+ BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (Preg)");
SET_PCREG (newpc);
BFIN_CPU_STATE.did_jump = true;
PROFILE_BRANCH_TAKEN (cpu);
IFETCH_CHECK (newpc);
if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
illegal_instruction_combination (cpu);
- TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (Preg)");
+ BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (Preg)");
/* If we're at the end of a hardware loop, RETS is going to be
the top of the loop rather than the next instruction. */
SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2));
IFETCH_CHECK (newpc);
if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
illegal_instruction_combination (cpu);
- TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (PC + Preg)");
+ BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "CALL (PC + Preg)");
SET_RETSREG (hwloop_get_next_pc (cpu, pc, 2));
SET_PCREG (newpc);
BFIN_CPU_STATE.did_jump = true;
IFETCH_CHECK (newpc);
if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
illegal_instruction_combination (cpu);
- TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (PC + Preg)");
+ BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP (PC + Preg)");
SET_PCREG (newpc);
BFIN_CPU_STATE.did_jump = true;
PROFILE_BRANCH_TAKEN (cpu);
if (cond)
{
bu32 newpc = pc + pcrel;
- TRACE_BRANCH (cpu, pc, newpc, -1, "Conditional JUMP");
+ BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "Conditional JUMP");
SET_PCREG (newpc);
BFIN_CPU_STATE.did_jump = true;
PROFILE_BRANCH_TAKEN (cpu);
if (PARALLEL_GROUP != BFIN_PARALLEL_NONE)
illegal_instruction_combination (cpu);
- TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.S");
+ BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.S");
SET_PCREG (newpc);
BFIN_CPU_STATE.did_jump = true;
int aop = ((iw0 >> LDST_aop_bits) & LDST_aop_mask);
int reg = ((iw0 >> LDST_reg_bits) & LDST_reg_mask);
int ptr = ((iw0 >> LDST_ptr_bits) & LDST_ptr_mask);
- const char * const posts[] = { "++", "--", "" };
+ const char * const posts[] = { "++", "--", "", "<INV>" };
const char *post = posts[aop];
const char *ptr_name = get_preg_name (ptr);
if (S == 1)
{
- TRACE_BRANCH (cpu, pc, newpc, -1, "CALL");
+ BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "CALL");
SET_RETSREG (hwloop_get_next_pc (cpu, pc, 4));
}
else
- TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.L");
+ BFIN_TRACE_BRANCH (cpu, pc, newpc, -1, "JUMP.L");
SET_PCREG (newpc);
BFIN_CPU_STATE.did_jump = true;
SET_AREG (1, 0);
}
else if ((aop == 0 || aop == 1 || aop == 2) && s == 1 && aopcde == 8
- && x == 0 && s == 1 && HL == 0)
+ && x == 0 && HL == 0)
{
bs40 acc0 = get_extended_acc (cpu, 0);
bs40 acc1 = get_extended_acc (cpu, 1);
else if ((aop == 0 || aop == 1) && aopcde == 14 && x == 0 && s == 0)
{
bs40 src_acc = get_extended_acc (cpu, aop);
- int v = 0;
+ bu32 v = 0;
TRACE_INSN (cpu, "A%i = - A%i;", HL, aop);
TRACE_INSN (cpu, "(R%i, R%i) = SEARCH R%i (%s);",
dst1, dst0, src0, searchmodes[aop]);
+ /* XXX: The parallel version is a bit weird in its limits:
+
+ This instruction can be issued in parallel with the combination of one
+ 16-bit length load instruction to the P0 register and one 16-bit NOP.
+ No other instructions can be issued in parallel with the Vector Search
+ instruction. Note the following legal and illegal forms.
+ (r1, r0) = search r2 (LT) || r2 = [p0++p3]; // ILLEGAL
+ (r1, r0) = search r2 (LT) || r2 = [p0++]; // LEGAL
+ (r1, r0) = search r2 (LT) || r2 = [p0++]; // LEGAL
+
+ Unfortunately, our parallel insn state doesn't (currently) track enough
+ details to be able to check this. */
+
if (dst0 == dst1)
illegal_instruction_combination (cpu);
bu32 fg = DREG (src0);
bu32 bg = DREG (src1);
bu32 len = fg & 0x1f;
- bu32 mask = (1 << MIN (16, len)) - 1;
+ bu32 mask = (1 << min (16, len)) - 1;
bu32 fgnd = (fg >> 16) & mask;
int shft = ((fg >> 8) & 0x1f);
int count = imm6 (immag);
TRACE_INSN (cpu, "R%i = R%i << %i (S);", dst0, src1, count);
- STORE (DREG (dst0), lshift (cpu, DREG (src1), count, 32, 1, 1));
+
+ if (count < 0)
+ STORE (DREG (dst0), ashiftrt (cpu, DREG (src1), -count, 32));
+ else
+ STORE (DREG (dst0), lshift (cpu, DREG (src1), count, 32, 1, 1));
}
else if (sop == 2 && sopcde == 2)
{