diff options
Diffstat (limited to 'sim/bfin')
-rw-r--r-- | sim/bfin/ChangeLog | 18 | ||||
-rw-r--r-- | sim/bfin/bfin-sim.c | 84 |
2 files changed, 84 insertions, 18 deletions
diff --git a/sim/bfin/ChangeLog b/sim/bfin/ChangeLog index f7fe209..cf6beb1 100644 --- a/sim/bfin/ChangeLog +++ b/sim/bfin/ChangeLog @@ -1,5 +1,23 @@ 2012-04-08 Mike Frysinger <vapier@gentoo.org> + * bfin-sim.c (illegal_instruction_or_combination): New helper. + (decode_ProgCtrl_0): Call illegal_instruction_or_combination instead + of illegal_instruction. + (decode_PushPopReg_0, decode_CCflag_0, decode_CC2dreg_0, + decode_LDSTpmod_0, decode_dagMODim_0, decode_dagMODik_0, + decode_dspLDST_0, decode_LDST_0, _interp_insn_bfin): Likewise. + (decode_PushPopMultiple_0): Call illegal_instruction_combination when + PARALLEL_GROUP is not BFIN_PARALLEL_NONE. + (decode_CCflag_0, decode_REGMV_0, decode_ALU2op_0, decode_PTR2op_0, + decode_COMPI2opD_0, decode_COMPI2opP_0): Likewise. + (decode_CC2stat_0): Check PARALLEL_GROUP before cbit. + (decode_LDSTpmod_0): Call illegal_instruction_combination when + PARALLEL_GROUP is BFIN_PARALLEL_GROUP2. + (decode_dagMODim_0, decode_dagMODik_0, decode_LDST_0, + decode_LDSTiiFP_0, decode_LDSTii_0): Likewise. + +2012-04-08 Mike Frysinger <vapier@gentoo.org> + * bfin-sim.h (bfin_parallel_group): New enum. (bfin_cpu_state): Add new "group" member. (PARALLEL_GROUP): Define. diff --git a/sim/bfin/bfin-sim.c b/sim/bfin/bfin-sim.c index 25cc6d1..03b9d7a 100644 --- a/sim/bfin/bfin-sim.c +++ b/sim/bfin/bfin-sim.c @@ -52,6 +52,15 @@ illegal_instruction_combination (SIM_CPU *cpu) } static __attribute__ ((noreturn)) void +illegal_instruction_or_combination (SIM_CPU *cpu) +{ + if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) + illegal_instruction_combination (cpu); + else + illegal_instruction (cpu); +} + +static __attribute__ ((noreturn)) void unhandled_instruction (SIM_CPU *cpu, const char *insn) { SIM_DESC sd = CPU_STATE (cpu); @@ -1975,7 +1984,7 @@ decode_ProgCtrl_0 (SIM_CPU *cpu, bu16 iw0, bu32 pc) CYCLE_DELAY = 2; } else - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); } static void @@ -2045,13 +2054,13 @@ decode_PushPopReg_0 (SIM_CPU *cpu, bu16 iw0) /* Can't push/pop reserved registers */ if (reg_is_reserved (grp, reg)) - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); if (W == 0) { /* Dreg and Preg are not supported by this instruction. */ if (grp == 0 || grp == 1) - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); TRACE_INSN (cpu, "%s = [SP++];", reg_name); /* Can't pop USP while in userspace. */ if (PARALLEL_GROUP != BFIN_PARALLEL_NONE @@ -2104,6 +2113,9 @@ decode_PushPopMultiple_0 (SIM_CPU *cpu, bu16 iw0) TRACE_EXTRACT (cpu, "%s: d:%i p:%i W:%i dr:%i pr:%i", __func__, d, p, W, dr, pr); + if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) + illegal_instruction_combination (cpu); + if ((d == 0 && p == 0) || (p && imm5 (pr) > 5) || (d && !p && pr) || (p && !d && dr)) illegal_instruction (cpu); @@ -2215,7 +2227,7 @@ decode_CCflag_0 (SIM_CPU *cpu, bu16 iw0) bs64 diff = acc0 - acc1; if (x != 0 || y != 0) - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); if (opc == 5 && I == 0 && G == 0) { @@ -2239,7 +2251,7 @@ decode_CCflag_0 (SIM_CPU *cpu, bu16 iw0) SET_CCREG (acc0 <= acc1); } else - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); SET_ASTATREG (az, diff == 0); SET_ASTATREG (an, diff < 0); @@ -2304,6 +2316,9 @@ decode_CCflag_0 (SIM_CPU *cpu, bu16 iw0) TRACE_INSN (cpu, "CC = %c%i %s %c%i%s;", s, x, op, d, y, sign); } + if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) + illegal_instruction_combination (cpu); + SET_CCREG (cc); /* Pointer compares only touch CC. */ if (!G) @@ -2350,7 +2365,7 @@ decode_CC2dreg_0 (SIM_CPU *cpu, bu16 iw0) SET_CCREG (!CCREG); } else - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); } static void @@ -2373,13 +2388,13 @@ decode_CC2stat_0 (SIM_CPU *cpu, bu16 iw0) TRACE_INSN (cpu, "%s %s= %s;", D ? astat_names[cbit] : "CC", op_names[op], D ? "CC" : astat_names[cbit]); + if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) + illegal_instruction_combination (cpu); + /* CC = CC; is invalid. */ if (cbit == 5) illegal_instruction (cpu); - if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) - illegal_instruction_combination (cpu); - pval = !!(ASTAT & (1 << cbit)); if (D == 0) switch (op) @@ -2491,6 +2506,9 @@ decode_REGMV_0 (SIM_CPU *cpu, bu16 iw0) TRACE_INSN (cpu, "%s = %s;", dstreg_name, srcreg_name); + if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) + illegal_instruction_combination (cpu); + /* Reserved slots cannot be a src/dst. */ if (reg_is_reserved (gs, src) || reg_is_reserved (gd, dst)) goto invalid_move; @@ -2539,6 +2557,9 @@ decode_ALU2op_0 (SIM_CPU *cpu, bu16 iw0) PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_ALU2op); TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst); + if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) + illegal_instruction_combination (cpu); + if (opc == 0) { TRACE_INSN (cpu, "R%i >>>= R%i;", dst, src); @@ -2647,6 +2668,9 @@ decode_PTR2op_0 (SIM_CPU *cpu, bu16 iw0) PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_PTR2op); TRACE_EXTRACT (cpu, "%s: opc:%i src:%i dst:%i", __func__, opc, src, dst); + if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) + illegal_instruction_combination (cpu); + if (opc == 0) { TRACE_INSN (cpu, "%s -= %s", dst_name, src_name); @@ -2780,6 +2804,9 @@ decode_COMP3op_0 (SIM_CPU *cpu, bu16 iw0) TRACE_EXTRACT (cpu, "%s: opc:%i dst:%i src1:%i src0:%i", __func__, opc, dst, src1, src0); + if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) + illegal_instruction_combination (cpu); + if (opc == 0) { TRACE_INSN (cpu, "R%i = R%i + R%i;", dst, src0, src1); @@ -2843,6 +2870,9 @@ decode_COMPI2opD_0 (SIM_CPU *cpu, bu16 iw0) TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst); TRACE_DECODE (cpu, "%s: imm7:%#x", __func__, imm); + if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) + illegal_instruction_combination (cpu); + if (op == 0) { TRACE_INSN (cpu, "R%i = %s (X);", dst, imm7_str (imm)); @@ -2872,6 +2902,9 @@ decode_COMPI2opP_0 (SIM_CPU *cpu, bu16 iw0) TRACE_EXTRACT (cpu, "%s: op:%i src:%i dst:%i", __func__, op, src, dst); TRACE_DECODE (cpu, "%s: imm:%#x", __func__, imm); + if (PARALLEL_GROUP != BFIN_PARALLEL_NONE) + illegal_instruction_combination (cpu); + if (op == 0) { TRACE_INSN (cpu, "%s = %s;", dst_name, imm7_str (imm)); @@ -2904,6 +2937,9 @@ decode_LDSTpmod_0 (SIM_CPU *cpu, bu16 iw0) TRACE_EXTRACT (cpu, "%s: W:%i aop:%i reg:%i idx:%i ptr:%i", __func__, W, aop, reg, idx, ptr); + if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) + illegal_instruction_combination (cpu); + if (aop == 1 && W == 0 && idx == ptr) { TRACE_INSN (cpu, "R%i.L = W[%s];", reg, ptr_name); @@ -3000,7 +3036,7 @@ decode_LDSTpmod_0 (SIM_CPU *cpu, bu16 iw0) STORE (PREG (ptr), addr + PREG (idx)); } else - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); } static void @@ -3018,6 +3054,9 @@ decode_dagMODim_0 (SIM_CPU *cpu, bu16 iw0) PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODim); TRACE_EXTRACT (cpu, "%s: br:%i op:%i m:%i i:%i", __func__, br, op, m, i); + if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) + illegal_instruction_combination (cpu); + if (op == 0 && br == 1) { TRACE_INSN (cpu, "I%i += M%i (BREV);", i, m); @@ -3034,7 +3073,7 @@ decode_dagMODim_0 (SIM_CPU *cpu, bu16 iw0) dagsub (cpu, i, MREG (m)); } else - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); } static void @@ -3050,6 +3089,9 @@ decode_dagMODik_0 (SIM_CPU *cpu, bu16 iw0) PROFILE_COUNT_INSN (cpu, pc, BFIN_INSN_dagMODik); TRACE_EXTRACT (cpu, "%s: op:%i i:%i", __func__, op, i); + if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) + illegal_instruction_combination (cpu); + if (op == 0) { TRACE_INSN (cpu, "I%i += 2;", i); @@ -3071,7 +3113,7 @@ decode_dagMODik_0 (SIM_CPU *cpu, bu16 iw0) dagsub (cpu, i, 4); } else - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); } static void @@ -3234,7 +3276,7 @@ decode_dspLDST_0 (SIM_CPU *cpu, bu16 iw0) PUT_LONG (addr, DREG (reg)); } else - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); } static void @@ -3258,8 +3300,8 @@ decode_LDST_0 (SIM_CPU *cpu, bu16 iw0) TRACE_EXTRACT (cpu, "%s: sz:%i W:%i aop:%i Z:%i ptr:%i reg:%i", __func__, sz, W, aop, Z, ptr, reg); - if (aop == 3) - illegal_instruction (cpu); + if (aop == 3 || PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) + illegal_instruction_or_combination (cpu); if (W == 0) { @@ -3296,7 +3338,7 @@ decode_LDST_0 (SIM_CPU *cpu, bu16 iw0) SET_DREG (reg, (bs32) (bs8) GET_BYTE (PREG (ptr))); } else - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); } else { @@ -3321,7 +3363,7 @@ decode_LDST_0 (SIM_CPU *cpu, bu16 iw0) PUT_BYTE (PREG (ptr), DREG (reg)); } else - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); } if (aop == 0) @@ -3353,6 +3395,9 @@ decode_LDSTiiFP_0 (SIM_CPU *cpu, bu16 iw0) W, offset, grp, reg); TRACE_DECODE (cpu, "%s: negimm5s4:%#x", __func__, imm); + if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) + illegal_instruction_or_combination (cpu); + if (W == 0) { TRACE_INSN (cpu, "%s = [FP + %s];", reg_name, imm_str); @@ -3393,6 +3438,9 @@ decode_LDSTii_0 (SIM_CPU *cpu, bu16 iw0) TRACE_DECODE (cpu, "%s: uimm4s4/uimm4s2:%#x", __func__, imm); + if (PARALLEL_GROUP == BFIN_PARALLEL_GROUP2) + illegal_instruction_combination (cpu); + if (W == 1 && op == 2) illegal_instruction (cpu); @@ -6165,7 +6213,7 @@ _interp_insn_bfin (SIM_CPU *cpu, bu32 pc) else { TRACE_EXTRACT (cpu, "%s: no matching 16-bit pattern", __func__); - illegal_instruction (cpu); + illegal_instruction_or_combination (cpu); } return insn_len; } |