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

📄 translate.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 5 页
字号:
    case 1: /* cmp.w */        opsize = OS_WORD;        s->cc_op = CC_OP_CMPW;        break;    case 2: /* cmp.l */        opsize = OS_LONG;        s->cc_op = CC_OP_SUB;        break;    default:        abort();    }    src = gen_ea(s, insn, opsize, -1, NULL);    reg = DREG(insn, 9);    dest = gen_new_qreg(QMODE_I32);    gen_op_sub32(dest, reg, src);    gen_op_update_cc_add(dest, src);}DISAS_INSN(cmpa){    int opsize;    int src;    int reg;    int dest;    if (insn & 0x100) {        opsize = OS_LONG;    } else {        opsize = OS_WORD;    }    src = gen_ea(s, insn, opsize, -1, NULL);    reg = AREG(insn, 9);    dest = gen_new_qreg(QMODE_I32);    gen_op_sub32(dest, reg, src);    gen_op_update_cc_add(dest, src);    s->cc_op = CC_OP_SUB;}DISAS_INSN(eor){    int src;    int reg;    int dest;    int addr;    src = gen_ea(s, insn, OS_LONG, 0, &addr);    reg = DREG(insn, 9);    dest = gen_new_qreg(QMODE_I32);    gen_op_xor32(dest, src, reg);    gen_logic_cc(s, dest);    gen_ea(s, insn, OS_LONG, dest, &addr);}DISAS_INSN(and){    int src;    int reg;    int dest;    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_and32(dest, src, reg);        gen_ea(s, insn, OS_LONG, dest, &addr);    } else {        src = gen_ea(s, insn, OS_LONG, 0, NULL);        gen_op_and32(dest, src, reg);        gen_op_mov32(reg, dest);    }    gen_logic_cc(s, dest);}DISAS_INSN(adda){    int src;    int reg;    src = gen_ea(s, insn, OS_LONG, 0, NULL);    reg = AREG(insn, 9);    gen_op_add32(reg, reg, src);}DISAS_INSN(addx){    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_addx_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(shift_im){    int reg;    int tmp;    reg = DREG(insn, 0);    tmp = (insn >> 9) & 7;    if (tmp == 0)      tmp = 8;    if (insn & 0x100) {        gen_op_shl_im_cc(reg, tmp);        s->cc_op = CC_OP_SHL;    } else {        if (insn & 8) {            gen_op_shr_im_cc(reg, tmp);            s->cc_op = CC_OP_SHR;        } else {            gen_op_sar_im_cc(reg, tmp);            s->cc_op = CC_OP_SAR;        }    }}DISAS_INSN(shift_reg){    int reg;    int src;    int tmp;    reg = DREG(insn, 0);    src = DREG(insn, 9);    tmp = gen_new_qreg(QMODE_I32);    gen_op_and32(tmp, src, gen_im32(63));    if (insn & 0x100) {        gen_op_shl_cc(reg, tmp);        s->cc_op = CC_OP_SHL;    } else {        if (insn & 8) {            gen_op_shr_cc(reg, tmp);            s->cc_op = CC_OP_SHR;        } else {            gen_op_sar_cc(reg, tmp);            s->cc_op = CC_OP_SAR;        }    }}DISAS_INSN(ff1){    cpu_abort(NULL, "Unimplemented insn: ff1");}DISAS_INSN(strldsr){    uint16_t ext;    uint32_t addr;    addr = s->pc - 2;    ext = lduw(s->pc);    s->pc += 2;    if (ext != 0x46FC)        gen_exception(s, addr, EXCP_UNSUPPORTED);    else        gen_exception(s, addr, EXCP_PRIVILEGE);}DISAS_INSN(move_from_sr){    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(move_to_sr){    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(move_from_usp){    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(move_to_usp){    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(halt){    gen_exception(s, s->pc, EXCP_HLT);}DISAS_INSN(stop){    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(rte){    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(movec){    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(intouch){    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(cpushl){    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(wddata){    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(wdebug){    gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);}DISAS_INSN(trap){    gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf));}/* ??? FP exceptions are not implemented.  Most exceptions are deferred until   immediately before the next FP instruction is executed.  */DISAS_INSN(fpu){    uint16_t ext;    int opmode;    int src;    int dest;    int res;    int round;    int opsize;    ext = lduw(s->pc);    s->pc += 2;    opmode = ext & 0x7f;    switch ((ext >> 13) & 7) {    case 0: case 2:        break;    case 1:        goto undef;    case 3: /* fmove out */        src = FREG(ext, 7);        /* fmove */        /* ??? TODO: Proper behavior on overflow.  */        switch ((ext >> 10) & 7) {        case 0:            opsize = OS_LONG;            res = gen_new_qreg(QMODE_I32);            gen_op_f64_to_i32(res, src);            break;        case 1:            opsize = OS_SINGLE;            res = gen_new_qreg(QMODE_F32);            gen_op_f64_to_f32(res, src);            break;        case 4:            opsize = OS_WORD;            res = gen_new_qreg(QMODE_I32);            gen_op_f64_to_i32(res, src);            break;        case 5:            opsize = OS_DOUBLE;            res = src;            break;        case 6:            opsize = OS_BYTE;            res = gen_new_qreg(QMODE_I32);            gen_op_f64_to_i32(res, src);            break;        default:            goto undef;        }        gen_ea(s, insn, opsize, res, NULL);        return;    case 4: /* fmove to control register.  */        switch ((ext >> 10) & 7) {        case 4: /* FPCR */            /* Not implemented.  Ignore writes.  */            break;        case 1: /* FPIAR */        case 2: /* FPSR */        default:            cpu_abort(NULL, "Unimplemented: fmove to control %d",                      (ext >> 10) & 7);        }        break;    case 5: /* fmove from control register.  */        switch ((ext >> 10) & 7) {        case 4: /* FPCR */            /* Not implemented.  Always return zero.  */            res = gen_im32(0);            break;        case 1: /* FPIAR */        case 2: /* FPSR */        default:            cpu_abort(NULL, "Unimplemented: fmove from control %d",                      (ext >> 10) & 7);            goto undef;        }        gen_ea(s, insn, OS_LONG, res, NULL);        break;    case 6: /* fmovem */     case 7:        {        int addr;        uint16_t mask;        if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)            goto undef;        src = gen_lea(s, insn, OS_LONG);        addr = gen_new_qreg(QMODE_I32);        gen_op_mov32(addr, src);        mask = 0x80;        dest = QREG_F0;        while (mask) {            if (ext & mask) {                if (ext & (1 << 13)) {                    /* store */                    gen_op_stf64(addr, dest);                } else {                    /* load */                    gen_op_ldf64(dest, addr);                }                if (ext & (mask - 1))                    gen_op_add32(addr, addr, gen_im32(8));            }            mask >>= 1;            dest++;        }        }        return;    }    if (ext & (1 << 14)) {        int tmp;        /* Source effective address.  */        switch ((ext >> 10) & 7) {        case 0: opsize = OS_LONG; break;        case 1: opsize = OS_SINGLE; break;        case 4: opsize = OS_WORD; break;        case 5: opsize = OS_DOUBLE; break;        case 6: opsize = OS_BYTE; break;        default:            goto undef;        }        tmp = gen_ea(s, insn, opsize, -1, NULL);        if (opsize == OS_DOUBLE) {            src = tmp;        } else {            src = gen_new_qreg(QMODE_F64);            switch (opsize) {            case OS_LONG:            case OS_WORD:            case OS_BYTE:                gen_op_i32_to_f64(src, tmp);                break;            case OS_SINGLE:                gen_op_f32_to_f64(src, tmp);                break;            }        }    } else {        /* Source register.  */        src = FREG(ext, 10);    }    dest = FREG(ext, 7);    res = gen_new_qreg(QMODE_F64);    if (opmode != 0x3a)        gen_op_movf64(res, dest);    round = 1;    switch (opmode) {    case 0: case 0x40: case 0x44: /* fmove */        gen_op_movf64(res, src);        break;    case 1: /* fint */        gen_op_iround_f64(res, src);        round = 0;        break;    case 3: /* fintrz */        gen_op_itrunc_f64(res, src);        round = 0;        break;    case 4: case 0x41: case 0x45: /* fsqrt */        gen_op_sqrtf64(res, src);        break;    case 0x18: case 0x58: case 0x5c: /* fabs */        gen_op_absf64(res, src);        break;    case 0x1a: case 0x5a: case 0x5e: /* fneg */        gen_op_chsf64(res, src);        break;    case 0x20: case 0x60: case 0x64: /* fdiv */        gen_op_divf64(res, res, src);        break;    case 0x22: case 0x62: case 0x66: /* fadd */        gen_op_addf64(res, res, src);        break;    case 0x23: case 0x63: case 0x67: /* fmul */        gen_op_mulf64(res, res, src);        break;    case 0x28: case 0x68: case 0x6c: /* fsub */        gen_op_subf64(res, res, src);        break;    case 0x38: /* fcmp */        gen_op_sub_cmpf64(res, res, src);        dest = 0;        round = 0;        break;    case 0x3a: /* ftst */        gen_op_movf64(res, src);        dest = 0;        round = 0;        break;    default:        goto undef;    }    if (round) {        if (opmode & 0x40) {            if ((opmode & 0x4) != 0)                round = 0;        } else if ((s->fpcr & M68K_FPCR_PREC) == 0) {            round = 0;        }    }    if (round) {        int tmp;        tmp = gen_new_qreg(QMODE_F32);        gen_op_f64_to_f32(tmp, res);        gen_op_f32_to_f64(res, tmp);    }     gen_op_fp_result(res);    if (dest) {        gen_op_movf64(dest, res);    }    return;undef:    s->pc -= 2;    disas_undef_fpu(s, insn);}DISAS_INSN(fbcc){    uint32_t offset;    uint32_t addr;    int flag;    int zero;    int l1;    addr = s->pc;    offset = ldsw(s->pc);    s->pc += 2;    if (insn & (1 << 6)) {        offset = (offset << 16) | lduw(s->pc);        s->pc += 2;    }    l1 = gen_new_label();    /* TODO: Raise BSUN exception.  */    flag = gen_new_qreg(QMODE_I32);    zero = gen_new_qreg(QMODE_F64);    gen_op_zerof64(zero);    gen_op_compare_quietf64(flag, QREG_FP_RESULT, zero);    /* Jump to l1 if condition is true.  */    switch (insn & 0xf) {    case 0: /* f */        break;    case 1: /* eq (=0) */        gen_op_jmp_z32(flag, l1);        break;    case 2: /* ogt (=1) */        gen_op_sub32(flag, flag, gen_im32(1));        gen_op_jmp_z32(flag, l1);        break;    case 3: /* oge (=0 or =1) */        gen_op_jmp_z32(flag, l1);        gen_op_sub32(flag, flag, gen_im32(1));        gen_op_jmp_z32(flag, l1);        break;    case 4: /* olt (=-1) */        gen_op_jmp_s32(flag, l1);        break;    case 5: /* ole (=-1 or =0) */        gen_op_jmp_s32(flag, l1);        gen_op_jmp_z32(flag, l1);        break;    case 6: /* ogl (=-1 or =1) */        gen_op_jmp_s32(flag, l1);        gen_op_sub32(flag, flag, gen_im32(1));        gen_op_jmp_z32(flag, l1);        break;    case 7: /* or (=2) */        gen_op_sub32(flag, flag, gen_im32(2));        gen_op_jmp_z32(flag, l1);        break;    case 8: /* un (<2) */        gen_op_sub32(flag, flag, gen_im32(2));        gen_op_jmp_s32(flag, l1);        break;    case 9: /* ueq (=0 or =2) */        gen_op_jmp_z32(flag, l1);        gen_op_sub32(flag, flag, gen_im32(2));        gen_op_jmp_z32(flag, l1);        break;    case 10: /* ugt (>0) */        /* ??? Add jmp_gtu.  */        gen_op_sub32(flag, flag, gen_im32(1));        gen_op_jmp_ns32(flag, l1);        break;    case 11: /* uge (>=0) */        gen_op_jmp_ns32(flag, l1);        break;

⌨️ 快捷键说明

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