From 8e96005d86cba6b2ce177f489463eda602d99238 Mon Sep 17 00:00:00 2001 From: bellard Date: Thu, 7 Apr 2005 19:42:46 +0000 Subject: [PATCH] VFP register ordering (Paul Brook) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1355 c046a42c-6fe2-441c-8c8c-71466251a162 --- target-arm/cpu.h | 11 ++++------- target-arm/translate.c | 31 ++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/target-arm/cpu.h b/target-arm/cpu.h index cf11c2f..1346175 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -35,9 +35,9 @@ precision respectively. Doing runtime conversions is tricky because VFP registers may contain integer values (eg. as the result of a FTOSI instruction). - A double precision register load/store must also load/store the - corresponding single precision pair, although it is undefined how - these overlap. */ + s<2n> maps to the least significant half of d + s<2n+1> maps to the most significant half of d + */ typedef struct CPUARMState { uint32_t regs[16]; @@ -71,10 +71,7 @@ typedef struct CPUARMState { memory was written */ /* VFP coprocessor state. */ struct { - union { - float32 s[32]; - float64 d[16]; - } regs; + float64 regs[16]; /* We store these fpcsr fields separately for convenience. */ int vec_len; diff --git a/target-arm/translate.c b/target-arm/translate.c index db38e33..39c28e7 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -385,28 +385,41 @@ VFP_OP(st) #undef VFP_OP +static inline long +vfp_reg_offset (int dp, int reg) +{ + if (dp) + return offsetof(CPUARMState, vfp.regs[reg]); + else if (reg & 1) { + return offsetof(CPUARMState, vfp.regs[reg >> 1]) + + offsetof(CPU_DoubleU, l.upper); + } else { + return offsetof(CPUARMState, vfp.regs[reg >> 1]) + + offsetof(CPU_DoubleU, l.lower); + } +} static inline void gen_mov_F0_vreg(int dp, int reg) { if (dp) - gen_op_vfp_getreg_F0d(offsetof(CPUARMState, vfp.regs.d[reg])); + gen_op_vfp_getreg_F0d(vfp_reg_offset(dp, reg)); else - gen_op_vfp_getreg_F0s(offsetof(CPUARMState, vfp.regs.s[reg])); + gen_op_vfp_getreg_F0s(vfp_reg_offset(dp, reg)); } static inline void gen_mov_F1_vreg(int dp, int reg) { if (dp) - gen_op_vfp_getreg_F1d(offsetof(CPUARMState, vfp.regs.d[reg])); + gen_op_vfp_getreg_F1d(vfp_reg_offset(dp, reg)); else - gen_op_vfp_getreg_F1s(offsetof(CPUARMState, vfp.regs.s[reg])); + gen_op_vfp_getreg_F1s(vfp_reg_offset(dp, reg)); } static inline void gen_mov_vreg_F0(int dp, int reg) { if (dp) - gen_op_vfp_setreg_F0d(offsetof(CPUARMState, vfp.regs.d[reg])); + gen_op_vfp_setreg_F0d(vfp_reg_offset(dp, reg)); else - gen_op_vfp_setreg_F0s(offsetof(CPUARMState, vfp.regs.s[reg])); + gen_op_vfp_setreg_F0s(vfp_reg_offset(dp, reg)); } /* Disassemble a VFP instruction. Returns nonzero if an error occured @@ -2120,9 +2133,9 @@ void cpu_dump_state(CPUState *env, FILE *f, env->cpsr & (1 << 28) ? 'V' : '-'); for (i = 0; i < 16; i++) { - s0.s = env->vfp.regs.s[i * 2]; - s1.s = env->vfp.regs.s[i * 2 + 1]; - d.d = env->vfp.regs.d[i]; + d.d = env->vfp.regs[i]; + s0.i = d.l.lower; + s1.i = d.l.upper; cpu_fprintf(f, "s%02d=%08x(%8f) s%02d=%08x(%8f) d%02d=%08x%08x(%8f)\n", i * 2, (int)s0.i, s0.s, i * 2 + 1, (int)s0.i, s0.s, -- 2.7.4