Commit 8e96005d86cba6b2ce177f489463eda602d99238

Authored by bellard
1 parent 85d8be6b

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
... ... @@ -35,9 +35,9 @@
35 35 precision respectively.
36 36 Doing runtime conversions is tricky because VFP registers may contain
37 37 integer values (eg. as the result of a FTOSI instruction).
38   - A double precision register load/store must also load/store the
39   - corresponding single precision pair, although it is undefined how
40   - these overlap. */
  38 + s<2n> maps to the least significant half of d<n>
  39 + s<2n+1> maps to the most significant half of d<n>
  40 + */
41 41  
42 42 typedef struct CPUARMState {
43 43 uint32_t regs[16];
... ... @@ -71,10 +71,7 @@ typedef struct CPUARMState {
71 71 memory was written */
72 72 /* VFP coprocessor state. */
73 73 struct {
74   - union {
75   - float32 s[32];
76   - float64 d[16];
77   - } regs;
  74 + float64 regs[16];
78 75  
79 76 /* We store these fpcsr fields separately for convenience. */
80 77 int vec_len;
... ...
target-arm/translate.c
... ... @@ -385,28 +385,41 @@ VFP_OP(st)
385 385  
386 386 #undef VFP_OP
387 387  
  388 +static inline long
  389 +vfp_reg_offset (int dp, int reg)
  390 +{
  391 + if (dp)
  392 + return offsetof(CPUARMState, vfp.regs[reg]);
  393 + else if (reg & 1) {
  394 + return offsetof(CPUARMState, vfp.regs[reg >> 1])
  395 + + offsetof(CPU_DoubleU, l.upper);
  396 + } else {
  397 + return offsetof(CPUARMState, vfp.regs[reg >> 1])
  398 + + offsetof(CPU_DoubleU, l.lower);
  399 + }
  400 +}
388 401 static inline void gen_mov_F0_vreg(int dp, int reg)
389 402 {
390 403 if (dp)
391   - gen_op_vfp_getreg_F0d(offsetof(CPUARMState, vfp.regs.d[reg]));
  404 + gen_op_vfp_getreg_F0d(vfp_reg_offset(dp, reg));
392 405 else
393   - gen_op_vfp_getreg_F0s(offsetof(CPUARMState, vfp.regs.s[reg]));
  406 + gen_op_vfp_getreg_F0s(vfp_reg_offset(dp, reg));
394 407 }
395 408  
396 409 static inline void gen_mov_F1_vreg(int dp, int reg)
397 410 {
398 411 if (dp)
399   - gen_op_vfp_getreg_F1d(offsetof(CPUARMState, vfp.regs.d[reg]));
  412 + gen_op_vfp_getreg_F1d(vfp_reg_offset(dp, reg));
400 413 else
401   - gen_op_vfp_getreg_F1s(offsetof(CPUARMState, vfp.regs.s[reg]));
  414 + gen_op_vfp_getreg_F1s(vfp_reg_offset(dp, reg));
402 415 }
403 416  
404 417 static inline void gen_mov_vreg_F0(int dp, int reg)
405 418 {
406 419 if (dp)
407   - gen_op_vfp_setreg_F0d(offsetof(CPUARMState, vfp.regs.d[reg]));
  420 + gen_op_vfp_setreg_F0d(vfp_reg_offset(dp, reg));
408 421 else
409   - gen_op_vfp_setreg_F0s(offsetof(CPUARMState, vfp.regs.s[reg]));
  422 + gen_op_vfp_setreg_F0s(vfp_reg_offset(dp, reg));
410 423 }
411 424  
412 425 /* Disassemble a VFP instruction. Returns nonzero if an error occured
... ... @@ -2120,9 +2133,9 @@ void cpu_dump_state(CPUState *env, FILE *f,
2120 2133 env->cpsr & (1 << 28) ? 'V' : '-');
2121 2134  
2122 2135 for (i = 0; i < 16; i++) {
2123   - s0.s = env->vfp.regs.s[i * 2];
2124   - s1.s = env->vfp.regs.s[i * 2 + 1];
2125   - d.d = env->vfp.regs.d[i];
  2136 + d.d = env->vfp.regs[i];
  2137 + s0.i = d.l.lower;
  2138 + s1.i = d.l.upper;
2126 2139 cpu_fprintf(f, "s%02d=%08x(%8f) s%02d=%08x(%8f) d%02d=%08x%08x(%8f)\n",
2127 2140 i * 2, (int)s0.i, s0.s,
2128 2141 i * 2 + 1, (int)s0.i, s0.s,
... ...