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

📄 translate.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
    if (insn & ARM_CP_RW_BIT) {        gen_op_movl_T0_cp15(insn);        /* If the destination register is r15 then sets condition codes.  */        if (rd != 15)            gen_movl_reg_T0(s, rd);    } else {        gen_movl_T0_reg(s, rd);        gen_op_movl_cp15_T0(insn);        /* Normally we would always end the TB here, but Linux         * arch/arm/mach-pxa/sleep.S expects two instructions following         * an MMU enable to execute from cache.  Imitate this behaviour.  */        if (!arm_feature(env, ARM_FEATURE_XSCALE) ||                (insn & 0x0fff0fff) != 0x0e010f10)            gen_lookup_tb(s);    }    return 0;}#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))#define VFP_SREG(insn, bigbit, smallbit) \  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))#define VFP_DREG(reg, insn, bigbit, smallbit) do { \    if (arm_feature(env, ARM_FEATURE_VFP3)) { \        reg = (((insn) >> (bigbit)) & 0x0f) \              | (((insn) >> ((smallbit) - 4)) & 0x10); \    } else { \        if (insn & (1 << (smallbit))) \            return 1; \        reg = ((insn) >> (bigbit)) & 0x0f; \    }} while (0)#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)static inline intvfp_enabled(CPUState * env){    return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);}/* Disassemble a VFP instruction.  Returns nonzero if an error occured   (ie. an undefined instruction).  */static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn){    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;    int dp, veclen;    if (!arm_feature(env, ARM_FEATURE_VFP))        return 1;    if (!vfp_enabled(env)) {        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */        if ((insn & 0x0fe00fff) != 0x0ee00a10)            return 1;        rn = (insn >> 16) & 0xf;        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)            return 1;    }    dp = ((insn & 0xf00) == 0xb00);    switch ((insn >> 24) & 0xf) {    case 0xe:        if (insn & (1 << 4)) {            /* single register transfer */            rd = (insn >> 12) & 0xf;            if (dp) {                int size;                int pass;                VFP_DREG_N(rn, insn);                if (insn & 0xf)                    return 1;                if (insn & 0x00c00060                    && !arm_feature(env, ARM_FEATURE_NEON))                    return 1;                pass = (insn >> 21) & 1;                if (insn & (1 << 22)) {                    size = 0;                    offset = ((insn >> 5) & 3) * 8;                } else if (insn & (1 << 5)) {                    size = 1;                    offset = (insn & (1 << 6)) ? 16 : 0;                } else {                    size = 2;                    offset = 0;                }                if (insn & ARM_CP_RW_BIT) {                    /* vfp->arm */                    switch (size) {                    case 0:                        NEON_GET_REG(T1, rn, pass);                        if (offset)                            gen_op_shrl_T1_im(offset);                        if (insn & (1 << 23))                            gen_op_uxtb_T1();                        else                            gen_op_sxtb_T1();                        break;                    case 1:                        NEON_GET_REG(T1, rn, pass);                        if (insn & (1 << 23)) {                            if (offset) {                                gen_op_shrl_T1_im(16);                            } else {                                gen_op_uxth_T1();                            }                        } else {                            if (offset) {                                gen_op_sarl_T1_im(16);                            } else {                                gen_op_sxth_T1();                            }                        }                        break;                    case 2:                        NEON_GET_REG(T1, rn, pass);                        break;                    }                    gen_movl_reg_T1(s, rd);                } else {                    /* arm->vfp */                    gen_movl_T0_reg(s, rd);                    if (insn & (1 << 23)) {                        /* VDUP */                        if (size == 0) {                            gen_op_neon_dup_u8(0);                        } else if (size == 1) {                            gen_op_neon_dup_low16();                        }                        NEON_SET_REG(T0, rn, 0);                        NEON_SET_REG(T0, rn, 1);                    } else {                        /* VMOV */                        switch (size) {                        case 0:                            NEON_GET_REG(T2, rn, pass);                            gen_op_movl_T1_im(0xff);                            gen_op_andl_T0_T1();                            gen_op_neon_insert_elt(offset, ~(0xff << offset));                            NEON_SET_REG(T2, rn, pass);                            break;                        case 1:                            NEON_GET_REG(T2, rn, pass);                            gen_op_movl_T1_im(0xffff);                            gen_op_andl_T0_T1();                            bank_mask = offset ? 0xffff : 0xffff0000;                            gen_op_neon_insert_elt(offset, bank_mask);                            NEON_SET_REG(T2, rn, pass);                            break;                        case 2:                            NEON_SET_REG(T0, rn, pass);                            break;                        }                    }                }            } else { /* !dp */                if ((insn & 0x6f) != 0x00)                    return 1;                rn = VFP_SREG_N(insn);                if (insn & ARM_CP_RW_BIT) {                    /* vfp->arm */                    if (insn & (1 << 21)) {                        /* system register */                        rn >>= 1;                        switch (rn) {                        case ARM_VFP_FPSID:                            /* VFP2 allows access for FSID from userspace.                               VFP3 restricts all id registers to privileged                               accesses.  */                            if (IS_USER(s)                                && arm_feature(env, ARM_FEATURE_VFP3))                                return 1;                            gen_op_vfp_movl_T0_xreg(rn);                            break;                        case ARM_VFP_FPEXC:                            if (IS_USER(s))                                return 1;                            gen_op_vfp_movl_T0_xreg(rn);                            break;                        case ARM_VFP_FPINST:                        case ARM_VFP_FPINST2:                            /* Not present in VFP3.  */                            if (IS_USER(s)                                || arm_feature(env, ARM_FEATURE_VFP3))                                return 1;                            gen_op_vfp_movl_T0_xreg(rn);                            break;                        case ARM_VFP_FPSCR:			    if (rd == 15)				gen_op_vfp_movl_T0_fpscr_flags();			    else				gen_op_vfp_movl_T0_fpscr();                            break;                        case ARM_VFP_MVFR0:                        case ARM_VFP_MVFR1:                            if (IS_USER(s)                                || !arm_feature(env, ARM_FEATURE_VFP3))                                return 1;                            gen_op_vfp_movl_T0_xreg(rn);                            break;                        default:                            return 1;                        }                    } else {                        gen_mov_F0_vreg(0, rn);                        gen_op_vfp_mrs();                    }                    if (rd == 15) {                        /* Set the 4 flag bits in the CPSR.  */                        gen_op_movl_cpsr_T0(0xf0000000);                    } else                        gen_movl_reg_T0(s, rd);                } else {                    /* arm->vfp */                    gen_movl_T0_reg(s, rd);                    if (insn & (1 << 21)) {                        rn >>= 1;                        /* system register */                        switch (rn) {                        case ARM_VFP_FPSID:                        case ARM_VFP_MVFR0:                        case ARM_VFP_MVFR1:                            /* Writes are ignored.  */                            break;                        case ARM_VFP_FPSCR:                            gen_op_vfp_movl_fpscr_T0();                            gen_lookup_tb(s);                            break;                        case ARM_VFP_FPEXC:                            if (IS_USER(s))                                return 1;                            gen_op_vfp_movl_xreg_T0(rn);                            gen_lookup_tb(s);                            break;                        case ARM_VFP_FPINST:                        case ARM_VFP_FPINST2:                            gen_op_vfp_movl_xreg_T0(rn);                            break;                        default:                            return 1;                        }                    } else {                        gen_op_vfp_msr();                        gen_mov_vreg_F0(0, rn);                    }                }            }        } else {            /* data processing */            /* The opcode is in bits 23, 21, 20 and 6.  */            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);            if (dp) {                if (op == 15) {                    /* rn is opcode */                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);                } else {                    /* rn is register number */                    VFP_DREG_N(rn, insn);                }                if (op == 15 && (rn == 15 || rn > 17)) {                    /* Integer or single precision destination.  */                    rd = VFP_SREG_D(insn);                } else {                    VFP_DREG_D(rd, insn);                }                if (op == 15 && (rn == 16 || rn == 17)) {                    /* Integer source.  */                    rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);                } else {                    VFP_DREG_M(rm, insn);                }            } else {                rn = VFP_SREG_N(insn);                if (op == 15 && rn == 15) {                    /* Double precision destination.  */                    VFP_DREG_D(rd, insn);                } else {                    rd = VFP_SREG_D(insn);                }                rm = VFP_SREG_M(insn);            }            veclen = env->vfp.vec_len;            if (op == 15 && rn > 3)                veclen = 0;            /* Shut up compiler warnings.  */            delta_m = 0;            delta_d = 0;            bank_mask = 0;            if (veclen > 0) {                if (dp)                    bank_mask = 0xc;                else                    bank_mask = 0x18;                /* Figure out what type of vector operation this is.  */                if ((rd & bank_mask) == 0) {                    /* scalar */                    veclen = 0;                } else {                    if (dp)                        delta_d = (env->vfp.vec_stride >> 1) + 1;                    else                        delta_d = env->vfp.vec_stride + 1;                    if ((rm & bank_mask) == 0) {                        /* mixed scalar/vector */                        delta_m = 0;                    } else {                        /* vector */                        delta_m = delta_d;                    }                }            }            /* Load the initial operands.  */            if (op == 15) {                switch (rn) {                case 16:                case 17:                    /* Integer source */                    gen_mov_F0_vreg(0, rm);                    break;                case 8:                case 9:                    /* Compare */                    gen_mov_F0_vreg(dp, rd);                    gen_mov_F1_vreg(dp, rm);                    break;                case 10:                case 11:                    /* Compare with zero */                    gen_mov_F0_vreg(dp, rd);                    gen_vfp_F1_ld0(dp);                    break;                case 20:                case 21:                case 22:                case 23:                    /* Source and destination the same.  */                    gen_mov_F0_vreg(dp, rd);                    break;                default:                    /* One source operand.  */                    gen_mov_F0_vreg(dp, rm);                    break;                }            } else {                /* Two source operands.  */                gen_mov_F0_vreg(dp, rn);                gen_mov_F1_vreg(dp, rm);            }            for (;;) {                /* Perform the calculation.  */                switch (op) {                case 0: /* mac: fd + (fn * fm) */                    gen_vfp_mul(dp);                    gen_mov_F1_vreg(dp, rd);                    gen_vfp_add(dp);                    break;                case 1: /* nmac: fd - (fn * fm) */                    gen_vfp_mul(dp);                    gen_vfp_neg(dp);                    gen_mov_F1_vreg(dp, rd);                    gen_vfp_add(dp);                    break;                case 2: /* msc: -fd + (fn * fm) */                    gen_vfp_mul(dp);                    gen_mov_F1_vreg(dp, rd);                    gen_vfp_sub(dp);                    break;                case 3: /* nmsc: -fd - (fn * fm)  */                    gen_vfp_mul(dp);                    gen_mov_F1_vreg(dp, rd);                    gen_vfp_add(dp);                    gen_vfp_neg(dp);                    break;                case 4: /* mul: fn * fm */                    gen_vfp_mul(dp);                    break;                case 5: /* nmul: -(fn * fm) */                    gen_vfp_mul(dp);                    gen_vfp_neg(dp);                    break;                case 6: /* add: fn + fm */                    gen_vfp_add(dp);                    break;                case 7: /* sub: fn - fm */                    gen_vfp_sub(dp);                    break;                case 8: /* div: fn / fm */                    gen_vfp_div(dp);                    break;                case 14: /* fconst */                    if (!arm_feature(env, ARM_FEATURE_VFP3))                      return 1;                    n = (insn << 12) & 0x80000000;                    i = ((insn >> 12) & 0x70) | (insn & 0xf);                    if (dp) {                        if (i & 0x40)                            i |= 0x3f80;                        else                            i |= 0x4000;                        n |= i << 16;                    } else {                        if (i & 0x40)                            i |= 0x780;                        else                            i |= 0x800;                        n |= i << 19;                    }                    gen_vfp_fconst(dp, n);                    break;                case 15: /* extension space */                    switch (rn) {                    case 0: /* cpy */                        /* no-op */                        break;                    case 1: /* abs */                        gen_vfp_abs(dp);                    

⌨️ 快捷键说明

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