translate.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,200 行 · 第 1/5 页
C
2,200 行
r_temp = tcg_temp_new(TCG_TYPE_I32); gen_movl_reg_TN(rd + 1, r_temp); tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp); asi = GET_FIELD(insn, 19, 26); tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi), tcg_const_i32(8));}#endif#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn){ int asi; gen_ld_asi(dst, addr, insn, 1, 0); asi = GET_FIELD(insn, 19, 26); tcg_gen_helper_0_4(helper_st_asi, addr, tcg_const_i64(0xffULL), tcg_const_i32(asi), tcg_const_i32(1));}#endifstatic inline TCGv get_src1(unsigned int insn, TCGv def){ TCGv r_rs1 = def; unsigned int rs1; rs1 = GET_FIELD(insn, 13, 17); if (rs1 == 0) //r_rs1 = tcg_const_tl(0); tcg_gen_movi_tl(def, 0); else if (rs1 < 8) //r_rs1 = cpu_gregs[rs1]; tcg_gen_mov_tl(def, cpu_gregs[rs1]); else tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong)); return r_rs1;}static inline TCGv get_src2(unsigned int insn, TCGv def){ TCGv r_rs2 = def; unsigned int rs2; if (IS_IMM) { /* immediate */ rs2 = GET_FIELDs(insn, 19, 31); r_rs2 = tcg_const_tl((int)rs2); } else { /* register */ rs2 = GET_FIELD(insn, 27, 31); if (rs2 == 0) r_rs2 = tcg_const_tl(0); else if (rs2 < 8) r_rs2 = cpu_gregs[rs2]; else tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong)); } return r_rs2;}#define CHECK_IU_FEATURE(dc, FEATURE) \ if (!((dc)->features & CPU_FEATURE_ ## FEATURE)) \ goto illegal_insn;#define CHECK_FPU_FEATURE(dc, FEATURE) \ if (!((dc)->features & CPU_FEATURE_ ## FEATURE)) \ goto nfpu_insn;/* before an instruction, dc->pc must be static */static void disas_sparc_insn(DisasContext * dc){ unsigned int insn, opc, rs1, rs2, rd; insn = ldl_code(dc->pc); opc = GET_FIELD(insn, 0, 1); rd = GET_FIELD(insn, 2, 6); cpu_dst = cpu_T[0]; cpu_src1 = cpu_T[0]; // const cpu_src2 = cpu_T[1]; // const // loads and stores cpu_addr = cpu_T[0]; cpu_val = cpu_T[1]; switch (opc) { case 0: /* branches/sethi */ { 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, cpu_cond); else if (cc == 2) do_branch(dc, target, insn, 1, cpu_cond); 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; cpu_src1 = get_src1(insn, cpu_src1); do_branch_reg(dc, target, insn, cpu_cond, cpu_src1); goto jmp_insn; } case 0x5: /* V9 FBPcc */ { int cc = GET_FIELD_SP(insn, 20, 21); if (gen_trap_ifnofpu(dc, cpu_cond)) goto jmp_insn; target = GET_FIELD_SP(insn, 0, 18); target = sign_extend(target, 19); target <<= 2; do_fbranch(dc, target, insn, cc, cpu_cond); goto jmp_insn; }#else case 0x7: /* CBN+x */ { goto ncp_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, cpu_cond); goto jmp_insn; } case 0x6: /* FBN+x */ { if (gen_trap_ifnofpu(dc, cpu_cond)) goto jmp_insn; target = GET_FIELD(insn, 10, 31); target = sign_extend(target, 22); target <<= 2; do_fbranch(dc, target, insn, 0, cpu_cond); goto jmp_insn; } case 0x4: /* SETHI */ if (rd) { // nop uint32_t value = GET_FIELD(insn, 10, 31); gen_movl_TN_reg(rd, tcg_const_tl(value << 10)); } break; case 0x0: /* UNIMPL */ default: goto illegal_insn; } break; } break; case 1: /*CALL*/ { target_long target = GET_FIELDs(insn, 2, 31) << 2; gen_movl_TN_reg(15, tcg_const_tl(dc->pc)); target += dc->pc; gen_mov_pc_npc(dc, cpu_cond); 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; cpu_src1 = get_src1(insn, cpu_src1); if (IS_IMM) { rs2 = GET_FIELD(insn, 25, 31); tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2); } else { rs2 = GET_FIELD(insn, 27, 31); if (rs2 != 0) { gen_movl_reg_TN(rs2, cpu_src2); tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2); } else tcg_gen_mov_tl(cpu_dst, cpu_src1); } cond = GET_FIELD(insn, 3, 6); if (cond == 0x8) { save_state(dc, cpu_cond); tcg_gen_helper_0_1(helper_trap, cpu_dst); } else if (cond != 0) { TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);#ifdef TARGET_SPARC64 /* V9 icc/xcc */ int cc = GET_FIELD_SP(insn, 11, 12); save_state(dc, cpu_cond); if (cc == 0) gen_cond(r_cond, 0, cond); else if (cc == 2) gen_cond(r_cond, 1, cond); else goto illegal_insn;#else save_state(dc, cpu_cond); gen_cond(r_cond, 0, cond);#endif tcg_gen_helper_0_2(helper_trapcc, cpu_dst, r_cond); } gen_op_next_insn(); tcg_gen_exit_tb(0); dc->is_br = 1; goto jmp_insn; } else if (xop == 0x28) { rs1 = GET_FIELD(insn, 13, 17); switch(rs1) { case 0: /* rdy */#ifndef TARGET_SPARC64 case 0x01 ... 0x0e: /* undefined in the SPARCv8 manual, rdy on the microSPARC II */ case 0x0f: /* stbar in the SPARCv8 manual, rdy on the microSPARC II */ case 0x10 ... 0x1f: /* implementation-dependent in the SPARCv8 manual, rdy on the microSPARC II */#endif tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, y)); gen_movl_TN_reg(rd, cpu_dst); break;#ifdef TARGET_SPARC64 case 0x2: /* V9 rdccr */ tcg_gen_helper_1_0(helper_rdccr, cpu_dst); gen_movl_TN_reg(rd, cpu_dst); break; case 0x3: /* V9 rdasi */ tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, asi)); tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); gen_movl_TN_reg(rd, cpu_dst); break; case 0x4: /* V9 rdtick */ { TCGv r_tickptr; r_tickptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tickptr, cpu_env, offsetof(CPUState, tick)); tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst, r_tickptr); gen_movl_TN_reg(rd, cpu_dst); } break; case 0x5: /* V9 rdpc */ gen_movl_TN_reg(rd, tcg_const_tl(dc->pc)); break; case 0x6: /* V9 rdfprs */ tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fprs)); tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); gen_movl_TN_reg(rd, cpu_dst); break; case 0xf: /* V9 membar */ break; /* no effect */ case 0x13: /* Graphics Status */ if (gen_trap_ifnofpu(dc, cpu_cond)) goto jmp_insn; tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, gsr)); gen_movl_TN_reg(rd, cpu_dst); break; case 0x17: /* Tick compare */ tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tick_cmpr)); gen_movl_TN_reg(rd, cpu_dst); break; case 0x18: /* System tick */ { TCGv r_tickptr; r_tickptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tickptr, cpu_env, offsetof(CPUState, stick)); tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst, r_tickptr); gen_movl_TN_reg(rd, cpu_dst); } break; case 0x19: /* System tick compare */ tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, stick_cmpr)); gen_movl_TN_reg(rd, cpu_dst); 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) } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */#ifndef TARGET_SPARC64 if (!supervisor(dc)) goto priv_insn; tcg_gen_helper_1_0(helper_rdpsr, cpu_dst);#else if (!hypervisor(dc)) goto priv_insn; rs1 = GET_FIELD(insn, 13, 17); switch (rs1) { case 0: // hpstate // gen_op_rdhpstate(); break; case 1: // htstate // gen_op_rdhtstate(); break; case 3: // hintp tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hintp)); tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); break; case 5: // htba tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, htba)); tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); break; case 6: // hver tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hver)); tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); break; case 31: // hstick_cmpr tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst); tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hstick_cmpr)); break; default: goto illegal_insn; }#endif gen_movl_TN_reg(rd, cpu_dst); break; } 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 { TCGv r_tsptr; r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); tcg_gen_ld_tl(cpu_dst, r_tsptr, offsetof(trap_state, tpc)); } break; case 1: // tnpc { TCGv r_tsptr; r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); tcg_gen_ld_tl(cpu_dst, r_tsptr, offsetof(trap_state, tnpc)); } break; case 2: // tstate { TCGv r_tsptr; r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); tcg_gen_ld_tl(cpu_dst, r_tsptr, offsetof(trap_state, tstate)); } break; case 3: // tt { TCGv r_tsptr; r_tsptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tsptr, cpu_env, offsetof(CPUState, tsptr)); tcg_gen_ld_i32(cpu_dst, r_tsptr, offsetof(trap_state, tt)); } break; case 4: // tick { TCGv r_tickptr; r_tickptr = tcg_temp_new(TCG_TYPE_PTR); tcg_gen_ld_ptr(r_tickptr, cpu_env, offsetof(CPUState, tick)); tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst, r_tickptr); gen_movl_TN_reg(rd, cpu_dst); } break; case 5: // tba tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr)); break; case 6: // pstate tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, pstate)); tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); break; case 7: // tl tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl)); tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); break; case 8: // pil tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, psrpil)); tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32); break; case 9: // cwp tcg_gen_helper_1_0(helper_rdcwp, cpu_dst); break; case 10: // cansav
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?