📄 translate.c
字号:
reg = DREG(insn, 0); gen_op_bswap32(reg, reg);}DISAS_INSN(move){ int src; int dest; int op; int opsize; switch (insn >> 12) { case 1: /* move.b */ opsize = OS_BYTE; break; case 2: /* move.l */ opsize = OS_LONG; break; case 3: /* move.w */ opsize = OS_WORD; break; default: abort(); } src = gen_ea(s, insn, opsize, -1, NULL); op = (insn >> 6) & 7; if (op == 1) { /* movea */ /* The value will already have been sign extended. */ dest = AREG(insn, 9); gen_op_mov32(dest, src); } else { /* normal move */ uint16_t dest_ea; dest_ea = ((insn >> 9) & 7) | (op << 3); gen_ea(s, dest_ea, opsize, src, NULL); /* This will be correct because loads sign extend. */ gen_logic_cc(s, src); }}DISAS_INSN(negx){ int reg; int dest; int tmp; gen_flush_flags(s); reg = DREG(insn, 0); dest = gen_new_qreg(QMODE_I32); gen_op_mov32 (dest, gen_im32(0)); gen_op_subx_cc(dest, reg); /* !Z is sticky. */ tmp = gen_new_qreg(QMODE_I32); gen_op_mov32 (tmp, QREG_CC_DEST); gen_op_update_cc_add(dest, reg); gen_op_mov32(reg, dest); s->cc_op = CC_OP_DYNAMIC; gen_flush_flags(s); gen_op_or32(tmp, tmp, gen_im32(~CCF_Z)); gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp); s->cc_op = CC_OP_FLAGS;}DISAS_INSN(lea){ int reg; int tmp; reg = AREG(insn, 9); tmp = gen_lea(s, insn, OS_LONG); gen_op_mov32(reg, tmp);}DISAS_INSN(clr){ int opsize; switch ((insn >> 6) & 3) { case 0: /* clr.b */ opsize = OS_BYTE; break; case 1: /* clr.w */ opsize = OS_WORD; break; case 2: /* clr.l */ opsize = OS_LONG; break; default: abort(); } gen_ea (s, insn, opsize, gen_im32(0), NULL); gen_logic_cc(s, gen_im32(0));}DISAS_INSN(move_from_ccr){ int reg; int dest; gen_flush_flags(s); dest = gen_new_qreg(QMODE_I32); gen_op_get_xflag(dest); gen_op_shl32(dest, dest, gen_im32(4)); gen_op_or32(dest, dest, QREG_CC_DEST); reg = DREG(insn, 0); gen_partset_reg(OS_WORD, reg, dest);}DISAS_INSN(neg){ int reg; int src1; reg = DREG(insn, 0); src1 = gen_new_qreg(QMODE_I32); gen_op_mov32(src1, reg); gen_op_neg32(reg, src1); s->cc_op = CC_OP_SUB; gen_op_update_cc_add(reg, src1); gen_op_update_xflag_lt(gen_im32(0), src1); s->cc_op = CC_OP_SUB;}DISAS_INSN(move_to_ccr){ int src1; int reg; s->cc_op = CC_OP_FLAGS; if ((insn & 0x38) == 0) { src1 = gen_new_qreg(QMODE_I32); reg = DREG(insn, 0); gen_op_and32(src1, reg, gen_im32(0xf)); gen_op_logic_cc(src1); gen_op_shr32(src1, reg, gen_im32(4)); gen_op_and32(src1, src1, gen_im32(1)); gen_op_update_xflag_tst(src1); } else if ((insn & 0x3f) != 0x3c) { uint8_t val; val = ldsb(s->pc); s->pc += 2; gen_op_logic_cc(gen_im32(val & 0xf)); gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4)); } else disas_undef(s, insn);}DISAS_INSN(not){ int reg; reg = DREG(insn, 0); gen_op_not32(reg, reg); gen_logic_cc(s, reg);}DISAS_INSN(swap){ int dest; int src1; int src2; int reg; dest = gen_new_qreg(QMODE_I32); src1 = gen_new_qreg(QMODE_I32); src2 = gen_new_qreg(QMODE_I32); reg = DREG(insn, 0); gen_op_shl32(src1, reg, gen_im32(16)); gen_op_shr32(src2, reg, gen_im32(16)); gen_op_or32(dest, src1, src2); gen_op_mov32(reg, dest); gen_logic_cc(s, dest);}DISAS_INSN(pea){ int tmp; tmp = gen_lea(s, insn, OS_LONG); gen_push(tmp);}DISAS_INSN(ext){ int reg; int op; int tmp; reg = DREG(insn, 0); op = (insn >> 6) & 7; tmp = gen_new_qreg(QMODE_I32); if (op == 3) gen_op_ext16s32(tmp, reg); else gen_op_ext8s32(tmp, reg); if (op == 2) gen_partset_reg(OS_WORD, reg, tmp); else gen_op_mov32(reg, tmp); gen_logic_cc(s, tmp);}DISAS_INSN(tst){ int opsize; int tmp; switch ((insn >> 6) & 3) { case 0: /* tst.b */ opsize = OS_BYTE; break; case 1: /* tst.w */ opsize = OS_WORD; break; case 2: /* tst.l */ opsize = OS_LONG; break; default: abort(); } tmp = gen_ea(s, insn, opsize, -1, NULL); gen_logic_cc(s, tmp);}DISAS_INSN(pulse){ /* Implemented as a NOP. */}DISAS_INSN(illegal){ gen_exception(s, s->pc - 2, EXCP_ILLEGAL);}/* ??? This should be atomic. */DISAS_INSN(tas){ int dest; int src1; int addr; dest = gen_new_qreg(QMODE_I32); src1 = gen_ea(s, insn, OS_BYTE, -1, &addr); gen_logic_cc(s, src1); gen_op_or32(dest, src1, gen_im32(0x80)); gen_ea(s, insn, OS_BYTE, dest, &addr);}DISAS_INSN(mull){ uint16_t ext; int reg; int src1; int dest; /* The upper 32 bits of the product are discarded, so muls.l and mulu.l are functionally equivalent. */ ext = lduw(s->pc); s->pc += 2; if (ext & 0x87ff) { gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); return; } reg = DREG(ext, 12); src1 = gen_ea(s, insn, OS_LONG, 0, NULL); dest = gen_new_qreg(QMODE_I32); gen_op_mul32(dest, src1, reg); gen_op_mov32(reg, dest); /* Unlike m68k, coldfire always clears the overflow bit. */ gen_logic_cc(s, dest);}DISAS_INSN(link){ int16_t offset; int reg; int tmp; offset = ldsw(s->pc); s->pc += 2; reg = AREG(insn, 0); tmp = gen_new_qreg(QMODE_I32); gen_op_sub32(tmp, QREG_SP, gen_im32(4)); gen_store(OS_LONG, tmp, reg); if (reg != QREG_SP) gen_op_mov32(reg, tmp); gen_op_add32(QREG_SP, tmp, gen_im32(offset));}DISAS_INSN(unlk){ int src; int reg; int tmp; src = gen_new_qreg(QMODE_I32); reg = AREG(insn, 0); gen_op_mov32(src, reg); tmp = gen_load(OS_LONG, src, 0); gen_op_mov32(reg, tmp); gen_op_add32(QREG_SP, src, gen_im32(4));}DISAS_INSN(nop){}DISAS_INSN(rts){ int tmp; tmp = gen_load(OS_LONG, QREG_SP, 0); gen_op_add32(QREG_SP, QREG_SP, gen_im32(4)); gen_jmp(s, tmp);}DISAS_INSN(jump){ int tmp; /* Load the target address first to ensure correct exception behavior. */ tmp = gen_lea(s, insn, OS_LONG); if ((insn & 0x40) == 0) { /* jsr */ gen_push(gen_im32(s->pc)); } gen_jmp(s, tmp);}DISAS_INSN(addsubq){ int src1; int src2; int dest; int val; int addr; src1 = gen_ea(s, insn, OS_LONG, 0, &addr); val = (insn >> 9) & 7; if (val == 0) val = 8; src2 = gen_im32(val); dest = gen_new_qreg(QMODE_I32); gen_op_mov32(dest, src1); if ((insn & 0x38) == 0x08) { /* Don't update condition codes if the destination is an address register. */ if (insn & 0x0100) { gen_op_sub32(dest, dest, src2); } else { gen_op_add32(dest, dest, src2); } } else { if (insn & 0x0100) { gen_op_update_xflag_lt(dest, src2); gen_op_sub32(dest, dest, src2); s->cc_op = CC_OP_SUB; } else { gen_op_add32(dest, dest, src2); gen_op_update_xflag_lt(dest, src2); s->cc_op = CC_OP_ADD; } gen_op_update_cc_add(dest, src2); } gen_ea(s, insn, OS_LONG, dest, &addr);}DISAS_INSN(tpf){ switch (insn & 7) { case 2: /* One extension word. */ s->pc += 2; break; case 3: /* Two extension words. */ s->pc += 4; break; case 4: /* No extension words. */ break; default: disas_undef(s, insn); }}DISAS_INSN(branch){ int32_t offset; uint32_t base; int op; int l1; base = s->pc; op = (insn >> 8) & 0xf; offset = (int8_t)insn; if (offset == 0) { offset = ldsw(s->pc); s->pc += 2; } else if (offset == -1) { offset = read_im32(s); } if (op == 1) { /* bsr */ gen_push(gen_im32(s->pc)); } gen_flush_cc_op(s); if (op > 1) { /* Bcc */ l1 = gen_new_label(); gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1); gen_jmp_tb(s, 1, base + offset); gen_set_label(l1); gen_jmp_tb(s, 0, s->pc); } else { /* Unconditional branch. */ gen_jmp_tb(s, 0, base + offset); }}DISAS_INSN(moveq){ int tmp; tmp = gen_im32((int8_t)insn); gen_op_mov32(DREG(insn, 9), tmp); gen_logic_cc(s, tmp);}DISAS_INSN(mvzs){ int opsize; int src; int reg; if (insn & 0x40) opsize = OS_WORD; else opsize = OS_BYTE; src = gen_ea(s, insn, opsize, (insn & 0x80) ? 0 : -1, NULL); reg = DREG(insn, 9); gen_op_mov32(reg, src); gen_logic_cc(s, src);}DISAS_INSN(or){ int reg; int dest; int src; int addr; reg = DREG(insn, 9); dest = gen_new_qreg(QMODE_I32); if (insn & 0x100) { src = gen_ea(s, insn, OS_LONG, 0, &addr); gen_op_or32(dest, src, reg); gen_ea(s, insn, OS_LONG, dest, &addr); } else { src = gen_ea(s, insn, OS_LONG, 0, NULL); gen_op_or32(dest, src, reg); gen_op_mov32(reg, dest); } gen_logic_cc(s, dest);}DISAS_INSN(suba){ int src; int reg; src = gen_ea(s, insn, OS_LONG, 0, NULL); reg = AREG(insn, 9); gen_op_sub32(reg, reg, src);}DISAS_INSN(subx){ int reg; int src; int dest; int tmp; gen_flush_flags(s); reg = DREG(insn, 9); src = DREG(insn, 0); dest = gen_new_qreg(QMODE_I32); gen_op_mov32 (dest, reg); gen_op_subx_cc(dest, src); /* !Z is sticky. */ tmp = gen_new_qreg(QMODE_I32); gen_op_mov32 (tmp, QREG_CC_DEST); gen_op_update_cc_add(dest, src); gen_op_mov32(reg, dest); s->cc_op = CC_OP_DYNAMIC; gen_flush_flags(s); gen_op_or32(tmp, tmp, gen_im32(~CCF_Z)); gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp); s->cc_op = CC_OP_FLAGS;}DISAS_INSN(mov3q){ int src; int val; val = (insn >> 9) & 7; if (val == 0) val = -1; src = gen_im32(val); gen_logic_cc(s, src); gen_ea(s, insn, OS_LONG, src, NULL);}DISAS_INSN(cmp){ int op; int src; int reg; int dest; int opsize; op = (insn >> 6) & 3; switch (op) { case 0: /* cmp.b */ opsize = OS_BYTE; s->cc_op = CC_OP_CMPB; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -