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

📄 translate.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
    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);        if (src == -1) {            gen_addr_fault(s);            return;        }        addr = gen_new_qreg(QMODE_I32);        gen_op_mov32(addr, src);        mask = 0x80;        dest = QREG_F0;        while (mask) {            if (ext & mask) {                s->is_mem = 1;                if (ext & (1 << 13)) {                    /* store */                    gen_st(s, f64, addr, dest);                } else {                    /* load */                    gen_ld(s, f64, 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;        }        SRC_EA(tmp, 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_code(s->pc);    s->pc += 2;    if (insn & (1 << 6)) {        offset = (offset << 16) | lduw_code(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;    case 12: /* ult (=-1 or =2) */        gen_op_jmp_s32(flag, l1);        gen_op_sub32(flag, flag, gen_im32(2));        gen_op_jmp_z32(flag, l1);        break;    case 13: /* ule (!=1) */        gen_op_sub32(flag, flag, gen_im32(1));        gen_op_jmp_nz32(flag, l1);        break;    case 14: /* ne (!=0) */        gen_op_jmp_nz32(flag, l1);        break;    case 15: /* t */        gen_op_mov32(flag, gen_im32(1));        break;    }    gen_jmp_tb(s, 0, s->pc);    gen_set_label(l1);    gen_jmp_tb(s, 1, addr + offset);}DISAS_INSN(frestore){    /* TODO: Implement frestore.  */    qemu_assert(0, "FRESTORE not implemented");}DISAS_INSN(fsave){    /* TODO: Implement fsave.  */    qemu_assert(0, "FSAVE not implemented");}static inline int gen_mac_extract_word(DisasContext *s, int val, int upper){    int tmp = gen_new_qreg(QMODE_I32);    if (s->env->macsr & MACSR_FI) {        if (upper)            gen_op_and32(tmp, val, gen_im32(0xffff0000));        else            gen_op_shl32(tmp, val, gen_im32(16));    } else if (s->env->macsr & MACSR_SU) {        if (upper)            gen_op_sar32(tmp, val, gen_im32(16));        else            gen_op_ext16s32(tmp, val);    } else {        if (upper)            gen_op_shr32(tmp, val, gen_im32(16));        else            gen_op_ext16u32(tmp, val);    }    return tmp;}DISAS_INSN(mac){    int rx;    int ry;    uint16_t ext;    int acc;    int l1;    int tmp;    int addr;    int loadval;    int dual;    int saved_flags = -1;    ext = lduw_code(s->pc);    s->pc += 2;    acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);    dual = ((insn & 0x30) != 0 && (ext & 3) != 0);    if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {        disas_undef(s, insn);        return;    }    if (insn & 0x30) {        /* MAC with load.  */        tmp = gen_lea(s, insn, OS_LONG);        addr = gen_new_qreg(QMODE_I32);        gen_op_and32(addr, tmp, QREG_MAC_MASK);        /* Load the value now to ensure correct exception behavior.           Perform writeback after reading the MAC inputs.  */        loadval = gen_load(s, OS_LONG, addr, 0);        acc ^= 1;        rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);        ry = (ext & 8) ? AREG(ext, 0) : DREG(ext, 0);    } else {        loadval = addr = -1;        rx = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);        ry = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);    }    gen_op_mac_clear_flags();    l1 = -1;    if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {        /* Skip the multiply if we know we will ignore it.  */        l1 = gen_new_label();        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_MACSR, gen_im32(1 << (acc + 8)));        gen_op_jmp_nz32(tmp, l1);    }    if ((ext & 0x0800) == 0) {        /* Word.  */        rx = gen_mac_extract_word(s, rx, (ext & 0x80) != 0);        ry = gen_mac_extract_word(s, ry, (ext & 0x40) != 0);    }    if (s->env->macsr & MACSR_FI) {        gen_op_macmulf(rx, ry);    } else {        if (s->env->macsr & MACSR_SU)            gen_op_macmuls(rx, ry);        else            gen_op_macmulu(rx, ry);        switch ((ext >> 9) & 3) {        case 1:            gen_op_macshl();            break;        case 3:            gen_op_macshr();            break;        }    }    if (dual) {        /* Save the overflow flag from the multiply.  */        saved_flags = gen_new_qreg(QMODE_I32);        gen_op_mov32(saved_flags, QREG_MACSR);    }    if ((s->env->macsr & MACSR_OMC) != 0 && dual) {        /* Skip the accumulate if the value is already saturated.  */        l1 = gen_new_label();        tmp = gen_new_qreg(QMODE_I32);        gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));        gen_op_jmp_nz32(tmp, l1);    }    if (insn & 0x100)        gen_op_macsub(acc);    else        gen_op_macadd(acc);    if (s->env->macsr & MACSR_FI)        gen_op_macsatf(acc);    else if (s->env->macsr & MACSR_SU)        gen_op_macsats(acc);    else        gen_op_macsatu(acc);    if (l1 != -1)        gen_set_label(l1);    if (dual) {        /* Dual accumulate variant.  */        acc = (ext >> 2) & 3;        /* Restore the overflow flag from the multiplier.  */        gen_op_mov32(QREG_MACSR, saved_flags);        if ((s->env->macsr & MACSR_OMC) != 0) {            /* Skip the accumulate if the value is already saturated.  */            l1 = gen_new_label();            tmp = gen_new_qreg(QMODE_I32);            gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));            gen_op_jmp_nz32(tmp, l1);        }        if (ext & 2)            gen_op_macsub(acc);        else            gen_op_macadd(acc);        if (s->env->macsr & MACSR_FI)            gen_op_macsatf(acc);        else if (s->env->macsr & MACSR_SU)            gen_op_macsats(acc);        else            gen_op_macsatu(acc);        if (l1 != -1)            gen_set_label(l1);    }    gen_op_mac_set_flags(acc);    if (insn & 0x30) {        int rw;        rw = (insn & 0x40) ? AREG(insn, 9) : DREG(insn, 9);        gen_op_mov32(rw, loadval);        /* FIXME: Should address writeback happen with the masked or           unmasked value?  */        switch ((insn >> 3) & 7) {        case 3: /* Post-increment.  */            gen_op_add32(AREG(insn, 0), addr, gen_im32(4));            break;        case 4: /* Pre-decrement.  */            gen_op_mov32(AREG(insn, 0), addr);        }    }}DISAS_INSN(from_mac){    int rx;    int acc;    rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);    acc = (insn >> 9) & 3;    if (s->env->macsr & MACSR_FI) {        gen_op_get_macf(rx, acc);    } else if ((s->env->macsr & MACSR_OMC) == 0) {        gen_op_get_maci(rx, acc);    } else if (s->env->macsr & MACSR_SU) {        gen_op_get_macs(rx, acc);    } else {        gen_op_get_macu(rx, acc);    }    if (insn & 0x40)        gen_op_clear_mac(acc);}DISAS_INSN(move_mac){    int src;    int dest;    src = insn & 3;    dest = (insn >> 9) & 3;    gen_op_move_mac(dest, src);    gen_op_mac_clear_flags();    gen_op_mac_set_flags(dest);}DISAS_INSN(from_macsr){    int reg;    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);    gen_op_mov32(reg, QREG_MACSR);}DISAS_INSN(from_mask){    int reg;    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);    gen_op_mov32(reg, QREG_MAC_MASK);}DISAS_INSN(from_mext){    int reg;    int acc;    reg = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);    acc = (insn & 0x400) ? 2 : 0;    if (s->env->macsr & MACSR_FI)        gen_op_get_mac_extf(reg, acc);    else        gen_op_get_mac_exti(reg, acc);}DISAS_INSN(macsr_to_ccr){    gen_op_mov32(QREG_CC_X, gen_im32(0));    gen_op_and32(QREG_CC_DEST, QREG_MACSR, gen_im32(0xf));    s->cc_op = CC_OP_FLAGS;}DISAS_INSN(to_mac){    int acc;    int val;    acc = (insn >>9) & 3;    SRC_EA(val, OS_LONG, 0, NULL);    if (s->env->macsr & MACSR_FI) {        gen_op_set_macf(val, acc);    } else if (s->env->macsr & MACSR_SU) {        gen_op_set_macs(val, acc);    } else {        gen_op_set_macu(val, acc);    }    gen_op_mac_clear_flags();    gen_op_mac_set_flags(acc);}DISAS_INSN(to_macsr){    int val;    SRC_EA(val, OS_LONG, 0, NULL);    gen_op_set_macsr(val);    gen_lookup_tb(s);}DISAS_INSN(to_mask){    int val;    SRC_EA(val, OS_LONG, 0, NULL);    gen_op_or32(QREG_MAC_MASK, val, gen_im32(0xffff0000));}DISAS_INSN(to_mext){    int val;    int acc;    SRC_EA(val, OS_LONG, 0, NULL);    acc = (insn & 0x400) ? 2 : 0;    if (s->env->macsr & MACSR_FI)        gen_op_set_mac_extf(val, acc);    else if (s->env->macsr & MACSR_SU)        gen_op_set_mac_exts(val, acc);    else        gen_op_set_mac_extu(val, acc);}static disas_proc opcode_table[65536];static voidregister_opcode (disas_proc proc, uint16_t opcode, uint16_t mask){  int i;  int from;  int to;  /* Sanity check.  All set bits must be included in the mask.  */  if (opcode & ~mask) {      fprintf(stderr,              "qemu internal error: bogus opcode definition %04x/%04x\n",              opcode, mask);      abort();  }  /* This could probably be cleverer.  For now just optimize the case where     the top bits are known.  */  /* Find the first zero bit in the mask.  */  i = 0x8000;  while ((i & mask) 

⌨️ 快捷键说明

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