arm: Enforce should-be-1 bits in MRS decoding

The MRS instruction requires that bits [19..16] are all 1s, and for
A/R profile also that bits [7..0] are all 0s. At this point in the
decode tree we have checked all of the rest of the instruction but
were allowing these to be any value. If these bits are not set then
the result is architecturally UNPREDICTABLE, but choosing to UNDEF is
more helpful to the user and avoids unexpected odd behaviour if the
encodings are used for some purpose in future architecture versions.

Backports commit 3d54026fb06d1aea7ebb4e9825970b06bebcacac from qemu
This commit is contained in:
Peter Maydell 2018-03-02 13:09:15 -05:00 committed by Lioncash
parent dc44eded51
commit d8eb259032
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -10660,6 +10660,14 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
break;
}
if (extract32(insn, 16, 4) != 0xf) {
goto illegal_op;
}
if (!arm_dc_feature(s, ARM_FEATURE_M) &&
extract32(insn, 0, 8) != 0) {
goto illegal_op;
}
/* mrs cpsr */
tmp = tcg_temp_new_i32(tcg_ctx);
if (arm_dc_feature(s, ARM_FEATURE_M)) {
@ -10687,6 +10695,12 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
goto illegal_op;
}
if (extract32(insn, 16, 4) != 0xf ||
extract32(insn, 0, 8) != 0) {
goto illegal_op;
}
tmp = load_cpu_field(s->uc, spsr);
store_reg(s, rd, tmp);
break;