mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-25 11:46:58 +00:00
target/arm: Restructure disas_fp_int_conv
For opcodes 0-5, move some if conditions into the structure of a switch statement. For opcodes 6 & 7, decode everything at once with a second switch. Backports commit 3c3ff68492c2d00bd8cb39ed2d02bdaf5caf5cb8 from qemu
This commit is contained in:
parent
5c153537f5
commit
d6fbc0f4f3
|
@ -6659,68 +6659,72 @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
|
||||||
int type = extract32(insn, 22, 2);
|
int type = extract32(insn, 22, 2);
|
||||||
bool sbit = extract32(insn, 29, 1);
|
bool sbit = extract32(insn, 29, 1);
|
||||||
bool sf = extract32(insn, 31, 1);
|
bool sf = extract32(insn, 31, 1);
|
||||||
|
bool itof = false;
|
||||||
|
|
||||||
if (sbit) {
|
if (sbit) {
|
||||||
unallocated_encoding(s);
|
goto do_unallocated;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcode > 5) {
|
switch (opcode) {
|
||||||
/* FMOV */
|
case 2: /* SCVTF */
|
||||||
bool itof = opcode & 1;
|
case 3: /* UCVTF */
|
||||||
|
itof = true;
|
||||||
if (rmode >= 2) {
|
/* fallthru */
|
||||||
unallocated_encoding(s);
|
case 4: /* FCVTAS */
|
||||||
return;
|
case 5: /* FCVTAU */
|
||||||
}
|
if (rmode != 0) {
|
||||||
|
goto do_unallocated;
|
||||||
switch (sf << 3 | type << 1 | rmode) {
|
|
||||||
case 0x0: /* 32 bit */
|
|
||||||
case 0xa: /* 64 bit */
|
|
||||||
case 0xd: /* 64 bit to top half of quad */
|
|
||||||
break;
|
|
||||||
case 0x6: /* 16-bit float, 32-bit int */
|
|
||||||
case 0xe: /* 16-bit float, 64-bit int */
|
|
||||||
if (dc_isar_feature(aa64_fp16, s)) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
/* fallthru */
|
/* fallthru */
|
||||||
default:
|
case 0: /* FCVT[NPMZ]S */
|
||||||
/* all other sf/type/rmode combinations are invalid */
|
case 1: /* FCVT[NPMZ]U */
|
||||||
unallocated_encoding(s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fp_access_check(s)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handle_fmov(s, rd, rn, type, itof);
|
|
||||||
} else {
|
|
||||||
/* actual FP conversions */
|
|
||||||
bool itof = extract32(opcode, 1, 1);
|
|
||||||
|
|
||||||
if (rmode != 0 && opcode > 1) {
|
|
||||||
unallocated_encoding(s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0: /* float32 */
|
case 0: /* float32 */
|
||||||
case 1: /* float64 */
|
case 1: /* float64 */
|
||||||
break;
|
break;
|
||||||
case 3: /* float16 */
|
case 3: /* float16 */
|
||||||
if (dc_isar_feature(aa64_fp16, s)) {
|
if (!dc_isar_feature(aa64_fp16, s)) {
|
||||||
|
goto do_unallocated;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
/* fallthru */
|
|
||||||
default:
|
default:
|
||||||
unallocated_encoding(s);
|
goto do_unallocated;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fp_access_check(s)) {
|
if (!fp_access_check(s)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type);
|
handle_fpfpcvt(s, rd, rn, opcode, itof, rmode, 64, sf, type);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
switch (sf << 7 | type << 5 | rmode << 3 | opcode) {
|
||||||
|
case 0x66: /* FMOV half <-> 32-bit int */
|
||||||
|
case 0x67:
|
||||||
|
case 0xE6: /* FMOV half <-> 64-bit int */
|
||||||
|
case 0xE7:
|
||||||
|
if (!dc_isar_feature(aa64_fp16, s)) {
|
||||||
|
goto do_unallocated;
|
||||||
|
}
|
||||||
|
/* fallthru */
|
||||||
|
case 0x06: /* FMOV 32-bit */
|
||||||
|
case 0x07:
|
||||||
|
case 0xA6: /* FMOV 64-bit */
|
||||||
|
case 0xA7:
|
||||||
|
case 0xCE: /* FMOV top half of 128-bit */
|
||||||
|
case 0xCF:
|
||||||
|
if (!fp_access_check(s)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
itof = opcode & 1;
|
||||||
|
handle_fmov(s, rd, rn, type, itof);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
do_unallocated:
|
||||||
|
unallocated_encoding(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue