aboutsummaryrefslogtreecommitdiff
path: root/target/arm/translate.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-05-31 13:29:43 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-06-04 14:58:29 +0100
commitf68f3b37645f1d994d9ec400ac1183911dabb207 (patch)
tree74cd012b96bbdd6edf6c1e97bf7a437e692f43fe /target/arm/translate.c
parent86030c0ea655a69aacc51fc620dc64e0faae0061 (diff)
target/arm: Convert VFP VMLA to decodetree
Convert the VFP VMLA instruction to decodetree. This is the first of the VFP 3-operand data processing instructions, so we include in this patch the code which loops over the elements for an old-style VFP vector operation. The existing code to do this looping uses the deprecated cpu_F0s/F0d/F1s/F1d TCG globals; since we are going to be converting instructions one at a time anyway we can take the opportunity to make the new loop use TCG temporaries, which means we can do that conversion one operation at a time rather than needing to do it all in one go. We include an UNDEF check which was missing in the old code: short-vector operations (with stride or length non-zero) were deprecated in v7A and must UNDEF in v8A, so if the MVFR0 FPShVec field does not indicate that support for short vectors is present we UNDEF the operations that would use them. (This is a change of behaviour for Cortex-A7, Cortex-A15 and the v8 CPUs, which previously were all incorrectly allowing short-vector operations.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/translate.c')
-rw-r--r--target/arm/translate.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 3e66048a42..6f0daddbbc 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -3123,6 +3123,14 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
rn = VFP_SREG_N(insn);
+ switch (op) {
+ case 0:
+ /* Already handled by decodetree */
+ return 1;
+ default:
+ break;
+ }
+
if (op == 15) {
/* rn is opcode, encoded as per VFP_SREG_N. */
switch (rn) {
@@ -3302,12 +3310,6 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
for (;;) {
/* Perform the calculation. */
switch (op) {
- case 0: /* VMLA: fd + (fn * fm) */
- /* Note that order of inputs to the add matters for NaNs */
- gen_vfp_F1_mul(dp);
- gen_mov_F0_vreg(dp, rd);
- gen_vfp_add(dp);
- break;
case 1: /* VMLS: fd + -(fn * fm) */
gen_vfp_mul(dp);
gen_vfp_F1_neg(dp);