📄 translate.c
字号:
unsigned int xop = GET_FIELD(insn, 7, 9); int32_t target; switch (xop) {#ifdef TARGET_SPARC64 case 0x1: /* V9 BPcc */ { int cc; target = GET_FIELD_SP(insn, 0, 18); target = sign_extend(target, 18); target <<= 2; cc = GET_FIELD_SP(insn, 20, 21); if (cc == 0) do_branch(dc, target, insn, 0); else if (cc == 2) do_branch(dc, target, insn, 1); else goto illegal_insn; goto jmp_insn; } case 0x3: /* V9 BPr */ { target = GET_FIELD_SP(insn, 0, 13) | (GET_FIELD_SP(insn, 20, 21) << 14); target = sign_extend(target, 16); target <<= 2; rs1 = GET_FIELD(insn, 13, 17); gen_movl_reg_T0(rs1); do_branch_reg(dc, target, insn); goto jmp_insn; } case 0x5: /* V9 FBPcc */ { int cc = GET_FIELD_SP(insn, 20, 21); if (gen_trap_ifnofpu(dc)) goto jmp_insn; target = GET_FIELD_SP(insn, 0, 18); target = sign_extend(target, 19); target <<= 2; do_fbranch(dc, target, insn, cc); goto jmp_insn; }#endif case 0x2: /* BN+x */ { target = GET_FIELD(insn, 10, 31); target = sign_extend(target, 22); target <<= 2; do_branch(dc, target, insn, 0); goto jmp_insn; } case 0x6: /* FBN+x */ { if (gen_trap_ifnofpu(dc)) goto jmp_insn; target = GET_FIELD(insn, 10, 31); target = sign_extend(target, 22); target <<= 2; do_fbranch(dc, target, insn, 0); goto jmp_insn; } case 0x4: /* SETHI */#define OPTIM#if defined(OPTIM) if (rd) { // nop#endif uint32_t value = GET_FIELD(insn, 10, 31); gen_movl_imm_T0(value << 10); gen_movl_T0_reg(rd);#if defined(OPTIM) }#endif break; case 0x0: /* UNIMPL */ default: goto illegal_insn; } break; } break; case 1: /*CALL*/ { target_long target = GET_FIELDs(insn, 2, 31) << 2;#ifdef TARGET_SPARC64 if (dc->pc == (uint32_t)dc->pc) { gen_op_movl_T0_im(dc->pc); } else { gen_op_movq_T0_im64(dc->pc >> 32, dc->pc); }#else gen_op_movl_T0_im(dc->pc);#endif gen_movl_T0_reg(15); target += dc->pc; gen_mov_pc_npc(dc); dc->npc = target; } goto jmp_insn; case 2: /* FPU & Logical Operations */ { unsigned int xop = GET_FIELD(insn, 7, 12); if (xop == 0x3a) { /* generate trap */ int cond; rs1 = GET_FIELD(insn, 13, 17); gen_movl_reg_T0(rs1); if (IS_IMM) { rs2 = GET_FIELD(insn, 25, 31);#if defined(OPTIM) if (rs2 != 0) {#endif gen_movl_simm_T1(rs2); gen_op_add_T1_T0();#if defined(OPTIM) }#endif } else { rs2 = GET_FIELD(insn, 27, 31);#if defined(OPTIM) if (rs2 != 0) {#endif gen_movl_reg_T1(rs2); gen_op_add_T1_T0();#if defined(OPTIM) }#endif } cond = GET_FIELD(insn, 3, 6); if (cond == 0x8) { save_state(dc); gen_op_trap_T0(); } else if (cond != 0) {#ifdef TARGET_SPARC64 /* V9 icc/xcc */ int cc = GET_FIELD_SP(insn, 11, 12); flush_T2(dc); save_state(dc); if (cc == 0) gen_cond[0][cond](); else if (cc == 2) gen_cond[1][cond](); else goto illegal_insn;#else flush_T2(dc); save_state(dc); gen_cond[0][cond]();#endif gen_op_trapcc_T0(); } gen_op_next_insn(); gen_op_movl_T0_0(); gen_op_exit_tb(); dc->is_br = 1; goto jmp_insn; } else if (xop == 0x28) { rs1 = GET_FIELD(insn, 13, 17); switch(rs1) { case 0: /* rdy */ gen_op_movtl_T0_env(offsetof(CPUSPARCState, y)); gen_movl_T0_reg(rd); break; case 15: /* stbar / V9 membar */ break; /* no effect? */#ifdef TARGET_SPARC64 case 0x2: /* V9 rdccr */ gen_op_rdccr(); gen_movl_T0_reg(rd); break; case 0x3: /* V9 rdasi */ gen_op_movl_T0_env(offsetof(CPUSPARCState, asi)); gen_movl_T0_reg(rd); break; case 0x4: /* V9 rdtick */ gen_op_rdtick(); gen_movl_T0_reg(rd); break; case 0x5: /* V9 rdpc */ if (dc->pc == (uint32_t)dc->pc) { gen_op_movl_T0_im(dc->pc); } else { gen_op_movq_T0_im64(dc->pc >> 32, dc->pc); } gen_movl_T0_reg(rd); break; case 0x6: /* V9 rdfprs */ gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs)); gen_movl_T0_reg(rd); break; case 0x13: /* Graphics Status */ if (gen_trap_ifnofpu(dc)) goto jmp_insn; gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr)); gen_movl_T0_reg(rd); break; case 0x17: /* Tick compare */ gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr)); gen_movl_T0_reg(rd); break; case 0x18: /* System tick */ gen_op_rdtick(); // XXX gen_movl_T0_reg(rd); break; case 0x19: /* System tick compare */ gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr)); gen_movl_T0_reg(rd); break; case 0x10: /* Performance Control */ case 0x11: /* Performance Instrumentation Counter */ case 0x12: /* Dispatch Control */ case 0x14: /* Softint set, WO */ case 0x15: /* Softint clear, WO */ case 0x16: /* Softint write */#endif default: goto illegal_insn; }#if !defined(CONFIG_USER_ONLY)#ifndef TARGET_SPARC64 } else if (xop == 0x29) { /* rdpsr / V9 unimp */ if (!supervisor(dc)) goto priv_insn; gen_op_rdpsr(); gen_movl_T0_reg(rd); break;#endif } else if (xop == 0x2a) { /* rdwim / V9 rdpr */ if (!supervisor(dc)) goto priv_insn;#ifdef TARGET_SPARC64 rs1 = GET_FIELD(insn, 13, 17); switch (rs1) { case 0: // tpc gen_op_rdtpc(); break; case 1: // tnpc gen_op_rdtnpc(); break; case 2: // tstate gen_op_rdtstate(); break; case 3: // tt gen_op_rdtt(); break; case 4: // tick gen_op_rdtick(); break; case 5: // tba gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr)); break; case 6: // pstate gen_op_rdpstate(); break; case 7: // tl gen_op_movl_T0_env(offsetof(CPUSPARCState, tl)); break; case 8: // pil gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil)); break; case 9: // cwp gen_op_rdcwp(); break; case 10: // cansave gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave)); break; case 11: // canrestore gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore)); break; case 12: // cleanwin gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin)); break; case 13: // otherwin gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin)); break; case 14: // wstate gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate)); break; case 31: // ver gen_op_movtl_T0_env(offsetof(CPUSPARCState, version)); break; case 15: // fq default: goto illegal_insn; }#else gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));#endif gen_movl_T0_reg(rd); break; } else if (xop == 0x2b) { /* rdtbr / V9 flushw */#ifdef TARGET_SPARC64 gen_op_flushw();#else if (!supervisor(dc)) goto priv_insn; gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr)); gen_movl_T0_reg(rd);#endif break;#endif } else if (xop == 0x34) { /* FPU Operations */ if (gen_trap_ifnofpu(dc)) goto jmp_insn; rs1 = GET_FIELD(insn, 13, 17); rs2 = GET_FIELD(insn, 27, 31); xop = GET_FIELD(insn, 18, 26); switch (xop) { case 0x1: /* fmovs */ gen_op_load_fpr_FT0(rs2); gen_op_store_FT0_fpr(rd); break; case 0x5: /* fnegs */ gen_op_load_fpr_FT1(rs2); gen_op_fnegs(); gen_op_store_FT0_fpr(rd); break; case 0x9: /* fabss */ gen_op_load_fpr_FT1(rs2); gen_op_fabss(); gen_op_store_FT0_fpr(rd); break; case 0x29: /* fsqrts */ gen_op_load_fpr_FT1(rs2); gen_op_fsqrts(); gen_op_store_FT0_fpr(rd); break; case 0x2a: /* fsqrtd */ gen_op_load_fpr_DT1(DFPREG(rs2)); gen_op_fsqrtd(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0x2b: /* fsqrtq */ goto nfpu_insn; case 0x41: gen_op_load_fpr_FT0(rs1); gen_op_load_fpr_FT1(rs2); gen_op_fadds(); gen_op_store_FT0_fpr(rd); break; case 0x42: gen_op_load_fpr_DT0(DFPREG(rs1)); gen_op_load_fpr_DT1(DFPREG(rs2)); gen_op_faddd(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0x43: /* faddq */ goto nfpu_insn; case 0x45: gen_op_load_fpr_FT0(rs1); gen_op_load_fpr_FT1(rs2); gen_op_fsubs(); gen_op_store_FT0_fpr(rd); break; case 0x46: gen_op_load_fpr_DT0(DFPREG(rs1)); gen_op_load_fpr_DT1(DFPREG(rs2)); gen_op_fsubd(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0x47: /* fsubq */ goto nfpu_insn; case 0x49: gen_op_load_fpr_FT0(rs1); gen_op_load_fpr_FT1(rs2); gen_op_fmuls(); gen_op_store_FT0_fpr(rd); break; case 0x4a: gen_op_load_fpr_DT0(DFPREG(rs1)); gen_op_load_fpr_DT1(DFPREG(rs2)); gen_op_fmuld(); gen_op_store_DT0_fpr(rd); break; case 0x4b: /* fmulq */ goto nfpu_insn; case 0x4d: gen_op_load_fpr_FT0(rs1); gen_op_load_fpr_FT1(rs2); gen_op_fdivs(); gen_op_store_FT0_fpr(rd); break; case 0x4e: gen_op_load_fpr_DT0(DFPREG(rs1)); gen_op_load_fpr_DT1(DFPREG(rs2)); gen_op_fdivd(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0x4f: /* fdivq */ goto nfpu_insn; case 0x69: gen_op_load_fpr_FT0(rs1); gen_op_load_fpr_FT1(rs2); gen_op_fsmuld(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0x6e: /* fdmulq */ goto nfpu_insn; case 0xc4: gen_op_load_fpr_FT1(rs2); gen_op_fitos(); gen_op_store_FT0_fpr(rd); break; case 0xc6: gen_op_load_fpr_DT1(DFPREG(rs2)); gen_op_fdtos(); gen_op_store_FT0_fpr(rd); break; case 0xc7: /* fqtos */ goto nfpu_insn; case 0xc8: gen_op_load_fpr_FT1(rs2); gen_op_fitod(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0xc9: gen_op_load_fpr_FT1(rs2); gen_op_fstod(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0xcb: /* fqtod */ goto nfpu_insn; case 0xcc: /* fitoq */ goto nfpu_insn; case 0xcd: /* fstoq */ goto nfpu_insn; case 0xce: /* fdtoq */ goto nfpu_insn; case 0xd1: gen_op_load_fpr_FT1(rs2); gen_op_fstoi(); gen_op_store_FT0_fpr(rd); break; case 0xd2: gen_op_load_fpr_DT1(rs2); gen_op_fdtoi(); gen_op_store_FT0_fpr(rd); break; case 0xd3: /* fqtoi */ goto nfpu_insn;#ifdef TARGET_SPARC64 case 0x2: /* V9 fmovd */ gen_op_load_fpr_DT0(DFPREG(rs2)); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0x6: /* V9 fnegd */ gen_op_load_fpr_DT1(DFPREG(rs2)); gen_op_fnegd(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0xa: /* V9 fabsd */ gen_op_load_fpr_DT1(DFPREG(rs2)); gen_op_fabsd(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0x81: /* V9 fstox */ gen_op_load_fpr_FT1(rs2); gen_op_fstox(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0x82: /* V9 fdtox */ gen_op_load_fpr_DT1(DFPREG(rs2)); gen_op_fdtox(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0x84: /* V9 fxtos */ gen_op_load_fpr_DT1(DFPREG(rs2)); gen_op_fxtos(); gen_op_store_FT0_fpr(rd); break; case 0x88: /* V9 fxtod */ gen_op_load_fpr_DT1(DFPREG(rs2)); gen_op_fxtod(); gen_op_store_DT0_fpr(DFPREG(rd)); break; case 0x3: /* V9 fmovq */ case 0x7: /* V9 fnegq */ case 0xb: /* V9 fabsq */ case 0x83: /* V9 fqtox */ case 0x8c: /* V9 fxtoq */ goto nfpu_insn;#endif default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -