summaryrefslogtreecommitdiffstats
path: root/target/arm/translate-vfp.c.inc
diff options
context:
space:
mode:
authorPeter Maydell2020-11-19 22:55:59 +0100
committerPeter Maydell2020-12-10 12:44:55 +0100
commit9542c30bcf13c495400d63616dd8dfa825b04685 (patch)
tree28e52be9f96cbcb73579ebaebea27ba6616b72d9 /target/arm/translate-vfp.c.inc
parenttarget/arm: Implement VLDR/VSTR system register (diff)
downloadqemu-9542c30bcf13c495400d63616dd8dfa825b04685.tar.gz
qemu-9542c30bcf13c495400d63616dd8dfa825b04685.tar.xz
qemu-9542c30bcf13c495400d63616dd8dfa825b04685.zip
target/arm: Implement M-profile FPSCR_nzcvqc
v8.1M defines a new FP system register FPSCR_nzcvqc; this behaves like the existing FPSCR, except that it reads and writes only bits [31:27] of the FPSCR (the N, Z, C, V and QC flag bits). (Unlike the FPSCR, the special case for Rt=15 of writing the CPSR.NZCV is not permitted.) Implement the register. Since we don't yet implement MVE, we handle the QC bit as RES0, with todo comments for where we will need to add support later. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20201119215617.29887-11-peter.maydell@linaro.org
Diffstat (limited to 'target/arm/translate-vfp.c.inc')
-rw-r--r--target/arm/translate-vfp.c.inc27
1 files changed, 27 insertions, 0 deletions
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
index f884d680a0..d698f3e1cd 100644
--- a/target/arm/translate-vfp.c.inc
+++ b/target/arm/translate-vfp.c.inc
@@ -648,6 +648,11 @@ static FPSysRegCheckResult fp_sysreg_checks(DisasContext *s, int regno)
case ARM_VFP_FPSCR:
case QEMU_VFP_FPSCR_NZCV:
break;
+ case ARM_VFP_FPSCR_NZCVQC:
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
+ return false;
+ }
+ break;
default:
return FPSysRegCheckFailed;
}
@@ -683,6 +688,22 @@ static bool gen_M_fp_sysreg_write(DisasContext *s, int regno,
tcg_temp_free_i32(tmp);
gen_lookup_tb(s);
break;
+ case ARM_VFP_FPSCR_NZCVQC:
+ {
+ TCGv_i32 fpscr;
+ tmp = loadfn(s, opaque);
+ /*
+ * TODO: when we implement MVE, write the QC bit.
+ * For non-MVE, QC is RES0.
+ */
+ tcg_gen_andi_i32(tmp, tmp, FPCR_NZCV_MASK);
+ fpscr = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
+ tcg_gen_andi_i32(fpscr, fpscr, ~FPCR_NZCV_MASK);
+ tcg_gen_or_i32(fpscr, fpscr, tmp);
+ store_cpu_field(fpscr, vfp.xregs[ARM_VFP_FPSCR]);
+ tcg_temp_free_i32(tmp);
+ break;
+ }
default:
g_assert_not_reached();
}
@@ -711,6 +732,12 @@ static bool gen_M_fp_sysreg_read(DisasContext *s, int regno,
gen_helper_vfp_get_fpscr(tmp, cpu_env);
storefn(s, opaque, tmp);
break;
+ case ARM_VFP_FPSCR_NZCVQC:
+ /*
+ * TODO: MVE has a QC bit, which we probably won't store
+ * in the xregs[] field. For non-MVE, where QC is RES0,
+ * we can just fall through to the FPSCR_NZCV case.
+ */
case QEMU_VFP_FPSCR_NZCV:
/*
* Read just NZCV; this is a special case to avoid the