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

Unified Diff: runtime/vm/assembler_mips.cc

Issue 20369003: Implements far branch targets for MIPS. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 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
Index: runtime/vm/assembler_mips.cc
===================================================================
--- runtime/vm/assembler_mips.cc (revision 25483)
+++ runtime/vm/assembler_mips.cc (working copy)
@@ -17,6 +17,7 @@
DECLARE_FLAG(bool, trace_sim);
#endif
DEFINE_FLAG(bool, print_stop_message, false, "Print stop message.");
+DEFINE_FLAG(bool, mips_far_branches, false, "Enable far branches on MIPS");
DECLARE_FLAG(bool, inline_alloc);
void Assembler::InitializeMemoryWithBreakpoints(uword data, int length) {
@@ -34,13 +35,30 @@
ASSERT(!label->IsBound());
int bound_pc = buffer_.Size();
while (label->IsLinked()) {
- const int32_t position = label->Position();
- const int32_t next = buffer_.Load<int32_t>(position);
- // Relative destination from an instruction after the branch.
- const int32_t dest = bound_pc - (position + Instr::kInstrSize);
- const int32_t encoded = Assembler::EncodeBranchOffset(dest, next);
- buffer_.Store<int32_t>(position, encoded);
- label->position_ = Assembler::DecodeBranchOffset(next);
+ if (FLAG_mips_far_branches) {
+ const int32_t position = label->Position();
+ const int32_t high = buffer_.Load<int32_t>(position);
+ const int32_t low = buffer_.Load<int32_t>(position + Instr::kInstrSize);
+
+ // Relative destination from an instruction after the branch.
+ const int32_t dest = bound_pc - (position + 7 * Instr::kInstrSize);
+ const int32_t encoded_low =
+ Assembler::EncodeLoadImmediate(dest & kBranchOffsetMask, low);
+ const int32_t encoded_high =
+ Assembler::EncodeLoadImmediate(dest >> 16, high);
+
+ buffer_.Store<int32_t>(position, encoded_high);
+ buffer_.Store<int32_t>(position + Instr::kInstrSize, encoded_low);
+ label->position_ = Assembler::DecodeLoadImmediate(low, high);
+ } else {
+ const int32_t position = label->Position();
+ const int32_t next = buffer_.Load<int32_t>(position);
+ // Relative destination from an instruction after the branch.
+ const int32_t dest = bound_pc - (position + Instr::kInstrSize);
+ const int32_t encoded = Assembler::EncodeBranchOffset(dest, next);
+ buffer_.Store<int32_t>(position, encoded);
+ label->position_ = Assembler::DecodeBranchOffset(next);
+ }
}
label->BindTo(bound_pc);
delay_slot_available_ = false;
@@ -64,6 +82,16 @@
}
+int32_t Assembler::DecodeLoadImmediate(int32_t low, int32_t high) {
+ return (((high & kBranchOffsetMask) << 16) | (low & kBranchOffsetMask));
+}
+
+
+int32_t Assembler::EncodeLoadImmediate(int32_t dest, int32_t instr) {
+ return ((instr & ~kBranchOffsetMask) | (dest & kBranchOffsetMask));
+}
+
+
void Assembler::LoadWordFromPoolOffset(Register rd, int32_t offset) {
ASSERT(rd != PP);
if (Address::CanHoldOffset(offset)) {
@@ -231,8 +259,8 @@
// if the bit is not set. We can't destroy the object.
nor(TMP1, ZR, object);
and_(TMP1, value, TMP1);
- andi(TMP1, TMP1, Immediate(kNewObjectAlignmentOffset));
- beq(TMP1, ZR, no_update);
+ andi(CMPRES1, TMP1, Immediate(kNewObjectAlignmentOffset));
+ beq(CMPRES1, ZR, no_update);
}
@@ -245,10 +273,10 @@
sll(TMP1, value, kObjectAlignmentLog2 - 1);
and_(TMP1, value, TMP1);
// And the result with the negated space bit of the object.
- nor(CMPRES, ZR, object);
- and_(TMP1, TMP1, CMPRES);
- andi(TMP1, TMP1, Immediate(kNewObjectAlignmentOffset));
- beq(TMP1, ZR, no_update);
+ nor(CMPRES1, ZR, object);
+ and_(TMP1, TMP1, CMPRES1);
+ andi(CMPRES1, TMP1, Immediate(kNewObjectAlignmentOffset));
+ beq(CMPRES1, ZR, no_update);
}
@@ -359,15 +387,13 @@
sw(PP, Address(SP, 0 * kWordSize));
addiu(FP, SP, Immediate(1 * kWordSize));
// Setup pool pointer for this stub.
- Label next;
- bal(&next);
- delay_slot()->mov(TMP1, RA);
+ GetNextPC(TMP1, false); // TMP1 gets the address of the next instruction.
+
const intptr_t object_pool_pc_dist =
Instructions::HeaderSize() - Instructions::object_pool_offset() +
CodeSize();
- Bind(&next);
lw(PP, Address(TMP1, -object_pool_pc_dist));
} else {
addiu(SP, SP, Immediate(-3 * kWordSize));
@@ -465,20 +491,13 @@
sw(FP, Address(SP, 1 * kWordSize));
sw(PP, Address(SP, 0 * kWordSize));
- Label next;
- // Branch and link to the instruction after the delay slot to get the PC.
- bal(&next);
- // RA is the address of the sw instruction below. Save it in T0.
- delay_slot()->mov(TMP1, RA);
+ GetNextPC(TMP1, false); // TMP1 gets the address of the next instruction.
// Calculate the offset of the pool pointer from the PC.
const intptr_t object_pool_pc_dist =
Instructions::HeaderSize() - Instructions::object_pool_offset() +
CodeSize();
- // TMP1 has the address of the next instruction.
- Bind(&next);
-
// Save PC in frame for fast identification of corresponding code.
AddImmediate(TMP1, -offset);
sw(TMP1, Address(SP, 3 * kWordSize));
@@ -501,12 +520,9 @@
// allocate. We must also set up the pool pointer for the function.
void Assembler::EnterOsrFrame(intptr_t extra_size) {
Comment("EnterOsrFrame");
- Label next;
- // Branch and link to the instruction after the delay slot to get the PC.
- bal(&next);
- // RA is the address of the sw instruction below. Save it in T0.
- delay_slot()->mov(TMP, RA);
+ GetNextPC(TMP, false); // TMP gets the address of the next instruction.
+
// The runtime system assumes that the code marker address is
// kEntryPointToPcMarkerOffset bytes from the entry. Since there is no
// code to set up the frame pointer, etc., the address needs to be adjusted.
@@ -516,9 +532,6 @@
Instructions::HeaderSize() - Instructions::object_pool_offset() +
CodeSize();
- // temp has the address of the next instruction.
- Bind(&next);
-
// Adjust PC by the offset, and store it in the stack frame.
AddImmediate(TMP, TMP, offset);
sw(TMP, Address(FP, kPcMarkerSlotFromFp * kWordSize));

Powered by Google App Engine
This is Rietveld 408576698