Commit 3018f2598c047e13b4479a47f55bfa7618e17381
1 parent
e4b3861d
Fix ARM NEON vdup and vtbl bugs.
Signed-off-by: Paul Brook <paul@codesourcery.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5286 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
7 additions
and
5 deletions
target-arm/op_helper.c
| ... | ... | @@ -56,7 +56,7 @@ uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, |
| 56 | 56 | for (shift = 0; shift < 32; shift += 8) { |
| 57 | 57 | index = (ireg >> shift) & 0xff; |
| 58 | 58 | if (index < maxindex) { |
| 59 | - tmp = (table[index >> 3] >> (index & 7)) & 0xff; | |
| 59 | + tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff; | |
| 60 | 60 | val |= tmp << shift; |
| 61 | 61 | } else { |
| 62 | 62 | val |= def & (0xff << shift); | ... | ... |
target-arm/translate.c
| ... | ... | @@ -2807,7 +2807,7 @@ static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) |
| 2807 | 2807 | tmp2 = new_tmp(); |
| 2808 | 2808 | tcg_gen_mov_i32(tmp2, tmp); |
| 2809 | 2809 | neon_store_reg(rn, 0, tmp2); |
| 2810 | - neon_store_reg(rn, 0, tmp); | |
| 2810 | + neon_store_reg(rn, 1, tmp); | |
| 2811 | 2811 | } else { |
| 2812 | 2812 | /* VMOV */ |
| 2813 | 2813 | switch (size) { |
| ... | ... | @@ -3814,7 +3814,7 @@ static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn) |
| 3814 | 3814 | tmp2 = new_tmp(); |
| 3815 | 3815 | tcg_gen_mov_i32(tmp2, tmp); |
| 3816 | 3816 | neon_store_reg(rd, 0, tmp2); |
| 3817 | - neon_store_reg(rd, 0, tmp); | |
| 3817 | + neon_store_reg(rd, 1, tmp); | |
| 3818 | 3818 | rd += stride; |
| 3819 | 3819 | } |
| 3820 | 3820 | stride = (1 << size) * nregs; |
| ... | ... | @@ -5498,7 +5498,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) |
| 5498 | 5498 | } |
| 5499 | 5499 | } else if ((insn & (1 << 10)) == 0) { |
| 5500 | 5500 | /* VTBL, VTBX. */ |
| 5501 | - n = (insn >> 5) & 0x18; | |
| 5501 | + n = ((insn >> 5) & 0x18) + 8; | |
| 5502 | 5502 | if (insn & (1 << 6)) { |
| 5503 | 5503 | tmp = neon_load_reg(rd, 0); |
| 5504 | 5504 | } else { |
| ... | ... | @@ -5508,6 +5508,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) |
| 5508 | 5508 | tmp2 = neon_load_reg(rm, 0); |
| 5509 | 5509 | gen_helper_neon_tbl(tmp2, tmp2, tmp, tcg_const_i32(rn), |
| 5510 | 5510 | tcg_const_i32(n)); |
| 5511 | + dead_tmp(tmp); | |
| 5511 | 5512 | if (insn & (1 << 6)) { |
| 5512 | 5513 | tmp = neon_load_reg(rd, 1); |
| 5513 | 5514 | } else { |
| ... | ... | @@ -5518,7 +5519,8 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn) |
| 5518 | 5519 | gen_helper_neon_tbl(tmp3, tmp3, tmp, tcg_const_i32(rn), |
| 5519 | 5520 | tcg_const_i32(n)); |
| 5520 | 5521 | neon_store_reg(rd, 0, tmp2); |
| 5521 | - neon_store_reg(rd, 1, tmp2); | |
| 5522 | + neon_store_reg(rd, 1, tmp3); | |
| 5523 | + dead_tmp(tmp); | |
| 5522 | 5524 | } else if ((insn & 0x380) == 0) { |
| 5523 | 5525 | /* VDUP */ |
| 5524 | 5526 | if (insn & (1 << 19)) { | ... | ... |