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, | ... | ... |