target/arm/translate-a64: Don't underdecode FP insns

In the encoding groups
* floating-point data-processing (1 source)
* floating-point data-processing (2 source)
* floating-point data-processing (3 source)
* floating-point immediate
* floating-point compare
* floating-ponit conditional compare
* floating-point conditional select

bit 31 is M and bit 29 is S (and bit 30 is 0, already checked at
this point in the decode). None of these groups allocate any
encoding for M=1 or S=1. We checked this in disas_fp_compare(),
disas_fp_ccomp() and disas_fp_csel(), but missed it in disas_fp_1src(),
disas_fp_2src(), disas_fp_3src() and disas_fp_imm().

We also missed that in the fp immediate encoding the imm5 field
must be all zeroes.

Correctly UNDEF the unallocated encodings here.

Backports commit c1e20801f5ee53472dbf2757df605543f3f4ce0b from qemu
This commit is contained in:
Peter Maydell 2019-02-03 17:39:09 -05:00 committed by Lioncash
parent 1128b4d77d
commit f7d78d9e08
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -5743,11 +5743,17 @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
*/
static void disas_fp_1src(DisasContext *s, uint32_t insn)
{
int mos = extract32(insn, 29, 3);
int type = extract32(insn, 22, 2);
int opcode = extract32(insn, 15, 6);
int rn = extract32(insn, 5, 5);
int rd = extract32(insn, 0, 5);
if (mos) {
unallocated_encoding(s);
return;
}
switch (opcode) {
case 0x4: case 0x5: case 0x7:
{
@ -5978,13 +5984,14 @@ static void handle_fp_2src_half(DisasContext *s, int opcode,
*/
static void disas_fp_2src(DisasContext *s, uint32_t insn)
{
int mos = extract32(insn, 29, 3);
int type = extract32(insn, 22, 2);
int rd = extract32(insn, 0, 5);
int rn = extract32(insn, 5, 5);
int rm = extract32(insn, 16, 5);
int opcode = extract32(insn, 12, 4);
if (opcode > 8) {
if (opcode > 8 || mos) {
unallocated_encoding(s);
return;
}
@ -6143,6 +6150,7 @@ static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1,
*/
static void disas_fp_3src(DisasContext *s, uint32_t insn)
{
int mos = extract32(insn, 29, 3);
int type = extract32(insn, 22, 2);
int rd = extract32(insn, 0, 5);
int rn = extract32(insn, 5, 5);
@ -6151,6 +6159,11 @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
bool o0 = extract32(insn, 15, 1);
bool o1 = extract32(insn, 21, 1);
if (mos) {
unallocated_encoding(s);
return;
}
switch (type) {
case 0:
if (!fp_access_check(s)) {
@ -6221,12 +6234,19 @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
int rd = extract32(insn, 0, 5);
int imm5 = extract32(insn, 5, 5);
int imm8 = extract32(insn, 13, 8);
int type = extract32(insn, 22, 2);
int mos = extract32(insn, 29, 3);
uint64_t imm;
TCGv_i64 tcg_res;
TCGMemOp sz;
if (mos || imm5) {
unallocated_encoding(s);
return;
}
switch (type) {
case 0:
sz = MO_32;