📄 translate.c
字号:
#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 */ { // XXX }#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) { gen_op_movl_T1_im(dc->pc); 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: /* V9 ldqfa */ goto nfpu_insn;#endif default: goto illegal_insn; } gen_movl_T1_reg(rd);#ifdef TARGET_SPARC64 skip_move: ;#endif } else if (xop >= 0x20 && xop < 0x24) {#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) gen_op_trap_ifnofpu();#endif switch (xop) { case 0x20: /* load fpreg */ gen_op_ldst(ldf); gen_op_store_FT0_fpr(rd); break; case 0x21: /* load fsr */ gen_op_ldst(ldf); gen_op_ldfsr(); break; case 0x22: /* load quad fpreg */ goto nfpu_insn; case 0x23: /* load double fpreg */ gen_op_ldst(lddf); gen_op_store_DT0_fpr(DFPREG(rd)); break; default: goto illegal_insn; } } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \ xop == 0xe || xop == 0x1e) { gen_movl_reg_T1(rd); switch (xop) { case 0x4: gen_op_ldst(st); break; case 0x5: gen_op_ldst(stb); break; case 0x6: gen_op_ldst(sth); break; case 0x7: flush_T2(dc); gen_movl_reg_T2(rd + 1); gen_op_ldst(std); break;#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) case 0x14:#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif gen_op_sta(insn, 0, 4, 0); break; case 0x15:#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif gen_op_stba(insn, 0, 1, 0); break; case 0x16:#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif gen_op_stha(insn, 0, 2, 0); break; case 0x17:#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn;#endif flush_T2(dc); gen_movl_reg_T2(rd + 1); gen_op_stda(insn, 0, 8, 0); break;#endif#ifdef TARGET_SPARC64 case 0x0e: /* V9 stx */ gen_op_ldst(stx); break; case 0x1e: /* V9 stxa */ gen_op_stxa(insn, 0, 8, 0); // XXX break;#endif default: goto illegal_insn; } } else if (xop > 0x23 && xop < 0x28) {#if !defined(CONFIG_USER_ONLY) gen_op_trap_ifnofpu();#endif switch (xop) { case 0x24: gen_op_load_fpr_FT0(rd); gen_op_ldst(stf); break; case 0x25: /* stfsr, V9 stxfsr */ gen_op_stfsr(); gen_op_ldst(stf); break; case 0x26: /* stdfq */ goto nfpu_insn; case 0x27: gen_op_load_fpr_DT0(DFPREG(rd)); gen_op_ldst(stdf); break; default: goto illegal_insn; } } else if (xop > 0x33 && xop < 0x3f) {#ifdef TARGET_SPARC64 switch (xop) { case 0x34: /* V9 stfa */ gen_op_stfa(insn, 0, 0, 0); // XXX break; case 0x37: /* V9 stdfa */ gen_op_stdfa(insn, 0, 0, 0); // XXX break; case 0x3c: /* V9 casa */ gen_op_casa(insn, 0, 4, 0); // XXX break; case 0x3e: /* V9 casxa */ gen_op_casxa(insn, 0, 8, 0); // XXX break; case 0x36: /* V9 stqfa */ goto nfpu_insn; default: goto illegal_insn; }#else goto illegal_insn;#endif } else goto illega
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -