summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiaxun Yang <jiaxun.yang@flygoat.com>2020-05-12 12:40:05 +0800
committerMoonchild <moonchild@palemoon.org>2020-05-20 14:00:15 +0000
commit609d904cc1340e240c875525dd79981e70c8524b (patch)
tree58eba992abe08bbcfc91e7d955f56be388e6ac57
parentfa1628f76785e18240c7c7aca63b99d490879461 (diff)
downloadUXP-609d904cc1340e240c875525dd79981e70c8524b.tar
UXP-609d904cc1340e240c875525dd79981e70c8524b.tar.gz
UXP-609d904cc1340e240c875525dd79981e70c8524b.tar.lz
UXP-609d904cc1340e240c875525dd79981e70c8524b.tar.xz
UXP-609d904cc1340e240c875525dd79981e70c8524b.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
-rw-r--r--js/src/jit/mips64/MacroAssembler-mips64.cpp55
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