MIPS: Optimize load/store with large offset on MIPSr6

Replace the sequence LUI+(D)ADD with (D)AUI

BUG=

Review-Url: https://codereview.chromium.org/2535703002
Cr-Commit-Position: refs/heads/master@{#41425}
This commit is contained in:
marija.antic 2016-12-01 05:10:27 -08:00 committed by Commit bot
parent 1bf32cf5f9
commit 51159360d4
2 changed files with 46 additions and 10 deletions

View File

@ -1778,9 +1778,18 @@ void Assembler::lsa(Register rd, Register rt, Register rs, uint8_t sa) {
// Helper for base-reg + offset, when offset is larger than int16.
void Assembler::LoadRegPlusOffsetToAt(const MemOperand& src) {
DCHECK(!src.rm().is(at));
lui(at, (src.offset_ >> kLuiShift) & kImm16Mask);
ori(at, at, src.offset_ & kImm16Mask); // Load 32-bit offset.
addu(at, at, src.rm()); // Add base register.
if (IsMipsArchVariant(kMips32r6)) {
int32_t hi = (src.offset_ >> kLuiShift) & kImm16Mask;
if (src.offset_ & kNegOffset) {
hi += 1;
}
aui(at, src.rm(), hi);
addiu(at, at, src.offset_ & kImm16Mask);
} else {
lui(at, (src.offset_ >> kLuiShift) & kImm16Mask);
ori(at, at, src.offset_ & kImm16Mask); // Load 32-bit offset.
addu(at, at, src.rm()); // Add base register.
}
}
// Helper for base-reg + upper part of offset, when offset is larger than int16.
@ -1796,8 +1805,13 @@ int32_t Assembler::LoadRegPlusUpperOffsetPartToAt(const MemOperand& src) {
if (src.offset_ & kNegOffset) {
hi += 1;
}
lui(at, hi);
addu(at, at, src.rm());
if (IsMipsArchVariant(kMips32r6)) {
aui(at, src.rm(), hi);
} else {
lui(at, hi);
addu(at, at, src.rm());
}
return (src.offset_ & kImm16Mask);
}

View File

@ -1939,9 +1939,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.
@ -1964,8 +1982,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);
}