aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-06-11 16:39:43 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-06-13 15:14:04 +0100
commitc2a46a914cd5c38fd0ee57ff0befc1c5bde27bcf (patch)
treed09d697f9ac270abbb2b9f9278512ce94e905529
parente3bb599d16e4678b228d80194cee328f894b1ceb (diff)
downloadqemu-c2a46a914cd5c38fd0ee57ff0befc1c5bde27bcf.zip
qemu-c2a46a914cd5c38fd0ee57ff0befc1c5bde27bcf.tar.gz
qemu-c2a46a914cd5c38fd0ee57ff0befc1c5bde27bcf.tar.bz2
target/arm: Convert VCVTA/VCVTN/VCVTP/VCVTM to decodetree
Convert the VCVTA/VCVTN/VCVTP/VCVTM instructions to decodetree. trans_VCVT() is temporarily left in translate.c. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
-rw-r--r--target/arm/translate.c72
-rw-r--r--target/arm/vfp-uncond.decode6
2 files changed, 39 insertions, 39 deletions
diff --git a/target/arm/translate.c b/target/arm/translate.c
index 99561c7..1f9ff97 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -3340,12 +3340,31 @@ static bool trans_VRINT(DisasContext *s, arg_VRINT *a)
return true;
}
-static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
- int rounding)
+static bool trans_VCVT(DisasContext *s, arg_VCVT *a)
{
- bool is_signed = extract32(insn, 7, 1);
- TCGv_ptr fpst = get_fpstatus_ptr(0);
+ uint32_t rd, rm;
+ bool dp = a->dp;
+ TCGv_ptr fpst;
TCGv_i32 tcg_rmode, tcg_shift;
+ int rounding = fp_decode_rm[a->rm];
+ bool is_signed = a->op;
+
+ if (!dc_isar_feature(aa32_vcvt_dr, s)) {
+ return false;
+ }
+
+ /* UNDEF accesses to D16-D31 if they don't exist */
+ if (dp && !dc_isar_feature(aa32_fp_d32, s) && (a->vm & 0x10)) {
+ return false;
+ }
+ rd = a->vd;
+ rm = a->vm;
+
+ if (!vfp_access_check(s)) {
+ return true;
+ }
+
+ fpst = get_fpstatus_ptr(0);
tcg_shift = tcg_const_i32(0);
@@ -3355,10 +3374,6 @@ static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
if (dp) {
TCGv_i64 tcg_double, tcg_res;
TCGv_i32 tcg_tmp;
- /* Rd is encoded as a single precision register even when the source
- * is double precision.
- */
- rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
tcg_double = tcg_temp_new_i64();
tcg_res = tcg_temp_new_i64();
tcg_tmp = tcg_temp_new_i32();
@@ -3395,28 +3410,7 @@ static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
tcg_temp_free_ptr(fpst);
- return 0;
-}
-
-static int disas_vfp_misc_insn(DisasContext *s, uint32_t insn)
-{
- uint32_t rd, rm, dp = extract32(insn, 8, 1);
-
- if (dp) {
- VFP_DREG_D(rd, insn);
- VFP_DREG_M(rm, insn);
- } else {
- rd = VFP_SREG_D(insn);
- rm = VFP_SREG_M(insn);
- }
-
- if ((insn & 0x0fbc0e50) == 0x0ebc0a40 &&
- dc_isar_feature(aa32_vcvt_dr, s)) {
- /* VCVTA, VCVTN, VCVTP, VCVTM */
- int rounding = fp_decode_rm[extract32(insn, 16, 2)];
- return handle_vcvt(insn, rd, rm, dp, rounding);
- }
- return 1;
+ return true;
}
/*
@@ -3452,6 +3446,15 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
}
}
+ if (extract32(insn, 28, 4) == 0xf) {
+ /*
+ * Encodings with T=1 (Thumb) or unconditional (ARM): these
+ * were all handled by the decodetree decoder, so any insn
+ * patterns which get here must be UNDEF.
+ */
+ return 1;
+ }
+
/*
* FIXME: this access check should not take precedence over UNDEF
* for invalid encodings; we will generate incorrect syndrome information
@@ -3468,15 +3471,6 @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
return 0;
}
- if (extract32(insn, 28, 4) == 0xf) {
- /*
- * Encodings with T=1 (Thumb) or unconditional (ARM):
- * only used for the "miscellaneous VFP features" added in v8A
- * and v7M (and gated on the MVFR2.FPMisc field).
- */
- return disas_vfp_misc_insn(s, insn);
- }
-
dp = ((insn & 0xf00) == 0xb00);
switch ((insn >> 24) & 0xf) {
case 0xe:
diff --git a/target/arm/vfp-uncond.decode b/target/arm/vfp-uncond.decode
index 0aa8328..5af1f2e 100644
--- a/target/arm/vfp-uncond.decode
+++ b/target/arm/vfp-uncond.decode
@@ -55,3 +55,9 @@ VRINT 1111 1110 1.11 10 rm:2 .... 1010 01.0 .... \
vm=%vm_sp vd=%vd_sp dp=0
VRINT 1111 1110 1.11 10 rm:2 .... 1011 01.0 .... \
vm=%vm_dp vd=%vd_dp dp=1
+
+# VCVT float to int with specified rounding mode; Vd is always single-precision
+VCVT 1111 1110 1.11 11 rm:2 .... 1010 op:1 1.0 .... \
+ vm=%vm_sp vd=%vd_sp dp=0
+VCVT 1111 1110 1.11 11 rm:2 .... 1011 op:1 1.0 .... \
+ vm=%vm_dp vd=%vd_sp dp=1