mirror of https://github.com/xemu-project/xemu.git
target-arm: fix neon vsri, vshl and vsli ops
Shift by immediate value is incorrectly overwritten by a temporary variable in the processing of NEON vsri, vshl and vsli instructions. This patch has been revised to also include a fix for the special case where the code would previously try to shift an integer value over 31 bits left/right. Signed-off-by: Juha Riihimäki <juha.riihimaki@nokia.com> Acked-by: Laurent Desnogues <laurent.desnogues@gmail.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
71b3c3dea2
commit
ca9a32e4f3
|
@ -4096,7 +4096,7 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
int pairwise;
|
int pairwise;
|
||||||
int u;
|
int u;
|
||||||
int n;
|
int n;
|
||||||
uint32_t imm;
|
uint32_t imm, mask;
|
||||||
TCGv tmp, tmp2, tmp3, tmp4, tmp5;
|
TCGv tmp, tmp2, tmp3, tmp4, tmp5;
|
||||||
TCGv_i64 tmp64;
|
TCGv_i64 tmp64;
|
||||||
|
|
||||||
|
@ -4624,31 +4624,35 @@ static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 0:
|
case 0:
|
||||||
if (op == 4)
|
if (op == 4)
|
||||||
imm = 0xff >> -shift;
|
mask = 0xff >> -shift;
|
||||||
else
|
else
|
||||||
imm = (uint8_t)(0xff << shift);
|
mask = (uint8_t)(0xff << shift);
|
||||||
imm |= imm << 8;
|
mask |= mask << 8;
|
||||||
imm |= imm << 16;
|
mask |= mask << 16;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
if (op == 4)
|
if (op == 4)
|
||||||
imm = 0xffff >> -shift;
|
mask = 0xffff >> -shift;
|
||||||
else
|
else
|
||||||
imm = (uint16_t)(0xffff << shift);
|
mask = (uint16_t)(0xffff << shift);
|
||||||
imm |= imm << 16;
|
mask |= mask << 16;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (op == 4)
|
if (shift < -31 || shift > 31) {
|
||||||
imm = 0xffffffffu >> -shift;
|
mask = 0;
|
||||||
else
|
} else {
|
||||||
imm = 0xffffffffu << shift;
|
if (op == 4)
|
||||||
|
mask = 0xffffffffu >> -shift;
|
||||||
|
else
|
||||||
|
mask = 0xffffffffu << shift;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
tmp2 = neon_load_reg(rd, pass);
|
tmp2 = neon_load_reg(rd, pass);
|
||||||
tcg_gen_andi_i32(tmp, tmp, imm);
|
tcg_gen_andi_i32(tmp, tmp, mask);
|
||||||
tcg_gen_andi_i32(tmp2, tmp2, ~imm);
|
tcg_gen_andi_i32(tmp2, tmp2, ~mask);
|
||||||
tcg_gen_or_i32(tmp, tmp, tmp2);
|
tcg_gen_or_i32(tmp, tmp, tmp2);
|
||||||
dead_tmp(tmp2);
|
dead_tmp(tmp2);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue