Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Unified Diff: src/mips64/assembler-mips64.cc

Issue 1147503002: MIPS64: Improve long branches utilizing code range. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixed typo, addressed stale comment. Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/mips64/assembler-mips64.h ('k') | src/mips64/assembler-mips64-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mips64/assembler-mips64.cc
diff --git a/src/mips64/assembler-mips64.cc b/src/mips64/assembler-mips64.cc
index 2bec3f064a3eeb99838d81cbd0c52fb72eedf5d7..75c94459753661348ad10d64cbd5e37f9871ad3f 100644
--- a/src/mips64/assembler-mips64.cc
+++ b/src/mips64/assembler-mips64.cc
@@ -637,7 +637,7 @@ int Assembler::target_at(int pos, bool is_internal) {
}
}
// Check we have a branch or jump instruction.
- DCHECK(IsBranch(instr) || IsLui(instr));
+ DCHECK(IsBranch(instr) || IsJ(instr) || IsJal(instr) || IsLui(instr));
// Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
// the compiler uses arithmetic shifts for signed integers.
if (IsBranch(instr)) {
@@ -673,8 +673,18 @@ int Assembler::target_at(int pos, bool is_internal) {
return pos - delta;
}
} else {
- UNREACHABLE();
- return 0;
+ DCHECK(IsJ(instr) || IsJal(instr));
+ int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
+ if (imm28 == kEndOfJumpChain) {
+ // EndOfChain sentinel is returned directly, not relative to pc or pos.
+ return kEndOfChain;
+ } else {
+ uint64_t instr_address = reinterpret_cast<int64_t>(buffer_ + pos);
+ instr_address &= kImm28Mask;
+ int delta = static_cast<int>(instr_address - imm28);
+ DCHECK(pos > delta);
+ return pos - delta;
+ }
}
}
@@ -694,7 +704,7 @@ void Assembler::target_at_put(int pos, int target_pos, bool is_internal) {
return;
}
- DCHECK(IsBranch(instr) || IsLui(instr));
+ DCHECK(IsBranch(instr) || IsJ(instr) || IsJal(instr) || IsLui(instr));
if (IsBranch(instr)) {
int32_t imm18 = target_pos - (pos + kBranchPCOffset);
DCHECK((imm18 & 3) == 0);
@@ -725,7 +735,16 @@ void Assembler::target_at_put(int pos, int target_pos, bool is_internal) {
instr_at_put(pos + 3 * Assembler::kInstrSize,
instr_ori2 | (imm & kImm16Mask));
} else {
- UNREACHABLE();
+ DCHECK(IsJ(instr) || IsJal(instr));
+ uint64_t imm28 = reinterpret_cast<uint64_t>(buffer_) + target_pos;
+ imm28 &= kImm28Mask;
+ DCHECK((imm28 & 3) == 0);
+
+ instr &= ~kImm26Mask;
+ uint32_t imm26 = imm28 >> 2;
+ DCHECK(is_uint26(imm26));
+
+ instr_at_put(pos, instr | (imm26 & kImm26Mask));
}
}
@@ -787,7 +806,8 @@ void Assembler::bind_to(Label* L, int pos) {
}
target_at_put(fixup_pos, pos, false);
} else {
- DCHECK(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr));
+ DCHECK(IsJ(instr) || IsJal(instr) || IsLui(instr) ||
+ IsEmittedConstant(instr));
target_at_put(fixup_pos, pos, false);
}
}
@@ -984,7 +1004,6 @@ uint64_t Assembler::jump_address(Label* L) {
return kEndOfJumpChain;
}
}
-
uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
DCHECK((imm & 3) == 0);
@@ -1359,12 +1378,14 @@ void Assembler::bnezc(Register rs, int32_t offset) {
void Assembler::j(int64_t target) {
#if DEBUG
// Get pc of delay slot.
- uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
- bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
- (kImm26Bits + kImmFieldShift)) == 0;
- DCHECK(in_range && ((target & 3) == 0));
+ if (target != kEndOfJumpChain) {
+ uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
+ bool in_range = ((ipc ^ static_cast<uint64_t>(target)) >>
+ (kImm26Bits + kImmFieldShift)) == 0;
+ DCHECK(in_range && ((target & 3) == 0));
+ }
#endif
- GenInstrJump(J, target >> 2);
+ GenInstrJump(J, (target >> 2) & kImm26Mask);
}
@@ -1385,13 +1406,15 @@ void Assembler::jr(Register rs) {
void Assembler::jal(int64_t target) {
#ifdef DEBUG
// Get pc of delay slot.
- uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
- bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
- (kImm26Bits + kImmFieldShift)) == 0;
- DCHECK(in_range && ((target & 3) == 0));
+ if (target != kEndOfJumpChain) {
+ uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
+ bool in_range = ((ipc ^ static_cast<uint64_t>(target)) >>
+ (kImm26Bits + kImmFieldShift)) == 0;
+ DCHECK(in_range && ((target & 3) == 0));
+ }
#endif
positions_recorder()->WriteRecordedPositions();
- GenInstrJump(JAL, target >> 2);
+ GenInstrJump(JAL, (target >> 2) & kImm26Mask);
}
@@ -2764,6 +2787,7 @@ int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
}
Instr instr = instr_at(pc);
DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode));
+ DCHECK(IsJ(instr) || IsLui(instr) || IsJal(instr));
if (IsLui(instr)) {
Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
@@ -2795,8 +2819,21 @@ int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
instr_ori2 | (imm & kImm16Mask));
return 4; // Number of instructions patched.
} else {
- UNREACHABLE();
- return 0; // Number of instructions patched.
+ uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
+ if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
+ return 0; // Number of instructions patched.
+ }
+
+ imm28 += pc_delta;
+ imm28 &= kImm28Mask;
+ DCHECK((imm28 & 3) == 0);
+
+ instr &= ~kImm26Mask;
+ uint32_t imm26 = imm28 >> 2;
+ DCHECK(is_uint26(imm26));
+
+ instr_at_put(pc, instr | (imm26 & kImm26Mask));
+ return 1; // Number of instructions patched.
}
}
@@ -2958,14 +2995,8 @@ void Assembler::CheckTrampolinePool() {
// references until associated instructions are emitted and available
// to be patched.
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
- // TODO(plind): Verify this, presume I cannot use macro-assembler
- // here.
- lui(at, (imm64 >> 32) & kImm16Mask);
- ori(at, at, (imm64 >> 16) & kImm16Mask);
- dsll(at, at, 16);
- ori(at, at, imm64 & kImm16Mask);
+ j(imm64);
}
- jr(at);
nop();
}
bind(&after_pool);
« no previous file with comments | « src/mips64/assembler-mips64.h ('k') | src/mips64/assembler-mips64-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698