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 + -
显示快捷键?