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

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

Issue 911623003: MIPS: Assembler support for internal references. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove comment. 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/mips/assembler-mips.h ('k') | src/mips/constants-mips.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mips/assembler-mips.cc
diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc
index 182183f547bc9f7f7bf81baffbac69c228c4cd50..96cccbb87a7a5b0395b86b6d6087a3738cb60dc2 100644
--- a/src/mips/assembler-mips.cc
+++ b/src/mips/assembler-mips.cc
@@ -673,8 +673,6 @@ int Assembler::target_at(int32_t pos) {
return (imm18 + pos);
}
}
- // Check we have a branch or jump instruction.
- DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr));
// Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
// the compiler uses arithmectic shifts for signed integers.
if (IsBranch(instr)) {
@@ -702,7 +700,7 @@ int Assembler::target_at(int32_t pos) {
DCHECK(pos > delta);
return pos - delta;
}
- } else {
+ } else if (IsJ(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.
@@ -714,6 +712,14 @@ int Assembler::target_at(int32_t pos) {
DCHECK(pos > delta);
return pos - delta;
}
+ } else { // IsLabel(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 {
+ return pos + imm28;
+ }
}
}
@@ -728,7 +734,6 @@ void Assembler::target_at_put(int32_t pos, int32_t target_pos) {
return;
}
- DCHECK(IsBranch(instr) || IsJ(instr) || IsLui(instr));
if (IsBranch(instr)) {
int32_t imm18 = target_pos - (pos + kBranchPCOffset);
DCHECK((imm18 & 3) == 0);
@@ -752,7 +757,7 @@ void Assembler::target_at_put(int32_t pos, int32_t target_pos) {
instr_lui | ((imm & kHiMask) >> kLuiShift));
instr_at_put(pos + 1 * Assembler::kInstrSize,
instr_ori | (imm & kImm16Mask));
- } else {
+ } else if (IsJ(instr)) {
uint32_t imm28 = reinterpret_cast<uint32_t>(buffer_) + target_pos;
imm28 &= kImm28Mask;
DCHECK((imm28 & 3) == 0);
@@ -762,6 +767,9 @@ void Assembler::target_at_put(int32_t pos, int32_t target_pos) {
DCHECK(is_uint26(imm26));
instr_at_put(pos, instr | (imm26 & kImm26Mask));
+ } else {
+ uint32_t imm = reinterpret_cast<uint32_t>(buffer_) + target_pos;
+ instr_at_put(pos, imm);
}
}
@@ -816,7 +824,6 @@ void Assembler::bind_to(Label* L, int pos) {
}
target_at_put(fixup_pos, pos);
} else {
- DCHECK(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr));
target_at_put(fixup_pos, pos);
}
}
@@ -2358,7 +2365,6 @@ void Assembler::RecordDeoptReason(const int reason, const int raw_position) {
int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) {
Instr instr = instr_at(pc);
- DCHECK(IsJ(instr) || IsLui(instr));
if (IsLui(instr)) {
Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
@@ -2379,7 +2385,7 @@ int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) {
instr_at_put(pc + 1 * Assembler::kInstrSize,
instr_ori | (imm & kImm16Mask));
return 2; // Number of instructions patched.
- } else {
+ } else if (IsJ(instr)) {
uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
return 0; // Number of instructions patched.
@@ -2394,6 +2400,14 @@ int Assembler::RelocateInternalReference(byte* pc, intptr_t pc_delta) {
instr_at_put(pc, instr | (imm26 & kImm26Mask));
return 1; // Number of instructions patched.
+ } else { // IsLabel(instr)
+ int32_t* p = reinterpret_cast<int32_t*>(pc);
+ uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
+ if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
+ return 0; // Number of instructions patched.
+ }
+ *p += pc_delta;
+ return 1; // Number of instructions patched.
}
}
@@ -2458,6 +2472,35 @@ void Assembler::dd(uint32_t data) {
}
+void Assembler::dd(Label* label) {
+ CheckBuffer();
+ RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
+ if (label->is_bound()) {
+ uint32_t data = reinterpret_cast<uint32_t>(buffer_ + label->pos());
+ *reinterpret_cast<uint32_t*>(pc_) = data;
+ pc_ += sizeof(uint32_t);
+ } else {
+ int target_pos;
+ if (label->is_linked()) {
+ // Point to previous instruction that uses the link.
+ target_pos = label->pos();
+ } else {
+ // First entry of the link chain points to itself.
+ target_pos = pc_offset();
+ }
+ label->link_to(pc_offset());
+ // Encode internal reference to unbound label. We set the least significant
+ // bit to distinguish unbound internal references in GrowBuffer() below.
+ int diff = target_pos - pc_offset();
+ DCHECK_EQ(0, diff & 3);
+ int imm26 = diff >> 2;
+ DCHECK(is_int26(imm26));
+ // Emit special LABEL instruction.
+ emit(LABEL | (imm26 & kImm26Mask));
+ }
+}
+
+
void Assembler::emit_code_stub_address(Code* stub) {
CheckBuffer();
*reinterpret_cast<uint32_t*>(pc_) =
« no previous file with comments | « src/mips/assembler-mips.h ('k') | src/mips/constants-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698