diff options
author | Jiaxun Yang <jiaxun.yang@flygoat.com> | 2020-05-12 12:40:05 +0800 |
---|---|---|
committer | Jiaxun Yang <jiaxun.yang@flygoat.com> | 2020-05-14 16:31:55 +0800 |
commit | a78f517c40f3c81bba5c2a718ee41af844ac7015 (patch) | |
tree | 67871a5e4c6624bcd12d0cd5af44a8794899697d /js/src/jit | |
parent | 4fc1cd5563bf3b7312ccd8317f296a8142ba2ff5 (diff) | |
download | UXP-a78f517c40f3c81bba5c2a718ee41af844ac7015.tar UXP-a78f517c40f3c81bba5c2a718ee41af844ac7015.tar.gz UXP-a78f517c40f3c81bba5c2a718ee41af844ac7015.tar.lz UXP-a78f517c40f3c81bba5c2a718ee41af844ac7015.tar.xz UXP-a78f517c40f3c81bba5c2a718ee41af844ac7015.zip |
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
Diffstat (limited to 'js/src/jit')
-rw-r--r-- | js/src/jit/mips64/MacroAssembler-mips64.cpp | 55 |
1 files changed, 32 insertions, 23 deletions
diff --git a/js/src/jit/mips64/MacroAssembler-mips64.cpp b/js/src/jit/mips64/MacroAssembler-mips64.cpp index f58184bca..7021d0f74 100644 --- a/js/src/jit/mips64/MacroAssembler-mips64.cpp +++ b/js/src/jit/mips64/MacroAssembler-mips64.cpp @@ -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()); + return; + } + if (0 == (value >> 16)) { + as_ori(dest, zero, value); + return; + } + + 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 { - uint64_t high = imm.value >> 32; - - if (imm.value >> 48) { - as_lui(dest, Imm16::Upper(Imm32(high)).encode()); - if (high & 0xffff) - as_ori(dest, dest, Imm16::Lower(Imm32(high)).encode()); + 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 |