📄 translate.c.svn-base
字号:
offset = (int8_t)insn; if (offset == 0) { offset = ldsw_code(s->pc); s->pc += 2; } else if (offset == -1) { offset = read_im32(s); } if (op == 1) { /* bsr */ gen_push(s, 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_EA(src, 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_EA(src, OS_LONG, 0, &addr); gen_op_or32(dest, src, reg); DEST_EA(insn, OS_LONG, dest, &addr); } else { SRC_EA(src, 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_EA(src, 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); DEST_EA(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; case 1: /* cmp.w */ opsize = OS_WORD; s->cc_op = CC_OP_CMPW; break; case 2: /* cmp.l */ opsize = OS_LONG; s->cc_op = CC_OP_SUB; break; default: abort(); } SRC_EA(src, opsize, -1, NULL); reg = DREG(insn, 9); dest = gen_new_qreg(QMODE_I32); gen_op_sub32(dest, reg, src); gen_op_update_cc_add(dest, src);}DISAS_INSN(cmpa){ int opsize; int src; int reg; int dest; if (insn & 0x100) { opsize = OS_LONG; } else { opsize = OS_WORD; } SRC_EA(src, opsize, -1, NULL); reg = AREG(insn, 9); dest = gen_new_qreg(QMODE_I32); gen_op_sub32(dest, reg, src); gen_op_update_cc_add(dest, src); s->cc_op = CC_OP_SUB;}DISAS_INSN(eor){ int src; int reg; int dest; int addr; SRC_EA(src, OS_LONG, 0, &addr); reg = DREG(insn, 9); dest = gen_new_qreg(QMODE_I32); gen_op_xor32(dest, src, reg); gen_logic_cc(s, dest); DEST_EA(insn, OS_LONG, dest, &addr);}DISAS_INSN(and){ int src; int reg; int dest; int addr; reg = DREG(insn, 9); dest = gen_new_qreg(QMODE_I32); if (insn & 0x100) { SRC_EA(src, OS_LONG, 0, &addr); gen_op_and32(dest, src, reg); DEST_EA(insn, OS_LONG, dest, &addr); } else { SRC_EA(src, OS_LONG, 0, NULL); gen_op_and32(dest, src, reg); gen_op_mov32(reg, dest); } gen_logic_cc(s, dest);}DISAS_INSN(adda){ int src; int reg; SRC_EA(src, OS_LONG, 0, NULL); reg = AREG(insn, 9); gen_op_add32(reg, reg, src);}DISAS_INSN(addx){ 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_addx_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(shift_im){ int reg; int tmp; reg = DREG(insn, 0); tmp = (insn >> 9) & 7; if (tmp == 0) tmp = 8; if (insn & 0x100) { gen_op_shl_im_cc(reg, tmp); s->cc_op = CC_OP_SHL; } else { if (insn & 8) { gen_op_shr_im_cc(reg, tmp); s->cc_op = CC_OP_SHR; } else { gen_op_sar_im_cc(reg, tmp); s->cc_op = CC_OP_SAR; } }}DISAS_INSN(shift_reg){ int reg; int src; int tmp; reg = DREG(insn, 0); src = DREG(insn, 9); tmp = gen_new_qreg(QMODE_I32); gen_op_and32(tmp, src, gen_im32(63)); if (insn & 0x100) { gen_op_shl_cc(reg, tmp); s->cc_op = CC_OP_SHL; } else { if (insn & 8) { gen_op_shr_cc(reg, tmp); s->cc_op = CC_OP_SHR; } else { gen_op_sar_cc(reg, tmp); s->cc_op = CC_OP_SAR; } }}DISAS_INSN(ff1){ int reg; reg = DREG(insn, 0); gen_logic_cc(s, reg); gen_op_ff1(reg, reg);}static int gen_get_sr(DisasContext *s){ int ccr; int sr; ccr = gen_get_ccr(s); sr = gen_new_qreg(QMODE_I32); gen_op_and32(sr, QREG_SR, gen_im32(0xffe0)); gen_op_or32(sr, sr, ccr); return sr;}DISAS_INSN(strldsr){ uint16_t ext; uint32_t addr; addr = s->pc - 2; ext = lduw_code(s->pc); s->pc += 2; if (ext != 0x46FC) { gen_exception(s, addr, EXCP_UNSUPPORTED); return; } ext = lduw_code(s->pc); s->pc += 2; if (IS_USER(s) || (ext & SR_S) == 0) { gen_exception(s, addr, EXCP_PRIVILEGE); return; } gen_push(s, gen_get_sr(s)); gen_set_sr_im(s, ext, 0);}DISAS_INSN(move_from_sr){ int reg; int sr; if (IS_USER(s)) { gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } sr = gen_get_sr(s); reg = DREG(insn, 0); gen_partset_reg(OS_WORD, reg, sr);}DISAS_INSN(move_to_sr){ if (IS_USER(s)) { gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } gen_set_sr(s, insn, 0); gen_lookup_tb(s);}DISAS_INSN(move_from_usp){ if (IS_USER(s)) { gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } /* TODO: Implement USP. */ gen_exception(s, s->pc - 2, EXCP_ILLEGAL);}DISAS_INSN(move_to_usp){ if (IS_USER(s)) { gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } /* TODO: Implement USP. */ gen_exception(s, s->pc - 2, EXCP_ILLEGAL);}DISAS_INSN(halt){ gen_jmp(s, gen_im32(s->pc)); gen_op_halt();}DISAS_INSN(stop){ uint16_t ext; if (IS_USER(s)) { gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } ext = lduw_code(s->pc); s->pc += 2; gen_set_sr_im(s, ext, 0); gen_jmp(s, gen_im32(s->pc)); gen_op_stop();}DISAS_INSN(rte){ if (IS_USER(s)) { gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } gen_exception(s, s->pc - 2, EXCP_RTE);}DISAS_INSN(movec){ uint16_t ext; int reg; if (IS_USER(s)) { gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } ext = lduw_code(s->pc); s->pc += 2; if (ext & 0x8000) { reg = AREG(ext, 12); } else { reg = DREG(ext, 12); } gen_op_movec(gen_im32(ext & 0xfff), reg); gen_lookup_tb(s);}DISAS_INSN(intouch){ if (IS_USER(s)) { gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } /* ICache fetch. Implement as no-op. */}DISAS_INSN(cpushl){ if (IS_USER(s)) { gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } /* Cache push/invalidate. Implement as no-op. */}DISAS_INSN(wddata){ gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(wdebug){ if (IS_USER(s)) { gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } /* TODO: Implement wdebug. */ qemu_assert(0, "WDEBUG not implemented");}DISAS_INSN(trap){ gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf));}/* ??? FP exceptions are not implemented. Most exceptions are deferred until immediately before the next FP instruction is executed. */DISAS_INSN(fpu){ uint16_t ext; int opmode; int src; int dest; int res; int round; int opsize; ext = lduw_code(s->pc); s->pc += 2; opmode = ext & 0x7f; switch ((ext >> 13) & 7) { case 0: case 2: break; case 1: goto undef; case 3: /* fmove out */ src = FREG(ext, 7); /* fmove */ /* ??? TODO: Proper behavior on overflow. */ switch ((ext >> 10) & 7) { case 0: opsize = OS_LONG; res = gen_new_qreg(QMODE_I32); gen_op_f64_to_i32(res, src); break; case 1: opsize = OS_SINGLE; res = gen_new_qreg(QMODE_F32); gen_op_f64_to_f32(res, src); break; case 4: opsize = OS_WORD; res = gen_new_qreg(QMODE_I32); gen_op_f64_to_i32(res, src); break; case 5: opsize = OS_DOUBLE; res = src; break; case 6: opsize = OS_BYTE; res = gen_new_qreg(QMODE_I32); gen_op_f64_to_i32(res, src); break; default: goto undef; } DEST_EA(insn, opsize, res, NULL); return; case 4: /* fmove to control register. */ switch ((ext >> 10) & 7) { case 4: /* FPCR */ /* Not implemented. Ignore writes. */ break; case 1: /* FPIAR */ case 2: /* FPSR */ default: cpu_abort(NULL, "Unimplemented: fmove to control %d", (ext >> 10) & 7); } break; case 5: /* fmove from control register. */ switch ((ext >> 10) & 7) { case 4: /* FPCR */ /* Not implemented. Always return zero. */ res = gen_im32(0); break; case 1: /* FPIAR */ case 2: /* FPSR */ default: cpu_abort(NULL, "Unimplemented: fmove from control %d", (ext >> 10) & 7); goto undef; } DEST_EA(insn, OS_LONG, res, NULL); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -