qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] target-arm: ARMv4 emulation


From: Laurent Desnogues
Subject: Re: [Qemu-devel] [PATCH] target-arm: ARMv4 emulation
Date: Thu, 14 Jan 2010 11:11:24 +0100

Since you wanted a "no, because..." there's at least
one :-)

On Tue, Dec 1, 2009 at 9:41 PM, Filip Navara <address@hidden> wrote:
> While most of the ARMv5 instructions are backward compatible with ARMv4, there
> are few important differences. Most notably the stack pop and load 
> instructions
> ignore the lowest bit, which is used by ARMv5 to switch to Thumb mode. A
> base-updated data-abort model is used on ARM7TDMI, CP15 coprocessor is not
> present and several instructions of later architectures are not implemented.
>
> This patch introduces flags for the V5, CP15 and ABORT_BU (base-updated abort
> model) features. When V5 feature is not set the bit 0 on POP, LD and LDM of PC
> register is ignored and doesn't swith to/from Thumb mode and several
> instructions are treated as unimplemented (BLX, PLD, BKPT, LDRD, STRD).
>
> Added are processor definitions for ARM7TDMI and ARM920T.
>
> Based on patches by Ulrich Hecht <address@hidden> and Vincent Sanders 
> <address@hidden>.
>
> Signed-off-by: Filip Navara <address@hidden>
> ---
>  target-arm/cpu.h       |    7 ++-
>  target-arm/helper.c    |   31 ++++++++++++
>  target-arm/translate.c |  119 ++++++++++++++++++++++++++++++++++-------------
>  3 files changed, 123 insertions(+), 34 deletions(-)
>
> diff --git a/target-arm/cpu.h b/target-arm/cpu.h
> index 4a1c53f..b8e1e4b 100644
> --- a/target-arm/cpu.h
> +++ b/target-arm/cpu.h
> @@ -334,6 +334,7 @@ enum arm_features {
>     ARM_FEATURE_AUXCR,  /* ARM1026 Auxiliary control register.  */
>     ARM_FEATURE_XSCALE, /* Intel XScale extensions.  */
>     ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension.  */
> +    ARM_FEATURE_V5,
>     ARM_FEATURE_V6,
>     ARM_FEATURE_V6K,
>     ARM_FEATURE_V7,
> @@ -345,7 +346,9 @@ enum arm_features {
>     ARM_FEATURE_DIV,
>     ARM_FEATURE_M, /* Microcontroller profile.  */
>     ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling.  */
> -    ARM_FEATURE_THUMB2EE
> +    ARM_FEATURE_THUMB2EE,
> +    ARM_FEATURE_CP15, /* ARM7TDMI, ARM7TDMI-S, ARM7EJ-S, and ARM9TDMI cores 
> do not have a CP15 */
> +    ARM_FEATURE_ABORT_BU /* base updated abort model, e.g. ARMxTDMI */
>  };
>
>  static inline int arm_feature(CPUARMState *env, int feature)
> @@ -371,6 +374,8 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
>  #define IS_M(env) arm_feature(env, ARM_FEATURE_M)
>  #define ARM_CPUID(env) (env->cp15.c0_cpuid)
>
> +#define ARM_CPUID_ARM7TDMI    0x41807000 /* guess; no CP15 on ARM7TDMI */
> +#define ARM_CPUID_ARM920T     0x41129200
>  #define ARM_CPUID_ARM1026     0x4106a262
>  #define ARM_CPUID_ARM926      0x41069265
>  #define ARM_CPUID_ARM946      0x41059461
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index b3aec99..b82959f 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -44,19 +44,34 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t 
> id)
>  {
>     env->cp15.c0_cpuid = id;
>     switch (id) {
> +    case ARM_CPUID_ARM7TDMI:
> +        set_feature(env, ARM_FEATURE_ABORT_BU);
> +        break;
> +    case ARM_CPUID_ARM920T:
> +        set_feature(env, ARM_FEATURE_ABORT_BU);

ARM920T is using an ARM9TDMI which uses the Base Restored
Data Abort Model and not the Updated one.

Ref: 
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0180a/ch02s01s01.html


Laurent

> +        set_feature(env, ARM_FEATURE_CP15);
> +        env->cp15.c0_cachetype = 0x0d172172;
> +        env->cp15.c1_sys = 0x00000078;
> +        break;
>     case ARM_CPUID_ARM926:
> +        set_feature(env, ARM_FEATURE_V5);
>         set_feature(env, ARM_FEATURE_VFP);
> +        set_feature(env, ARM_FEATURE_CP15);
>         env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090;
>         env->cp15.c0_cachetype = 0x1dd20d2;
>         env->cp15.c1_sys = 0x00090078;
>         break;
>     case ARM_CPUID_ARM946:
> +        set_feature(env, ARM_FEATURE_V5);
> +        set_feature(env, ARM_FEATURE_CP15);
>         set_feature(env, ARM_FEATURE_MPU);
>         env->cp15.c0_cachetype = 0x0f004006;
>         env->cp15.c1_sys = 0x00000078;
>         break;
>     case ARM_CPUID_ARM1026:
> +        set_feature(env, ARM_FEATURE_V5);
>         set_feature(env, ARM_FEATURE_VFP);
> +        set_feature(env, ARM_FEATURE_CP15);
>         set_feature(env, ARM_FEATURE_AUXCR);
>         env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0;
>         env->cp15.c0_cachetype = 0x1dd20d2;
> @@ -64,8 +79,10 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t 
> id)
>         break;
>     case ARM_CPUID_ARM1136_R2:
>     case ARM_CPUID_ARM1136:
> +        set_feature(env, ARM_FEATURE_V5);
>         set_feature(env, ARM_FEATURE_V6);
>         set_feature(env, ARM_FEATURE_VFP);
> +        set_feature(env, ARM_FEATURE_CP15);
>         set_feature(env, ARM_FEATURE_AUXCR);
>         env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
>         env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
> @@ -75,9 +92,11 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t 
> id)
>         env->cp15.c0_cachetype = 0x1dd20d2;
>         break;
>     case ARM_CPUID_ARM11MPCORE:
> +        set_feature(env, ARM_FEATURE_V5);
>         set_feature(env, ARM_FEATURE_V6);
>         set_feature(env, ARM_FEATURE_V6K);
>         set_feature(env, ARM_FEATURE_VFP);
> +        set_feature(env, ARM_FEATURE_CP15);
>         set_feature(env, ARM_FEATURE_AUXCR);
>         env->vfp.xregs[ARM_VFP_FPSID] = 0x410120b4;
>         env->vfp.xregs[ARM_VFP_MVFR0] = 0x11111111;
> @@ -87,9 +106,11 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t 
> id)
>         env->cp15.c0_cachetype = 0x1dd20d2;
>         break;
>     case ARM_CPUID_CORTEXA8:
> +        set_feature(env, ARM_FEATURE_V5);
>         set_feature(env, ARM_FEATURE_V6);
>         set_feature(env, ARM_FEATURE_V6K);
>         set_feature(env, ARM_FEATURE_V7);
> +        set_feature(env, ARM_FEATURE_CP15);
>         set_feature(env, ARM_FEATURE_AUXCR);
>         set_feature(env, ARM_FEATURE_THUMB2);
>         set_feature(env, ARM_FEATURE_VFP);
> @@ -129,6 +150,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t 
> id)
>         env->cp15.c0_ccsid[1] = 0x200fe015; /* 16k L1 icache. */
>         break;
>     case ARM_CPUID_CORTEXM3:
> +        set_feature(env, ARM_FEATURE_V5);
>         set_feature(env, ARM_FEATURE_V6);
>         set_feature(env, ARM_FEATURE_THUMB2);
>         set_feature(env, ARM_FEATURE_V7);
> @@ -136,6 +158,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t 
> id)
>         set_feature(env, ARM_FEATURE_DIV);
>         break;
>     case ARM_CPUID_ANY: /* For userspace emulation.  */
> +        set_feature(env, ARM_FEATURE_V5);
>         set_feature(env, ARM_FEATURE_V6);
>         set_feature(env, ARM_FEATURE_V6K);
>         set_feature(env, ARM_FEATURE_V7);
> @@ -149,6 +172,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t 
> id)
>         break;
>     case ARM_CPUID_TI915T:
>     case ARM_CPUID_TI925T:
> +        set_feature(env, ARM_FEATURE_V5);
> +        set_feature(env, ARM_FEATURE_CP15);
>         set_feature(env, ARM_FEATURE_OMAPCP);
>         env->cp15.c0_cpuid = ARM_CPUID_TI925T; /* Depends on wiring.  */
>         env->cp15.c0_cachetype = 0x5109149;
> @@ -161,6 +186,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t 
> id)
>     case ARM_CPUID_PXA260:
>     case ARM_CPUID_PXA261:
>     case ARM_CPUID_PXA262:
> +        set_feature(env, ARM_FEATURE_V5);
> +        set_feature(env, ARM_FEATURE_CP15);
>         set_feature(env, ARM_FEATURE_XSCALE);
>         /* JTAG_ID is ((id << 28) | 0x09265013) */
>         env->cp15.c0_cachetype = 0xd172172;
> @@ -172,6 +199,8 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t 
> id)
>     case ARM_CPUID_PXA270_B1:
>     case ARM_CPUID_PXA270_C0:
>     case ARM_CPUID_PXA270_C5:
> +        set_feature(env, ARM_FEATURE_V5);
> +        set_feature(env, ARM_FEATURE_CP15);
>         set_feature(env, ARM_FEATURE_XSCALE);
>         /* JTAG_ID is ((id << 28) | 0x09265013) */
>         set_feature(env, ARM_FEATURE_IWMMXT);
> @@ -306,6 +335,8 @@ struct arm_cpu_t {
>  };
>
>  static const struct arm_cpu_t arm_cpu_names[] = {
> +       { ARM_CPUID_ARM7TDMI, "arm7tdmi"},
> +    { ARM_CPUID_ARM920T, "arm920t"},
>     { ARM_CPUID_ARM926, "arm926"},
>     { ARM_CPUID_ARM946, "arm946"},
>     { ARM_CPUID_ARM1026, "arm1026"},
> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index 45bf772..48602bb 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -34,9 +34,10 @@
>  #define GEN_HELPER 1
>  #include "helpers.h"
>
> +#define ENABLE_ARCH_5     arm_feature(env, ARM_FEATURE_V5)
>  #define ENABLE_ARCH_5J    0
>  #define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
> -#define ENABLE_ARCH_6K   arm_feature(env, ARM_FEATURE_V6K)
> +#define ENABLE_ARCH_6K    arm_feature(env, ARM_FEATURE_V6K)
>  #define ENABLE_ARCH_6T2   arm_feature(env, ARM_FEATURE_THUMB2)
>  #define ENABLE_ARCH_7     arm_feature(env, ARM_FEATURE_V7)
>
> @@ -2463,8 +2464,10 @@ static int disas_cp15_insn(CPUState *env, DisasContext 
> *s, uint32_t insn)
>     TCGv tmp, tmp2;
>
>     /* M profile cores use memory mapped registers instead of cp15.  */
> -    if (arm_feature(env, ARM_FEATURE_M))
> -       return 1;
> +    if (arm_feature(env, ARM_FEATURE_M) ||
> +        !arm_feature(env, ARM_FEATURE_CP15)) {
> +           return 1;
> +    }
>
>     if ((insn & (1 << 25)) == 0) {
>         if (insn & (1 << 20)) {
> @@ -6000,9 +6003,10 @@ static void disas_arm_insn(CPUState * env, 
> DisasContext *s)
>                 goto illegal_op;
>             return;
>         }
> -        if ((insn & 0x0d70f000) == 0x0550f000)
> +        if ((insn & 0x0d70f000) == 0x0550f000) {
> +            ARCH(5);
>             return; /* PLD */
> -        else if ((insn & 0x0ffffdff) == 0x01010000) {
> +        } else if ((insn & 0x0ffffdff) == 0x01010000) {
>             ARCH(6);
>             /* setend */
>             if (insn & (1 << 9)) {
> @@ -6119,7 +6123,7 @@ static void disas_arm_insn(CPUState * env, DisasContext 
> *s)
>         } else if ((insn & 0x0e000000) == 0x0a000000) {
>             /* branch link and change to thumb (blx <offset>) */
>             int32_t offset;
> -
> +            ARCH(5);
>             val = (uint32_t)s->pc;
>             tmp = new_tmp();
>             tcg_gen_movi_i32(tmp, val);
> @@ -6141,8 +6145,10 @@ static void disas_arm_insn(CPUState * env, 
> DisasContext *s)
>             }
>         } else if ((insn & 0x0fe00000) == 0x0c400000) {
>             /* Coprocessor double register transfer.  */
> +            ARCH(5);
>         } else if ((insn & 0x0f000010) == 0x0e000010) {
>             /* Additional coprocessor register transfer.  */
> +            ARCH(5);
>         } else if ((insn & 0x0ff10020) == 0x01000000) {
>             uint32_t mask;
>             uint32_t val;
> @@ -6245,6 +6251,7 @@ static void disas_arm_insn(CPUState * env, DisasContext 
> *s)
>                 gen_bx(s, tmp);
>             } else if (op1 == 3) {
>                 /* clz */
> +                               ARCH(5);
>                 rd = (insn >> 12) & 0xf;
>                 tmp = load_reg(s, rm);
>                 gen_helper_clz(tmp, tmp);
> @@ -6266,8 +6273,8 @@ static void disas_arm_insn(CPUState * env, DisasContext 
> *s)
>         case 0x3:
>             if (op1 != 1)
>               goto illegal_op;
> -
>             /* branch link/exchange thumb (blx) */
> +            ARCH(5);
>             tmp = load_reg(s, rm);
>             tmp2 = new_tmp();
>             tcg_gen_movi_i32(tmp2, s->pc);
> @@ -6275,6 +6282,7 @@ static void disas_arm_insn(CPUState * env, DisasContext 
> *s)
>             gen_bx(s, tmp);
>             break;
>         case 0x5: /* saturating add/subtract */
> +            ARCH(5);
>             rd = (insn >> 12) & 0xf;
>             rn = (insn >> 16) & 0xf;
>             tmp = load_reg(s, rm);
> @@ -6289,6 +6297,7 @@ static void disas_arm_insn(CPUState * env, DisasContext 
> *s)
>             store_reg(s, rd, tmp);
>             break;
>         case 7: /* bkpt */
> +            ARCH(5);
>             gen_set_condexec(s);
>             gen_set_pc_im(s->pc - 4);
>             gen_exception(EXCP_BKPT);
> @@ -6298,6 +6307,7 @@ static void disas_arm_insn(CPUState * env, DisasContext 
> *s)
>         case 0xa:
>         case 0xc:
>         case 0xe:
> +            ARCH(5);
>             rs = (insn >> 8) & 0xf;
>             rn = (insn >> 12) & 0xf;
>             rd = (insn >> 16) & 0xf;
> @@ -7019,7 +7029,7 @@ static void disas_arm_insn(CPUState * env, DisasContext 
> *s)
>             }
>             if (insn & (1 << 20)) {
>                 /* Complete the load.  */
> -                if (rd == 15)
> +                if (rd == 15 && ENABLE_ARCH_5)
>                     gen_bx(s, tmp);
>                 else
>                     store_reg(s, rd, tmp);
> @@ -7029,6 +7039,7 @@ static void disas_arm_insn(CPUState * env, DisasContext 
> *s)
>         case 0x09:
>             {
>                 int j, n, user, loaded_base;
> +                int crement = 0;
>                 TCGv loaded_var;
>                 /* load/store multiple words */
>                 /* XXX: store correct base if write back */
> @@ -7069,6 +7080,38 @@ static void disas_arm_insn(CPUState * env, 
> DisasContext *s)
>                         tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
>                     }
>                 }
> +
> +                if (insn & (1 << 21)) {
> +                    /* write back */
> +                    if (insn & (1 << 23)) {
> +                        if (insn & (1 << 24)) {
> +                            /* pre increment */
> +                        } else {
> +                            /* post increment */
> +                            crement = 4;
> +                        }
> +                    } else {
> +                        if (insn & (1 << 24)) {
> +                            /* pre decrement */
> +                            if (n != 1) {
> +                                crement = -((n - 1) * 4);
> +                            }
> +                        } else {
> +                            /* post decrement */
> +                            crement = -(n * 4);
> +                        }
> +                    }
> +                    if (arm_feature(env, ARM_FEATURE_ABORT_BU)) {
> +                        /* base-updated abort model: update base register
> +                           before an abort can happen */
> +                        crement += (n - 1) * 4;
> +                        tmp = new_tmp();
> +                        tcg_gen_addi_i32(tmp, addr, crement);
> +                        store_reg(s, rn, tmp);
> +                    }
> +
> +                }
> +
>                 j = 0;
>                 for(i=0;i<16;i++) {
>                     if (insn & (1 << i)) {
> @@ -7076,7 +7119,11 @@ static void disas_arm_insn(CPUState * env, 
> DisasContext *s)
>                             /* load */
>                             tmp = gen_ld32(addr, IS_USER(s));
>                             if (i == 15) {
> -                                gen_bx(s, tmp);
> +                                if (ENABLE_ARCH_5) {
> +                                    gen_bx(s, tmp);
> +                                } else {
> +                                    store_reg(s, i, tmp);
> +                                }
>                             } else if (user) {
>                                 tmp2 = tcg_const_i32(i);
>                                 gen_helper_set_user_reg(tmp2, tmp);
> @@ -7111,25 +7158,8 @@ static void disas_arm_insn(CPUState * env, 
> DisasContext *s)
>                             tcg_gen_addi_i32(addr, addr, 4);
>                     }
>                 }
> -                if (insn & (1 << 21)) {
> -                    /* write back */
> -                    if (insn & (1 << 23)) {
> -                        if (insn & (1 << 24)) {
> -                            /* pre increment */
> -                        } else {
> -                            /* post increment */
> -                            tcg_gen_addi_i32(addr, addr, 4);
> -                        }
> -                    } else {
> -                        if (insn & (1 << 24)) {
> -                            /* pre decrement */
> -                            if (n != 1)
> -                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
> -                        } else {
> -                            /* post decrement */
> -                            tcg_gen_addi_i32(addr, addr, -(n * 4));
> -                        }
> -                    }
> +                if (!arm_feature(env, ARM_FEATURE_ABORT_BU) && (insn & (1 << 
> 21))) {
> +                    tcg_gen_addi_i32(addr, addr, crement);
>                     store_reg(s, rn, addr);
>                 } else {
>                     dead_tmp(addr);
> @@ -7290,6 +7320,7 @@ static int disas_thumb2_insn(CPUState *env, 
> DisasContext *s, uint16_t insn_hw1)
>            16-bit instructions to get correct prefetch abort behavior.  */
>         insn = insn_hw1;
>         if ((insn & (1 << 12)) == 0) {
> +            ARCH(5);
>             /* Second half of blx.  */
>             offset = ((insn & 0x7ff) << 1);
>             tmp = load_reg(s, 14);
> @@ -7346,6 +7377,7 @@ static int disas_thumb2_insn(CPUState *env, 
> DisasContext *s, uint16_t insn_hw1)
>             /* Other load/store, table branch.  */
>             if (insn & 0x01200000) {
>                 /* Load/store doubleword.  */
> +                ARCH(5);
>                 if (rn == 15) {
>                     addr = new_tmp();
>                     tcg_gen_movi_i32(addr, s->pc & ~3);
> @@ -7516,7 +7548,7 @@ static int disas_thumb2_insn(CPUState *env, 
> DisasContext *s, uint16_t insn_hw1)
>                     if (insn & (1 << 20)) {
>                         /* Load.  */
>                         tmp = gen_ld32(addr, IS_USER(s));
> -                        if (i == 15) {
> +                        if (i == 15 && ENABLE_ARCH_5) {
>                             gen_bx(s, tmp);
>                         } else {
>                             store_reg(s, i, tmp);
> @@ -7863,6 +7895,7 @@ static int disas_thumb2_insn(CPUState *env, 
> DisasContext *s, uint16_t insn_hw1)
>                     gen_jmp(s, offset);
>                 } else {
>                     /* blx */
> +                    ARCH(5);
>                     offset &= ~(uint32_t)2;
>                     gen_bx_im(s, offset);
>                 }
> @@ -8227,7 +8260,7 @@ static int disas_thumb2_insn(CPUState *env, 
> DisasContext *s, uint16_t insn_hw1)
>                 case 2: tmp = gen_ld32(addr, user); break;
>                 default: goto illegal_op;
>                 }
> -                if (rs == 15) {
> +                if (rs == 15 && ENABLE_ARCH_5) {
>                     gen_bx(s, tmp);
>                 } else {
>                     store_reg(s, rs, tmp);
> @@ -8270,6 +8303,7 @@ static void disas_thumb_insn(CPUState *env, 
> DisasContext *s)
>     TCGv tmp;
>     TCGv tmp2;
>     TCGv addr;
> +    int crement;
>
>     if (s->condexec_mask) {
>         cond = s->condexec_cond;
> @@ -8402,6 +8436,7 @@ static void disas_thumb_insn(CPUState *env, 
> DisasContext *s)
>             case 3:/* branch [and link] exchange thumb register */
>                 tmp = load_reg(s, rm);
>                 if (insn & (1 << 7)) {
> +                    ARCH(5);
>                     val = (uint32_t)s->pc | 1;
>                     tmp2 = new_tmp();
>                     tcg_gen_movi_i32(tmp2, val);
> @@ -8766,8 +8801,13 @@ static void disas_thumb_insn(CPUState *env, 
> DisasContext *s)
>             /* write back the new stack pointer */
>             store_reg(s, 13, addr);
>             /* set the new PC value */
> -            if ((insn & 0x0900) == 0x0900)
> -                gen_bx(s, tmp);
> +            if ((insn & 0x0900) == 0x0900) {
> +                if (ENABLE_ARCH_5) {
> +                    gen_bx(s, tmp);
> +                } else {
> +                    store_reg(s, 15, tmp);
> +                }
> +            }
>             break;
>
>         case 1: case 3: case 9: case 11: /* czb */
> @@ -8856,6 +8896,19 @@ static void disas_thumb_insn(CPUState *env, 
> DisasContext *s)
>         /* load/store multiple */
>         rn = (insn >> 8) & 0x7;
>         addr = load_reg(s, rn);
> +        if (arm_feature(env, ARM_FEATURE_ABORT_BU) && (insn & (1 << rn)) == 
> 0) {
> +            /* base-updated abort model: update base register
> +               before an abort can happen */
> +            crement = 0;
> +            for (i = 0; i < 8; i++) {
> +                if (insn & (1 << i)) {
> +                    crement += 4;
> +                }
> +            }
> +            tmp = new_tmp();
> +            tcg_gen_addi_i32(tmp, addr, crement);
> +            store_reg(s, rn, tmp);
> +        }
>         for (i = 0; i < 8; i++) {
>             if (insn & (1 << i)) {
>                 if (insn & (1 << 11)) {
> @@ -8872,7 +8925,7 @@ static void disas_thumb_insn(CPUState *env, 
> DisasContext *s)
>             }
>         }
>         /* Base register writeback.  */
> -        if ((insn & (1 << rn)) == 0) {
> +        if (!arm_feature(env, ARM_FEATURE_ABORT_BU) && (insn & (1 << rn)) == 
> 0) {
>             store_reg(s, rn, addr);
>         } else {
>             dead_tmp(addr);
> --
> 1.6.5.1.1367.gcd48
>
>
>
>
>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]