⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 translate.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                    }                    break;                }                /* Setup the next operands.  */                veclen--;                rd = ((rd + delta_d) & (bank_mask - 1))                     | (rd & bank_mask);                if (op == 15) {                    /* One source operand.  */                    rm = ((rm + delta_m) & (bank_mask - 1))                         | (rm & bank_mask);                    gen_mov_F0_vreg(dp, rm);                } else {                    /* Two source operands.  */                    rn = ((rn + delta_d) & (bank_mask - 1))                         | (rn & bank_mask);                    gen_mov_F0_vreg(dp, rn);                    if (delta_m) {                        rm = ((rm + delta_m) & (bank_mask - 1))                             | (rm & bank_mask);                        gen_mov_F1_vreg(dp, rm);                    }                }            }        }        break;    case 0xc:    case 0xd:        if (dp && (insn & (1 << 22))) {            /* two-register transfer */            rn = (insn >> 16) & 0xf;            rd = (insn >> 12) & 0xf;            if (dp) {                if (insn & (1 << 5))                    return 1;                rm = insn & 0xf;            } else                rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);            if (insn & (1 << 20)) {                /* vfp->arm */                if (dp) {                    gen_mov_F0_vreg(1, rm);                    gen_op_vfp_mrrd();                    gen_movl_reg_T0(s, rd);                    gen_movl_reg_T1(s, rn);                } else {                    gen_mov_F0_vreg(0, rm);                    gen_op_vfp_mrs();                    gen_movl_reg_T0(s, rn);                    gen_mov_F0_vreg(0, rm + 1);                    gen_op_vfp_mrs();                    gen_movl_reg_T0(s, rd);                }            } else {                /* arm->vfp */                if (dp) {                    gen_movl_T0_reg(s, rd);                    gen_movl_T1_reg(s, rn);                    gen_op_vfp_mdrr();                    gen_mov_vreg_F0(1, rm);                } else {                    gen_movl_T0_reg(s, rn);                    gen_op_vfp_msr();                    gen_mov_vreg_F0(0, rm);                    gen_movl_T0_reg(s, rd);                    gen_op_vfp_msr();                    gen_mov_vreg_F0(0, rm + 1);                }            }        } else {            /* Load/store */            rn = (insn >> 16) & 0xf;            if (dp)                rd = (insn >> 12) & 0xf;            else                rd = ((insn >> 11) & 0x1e) | ((insn >> 22) & 1);            gen_movl_T1_reg(s, rn);            if ((insn & 0x01200000) == 0x01000000) {                /* Single load/store */                offset = (insn & 0xff) << 2;                if ((insn & (1 << 23)) == 0)                    offset = -offset;                gen_op_addl_T1_im(offset);                if (insn & (1 << 20)) {                    gen_vfp_ld(s, dp);                    gen_mov_vreg_F0(dp, rd);                } else {                    gen_mov_F0_vreg(dp, rd);                    gen_vfp_st(s, dp);                }            } else {                /* load/store multiple */                if (dp)                    n = (insn >> 1) & 0x7f;                else                    n = insn & 0xff;                if (insn & (1 << 24)) /* pre-decrement */                    gen_op_addl_T1_im(-((insn & 0xff) << 2));                if (dp)                    offset = 8;                else                    offset = 4;                for (i = 0; i < n; i++) {                    if (insn & (1 << 20)) {                        /* load */                        gen_vfp_ld(s, dp);                        gen_mov_vreg_F0(dp, rd + i);                    } else {                        /* store */                        gen_mov_F0_vreg(dp, rd + i);                        gen_vfp_st(s, dp);                    }                    gen_op_addl_T1_im(offset);                }                if (insn & (1 << 21)) {                    /* writeback */                    if (insn & (1 << 24))                        offset = -offset * n;                    else if (dp && (insn & 1))                        offset = 4;                    else                        offset = 0;                    if (offset != 0)                        gen_op_addl_T1_im(offset);                    gen_movl_reg_T1(s, rn);                }            }        }        break;    default:        /* Should never happen.  */        return 1;    }    return 0;}static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest){    TranslationBlock *tb;    tb = s->tb;    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {        if (n == 0)            gen_op_goto_tb0(TBPARAM(tb));        else            gen_op_goto_tb1(TBPARAM(tb));        gen_op_movl_T0_im(dest);        gen_op_movl_r15_T0();        gen_op_movl_T0_im((long)tb + n);        gen_op_exit_tb();    } else {        gen_op_movl_T0_im(dest);        gen_op_movl_r15_T0();        gen_op_movl_T0_0();        gen_op_exit_tb();    }}static inline void gen_jmp (DisasContext *s, uint32_t dest){    if (__builtin_expect(s->singlestep_enabled, 0)) {        /* An indirect jump so that we still trigger the debug exception.  */        if (s->thumb)          dest |= 1;        gen_op_movl_T0_im(dest);        gen_bx(s);    } else {        gen_goto_tb(s, 0, dest);        s->is_jmp = DISAS_TB_JUMP;    }}static inline void gen_mulxy(int x, int y){    if (x)        gen_op_sarl_T0_im(16);    else        gen_op_sxth_T0();    if (y)        gen_op_sarl_T1_im(16);    else        gen_op_sxth_T1();    gen_op_mul_T0_T1();}/* Return the mask of PSR bits set by a MSR instruction.  */static uint32_t msr_mask(DisasContext *s, int flags, int spsr) {    uint32_t mask;    mask = 0;    if (flags & (1 << 0))        mask |= 0xff;    if (flags & (1 << 1))        mask |= 0xff00;    if (flags & (1 << 2))        mask |= 0xff0000;    if (flags & (1 << 3))        mask |= 0xff000000;    /* Mask out undefined bits.  */    mask &= 0xf90f03ff;    /* Mask out state bits.  */    if (!spsr)        mask &= ~0x01000020;    /* Mask out privileged bits.  */    if (IS_USER(s))        mask &= 0xf80f0200;    return mask;}/* Returns nonzero if access to the PSR is not permitted.  */static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr){    if (spsr) {        /* ??? This is also undefined in system mode.  */        if (IS_USER(s))            return 1;        gen_op_movl_spsr_T0(mask);    } else {        gen_op_movl_cpsr_T0(mask);    }    gen_lookup_tb(s);    return 0;}static void gen_exception_return(DisasContext *s){    gen_op_movl_reg_TN[0][15]();    gen_op_movl_T0_spsr();    gen_op_movl_cpsr_T0(0xffffffff);    s->is_jmp = DISAS_UPDATE;}static void disas_arm_insn(CPUState * env, DisasContext *s){    unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;        insn = ldl_code(s->pc);    s->pc += 4;        cond = insn >> 28;    if (cond == 0xf){        /* Unconditional instructions.  */        if ((insn & 0x0d70f000) == 0x0550f000)            return; /* PLD */        else if ((insn & 0x0e000000) == 0x0a000000) {            /* branch link and change to thumb (blx <offset>) */            int32_t offset;            val = (uint32_t)s->pc;            gen_op_movl_T0_im(val);            gen_movl_reg_T0(s, 14);            /* Sign-extend the 24-bit offset */            offset = (((int32_t)insn) << 8) >> 8;            /* offset * 4 + bit24 * 2 + (thumb bit) */            val += (offset << 2) | ((insn >> 23) & 2) | 1;            /* pipeline offset */            val += 4;            gen_op_movl_T0_im(val);            gen_bx(s);            return;        } else if ((insn & 0x0fe00000) == 0x0c400000) {            /* Coprocessor double register transfer.  */        } else if ((insn & 0x0f000010) == 0x0e000010) {            /* Additional coprocessor register transfer.  */        } else if ((insn & 0x0ff10010) == 0x01000000) {            /* cps (privileged) */        } else if ((insn & 0x0ffffdff) == 0x01010000) {            /* setend */            if (insn & (1 << 9)) {                /* BE8 mode not implemented.  */                goto illegal_op;            }            return;        }        goto illegal_op;    }    if (cond != 0xe) {        /* if not always execute, we generate a conditional jump to           next instruction */        s->condlabel = gen_new_label();        gen_test_cc[cond ^ 1](s->condlabel);        s->condjmp = 1;        //gen_test_cc[cond ^ 1]((long)s->tb, (long)s->pc);        //s->is_jmp = DISAS_JUMP_NEXT;    }    if ((insn & 0x0f900000) == 0x03000000) {        if ((insn & 0x0fb0f000) != 0x0320f000)            goto illegal_op;        /* CPSR = immediate */        val = insn & 0xff;        shift = ((insn >> 8) & 0xf) * 2;        if (shift)            val = (val >> shift) | (val << (32 - shift));        gen_op_movl_T0_im(val);        i = ((insn & (1 << 22)) != 0);        if (gen_set_psr_T0(s, msr_mask(s, (insn >> 16) & 0xf, i), i))            goto illegal_op;    } else if ((insn & 0x0f900000) == 0x01000000               && (insn & 0x00000090) != 0x00000090) {        /* miscellaneous instructions */        op1 = (insn >> 21) & 3;        sh = (insn >> 4) & 0xf;        rm = insn & 0xf;        switch (sh) {        case 0x0: /* move program status register */            if (op1 & 1) {                /* PSR = reg */                gen_movl_T0_reg(s, rm);                i = ((op1 & 2) != 0);                if (gen_set_psr_T0(s, msr_mask(s, (insn >> 16) & 0xf, i), i))                    goto illegal_op;            } else {                /* reg = PSR */                rd = (insn >> 12) & 0xf;                if (op1 & 2) {                    if (IS_USER(s))                        goto illegal_op;                    gen_op_movl_T0_spsr();                } else {                    gen_op_movl_T0_cpsr();                }                gen_movl_reg_T0(s, rd);            }            break;        case 0x1:            if (op1 == 1) {                /* branch/exchange thumb (bx).  */                gen_movl_T0_reg(s, rm);                gen_bx(s);            } else if (op1 == 3) {                /* clz */                rd = (insn >> 12) & 0xf;                gen_movl_T0_reg(s, rm);                gen_op_clz_T0();                gen_movl_reg_T0(s, rd);            } else {                goto illegal_op;            }            break;        case 0x2:            if (op1 == 1) {                ARCH(5J); /* bxj */                /* Trivial implementation equivalent to bx.  */                gen_movl_T0_reg(s, rm);                gen_bx(s);            } else {                goto illegal_op;            }            break;        case 0x3:            if (op1 != 1)              goto illegal_op;            /* branch link/exchange thumb (blx) */            val = (uint32_t)s->pc;            gen_op_movl_T0_im(val);            gen_movl_reg_T0(s, 14);            gen_movl_T0_reg(s, rm);            gen_bx(s);            break;        case 0x5: /* saturating add/subtract */            rd = (insn >> 12) & 0xf;            rn = (insn >> 16) & 0xf;            gen_movl_T0_reg(s, rm);            gen_movl_T1_reg(s, rn);            if (op1 & 2)                gen_op_double_T1_saturate();            if (op1 & 1)                gen_op_subl_T0_T1_saturate();            else                gen_op_addl_T0_T1_saturate();            gen_movl_reg_T0(s, rd);            break;        case 7: /* bkpt */            gen_op_movl_T0_im((long)s->pc - 4);            gen_op_movl_reg_TN[0][15]();            gen_op_bkpt();            s->is_jmp = DISAS_JUMP;            break;        case 0x8: /* signed multiply */        case 0xa:        case 0xc:        case 0xe:            rs = (insn >> 8) & 0xf;            rn = (insn >> 12) & 0xf;            rd = (insn >> 16) & 0xf;            if (op1 == 1) {                /* (32 * 16) >> 16 */                gen_movl_T0_reg(s, rm);                gen_movl_T1_reg(s, rs);                if (sh & 4)                    gen_op_sarl_T1_im(16);                else                    gen_op_sxth_T1();                gen_op_imulw_T0_T1();                if ((sh & 2) == 0) {                    gen_movl_T1_reg(s, rn);                    gen_op_addl_T0_T1_setq();                }                gen_movl_reg_T0(s, rd);            } else {                /* 16 * 16 */                gen_movl_T0_reg(s, rm);                gen_movl_T1_reg(s, rs);                gen_mulxy(sh & 2, sh & 4);                if (op1 == 2) {                    gen_op_signbit_T1_T0();                    gen_op_addq_T0_T1(rn, rd);                    gen_movl_reg_T0(s, rn);                    gen_movl_reg_T1(s, rd);                } else {                    if (op1 == 0) {                        gen_movl_T1_reg(s, rn);                        gen_op_addl_T0_T1_setq();                    }                    gen_movl_reg_T0(s, rd);                }            }            break;        default:            goto illegal_op;        }    } else if (((insn & 0x0e000000) == 0 &&                (insn & 0x00000090) != 0x90) ||               ((insn & 0x0e000000) == (1 << 25))) {        int set_cc, logic_cc, shiftop;                op1 = (insn >> 21) & 0xf;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -