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

📄 translate.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                            /* pre increment */                        } else {                            /* post increment */                            gen_op_addl_T1_im(4);                        }                    } else {                        if (insn & (1 << 24)) {                            /* pre decrement */                            if (n != 1)                                gen_op_addl_T1_im(-((n - 1) * 4));                        } else {                            /* post decrement */                            gen_op_addl_T1_im(-(n * 4));                        }                    }                    gen_movl_reg_T1(s, rn);                }                if (loaded_base) {                    gen_op_movl_T0_T2();                    gen_movl_reg_T0(s, rn);                }                if ((insn & (1 << 22)) && !user) {                    /* Restore CPSR from SPSR.  */                    gen_op_movl_T0_spsr();                    gen_op_movl_cpsr_T0(0xffffffff);                    s->is_jmp = DISAS_UPDATE;                }            }            break;        case 0xa:        case 0xb:            {                int32_t offset;                                /* branch (and link) */                val = (int32_t)s->pc;                if (insn & (1 << 24)) {                    gen_op_movl_T0_im(val);                    gen_op_movl_reg_TN[0][14]();                }                offset = (((int32_t)insn << 8) >> 8);                val += (offset << 2) + 4;                gen_jmp(s, val);            }            break;        case 0xc:        case 0xd:        case 0xe:            /* Coprocessor.  */            op1 = (insn >> 8) & 0xf;            switch (op1) {            case 10:            case 11:                if (disas_vfp_insn (env, s, insn))                    goto illegal_op;                break;            case 15:                if (disas_cp15_insn (s, insn))                    goto illegal_op;                break;            default:                /* unknown coprocessor.  */                goto illegal_op;            }            break;        case 0xf:            /* swi */            gen_op_movl_T0_im((long)s->pc);            gen_op_movl_reg_TN[0][15]();            gen_op_swi();            s->is_jmp = DISAS_JUMP;            break;        default:        illegal_op:            gen_op_movl_T0_im((long)s->pc - 4);            gen_op_movl_reg_TN[0][15]();            gen_op_undef_insn();            s->is_jmp = DISAS_JUMP;            break;        }    }}static void disas_thumb_insn(DisasContext *s){    uint32_t val, insn, op, rm, rn, rd, shift, cond;    int32_t offset;    int i;    insn = lduw_code(s->pc);    s->pc += 2;    switch (insn >> 12) {    case 0: case 1:        rd = insn & 7;        op = (insn >> 11) & 3;        if (op == 3) {            /* add/subtract */            rn = (insn >> 3) & 7;            gen_movl_T0_reg(s, rn);            if (insn & (1 << 10)) {                /* immediate */                gen_op_movl_T1_im((insn >> 6) & 7);            } else {                /* reg */                rm = (insn >> 6) & 7;                gen_movl_T1_reg(s, rm);            }            if (insn & (1 << 9))                gen_op_subl_T0_T1_cc();            else                gen_op_addl_T0_T1_cc();            gen_movl_reg_T0(s, rd);        } else {            /* shift immediate */            rm = (insn >> 3) & 7;            shift = (insn >> 6) & 0x1f;            gen_movl_T0_reg(s, rm);            gen_shift_T0_im_thumb[op](shift);            gen_movl_reg_T0(s, rd);        }        break;    case 2: case 3:        /* arithmetic large immediate */        op = (insn >> 11) & 3;        rd = (insn >> 8) & 0x7;        if (op == 0) {            gen_op_movl_T0_im(insn & 0xff);        } else {            gen_movl_T0_reg(s, rd);            gen_op_movl_T1_im(insn & 0xff);        }        switch (op) {        case 0: /* mov */            gen_op_logic_T0_cc();            break;        case 1: /* cmp */            gen_op_subl_T0_T1_cc();            break;        case 2: /* add */            gen_op_addl_T0_T1_cc();            break;        case 3: /* sub */            gen_op_subl_T0_T1_cc();            break;        }        if (op != 1)            gen_movl_reg_T0(s, rd);        break;    case 4:        if (insn & (1 << 11)) {            rd = (insn >> 8) & 7;            /* load pc-relative.  Bit 1 of PC is ignored.  */            val = s->pc + 2 + ((insn & 0xff) * 4);            val &= ~(uint32_t)2;            gen_op_movl_T1_im(val);            gen_ldst(ldl, s);            gen_movl_reg_T0(s, rd);            break;        }        if (insn & (1 << 10)) {            /* data processing extended or blx */            rd = (insn & 7) | ((insn >> 4) & 8);            rm = (insn >> 3) & 0xf;            op = (insn >> 8) & 3;            switch (op) {            case 0: /* add */                gen_movl_T0_reg(s, rd);                gen_movl_T1_reg(s, rm);                gen_op_addl_T0_T1();                gen_movl_reg_T0(s, rd);                break;            case 1: /* cmp */                gen_movl_T0_reg(s, rd);                gen_movl_T1_reg(s, rm);                gen_op_subl_T0_T1_cc();                break;            case 2: /* mov/cpy */                gen_movl_T0_reg(s, rm);                gen_movl_reg_T0(s, rd);                break;            case 3:/* branch [and link] exchange thumb register */                if (insn & (1 << 7)) {                    val = (uint32_t)s->pc | 1;                    gen_op_movl_T1_im(val);                    gen_movl_reg_T1(s, 14);                }                gen_movl_T0_reg(s, rm);                gen_bx(s);                break;            }            break;        }        /* data processing register */        rd = insn & 7;        rm = (insn >> 3) & 7;        op = (insn >> 6) & 0xf;        if (op == 2 || op == 3 || op == 4 || op == 7) {            /* the shift/rotate ops want the operands backwards */            val = rm;            rm = rd;            rd = val;            val = 1;        } else {            val = 0;        }        if (op == 9) /* neg */            gen_op_movl_T0_im(0);        else if (op != 0xf) /* mvn doesn't read its first operand */            gen_movl_T0_reg(s, rd);        gen_movl_T1_reg(s, rm);        switch (op) {        case 0x0: /* and */            gen_op_andl_T0_T1();            gen_op_logic_T0_cc();            break;        case 0x1: /* eor */            gen_op_xorl_T0_T1();            gen_op_logic_T0_cc();            break;        case 0x2: /* lsl */            gen_op_shll_T1_T0_cc();            gen_op_logic_T1_cc();            break;        case 0x3: /* lsr */            gen_op_shrl_T1_T0_cc();            gen_op_logic_T1_cc();            break;        case 0x4: /* asr */            gen_op_sarl_T1_T0_cc();            gen_op_logic_T1_cc();            break;        case 0x5: /* adc */            gen_op_adcl_T0_T1_cc();            break;        case 0x6: /* sbc */            gen_op_sbcl_T0_T1_cc();            break;        case 0x7: /* ror */            gen_op_rorl_T1_T0_cc();            gen_op_logic_T1_cc();            break;        case 0x8: /* tst */            gen_op_andl_T0_T1();            gen_op_logic_T0_cc();            rd = 16;            break;        case 0x9: /* neg */            gen_op_subl_T0_T1_cc();            break;        case 0xa: /* cmp */            gen_op_subl_T0_T1_cc();            rd = 16;            break;        case 0xb: /* cmn */            gen_op_addl_T0_T1_cc();            rd = 16;            break;        case 0xc: /* orr */            gen_op_orl_T0_T1();            gen_op_logic_T0_cc();            break;        case 0xd: /* mul */            gen_op_mull_T0_T1();            gen_op_logic_T0_cc();            break;        case 0xe: /* bic */            gen_op_bicl_T0_T1();            gen_op_logic_T0_cc();            break;        case 0xf: /* mvn */            gen_op_notl_T1();            gen_op_logic_T1_cc();            val = 1;            rm = rd;            break;        }        if (rd != 16) {            if (val)                gen_movl_reg_T1(s, rm);            else                gen_movl_reg_T0(s, rd);        }        break;    case 5:        /* load/store register offset.  */        rd = insn & 7;        rn = (insn >> 3) & 7;        rm = (insn >> 6) & 7;        op = (insn >> 9) & 7;        gen_movl_T1_reg(s, rn);        gen_movl_T2_reg(s, rm);        gen_op_addl_T1_T2();        if (op < 3) /* store */            gen_movl_T0_reg(s, rd);        switch (op) {        case 0: /* str */            gen_ldst(stl, s);            break;        case 1: /* strh */            gen_ldst(stw, s);            break;        case 2: /* strb */            gen_ldst(stb, s);            break;        case 3: /* ldrsb */            gen_ldst(ldsb, s);            break;        case 4: /* ldr */            gen_ldst(ldl, s);            break;        case 5: /* ldrh */            gen_ldst(lduw, s);            break;        case 6: /* ldrb */            gen_ldst(ldub, s);            break;        case 7: /* ldrsh */            gen_ldst(ldsw, s);            break;        }        if (op >= 3) /* load */            gen_movl_reg_T0(s, rd);        break;    case 6:        /* load/store word immediate offset */        rd = insn & 7;        rn = (insn >> 3) & 7;        gen_movl_T1_reg(s, rn);        val = (insn >> 4) & 0x7c;        gen_op_movl_T2_im(val);        gen_op_addl_T1_T2();        if (insn & (1 << 11)) {            /* load */            gen_ldst(ldl, s);            gen_movl_reg_T0(s, rd);        } else {            /* store */            gen_movl_T0_reg(s, rd);            gen_ldst(stl, s);        }        break;    case 7:        /* load/store byte immediate offset */        rd = insn & 7;        rn = (insn >> 3) & 7;        gen_movl_T1_reg(s, rn);        val = (insn >> 6) & 0x1f;        gen_op_movl_T2_im(val);        gen_op_addl_T1_T2();        if (insn & (1 << 11)) {            /* load */            gen_ldst(ldub, s);            gen_movl_reg_T0(s, rd);        } else {            /* store */            gen_movl_T0_reg(s, rd);            gen_ldst(stb, s);        }        break;    case 8:        /* load/store halfword immediate offset */        rd = insn & 7;        rn = (insn >> 3) & 7;        gen_movl_T1_reg(s, rn);        val = (insn >> 5) & 0x3e;        gen_op_movl_T2_im(val);        gen_op_addl_T1_T2();        if (insn & (1 << 11)) {            /* load */            gen_ldst(lduw, s);            gen_movl_reg_T0(s, rd);        } else {            /* store */            gen_movl_T0_reg(s, rd);            gen_ldst(stw, s);        }        break;    case 9:        /* load/store from stack */        rd = (insn >> 8) & 7;        gen_movl_T1_reg(s, 13);        val = (insn & 0xff) * 4;        gen_op_movl_T2_im(val);        gen_op_addl_T1_T2();        if (insn & (1 << 11)) {            /* load */            gen_ldst(ldl, s);            gen_movl_reg_T0(s, rd);        } else {            /* store */            gen_movl_T0_reg(s, rd);            gen_ldst(stl, s);        }        break;    case 10:        /* add to high reg */        rd = (insn >> 8) & 7;        if (insn & (1 << 11)) {            /* SP */            gen_movl_T0_reg(s, 13);        } else {            /* PC. bit 1 is ignored.  */            gen_op_movl_T0_im((s->pc + 2) & ~(uint32_t)2);        }        val = (insn & 0xff) * 4;        gen_op_movl_T1_im(val);        gen_op_addl_T0_T1();        gen_movl_reg_T0(s, rd);        break;    case 11:        /* misc */        op = (insn >> 8) & 0xf;        switch (op) {        case 0:            /* adjust stack pointer */            gen_movl_T1_reg(s, 13

⌨️ 快捷键说明

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