Commit 8e96005d86cba6b2ce177f489463eda602d99238
1 parent
85d8be6b
VFP register ordering (Paul Brook)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1355 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
26 additions
and
16 deletions
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, | ... | ... |