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

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

Issue 887073007: [arm] Assembler support for internal references. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Use different bit pattern 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/arm/assembler-arm.h ('k') | src/arm/constants-arm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/assembler-arm.cc
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index 33b61a3480321fcf083ccd0cd7aa1ca5c5056c8f..7a6155f2e8388fad1cfc6ec8e97ebd7a6f02871f 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -228,7 +228,8 @@ const char* DwVfpRegister::AllocationIndexToString(int index) {
// -----------------------------------------------------------------------------
// Implementation of RelocInfo
-const int RelocInfo::kApplyMask = 0;
+// static
+const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE;
bool RelocInfo::IsCodedSpecially() {
@@ -796,14 +797,20 @@ int Assembler::target_at(int pos) {
// Emitted link to a label, not part of a branch.
return instr;
}
- DCHECK((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
- int imm26 = ((instr & kImm24Mask) << 8) >> 6;
- if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
- ((instr & B24) != 0)) {
- // blx uses bit 24 to encode bit 2 of imm26
- imm26 += 2;
+ if ((instr & 7 * B25) == 5 * B25) {
+ int imm26 = ((instr & kImm24Mask) << 8) >> 6;
+ // b, bl, or blx imm24
+ if ((Instruction::ConditionField(instr) == kSpecialCondition) &&
+ ((instr & B24) != 0)) {
+ // blx uses bit 24 to encode bit 2 of imm26
+ imm26 += 2;
+ }
+ return pos + kPcLoadDelta + imm26;
}
- return pos + kPcLoadDelta + imm26;
+ // Internal reference to the label.
+ DCHECK_EQ(7 * B25 | 1 * B0, instr & (7 * B25 | 1 * B0));
+ int imm26 = (((instr >> 1) & kImm24Mask) << 8) >> 6;
+ return pos + imm26;
}
@@ -877,19 +884,25 @@ void Assembler::target_at_put(int pos, int target_pos) {
}
return;
}
- int imm26 = target_pos - (pos + kPcLoadDelta);
- DCHECK((instr & 7*B25) == 5*B25); // b, bl, or blx imm24
- if (Instruction::ConditionField(instr) == kSpecialCondition) {
- // blx uses bit 24 to encode bit 2 of imm26
- DCHECK((imm26 & 1) == 0);
- instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1)*B24;
- } else {
- DCHECK((imm26 & 3) == 0);
- instr &= ~kImm24Mask;
+ if ((instr & 7 * B25) == 5 * B25) {
+ // b, bl, or blx imm24
+ int imm26 = target_pos - (pos + kPcLoadDelta);
+ if (Instruction::ConditionField(instr) == kSpecialCondition) {
+ // blx uses bit 24 to encode bit 2 of imm26
+ DCHECK((imm26 & 1) == 0);
+ instr = (instr & ~(B24 | kImm24Mask)) | ((imm26 & 2) >> 1) * B24;
+ } else {
+ DCHECK((imm26 & 3) == 0);
+ instr &= ~kImm24Mask;
+ }
+ int imm24 = imm26 >> 2;
+ DCHECK(is_int24(imm24));
+ instr_at_put(pos, instr | (imm24 & kImm24Mask));
+ return;
}
- int imm24 = imm26 >> 2;
- DCHECK(is_int24(imm24));
- instr_at_put(pos, instr | (imm24 & kImm24Mask));
+ // Patch internal reference to label.
+ DCHECK_EQ(7 * B25 | 1 * B0, instr & (7 * B25 | 1 * B0));
+ instr_at_put(pos, reinterpret_cast<Instr>(buffer_ + target_pos));
}
@@ -3426,9 +3439,16 @@ void Assembler::GrowBuffer() {
reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
reloc_info_writer.last_pc() + pc_delta);
- // None of our relocation types are pc relative pointing outside the code
- // buffer nor pc absolute pointing inside the code buffer, so there is no need
- // to relocate any emitted relocation entries.
+ // Relocate internal references.
+ for (RelocIterator it(desc); !it.done(); it.next()) {
+ if (it.rinfo()->rmode() == RelocInfo::INTERNAL_REFERENCE) {
+ // Don't patch unbound internal references (bit 0 set); those are still
+ // hooked up in the Label chain and will be automatically patched once
+ // the label is bound.
+ int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
+ if ((*p & 1 * B0) == 0) *p += pc_delta;
+ }
+ }
// Relocate pending relocation entries.
for (int i = 0; i < num_pending_32_bit_reloc_info_; i++) {
@@ -3472,6 +3492,37 @@ 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());
+ DCHECK_EQ(0u, data & 1 * B0);
+ *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 imm26 = target_pos - pc_offset();
+ DCHECK_EQ(0, imm26 & 3);
+ int imm24 = imm26 >> 2;
+ DCHECK(is_int24(imm24));
+ // We use bit pattern 0000111<imm24>1 because that doesn't match any branch
+ // or load that would also appear on the label chain.
+ emit(7 * B25 | ((imm24 & kImm24Mask) << 1) | 1 * B0);
+ }
+}
+
+
void Assembler::emit_code_stub_address(Code* stub) {
CheckBuffer();
*reinterpret_cast<uint32_t*>(pc_) =
« no previous file with comments | « src/arm/assembler-arm.h ('k') | src/arm/constants-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698