mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-08 00:38:39 +09:00
Bug 1323642 - IonMonkey: MIPS64: Fix load unsigned 48-bit immediate
Issue: In ma_li(Register, ImmWord): Load unsigned 48-bit immediate: 0x0000_8000_0000_0000 Wrong instructions stream: lui reg, 0x8000 dsll reg, reg, 16 # reg = 0xffff_8000_0000_0000 Fixed instructions stream: lui reg, 0x8000 dinsu reg, zero, 32, 32 dsll reg, reg, 16 Tag: #1542
This commit is contained in:
parent
c15d832a98
commit
e293ccbcd4
1 changed files with 32 additions and 23 deletions
|
|
@ -258,36 +258,45 @@ MacroAssemblerMIPS64::ma_li(Register dest, ImmWord imm)
|
|||
{
|
||||
int64_t value = imm.value;
|
||||
|
||||
if (value >= INT16_MIN && value <= INT16_MAX) {
|
||||
if (-1 == (value >> 15) || 0 == (value >> 15)) {
|
||||
as_addiu(dest, zero, value);
|
||||
} else if (imm.value <= UINT16_MAX) {
|
||||
as_ori(dest, zero, Imm16::Lower(Imm32(value)).encode());
|
||||
} else if (value >= INT32_MIN && value <= INT32_MAX) {
|
||||
as_lui(dest, Imm16::Upper(Imm32(value)).encode());
|
||||
if (value & 0xffff)
|
||||
as_ori(dest, dest, Imm16::Lower(Imm32(value)).encode());
|
||||
} else if (imm.value <= UINT32_MAX) {
|
||||
as_lui(dest, Imm16::Upper(Imm32(value)).encode());
|
||||
if (value & 0xffff)
|
||||
as_ori(dest, dest, Imm16::Lower(Imm32(value)).encode());
|
||||
as_dinsu(dest, zero, 32, 32);
|
||||
} else {
|
||||
uint64_t high = imm.value >> 32;
|
||||
return;
|
||||
}
|
||||
if (0 == (value >> 16)) {
|
||||
as_ori(dest, zero, value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (imm.value >> 48) {
|
||||
as_lui(dest, Imm16::Upper(Imm32(high)).encode());
|
||||
if (high & 0xffff)
|
||||
as_ori(dest, dest, Imm16::Lower(Imm32(high)).encode());
|
||||
if (-1 == (value >> 31) || 0 == (value >> 31)) {
|
||||
as_lui(dest, uint16_t(value >> 16));
|
||||
} else if (0 == (value >> 32)) {
|
||||
as_lui(dest, uint16_t(value >> 16));
|
||||
as_dinsu(dest, zero, 32, 32);
|
||||
} else if (-1 == (value >> 47) || 0 == (value >> 47)) {
|
||||
as_lui(dest, uint16_t(value >> 32));
|
||||
if (uint16_t(value >> 16))
|
||||
as_ori(dest, dest, uint16_t(value >> 16));
|
||||
as_dsll(dest, dest, 16);
|
||||
} else if (0 == (value >> 48)) {
|
||||
as_lui(dest, uint16_t(value >> 32));
|
||||
as_dinsu(dest, zero, 32, 32);
|
||||
if (uint16_t(value >> 16))
|
||||
as_ori(dest, dest, uint16_t(value >> 16));
|
||||
as_dsll(dest, dest, 16);
|
||||
} else {
|
||||
as_lui(dest, uint16_t(value >> 48));
|
||||
if (uint16_t(value >> 32))
|
||||
as_ori(dest, dest, uint16_t(value >> 32));
|
||||
if (uint16_t(value >> 16)) {
|
||||
as_dsll(dest, dest, 16);
|
||||
as_ori(dest, dest, uint16_t(value >> 16));
|
||||
as_dsll(dest, dest, 16);
|
||||
} else {
|
||||
as_lui(dest, Imm16::Lower(Imm32(high)).encode());
|
||||
as_dsll32(dest, dest, 32);
|
||||
}
|
||||
if ((imm.value >> 16) & 0xffff)
|
||||
as_ori(dest, dest, Imm16::Upper(Imm32(value)).encode());
|
||||
as_dsll(dest, dest, 16);
|
||||
if (value & 0xffff)
|
||||
as_ori(dest, dest, Imm16::Lower(Imm32(value)).encode());
|
||||
}
|
||||
if (uint16_t(value))
|
||||
as_ori(dest, dest, uint16_t(value));
|
||||
}
|
||||
|
||||
// This method generates lui, dsll and ori instruction block that can be modified
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue