📄 translate.c
字号:
default: goto illegal_insn; }#else gen_op_xor_T1_T0(); gen_op_wrpsr(); save_state(dc); gen_op_next_insn(); gen_op_movl_T0_0(); gen_op_exit_tb(); dc->is_br = 1;#endif } break; case 0x32: /* wrwim, V9 wrpr */ { if (!supervisor(dc)) goto priv_insn; gen_op_xor_T1_T0();#ifdef TARGET_SPARC64 switch (rd) { case 0: // tpc gen_op_wrtpc(); break; case 1: // tnpc gen_op_wrtnpc(); break; case 2: // tstate gen_op_wrtstate(); break; case 3: // tt gen_op_wrtt(); break; case 4: // tick gen_op_wrtick(); break; case 5: // tba gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr)); break; case 6: // pstate gen_op_wrpstate(); save_state(dc); gen_op_next_insn(); gen_op_movl_T0_0(); gen_op_exit_tb(); dc->is_br = 1; break; case 7: // tl gen_op_movl_env_T0(offsetof(CPUSPARCState, tl)); break; case 8: // pil gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil)); break; case 9: // cwp gen_op_wrcwp(); break; case 10: // cansave gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave)); break; case 11: // canrestore gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore)); break; case 12: // cleanwin gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin)); break; case 13: // otherwin gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin)); break; case 14: // wstate gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate)); break; default: goto illegal_insn; }#else gen_op_wrwim();#endif } break;#ifndef TARGET_SPARC64 case 0x33: /* wrtbr, V9 unimp */ { if (!supervisor(dc)) goto priv_insn; gen_op_xor_T1_T0(); gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr)); } break;#endif#endif#ifdef TARGET_SPARC64 case 0x2c: /* V9 movcc */ { int cc = GET_FIELD_SP(insn, 11, 12); int cond = GET_FIELD_SP(insn, 14, 17); if (IS_IMM) { /* immediate */ rs2 = GET_FIELD_SPs(insn, 0, 10); gen_movl_simm_T1(rs2); } else { rs2 = GET_FIELD_SP(insn, 0, 4); gen_movl_reg_T1(rs2); } gen_movl_reg_T0(rd); flush_T2(dc); if (insn & (1 << 18)) { if (cc == 0) gen_cond[0][cond](); else if (cc == 2) gen_cond[1][cond](); else goto illegal_insn; } else { gen_fcond[cc][cond](); } gen_op_mov_cc(); gen_movl_T0_reg(rd); break; } case 0x2d: /* V9 sdivx */ gen_op_sdivx_T1_T0(); gen_movl_T0_reg(rd); break; case 0x2e: /* V9 popc */ { if (IS_IMM) { /* immediate */ rs2 = GET_FIELD_SPs(insn, 0, 12); gen_movl_simm_T1(rs2); // XXX optimize: popc(constant) } else { rs2 = GET_FIELD_SP(insn, 0, 4); gen_movl_reg_T1(rs2); } gen_op_popc(); gen_movl_T0_reg(rd); } case 0x2f: /* V9 movr */ { int cond = GET_FIELD_SP(insn, 10, 12); rs1 = GET_FIELD(insn, 13, 17); flush_T2(dc); gen_movl_reg_T0(rs1); gen_cond_reg(cond); if (IS_IMM) { /* immediate */ rs2 = GET_FIELD_SPs(insn, 0, 10); gen_movl_simm_T1(rs2); } else { rs2 = GET_FIELD_SP(insn, 0, 4); gen_movl_reg_T1(rs2); } gen_movl_reg_T0(rd); gen_op_mov_cc(); gen_movl_T0_reg(rd); break; } case 0x36: /* UltraSparc shutdown, VIS */ { int opf = GET_FIELD_SP(insn, 5, 13); rs1 = GET_FIELD(insn, 13, 17); rs2 = GET_FIELD(insn, 27, 31); switch (opf) { case 0x018: /* VIS I alignaddr */ if (gen_trap_ifnofpu(dc)) goto jmp_insn; gen_movl_reg_T0(rs1); gen_movl_reg_T1(rs2); gen_op_alignaddr(); gen_movl_T0_reg(rd); break; case 0x01a: /* VIS I alignaddrl */ if (gen_trap_ifnofpu(dc)) goto jmp_insn; // XXX break; case 0x048: /* VIS I faligndata */ if (gen_trap_ifnofpu(dc)) goto jmp_insn; gen_op_load_fpr_DT0(rs1); gen_op_load_fpr_DT1(rs2); gen_op_faligndata(); gen_op_store_DT0_fpr(rd); break; default: goto illegal_insn; } break; }#endif default: goto illegal_insn; } }#ifdef TARGET_SPARC64 } else if (xop == 0x39) { /* V9 return */ rs1 = GET_FIELD(insn, 13, 17); gen_movl_reg_T0(rs1); if (IS_IMM) { /* immediate */ rs2 = GET_FIELDs(insn, 19, 31);#if defined(OPTIM) if (rs2) {#endif gen_movl_simm_T1(rs2); gen_op_add_T1_T0();#if defined(OPTIM) }#endif } else { /* register */ rs2 = GET_FIELD(insn, 27, 31);#if defined(OPTIM) if (rs2) {#endif gen_movl_reg_T1(rs2); gen_op_add_T1_T0();#if defined(OPTIM) }#endif } gen_op_restore(); gen_mov_pc_npc(dc); gen_op_movl_npc_T0(); dc->npc = DYNAMIC_PC; goto jmp_insn;#endif } else { rs1 = GET_FIELD(insn, 13, 17); gen_movl_reg_T0(rs1); if (IS_IMM) { /* immediate */ rs2 = GET_FIELDs(insn, 19, 31);#if defined(OPTIM) if (rs2) {#endif gen_movl_simm_T1(rs2); gen_op_add_T1_T0();#if defined(OPTIM) }#endif } else { /* register */ rs2 = GET_FIELD(insn, 27, 31);#if defined(OPTIM) if (rs2) {#endif gen_movl_reg_T1(rs2); gen_op_add_T1_T0();#if defined(OPTIM) }#endif } switch (xop) { case 0x38: /* jmpl */ { if (rd != 0) {#ifdef TARGET_SPARC64 if (dc->pc == (uint32_t)dc->pc) { gen_op_movl_T1_im(dc->pc); } else { gen_op_movq_T1_im64(dc->pc >> 32, dc->pc); }#else gen_op_movl_T1_im(dc->pc);#endif gen_movl_T1_reg(rd); } gen_mov_pc_npc(dc); gen_op_movl_npc_T0(); dc->npc = DYNAMIC_PC; } goto jmp_insn;#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64) case 0x39: /* rett, V9 return */ { if (!supervisor(dc)) goto priv_insn; gen_mov_pc_npc(dc); gen_op_movl_npc_T0(); dc->npc = DYNAMIC_PC; gen_op_rett(); } goto jmp_insn;#endif case 0x3b: /* flush */ gen_op_flush_T0(); break; case 0x3c: /* save */ save_state(dc); gen_op_save(); gen_movl_T0_reg(rd); break; case 0x3d: /* restore */ save_state(dc); gen_op_restore(); gen_movl_T0_reg(rd); break;#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64) case 0x3e: /* V9 done/retry */ { switch (rd) { case 0: if (!supervisor(dc)) goto priv_insn; dc->npc = DYNAMIC_PC; dc->pc = DYNAMIC_PC; gen_op_done(); goto jmp_insn; case 1: if (!supervisor(dc)) goto priv_insn; dc->npc = DYNAMIC_PC; dc->pc = DYNAMIC_PC; gen_op_retry(); goto jmp_insn; default: goto illegal_insn; } } break;#endif default: goto illegal_insn; } } break; } break; case 3: /* load/store instructions */ { unsigned int xop = GET_FIELD(insn, 7, 12); rs1 = GET_FIELD(insn, 13, 17); gen_movl_reg_T0(rs1); if (IS_IMM) { /* immediate */ rs2 = GET_FIELDs(insn, 19, 31);#if defined(OPTIM) if (rs2 != 0) {#endif gen_movl_simm_T1(rs2); gen_op_add_T1_T0();#if defined(OPTIM) }#endif } else { /* register */ 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 } if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) || \ (xop > 0x17 && xop < 0x1d ) || \ (xop > 0x2c && xop < 0x33) || xop == 0x1f) { switch (xop) { case 0x0: /* load word */ gen_op_ldst(ld); break; case 0x1: /* load unsigned byte */ gen_op_ldst(ldub); break; case 0x2: /* load unsigned halfword */ gen_op_ldst(lduh); break; case 0x3: /* load double word */ gen_op_ldst(ldd); gen_movl_T0_reg(rd + 1); break; case 0x9: /* load signed byte */ gen_op_ldst(ldsb); break; case 0xa: /* load signed halfword */ gen_op_ldst(ldsh); break; case 0xd: /* ldstub -- XXX: should be atomically */ gen_op_ldst(ldstub); break; case 0x0f: /* swap register with memory. Also atomically */ gen_movl_reg_T1(rd); gen_op_ldst(swap); break;#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) case 0x10: /* load word alternate */#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif gen_op_lda(insn, 1, 4, 0); break; case 0x11: /* load unsigned byte alternate */#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif gen_op_lduba(insn, 1, 1, 0); break; case 0x12: /* load unsigned halfword alternate */#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif gen_op_lduha(insn, 1, 2, 0); break; case 0x13: /* load double word alternate */#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif gen_op_ldda(insn, 1, 8, 0); gen_movl_T0_reg(rd + 1); break; case 0x19: /* load signed byte alternate */#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif gen_op_ldsba(insn, 1, 1, 1); break; case 0x1a: /* load signed halfword alternate */#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif gen_op_ldsha(insn, 1, 2 ,1); break; case 0x1d: /* ldstuba -- XXX: should be atomically */#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif gen_op_ldstuba(insn, 1, 1, 0); break; case 0x1f: /* swap reg with alt. memory. Also atomically */#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif gen_movl_reg_T1(rd); gen_op_swapa(insn, 1, 4, 0); break;#ifndef TARGET_SPARC64 /* avoid warnings */ (void) &gen_op_stfa; (void) &gen_op_stdfa; (void) &gen_op_ldfa; (void) &gen_op_lddfa;#else#if !defined(CONFIG_USER_ONLY) (void) &gen_op_cas; (void) &gen_op_casx;#endif#endif#endif#ifdef TARGET_SPARC64 case 0x08: /* V9 ldsw */ gen_op_ldst(ldsw); break; case 0x0b: /* V9 ldx */ gen_op_ldst(ldx); break; case 0x18: /* V9 ldswa */ gen_op_ldswa(insn, 1, 4, 1); break; case 0x1b: /* V9 ldxa */ gen_op_ldxa(insn, 1, 8, 0); break; case 0x2d: /* V9 prefetch, no effect */ goto skip_move; case 0x30: /* V9 ldfa */ gen_op_ldfa(insn, 1, 8, 0); // XXX break; case 0x33: /* V9 lddfa */ gen_op_lddfa(insn, 1, 8, 0); // XXX break; case 0x3d: /* V9 prefetcha, no effect */ goto skip_move; case 0x32:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -