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

📄 translate.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 5 页
字号:
        gen_op_jmp_nz32(tmp, l1);        break;    case 6: /* NE (!Z) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));        gen_op_jmp_z32(tmp, l1);        break;    case 7: /* EQ (Z) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));        gen_op_jmp_nz32(tmp, l1);        break;    case 8: /* VC (!V) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));        gen_op_jmp_z32(tmp, l1);        break;    case 9: /* VS (V) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));        gen_op_jmp_nz32(tmp, l1);        break;    case 10: /* PL (!N) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));        gen_op_jmp_z32(tmp, l1);        break;    case 11: /* MI (N) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_N));        gen_op_jmp_nz32(tmp, l1);        break;    case 12: /* GE (!(N ^ V)) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));        gen_op_xor32(tmp, tmp, QREG_CC_DEST);        gen_op_and32(tmp, tmp, gen_im32(CCF_V));        gen_op_jmp_z32(tmp, l1);        break;    case 13: /* LT (N ^ V) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));        gen_op_xor32(tmp, tmp, QREG_CC_DEST);        gen_op_and32(tmp, tmp, gen_im32(CCF_V));        gen_op_jmp_nz32(tmp, l1);        break;    case 14: /* GT (!(Z || (N ^ V))) */        {            int l2;            l2 = gen_new_label();            tmp = gen_new_qreg(QMODE_I32);            gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));            gen_op_jmp_nz32(tmp, l2);            tmp = gen_new_qreg(QMODE_I32);            gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));            gen_op_xor32(tmp, tmp, QREG_CC_DEST);            gen_op_and32(tmp, tmp, gen_im32(CCF_V));            gen_op_jmp_nz32(tmp, l2);            gen_op_jmp(l1);            gen_set_label(l2);        }        break;    case 15: /* LE (Z || (N ^ V)) */        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_Z));        gen_op_jmp_nz32(tmp, l1);        tmp = gen_new_qreg(QMODE_I32);        gen_op_shr32(tmp, QREG_CC_DEST, gen_im32(2));        gen_op_xor32(tmp, tmp, QREG_CC_DEST);        gen_op_and32(tmp, tmp, gen_im32(CCF_V));        gen_op_jmp_nz32(tmp, l1);        break;    default:        /* Should ever happen.  */        abort();    }}DISAS_INSN(scc){    int l1;    int cond;    int reg;    l1 = gen_new_label();    cond = (insn >> 8) & 0xf;    reg = DREG(insn, 0);    gen_op_and32(reg, reg, gen_im32(0xffffff00));    gen_jmpcc(s, cond ^ 1, l1);    gen_op_or32(reg, reg, gen_im32(0xff));    gen_set_label(l1);}/* Generate a jump to to the address in qreg DEST.  */static void gen_jmp(DisasContext *s, int dest){    gen_flush_cc_op(s);    gen_op_mov32(QREG_PC, dest);    s->is_jmp = DISAS_JUMP;}static void gen_exception(DisasContext *s, uint32_t where, int nr){    gen_flush_cc_op(s);    gen_jmp(s, gen_im32(where));    gen_op_raise_exception(nr);}/* Generate a jump to an immediate address.  */static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest){    TranslationBlock *tb;    tb = s->tb;    if (__builtin_expect (s->singlestep_enabled, 0)) {        gen_exception(s, dest, EXCP_DEBUG);    } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||               (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {        gen_op_goto_tb(0, n, (long)tb);        gen_op_mov32(QREG_PC, gen_im32(dest));        gen_op_mov32(QREG_T0, gen_im32((long)tb + n));        gen_op_exit_tb();    } else {        gen_jmp(s, gen_im32(dest));        gen_op_mov32(QREG_T0, gen_im32(0));        gen_op_exit_tb();    }    s->is_jmp = DISAS_TB_JUMP;}DISAS_INSN(undef_mac){    gen_exception(s, s->pc - 2, EXCP_LINEA);}DISAS_INSN(undef_fpu){    gen_exception(s, s->pc - 2, EXCP_LINEF);}DISAS_INSN(undef){    gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);    cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",              insn, s->pc - 2);}DISAS_INSN(mulw){    int reg;    int tmp;    int src;    int sign;    sign = (insn & 0x100) != 0;    reg = DREG(insn, 9);    tmp = gen_new_qreg(QMODE_I32);    if (sign)        gen_op_ext16s32(tmp, reg);    else        gen_op_ext16u32(tmp, reg);    src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);    gen_op_mul32(tmp, tmp, src);    gen_op_mov32(reg, tmp);    /* Unlike m68k, coldfire always clears the overflow bit.  */    gen_logic_cc(s, tmp);}DISAS_INSN(divw){    int reg;    int tmp;    int src;    int sign;    sign = (insn & 0x100) != 0;    reg = DREG(insn, 9);    if (sign) {        gen_op_ext16s32(QREG_DIV1, reg);    } else {        gen_op_ext16u32(QREG_DIV1, reg);    }    src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL);    gen_op_mov32(QREG_DIV2, src);    if (sign) {        gen_op_divs(1);    } else {        gen_op_divu(1);    }    tmp = gen_new_qreg(QMODE_I32);    src = gen_new_qreg(QMODE_I32);    gen_op_ext16u32(tmp, QREG_DIV1);    gen_op_shl32(src, QREG_DIV2, gen_im32(16));    gen_op_or32(reg, tmp, src);    gen_op_flags_set();    s->cc_op = CC_OP_FLAGS;}DISAS_INSN(divl){    int num;    int den;    int reg;    uint16_t ext;    ext = lduw(s->pc);    s->pc += 2;    if (ext & 0x87f8) {        gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);        return;    }    num = DREG(ext, 12);    reg = DREG(ext, 0);    gen_op_mov32(QREG_DIV1, num);    den = gen_ea(s, insn, OS_LONG, 0, NULL);    gen_op_mov32(QREG_DIV2, den);    if (ext & 0x0800) {        gen_op_divs(2);    } else {        gen_op_divu(2);    }    if (num == reg) {        /* div */        gen_op_mov32 (reg, QREG_DIV1);    } else {        /* rem */        gen_op_mov32 (reg, QREG_DIV2);    }    gen_op_flags_set();    s->cc_op = CC_OP_FLAGS;}DISAS_INSN(addsub){    int reg;    int dest;    int src;    int tmp;    int addr;    int add;    add = (insn & 0x4000) != 0;    reg = DREG(insn, 9);    dest = gen_new_qreg(QMODE_I32);    if (insn & 0x100) {        tmp = gen_ea(s, insn, OS_LONG, 0, &addr);        src = reg;    } else {        tmp = reg;        src = gen_ea(s, insn, OS_LONG, 0, NULL);    }    if (add) {        gen_op_add32(dest, tmp, src);        gen_op_update_xflag_lt(dest, src);        s->cc_op = CC_OP_ADD;    } else {        gen_op_update_xflag_lt(tmp, src);        gen_op_sub32(dest, tmp, src);        s->cc_op = CC_OP_SUB;    }    gen_op_update_cc_add(dest, src);    if (insn & 0x100) {        gen_ea(s, insn, OS_LONG, dest, &addr);    } else {        gen_op_mov32(reg, dest);    }}/* Reverse the order of the bits in REG.  */DISAS_INSN(bitrev){    int val;    int tmp1;    int tmp2;    int reg;    val = gen_new_qreg(QMODE_I32);    tmp1 = gen_new_qreg(QMODE_I32);    tmp2 = gen_new_qreg(QMODE_I32);    reg = DREG(insn, 0);    gen_op_mov32(val, reg);    /* Reverse bits within each nibble.  */    gen_op_shl32(tmp1, val, gen_im32(3));    gen_op_and32(tmp1, tmp1, gen_im32(0x88888888));    gen_op_shl32(tmp2, val, gen_im32(1));    gen_op_and32(tmp2, tmp2, gen_im32(0x44444444));    gen_op_or32(tmp1, tmp1, tmp2);    gen_op_shr32(tmp2, val, gen_im32(1));    gen_op_and32(tmp2, tmp2, gen_im32(0x22222222));    gen_op_or32(tmp1, tmp1, tmp2);    gen_op_shr32(tmp2, val, gen_im32(3));    gen_op_and32(tmp2, tmp2, gen_im32(0x11111111));    gen_op_or32(tmp1, tmp1, tmp2);    /* Reverse nibbles withing bytes.  */    gen_op_shl32(val, tmp1, gen_im32(4));    gen_op_and32(val, val, gen_im32(0xf0f0f0f0));    gen_op_shr32(tmp2, tmp1, gen_im32(4));    gen_op_and32(tmp2, tmp2, gen_im32(0x0f0f0f0f));    gen_op_or32(val, val, tmp2);    /* Reverse bytes.  */    gen_op_bswap32(reg, val);    gen_op_mov32(reg, val);}DISAS_INSN(bitop_reg){    int opsize;    int op;    int src1;    int src2;    int tmp;    int addr;    int dest;    if ((insn & 0x38) != 0)        opsize = OS_BYTE;    else        opsize = OS_LONG;    op = (insn >> 6) & 3;    src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);    src2 = DREG(insn, 9);    dest = gen_new_qreg(QMODE_I32);    gen_flush_flags(s);    tmp = gen_new_qreg(QMODE_I32);    if (opsize == OS_BYTE)        gen_op_and32(tmp, src2, gen_im32(7));    else        gen_op_and32(tmp, src2, gen_im32(31));    src2 = tmp;    tmp = gen_new_qreg(QMODE_I32);    gen_op_shl32(tmp, gen_im32(1), src2);    gen_op_btest(src1, tmp);    switch (op) {    case 1: /* bchg */        gen_op_xor32(dest, src1, tmp);        break;    case 2: /* bclr */        gen_op_not32(tmp, tmp);        gen_op_and32(dest, src1, tmp);        break;    case 3: /* bset */        gen_op_or32(dest, src1, tmp);        break;    default: /* btst */        break;    }    if (op)        gen_ea(s, insn, opsize, dest, &addr);}DISAS_INSN(sats){    int reg;    int tmp;    int l1;    reg = DREG(insn, 0);    tmp = gen_new_qreg(QMODE_I32);    gen_flush_flags(s);    gen_op_and32(tmp, QREG_CC_DEST, gen_im32(CCF_V));    l1 = gen_new_label();    gen_op_jmp_z32(tmp, l1);    tmp = gen_new_qreg(QMODE_I32);    gen_op_shr32(tmp, reg, gen_im32(31));    gen_op_xor32(tmp, tmp, gen_im32(0x80000000));    gen_op_mov32(reg, tmp);    gen_set_label(l1);    gen_logic_cc(s, tmp);}static void gen_push(int val){    int tmp;    tmp = gen_new_qreg(QMODE_I32);    gen_op_sub32(tmp, QREG_SP, gen_im32(4));    gen_store(OS_LONG, tmp, val);    gen_op_mov32(QREG_SP, tmp);}DISAS_INSN(movem){    int addr;    int i;    uint16_t mask;    int reg;    int tmp;    int is_load;    mask = lduw(s->pc);    s->pc += 2;    tmp = gen_lea(s, insn, OS_LONG);    addr = gen_new_qreg(QMODE_I32);    gen_op_mov32(addr, tmp);    is_load = ((insn & 0x0400) != 0);    for (i = 0; i < 16; i++, mask >>= 1) {        if (mask & 1) {            if (i < 8)                reg = DREG(i, 0);            else                reg = AREG(i, 0);            if (is_load) {                tmp = gen_load(OS_LONG, addr, 0);                gen_op_mov32(reg, tmp);            } else {                gen_store(OS_LONG, addr, reg);            }            if (mask != 1)                gen_op_add32(addr, addr, gen_im32(4));        }    }}DISAS_INSN(bitop_im){    int opsize;    int op;    int src1;    uint32_t mask;    int bitnum;    int tmp;    int addr;    int dest;    if ((insn & 0x38) != 0)        opsize = OS_BYTE;    else        opsize = OS_LONG;    op = (insn >> 6) & 3;    bitnum = lduw(s->pc);    s->pc += 2;    if (bitnum & 0xff00) {        disas_undef(s, insn);        return;    }    src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL);    gen_flush_flags(s);    tmp = gen_new_qreg(QMODE_I32);    if (opsize == OS_BYTE)        bitnum &= 7;    else        bitnum &= 31;    mask = 1 << bitnum;    gen_op_btest(src1, gen_im32(mask));    if (op)        dest = gen_new_qreg(QMODE_I32);    else        dest = -1;    switch (op) {    case 1: /* bchg */        gen_op_xor32(dest, src1, gen_im32(mask));        break;    case 2: /* bclr */        gen_op_and32(dest, src1, gen_im32(~mask));        break;    case 3: /* bset */        gen_op_or32(dest, src1, gen_im32(mask));        break;    default: /* btst */        break;    }    if (op)        gen_ea(s, insn, opsize, dest, &addr);}DISAS_INSN(arith_im){    int op;    int src1;    int dest;    int src2;    int addr;    op = (insn >> 9) & 7;    src1 = gen_ea(s, insn, OS_LONG, 0, (op == 6) ? NULL : &addr);    src2 = gen_im32(read_im32(s));    dest = gen_new_qreg(QMODE_I32);    switch (op) {    case 0: /* ori */        gen_op_or32(dest, src1, src2);        gen_logic_cc(s, dest);        break;    case 1: /* andi */        gen_op_and32(dest, src1, src2);        gen_logic_cc(s, dest);        break;    case 2: /* subi */        gen_op_mov32(dest, src1);        gen_op_update_xflag_lt(dest, src2);        gen_op_sub32(dest, dest, src2);        gen_op_update_cc_add(dest, src2);        s->cc_op = CC_OP_SUB;        break;    case 3: /* addi */        gen_op_mov32(dest, src1);        gen_op_add32(dest, dest, src2);        gen_op_update_cc_add(dest, src2);        gen_op_update_xflag_lt(dest, src2);        s->cc_op = CC_OP_ADD;        break;    case 5: /* eori */        gen_op_xor32(dest, src1, src2);        gen_logic_cc(s, dest);        break;    case 6: /* cmpi */        gen_op_mov32(dest, src1);        gen_op_sub32(dest, dest, src2);        gen_op_update_cc_add(dest, src2);        s->cc_op = CC_OP_SUB;        break;    default:        abort();    }    if (op != 6) {        gen_ea(s, insn, OS_LONG, dest, &addr);    }}DISAS_INSN(byterev){    int reg;

⌨️ 快捷键说明

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