mirror of https://github.com/xqemu/xqemu.git
target-arm: Handle UNDEF cases for Neon "2 regs and shift" insns
Correctly handle all the UNDEF cases for Neon instructions of the "2 registers and shift" form, and make sure that we check for these cases early enough not to leak TCG temporaries. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
a5a14945da
commit
cc13115bde
|
@ -4744,7 +4744,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
/* Two registers and shift. */
|
/* Two registers and shift. */
|
||||||
op = (insn >> 8) & 0xf;
|
op = (insn >> 8) & 0xf;
|
||||||
if (insn & (1 << 7)) {
|
if (insn & (1 << 7)) {
|
||||||
/* 64-bit shift. */
|
/* 64-bit shift. */
|
||||||
|
if (op > 7) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
size = 3;
|
size = 3;
|
||||||
} else {
|
} else {
|
||||||
size = 2;
|
size = 2;
|
||||||
|
@ -4757,6 +4760,12 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
if (op < 8) {
|
if (op < 8) {
|
||||||
/* Shift by immediate:
|
/* Shift by immediate:
|
||||||
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
|
VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
|
||||||
|
if (q && ((rd | rm) & 1)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!u && (op == 4 || op == 6)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/* Right shifts are encoded as N - shift, where N is the
|
/* Right shifts are encoded as N - shift, where N is the
|
||||||
element size in bits. */
|
element size in bits. */
|
||||||
if (op <= 4)
|
if (op <= 4)
|
||||||
|
@ -4804,20 +4813,13 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
|
gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
|
||||||
break;
|
break;
|
||||||
case 4: /* VSRI */
|
case 4: /* VSRI */
|
||||||
if (!u)
|
|
||||||
return 1;
|
|
||||||
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
|
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
|
||||||
break;
|
break;
|
||||||
case 5: /* VSHL, VSLI */
|
case 5: /* VSHL, VSLI */
|
||||||
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
|
gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
|
||||||
break;
|
break;
|
||||||
case 6: /* VQSHLU */
|
case 6: /* VQSHLU */
|
||||||
if (u) {
|
gen_helper_neon_qshlu_s64(cpu_V0, cpu_V0, cpu_V1);
|
||||||
gen_helper_neon_qshlu_s64(cpu_V0,
|
|
||||||
cpu_V0, cpu_V1);
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 7: /* VQSHL */
|
case 7: /* VQSHL */
|
||||||
if (u) {
|
if (u) {
|
||||||
|
@ -4865,8 +4867,6 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
GEN_NEON_INTEGER_OP(rshl);
|
GEN_NEON_INTEGER_OP(rshl);
|
||||||
break;
|
break;
|
||||||
case 4: /* VSRI */
|
case 4: /* VSRI */
|
||||||
if (!u)
|
|
||||||
return 1;
|
|
||||||
GEN_NEON_INTEGER_OP(shl);
|
GEN_NEON_INTEGER_OP(shl);
|
||||||
break;
|
break;
|
||||||
case 5: /* VSHL, VSLI */
|
case 5: /* VSHL, VSLI */
|
||||||
|
@ -4874,13 +4874,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
|
case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
|
||||||
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
|
case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
|
||||||
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
|
case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
|
||||||
default: return 1;
|
default: abort();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 6: /* VQSHLU */
|
case 6: /* VQSHLU */
|
||||||
if (!u) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 0:
|
case 0:
|
||||||
gen_helper_neon_qshlu_s8(tmp, tmp, tmp2);
|
gen_helper_neon_qshlu_s8(tmp, tmp, tmp2);
|
||||||
|
@ -4892,7 +4889,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
gen_helper_neon_qshlu_s32(tmp, tmp, tmp2);
|
gen_helper_neon_qshlu_s32(tmp, tmp, tmp2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 1;
|
abort();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 7: /* VQSHL */
|
case 7: /* VQSHL */
|
||||||
|
@ -4950,7 +4947,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
/* Shift by immediate and narrow:
|
/* Shift by immediate and narrow:
|
||||||
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
|
VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
|
||||||
int input_unsigned = (op == 8) ? !u : u;
|
int input_unsigned = (op == 8) ? !u : u;
|
||||||
|
if (rm & 1) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
shift = shift - (1 << (size + 3));
|
shift = shift - (1 << (size + 3));
|
||||||
size++;
|
size++;
|
||||||
if (size == 3) {
|
if (size == 3) {
|
||||||
|
@ -5018,9 +5017,10 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
tcg_temp_free_i32(tmp2);
|
tcg_temp_free_i32(tmp2);
|
||||||
}
|
}
|
||||||
} else if (op == 10) {
|
} else if (op == 10) {
|
||||||
/* VSHLL */
|
/* VSHLL, VMOVL */
|
||||||
if (q || size == 3)
|
if (q || (rd & 1)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
tmp = neon_load_reg(rm, 0);
|
tmp = neon_load_reg(rm, 0);
|
||||||
tmp2 = neon_load_reg(rm, 1);
|
tmp2 = neon_load_reg(rm, 1);
|
||||||
for (pass = 0; pass < 2; pass++) {
|
for (pass = 0; pass < 2; pass++) {
|
||||||
|
@ -5061,6 +5061,9 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
}
|
}
|
||||||
} else if (op >= 14) {
|
} else if (op >= 14) {
|
||||||
/* VCVT fixed-point. */
|
/* VCVT fixed-point. */
|
||||||
|
if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/* We have already masked out the must-be-1 top bit of imm6,
|
/* We have already masked out the must-be-1 top bit of imm6,
|
||||||
* hence this 32-shift where the ARM ARM has 64-imm6.
|
* hence this 32-shift where the ARM ARM has 64-imm6.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue