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

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

Issue 930623003: MIPS64: Assembler support for internal references. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix compilation problem. Created 5 years, 10 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 7c0c76e9fcbd600dff16a3561fa11ab8259cf26a..4ce970da332c9e3a2a6ff0fbed5fedef7209a1c3 100644
--- a/src/mips64/assembler-mips64.cc
+++ b/src/mips64/assembler-mips64.cc
@@ -175,7 +175,8 @@ Register ToRegister(int num) {
// Implementation of RelocInfo.
const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
- 1 << RelocInfo::INTERNAL_REFERENCE;
+ 1 << RelocInfo::INTERNAL_REFERENCE |
+ 1 << RelocInfo::INTERNAL_REFERENCE_ENCODED;
bool RelocInfo::IsCodedSpecially() {
@@ -634,7 +635,19 @@ bool Assembler::IsAndImmediate(Instr instr) {
}
-int64_t Assembler::target_at(int64_t pos) {
+int64_t Assembler::target_at(int64_t pos, bool is_internal) {
+ if (is_internal) {
+ int64_t* p = reinterpret_cast<int64_t*>(buffer_ + pos);
+ int64_t address = *p;
+ if (address == kEndOfJumpChain) {
+ return kEndOfChain;
+ } else {
+ int64_t instr_address = reinterpret_cast<int64_t>(p);
+ int64_t delta = instr_address - address;
+ DCHECK(pos > delta);
+ return pos - delta;
+ }
+ }
Instr instr = instr_at(pos);
if ((instr & ~kImm16Mask) == 0) {
// Emitted label constant, not part of a branch.
@@ -696,7 +709,13 @@ int64_t Assembler::target_at(int64_t pos) {
}
-void Assembler::target_at_put(int64_t pos, int64_t target_pos) {
+void Assembler::target_at_put(int64_t pos, int64_t target_pos,
+ bool is_internal) {
+ if (is_internal) {
+ uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
+ *reinterpret_cast<uint64_t*>(buffer_ + pos) = imm;
+ return;
+ }
Instr instr = instr_at(pos);
if ((instr & ~kImm16Mask) == 0) {
DCHECK(target_pos == kEndOfChain || target_pos >= 0);
@@ -766,7 +785,8 @@ void Assembler::print(Label* L) {
} else {
PrintF("%d\n", instr);
}
- next(&l);
+ next(&l, internal_reference_positions_.find(l.pos()) !=
+ internal_reference_positions_.end());
}
} else {
PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
@@ -777,6 +797,7 @@ void Assembler::print(Label* L) {
void Assembler::bind_to(Label* L, int pos) {
DCHECK(0 <= pos && pos <= pc_offset()); // Must have valid binding position.
int32_t trampoline_pos = kInvalidSlotPos;
+ bool is_internal = false;
if (L->is_linked() && !trampoline_emitted_) {
unbound_labels_count_--;
next_buffer_check_ += kTrampolineSlotsSize;
@@ -785,23 +806,28 @@ void Assembler::bind_to(Label* L, int pos) {
while (L->is_linked()) {
int32_t fixup_pos = L->pos();
int32_t dist = pos - fixup_pos;
- next(L); // Call next before overwriting link with target at fixup_pos.
+ is_internal = internal_reference_positions_.find(fixup_pos) !=
+ internal_reference_positions_.end();
+ next(L, is_internal); // Call next before overwriting link with target at
+ // fixup_pos.
Instr instr = instr_at(fixup_pos);
- if (IsBranch(instr)) {
+ if (is_internal) {
+ target_at_put(fixup_pos, pos, is_internal);
+ } else if (IsBranch(instr)) {
if (dist > kMaxBranchOffset) {
if (trampoline_pos == kInvalidSlotPos) {
trampoline_pos = get_trampoline_entry(fixup_pos);
CHECK(trampoline_pos != kInvalidSlotPos);
}
DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset);
- target_at_put(fixup_pos, trampoline_pos);
+ target_at_put(fixup_pos, trampoline_pos, false);
fixup_pos = trampoline_pos;
dist = pos - fixup_pos;
}
- target_at_put(fixup_pos, pos);
+ target_at_put(fixup_pos, pos, false);
} else {
DCHECK(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr));
- target_at_put(fixup_pos, pos);
+ target_at_put(fixup_pos, pos, false);
}
}
L->bind_to(pos);
@@ -819,9 +845,9 @@ void Assembler::bind(Label* L) {
}
-void Assembler::next(Label* L) {
+void Assembler::next(Label* L, bool is_internal) {
DCHECK(L->is_linked());
- int link = target_at(L->pos());
+ int link = target_at(L->pos(), is_internal);
if (link == kEndOfChain) {
L->Unuse();
} else {
@@ -2559,8 +2585,18 @@ void Assembler::bc1t(int16_t offset, uint16_t cc) {
// Debugging.
-int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) {
+int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
+ intptr_t pc_delta) {
+ if (RelocInfo::IsInternalReference(rmode)) {
+ int64_t* p = reinterpret_cast<int64_t*>(pc);
+ if (*p == kEndOfJumpChain) {
+ return 0; // Number of instructions patched.
+ }
+ *p += pc_delta;
+ return 2; // Number of instructions patched.
+ }
Instr instr = instr_at(pc);
+ DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode));
DCHECK(IsJ(instr) || IsLui(instr));
if (IsLui(instr)) {
Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
@@ -2649,12 +2685,12 @@ void Assembler::GrowBuffer() {
// Relocate runtime entries.
for (RelocIterator it(desc); !it.done(); it.next()) {
RelocInfo::Mode rmode = it.rinfo()->rmode();
- if (rmode == RelocInfo::INTERNAL_REFERENCE) {
+ if (rmode == RelocInfo::INTERNAL_REFERENCE_ENCODED ||
+ rmode == RelocInfo::INTERNAL_REFERENCE) {
byte* p = reinterpret_cast<byte*>(it.rinfo()->pc());
- RelocateInternalReference(p, pc_delta);
+ RelocateInternalReference(rmode, p, pc_delta);
}
}
-
DCHECK(!overflow());
}
@@ -2673,6 +2709,21 @@ void Assembler::dd(uint32_t data) {
}
+void Assembler::dd(Label* label) {
+ CheckBuffer();
+ RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
+ if (label->is_bound()) {
+ uint64_t data = reinterpret_cast<uint64_t>(buffer_ + label->pos());
+ *reinterpret_cast<uint64_t*>(pc_) = data;
+ pc_ += sizeof(uint64_t);
+ } else {
+ uint64_t target_pos = jump_address(label);
+ emit(target_pos);
+ internal_reference_positions_.insert(label->pos());
+ }
+}
+
+
void Assembler::emit_code_stub_address(Code* stub) {
CheckBuffer();
*reinterpret_cast<uint64_t*>(pc_) =
@@ -2753,7 +2804,7 @@ void Assembler::CheckTrampolinePool() {
// Buffer growth (and relocation) must be blocked for internal
// references until associated instructions are emitted and available
// to be patched.
- RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
+ RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
// TODO(plind): Verify this, presume I cannot use macro-assembler
// here.
lui(at, (imm64 >> 32) & kImm16Mask);
« 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