target-arm: Fix garbage collection of temporaries in Neon emulation.
Fix garbage collection of temporaries in Neon emulation.
Signed-off-by: Christophe Lyon <christophe.lyon@st.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
diff --git a/target-arm/translate.c b/target-arm/translate.c
index f445c87..41cbb96 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -4183,6 +4183,13 @@
break;
default: abort();
}
+
+ /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
+ Don't forget to clean them now. */
+ if (size < 2) {
+ dead_tmp(a);
+ dead_tmp(b);
+ }
}
/* Translate a NEON data processing instruction. Return nonzero if the
@@ -4847,7 +4854,7 @@
if (size == 3) {
tcg_temp_free_i64(tmp64);
} else {
- dead_tmp(tmp2);
+ tcg_temp_free_i32(tmp2);
}
} else if (op == 10) {
/* VSHLL */
@@ -5083,8 +5090,6 @@
case 8: case 9: case 10: case 11: case 12: case 13:
/* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
- dead_tmp(tmp2);
- dead_tmp(tmp);
break;
case 14: /* Polynomial VMULL */
cpu_abort(env, "Polynomial VMULL not implemented");
@@ -5235,6 +5240,10 @@
return 1;
tmp2 = neon_get_scalar(size, rm);
+ /* We need a copy of tmp2 because gen_neon_mull
+ * deletes it during pass 0. */
+ tmp4 = new_tmp();
+ tcg_gen_mov_i32(tmp4, tmp2);
tmp3 = neon_load_reg(rn, 1);
for (pass = 0; pass < 2; pass++) {
@@ -5242,9 +5251,9 @@
tmp = neon_load_reg(rn, 0);
} else {
tmp = tmp3;
+ tmp2 = tmp4;
}
gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
- dead_tmp(tmp);
if (op == 6 || op == 7) {
gen_neon_negl(cpu_V0, size);
}
@@ -5271,7 +5280,6 @@
neon_store_reg64(cpu_V0, rd + pass);
}
- dead_tmp(tmp2);
break;
default: /* 14 and 15 are RESERVED */