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

📄 translate.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 5 页
字号:
    reg = DREG(insn, 0);    gen_op_bswap32(reg, reg);}DISAS_INSN(move){    int src;    int dest;    int op;    int opsize;    switch (insn >> 12) {    case 1: /* move.b */        opsize = OS_BYTE;        break;    case 2: /* move.l */        opsize = OS_LONG;        break;    case 3: /* move.w */        opsize = OS_WORD;        break;    default:        abort();    }    src = gen_ea(s, insn, opsize, -1, NULL);    op = (insn >> 6) & 7;    if (op == 1) {        /* movea */        /* The value will already have been sign extended.  */        dest = AREG(insn, 9);        gen_op_mov32(dest, src);    } else {        /* normal move */        uint16_t dest_ea;        dest_ea = ((insn >> 9) & 7) | (op << 3);        gen_ea(s, dest_ea, opsize, src, NULL);        /* This will be correct because loads sign extend.  */        gen_logic_cc(s, src);    }}DISAS_INSN(negx){    int reg;    int dest;    int tmp;    gen_flush_flags(s);    reg = DREG(insn, 0);    dest = gen_new_qreg(QMODE_I32);    gen_op_mov32 (dest, gen_im32(0));    gen_op_subx_cc(dest, reg);    /* !Z is sticky.  */    tmp = gen_new_qreg(QMODE_I32);    gen_op_mov32 (tmp, QREG_CC_DEST);    gen_op_update_cc_add(dest, reg);    gen_op_mov32(reg, dest);    s->cc_op = CC_OP_DYNAMIC;    gen_flush_flags(s);    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);    s->cc_op = CC_OP_FLAGS;}DISAS_INSN(lea){    int reg;    int tmp;    reg = AREG(insn, 9);    tmp = gen_lea(s, insn, OS_LONG);    gen_op_mov32(reg, tmp);}DISAS_INSN(clr){    int opsize;    switch ((insn >> 6) & 3) {    case 0: /* clr.b */        opsize = OS_BYTE;        break;    case 1: /* clr.w */        opsize = OS_WORD;        break;    case 2: /* clr.l */        opsize = OS_LONG;        break;    default:        abort();    }    gen_ea (s, insn, opsize, gen_im32(0), NULL);    gen_logic_cc(s, gen_im32(0));}DISAS_INSN(move_from_ccr){    int reg;    int dest;    gen_flush_flags(s);    dest = gen_new_qreg(QMODE_I32);    gen_op_get_xflag(dest);    gen_op_shl32(dest, dest, gen_im32(4));    gen_op_or32(dest, dest, QREG_CC_DEST);    reg = DREG(insn, 0);    gen_partset_reg(OS_WORD, reg, dest);}DISAS_INSN(neg){    int reg;    int src1;    reg = DREG(insn, 0);    src1 = gen_new_qreg(QMODE_I32);    gen_op_mov32(src1, reg);    gen_op_neg32(reg, src1);    s->cc_op = CC_OP_SUB;    gen_op_update_cc_add(reg, src1);    gen_op_update_xflag_lt(gen_im32(0), src1);    s->cc_op = CC_OP_SUB;}DISAS_INSN(move_to_ccr){    int src1;    int reg;    s->cc_op = CC_OP_FLAGS;    if ((insn & 0x38) == 0)      {        src1 = gen_new_qreg(QMODE_I32);        reg = DREG(insn, 0);        gen_op_and32(src1, reg, gen_im32(0xf));        gen_op_logic_cc(src1);        gen_op_shr32(src1, reg, gen_im32(4));        gen_op_and32(src1, src1, gen_im32(1));        gen_op_update_xflag_tst(src1);      }    else if ((insn & 0x3f) != 0x3c)      {        uint8_t val;        val = ldsb(s->pc);        s->pc += 2;        gen_op_logic_cc(gen_im32(val & 0xf));        gen_op_update_xflag_tst(gen_im32((val & 0x10) >> 4));      }    else        disas_undef(s, insn);}DISAS_INSN(not){    int reg;    reg = DREG(insn, 0);    gen_op_not32(reg, reg);    gen_logic_cc(s, reg);}DISAS_INSN(swap){    int dest;    int src1;    int src2;    int reg;    dest = gen_new_qreg(QMODE_I32);    src1 = gen_new_qreg(QMODE_I32);    src2 = gen_new_qreg(QMODE_I32);    reg = DREG(insn, 0);    gen_op_shl32(src1, reg, gen_im32(16));    gen_op_shr32(src2, reg, gen_im32(16));    gen_op_or32(dest, src1, src2);    gen_op_mov32(reg, dest);    gen_logic_cc(s, dest);}DISAS_INSN(pea){    int tmp;    tmp = gen_lea(s, insn, OS_LONG);    gen_push(tmp);}DISAS_INSN(ext){    int reg;    int op;    int tmp;    reg = DREG(insn, 0);    op = (insn >> 6) & 7;    tmp = gen_new_qreg(QMODE_I32);    if (op == 3)        gen_op_ext16s32(tmp, reg);    else        gen_op_ext8s32(tmp, reg);    if (op == 2)        gen_partset_reg(OS_WORD, reg, tmp);    else      gen_op_mov32(reg, tmp);    gen_logic_cc(s, tmp);}DISAS_INSN(tst){    int opsize;    int tmp;    switch ((insn >> 6) & 3) {    case 0: /* tst.b */        opsize = OS_BYTE;        break;    case 1: /* tst.w */        opsize = OS_WORD;        break;    case 2: /* tst.l */        opsize = OS_LONG;        break;    default:        abort();    }    tmp = gen_ea(s, insn, opsize, -1, NULL);    gen_logic_cc(s, tmp);}DISAS_INSN(pulse){  /* Implemented as a NOP.  */}DISAS_INSN(illegal){    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);}/* ??? This should be atomic.  */DISAS_INSN(tas){    int dest;    int src1;    int addr;    dest = gen_new_qreg(QMODE_I32);    src1 = gen_ea(s, insn, OS_BYTE, -1, &addr);    gen_logic_cc(s, src1);    gen_op_or32(dest, src1, gen_im32(0x80));    gen_ea(s, insn, OS_BYTE, dest, &addr);}DISAS_INSN(mull){    uint16_t ext;    int reg;    int src1;    int dest;    /* The upper 32 bits of the product are discarded, so       muls.l and mulu.l are functionally equivalent.  */    ext = lduw(s->pc);    s->pc += 2;    if (ext & 0x87ff) {        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);        return;    }    reg = DREG(ext, 12);    src1 = gen_ea(s, insn, OS_LONG, 0, NULL);    dest = gen_new_qreg(QMODE_I32);    gen_op_mul32(dest, src1, reg);    gen_op_mov32(reg, dest);    /* Unlike m68k, coldfire always clears the overflow bit.  */    gen_logic_cc(s, dest);}DISAS_INSN(link){    int16_t offset;    int reg;    int tmp;    offset = ldsw(s->pc);    s->pc += 2;    reg = AREG(insn, 0);    tmp = gen_new_qreg(QMODE_I32);    gen_op_sub32(tmp, QREG_SP, gen_im32(4));    gen_store(OS_LONG, tmp, reg);    if (reg != QREG_SP)        gen_op_mov32(reg, tmp);    gen_op_add32(QREG_SP, tmp, gen_im32(offset));}DISAS_INSN(unlk){    int src;    int reg;    int tmp;    src = gen_new_qreg(QMODE_I32);    reg = AREG(insn, 0);    gen_op_mov32(src, reg);    tmp = gen_load(OS_LONG, src, 0);    gen_op_mov32(reg, tmp);    gen_op_add32(QREG_SP, src, gen_im32(4));}DISAS_INSN(nop){}DISAS_INSN(rts){    int tmp;    tmp = gen_load(OS_LONG, QREG_SP, 0);    gen_op_add32(QREG_SP, QREG_SP, gen_im32(4));    gen_jmp(s, tmp);}DISAS_INSN(jump){    int tmp;    /* Load the target address first to ensure correct exception       behavior.  */    tmp = gen_lea(s, insn, OS_LONG);    if ((insn & 0x40) == 0) {        /* jsr */        gen_push(gen_im32(s->pc));    }    gen_jmp(s, tmp);}DISAS_INSN(addsubq){    int src1;    int src2;    int dest;    int val;    int addr;    src1 = gen_ea(s, insn, OS_LONG, 0, &addr);    val = (insn >> 9) & 7;    if (val == 0)        val = 8;    src2 = gen_im32(val);    dest = gen_new_qreg(QMODE_I32);    gen_op_mov32(dest, src1);    if ((insn & 0x38) == 0x08) {        /* Don't update condition codes if the destination is an           address register.  */        if (insn & 0x0100) {            gen_op_sub32(dest, dest, src2);        } else {            gen_op_add32(dest, dest, src2);        }    } else {        if (insn & 0x0100) {            gen_op_update_xflag_lt(dest, src2);            gen_op_sub32(dest, dest, src2);            s->cc_op = CC_OP_SUB;        } else {            gen_op_add32(dest, dest, src2);            gen_op_update_xflag_lt(dest, src2);            s->cc_op = CC_OP_ADD;        }        gen_op_update_cc_add(dest, src2);    }    gen_ea(s, insn, OS_LONG, dest, &addr);}DISAS_INSN(tpf){    switch (insn & 7) {    case 2: /* One extension word.  */        s->pc += 2;        break;    case 3: /* Two extension words.  */        s->pc += 4;        break;    case 4: /* No extension words.  */        break;    default:        disas_undef(s, insn);    }}DISAS_INSN(branch){    int32_t offset;    uint32_t base;    int op;    int l1;        base = s->pc;    op = (insn >> 8) & 0xf;    offset = (int8_t)insn;    if (offset == 0) {        offset = ldsw(s->pc);        s->pc += 2;    } else if (offset == -1) {        offset = read_im32(s);    }    if (op == 1) {        /* bsr */        gen_push(gen_im32(s->pc));    }    gen_flush_cc_op(s);    if (op > 1) {        /* Bcc */        l1 = gen_new_label();        gen_jmpcc(s, ((insn >> 8) & 0xf) ^ 1, l1);        gen_jmp_tb(s, 1, base + offset);        gen_set_label(l1);        gen_jmp_tb(s, 0, s->pc);    } else {        /* Unconditional branch.  */        gen_jmp_tb(s, 0, base + offset);    }}DISAS_INSN(moveq){    int tmp;    tmp = gen_im32((int8_t)insn);    gen_op_mov32(DREG(insn, 9), tmp);    gen_logic_cc(s, tmp);}DISAS_INSN(mvzs){    int opsize;    int src;    int reg;    if (insn & 0x40)        opsize = OS_WORD;    else        opsize = OS_BYTE;    src = gen_ea(s, insn, opsize, (insn & 0x80) ? 0 : -1, NULL);    reg = DREG(insn, 9);    gen_op_mov32(reg, src);    gen_logic_cc(s, src);}DISAS_INSN(or){    int reg;    int dest;    int src;    int addr;    reg = DREG(insn, 9);    dest = gen_new_qreg(QMODE_I32);    if (insn & 0x100) {        src = gen_ea(s, insn, OS_LONG, 0, &addr);        gen_op_or32(dest, src, reg);        gen_ea(s, insn, OS_LONG, dest, &addr);    } else {        src = gen_ea(s, insn, OS_LONG, 0, NULL);        gen_op_or32(dest, src, reg);        gen_op_mov32(reg, dest);    }    gen_logic_cc(s, dest);}DISAS_INSN(suba){    int src;    int reg;    src = gen_ea(s, insn, OS_LONG, 0, NULL);    reg = AREG(insn, 9);    gen_op_sub32(reg, reg, src);}DISAS_INSN(subx){    int reg;    int src;    int dest;    int tmp;    gen_flush_flags(s);    reg = DREG(insn, 9);    src = DREG(insn, 0);    dest = gen_new_qreg(QMODE_I32);    gen_op_mov32 (dest, reg);    gen_op_subx_cc(dest, src);    /* !Z is sticky.  */    tmp = gen_new_qreg(QMODE_I32);    gen_op_mov32 (tmp, QREG_CC_DEST);    gen_op_update_cc_add(dest, src);    gen_op_mov32(reg, dest);    s->cc_op = CC_OP_DYNAMIC;    gen_flush_flags(s);    gen_op_or32(tmp, tmp, gen_im32(~CCF_Z));    gen_op_and32(QREG_CC_DEST, QREG_CC_DEST, tmp);    s->cc_op = CC_OP_FLAGS;}DISAS_INSN(mov3q){    int src;    int val;    val = (insn >> 9) & 7;    if (val == 0)        val = -1;    src = gen_im32(val);    gen_logic_cc(s, src);    gen_ea(s, insn, OS_LONG, src, NULL);}DISAS_INSN(cmp){    int op;    int src;    int reg;    int dest;    int opsize;    op = (insn >> 6) & 3;    switch (op) {    case 0: /* cmp.b */        opsize = OS_BYTE;        s->cc_op = CC_OP_CMPB;        break;

⌨️ 快捷键说明

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