@samitouri / QOSamiQemu / commits / 2931a675e9

target/arm: Make Thumb T1 hint space UNDEF before v6T2

The "hint space" is a region of the encoding space which is defined to NOP if not specified as an architected instruction, so that future instructions can be added there which fall back to NOPs on older CPUs. In the A32 encoding, this hint space was carved out of the MSR (imm) insn by using the fact that a field_mask (bits [19:15]) of 0b0000 meant that an MSR (imm) would set no parts of the CPSR from the immediate, so it was always NOP on existing CPUs. For the T1 encoding, the hint space is in a range that used to UNDEF in Armv5, and so the hint insns and the NOP region must all UNDEF before v6T2. Rather than putting this check in the trans functions for each hint insn and for the NOP space (which is a lot of places, and awkward since those trans functions are often shared with the A64 and A32 encodings), put in a decode line that covers the whole space which we check before any of the hints and which will explicitly UNDEF if necessary. Cc: qemu-stable@nongnu.org Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4208 Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260821132550.168896-4-peter.maydell@linaro.org

Peter Maydell committed Aug 21, 2026 at 14:25 UTC 2931a675e9d3fcddedf673509fe9759955fc616d
2 files changed +21
target/arm/tcg/t16.decode
+3
@@ -224,6 +224,9 @@ REVSH 1011 1010 11 ... ... @rdm
224
225 {
226 {
227 + # Before v6T2 this was not NOP space and must UNDEF
228 + MAYBE_UNDEF_T1_HINT 1011 1111 ---- 0000
229 +
230 YIELD 1011 1111 0001 0000
231 WFE 1011 1111 0010 0000
232 WFI 1011 1111 0011 0000
target/arm/tcg/translate.c
+18
@@ -3340,6 +3340,24 @@ static bool trans_NOP(DisasContext *s, arg_NOP *a)
3340 return true;
3341 }
3342
3343 +static bool trans_MAYBE_UNDEF_T1_HINT(DisasContext *s,
3344 + arg_MAYBE_UNDEF_T1_HINT *a)
3345 +{
3346 + /*
3347 + * The Thumb T1 encoding hint space was only defined starting
3348 + * in v6T2 for A-profile. For M-profile it always exists, even
3349 + * in v6M.
3350 + */
3351 + if (arm_dc_feature(s, ARM_FEATURE_M) ||
3352 + arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
3353 + /* Allow decode to fall through to the hint insns and NOP space */
3354 + return false;
3355 + }
3356 + /* On the earlier cores, we must UNDEF */
3357 + unallocated_encoding(s);
3358 + return true;
3359 +}
3360 +
3361 static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
3362 {
3363 uint32_t val = ror32(a->imm, a->rot * 2);