aboutsummaryrefslogtreecommitdiff
path: root/target/arm/translate-vfp.c.inc
diff options
context:
space:
mode:
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