Skip to content

Commit

Permalink
target/arm: Don't NOCP fault for FPCXT_NS accesses
Browse files Browse the repository at this point in the history
The M-profile architecture requires that accesses to FPCXT_NS when
there is no active FP state must not take a NOCP fault even if the
FPU is disabled. We were not implementing this correctly, because
in our decode we catch the NOCP faults early in m-nocp.decode.

Fix this bug by moving all the handling of M-profile FP system
register accesses from vfp.decode into m-nocp.decode and putting
it above the NOCP blocks. This provides the correct behaviour:
 * for accesses other than FPCXT_NS the trans functions call
   vfp_access_check(), which will check for FPU disabled and
   raise a NOCP exception if necessary
 * for FPCXT_NS we have the special case code that doesn't
   call vfp_access_check()
 * when these trans functions want to raise an UNDEF they return
   false, so the decoder will fall through into the NOCP blocks.
   This means that NOCP correctly takes precedence over UNDEF
   for these insns. (This is a difference from the other insns
   handled by m-nocp.decode, where UNDEF takes precedence and
   which we implement by having those trans functions call
   unallocated_encoding() in the appropriate places.)

[Note for backport to stable: this commit has a semantic dependency
on commit 9a48685, which was not marked as cc-stable because
we didn't know we'd need it for a for-stable bugfix.]

Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210618141019.10671-4-peter.maydell@linaro.org
  • Loading branch information
pm215 committed Jun 21, 2021
1 parent 9931d9d commit fa85673
Show file tree
Hide file tree
Showing 5 changed files with 542 additions and 528 deletions.
24 changes: 24 additions & 0 deletions target/arm/m-nocp.decode
Expand Up @@ -34,13 +34,37 @@

&nocp cp

# M-profile VLDR/VSTR to sysreg
%vldr_sysreg 22:1 13:3
%imm7_0x4 0:7 !function=times_4

&vldr_sysreg rn reg imm a w p
@vldr_sysreg .... ... . a:1 . . . rn:4 ... . ... .. ....... \
reg=%vldr_sysreg imm=%imm7_0x4 &vldr_sysreg

{
# Special cases which do not take an early NOCP: VLLDM and VLSTM
VLLDM_VLSTM 1110 1100 001 l:1 rn:4 0000 1010 op:1 000 0000
# VSCCLRM (new in v8.1M) is similar:
VSCCLRM 1110 1100 1.01 1111 .... 1011 imm:7 0 vd=%vd_dp size=3
VSCCLRM 1110 1100 1.01 1111 .... 1010 imm:8 vd=%vd_sp size=2

# FP system register accesses: these are a special case because accesses
# to FPCXT_NS succeed even if the FPU is disabled. We therefore need
# to handle them before the big NOCP blocks. Note that within these
# insns NOCP still has higher priority than UNDEFs; this is implemented
# by their returning 'false' for UNDEF so as to fall through into the
# NOCP check (in contrast to VLLDM etc, which call unallocated_encoding()
# for the UNDEFs there that must take precedence over NOCP.)

VMSR_VMRS ---- 1110 111 l:1 reg:4 rt:4 1010 0001 0000

# P=0 W=0 is SEE "Related encodings", so split into two patterns
VLDR_sysreg ---- 110 1 . . w:1 1 .... ... 0 111 11 ....... @vldr_sysreg p=1
VLDR_sysreg ---- 110 0 . . 1 1 .... ... 0 111 11 ....... @vldr_sysreg p=0 w=1
VSTR_sysreg ---- 110 1 . . w:1 0 .... ... 0 111 11 ....... @vldr_sysreg p=1
VSTR_sysreg ---- 110 0 . . 1 0 .... ... 0 111 11 ....... @vldr_sysreg p=0 w=1

NOCP 111- 1110 ---- ---- ---- cp:4 ---- ---- &nocp
NOCP 111- 110- ---- ---- ---- cp:4 ---- ---- &nocp
# From v8.1M onwards this range will also NOCP:
Expand Down
1 change: 1 addition & 0 deletions target/arm/translate-a32.h
Expand Up @@ -32,6 +32,7 @@ bool disas_neon_shared(DisasContext *s, uint32_t insn);
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
void arm_gen_condlabel(DisasContext *s);
bool vfp_access_check(DisasContext *s);
void gen_preserve_fp_state(DisasContext *s);
void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop);
void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop);
void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop);
Expand Down

0 comments on commit fa85673

Please sign in to comment.