Index: src/mips64/assembler-mips64.cc |
diff --git a/src/mips64/assembler-mips64.cc b/src/mips64/assembler-mips64.cc |
index 09a19169d677454b241592a05424405c46729680..f9032aa051ac5bfa5ac3922a465941073e1022a5 100644 |
--- a/src/mips64/assembler-mips64.cc |
+++ b/src/mips64/assembler-mips64.cc |
@@ -1940,9 +1940,27 @@ void Assembler::dlsa(Register rd, Register rt, Register rs, uint8_t sa) { |
void Assembler::LoadRegPlusOffsetToAt(const MemOperand& src) { |
DCHECK(!src.rm().is(at)); |
DCHECK(is_int32(src.offset_)); |
- lui(at, (src.offset_ >> kLuiShift) & kImm16Mask); |
- ori(at, at, src.offset_ & kImm16Mask); // Load 32-bit offset. |
- daddu(at, at, src.rm()); // Add base register. |
+ |
+ if (kArchVariant == kMips64r6) { |
+ int32_t hi = (src.offset_ >> kLuiShift) & kImm16Mask; |
+ if (src.offset_ & kNegOffset) { |
+ if ((hi & kNegOffset) != ((hi + 1) & kNegOffset)) { |
+ lui(at, (src.offset_ >> kLuiShift) & kImm16Mask); |
+ ori(at, at, src.offset_ & kImm16Mask); // Load 32-bit offset. |
+ daddu(at, at, src.rm()); // Add base register. |
+ return; |
+ } |
+ |
+ hi += 1; |
+ } |
+ |
+ daui(at, src.rm(), hi); |
+ daddiu(at, at, src.offset_ & kImm16Mask); |
+ } else { |
+ lui(at, (src.offset_ >> kLuiShift) & kImm16Mask); |
+ ori(at, at, src.offset_ & kImm16Mask); // Load 32-bit offset. |
+ daddu(at, at, src.rm()); // Add base register. |
+ } |
} |
// Helper for base-reg + upper part of offset, when offset is larger than int16. |
@@ -1965,8 +1983,12 @@ int32_t Assembler::LoadRegPlusUpperOffsetPartToAt(const MemOperand& src) { |
hi += 1; |
} |
- lui(at, hi); |
- daddu(at, at, src.rm()); |
+ if (kArchVariant == kMips64r6) { |
+ daui(at, src.rm(), hi); |
+ } else { |
+ lui(at, hi); |
+ daddu(at, at, src.rm()); |
+ } |
return (src.offset_ & kImm16Mask); |
} |