diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2011-03-01 17:35:19 +0000 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2011-03-06 20:28:08 +0100 |
commit | 8387da81975a1f5d310d5f3008514c419b3e82de (patch) | |
tree | e7c3249b36e2a08736f917bb780f692585ca8c8d | |
parent | e095e2f3b47ced1ced72f3f2c72260e55f39903b (diff) |
target-arm: Handle VMOV between two core and VFP single regs
Fix two bugs in the translation of the instructions VMOV sa,sb,rx,ry and
VMOV rx,ry,sa,sb (which copy between a pair of ARM core registers and a
pair of VFP single precision registers):
* An incorrect condition meant these instruction patterns were being
treated as load/store multiple, which resulted in the generation
of bad code and a runtime segfault
* The order of the core register pair was reversed so the values would
go to the wrong registers
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-rw-r--r-- | target-arm/translate.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/target-arm/translate.c b/target-arm/translate.c index baa12563e7..5be504c800 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -3257,7 +3257,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) break; case 0xc: case 0xd: - if (dp && (insn & 0x03e00000) == 0x00400000) { + if ((insn & 0x03e00000) == 0x00400000) { /* two-register transfer */ rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; @@ -3279,10 +3279,10 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) } else { gen_mov_F0_vreg(0, rm); tmp = gen_vfp_mrs(); - store_reg(s, rn, tmp); + store_reg(s, rd, tmp); gen_mov_F0_vreg(0, rm + 1); tmp = gen_vfp_mrs(); - store_reg(s, rd, tmp); + store_reg(s, rn, tmp); } } else { /* arm->vfp */ @@ -3294,10 +3294,10 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm * 2 + 1); } else { - tmp = load_reg(s, rn); + tmp = load_reg(s, rd); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm); - tmp = load_reg(s, rd); + tmp = load_reg(s, rn); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm + 1); } |