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

Unified Diff: src/arm/assembler-arm-inl.h

Issue 356393003: [Arm]: Enable use of extended out-of-line constant pool for Arm. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Formatted with git cl format Created 6 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/arm/assembler-arm.cc ('k') | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/assembler-arm-inl.h
diff --git a/src/arm/assembler-arm-inl.h b/src/arm/assembler-arm-inl.h
index 2c44c78993f2d284c1ed07b8638ff77874654519..f5b901578e3a0e1d75d12dfb8ab64407e82d9360 100644
--- a/src/arm/assembler-arm-inl.h
+++ b/src/arm/assembler-arm-inl.h
@@ -429,8 +429,15 @@ Address Assembler::target_address_from_return_address(Address pc) {
// movt ip, #... @ call address high 16
// blx ip
// @ return address
- // Or pre-V7 or cases that need frequent patching:
- // ldr ip, [pc, #...] @ call address
+ // Or pre-V7 or cases that need frequent patching, the address is in the
+ // constant pool. It could be a small constant pool load:
+ // ldr ip, [pc / pp, #...] @ call address
+ // blx ip
+ // @ return address
+ // Or an extended constant pool load:
+ // movw ip, #...
+ // movt ip, #...
+ // ldr ip, [pc, ip] @ call address
// blx ip
// @ return address
Address candidate = pc - 2 * Assembler::kInstrSize;
@@ -438,22 +445,35 @@ Address Assembler::target_address_from_return_address(Address pc) {
if (IsLdrPcImmediateOffset(candidate_instr) |
IsLdrPpImmediateOffset(candidate_instr)) {
return candidate;
+ } else if (IsLdrPpRegOffset(candidate_instr)) {
+ candidate = pc - 4 * Assembler::kInstrSize;
+ ASSERT(IsMovW(Memory::int32_at(candidate)) &&
+ IsMovT(Memory::int32_at(candidate + Assembler::kInstrSize)));
+ return candidate;
+ } else {
+ candidate = pc - 3 * Assembler::kInstrSize;
+ ASSERT(IsMovW(Memory::int32_at(candidate)) &&
+ IsMovT(Memory::int32_at(candidate + kInstrSize)));
+ return candidate;
}
- candidate = pc - 3 * Assembler::kInstrSize;
- ASSERT(IsMovW(Memory::int32_at(candidate)) &&
- IsMovT(Memory::int32_at(candidate + kInstrSize)));
- return candidate;
}
Address Assembler::return_address_from_call_start(Address pc) {
if (IsLdrPcImmediateOffset(Memory::int32_at(pc)) |
IsLdrPpImmediateOffset(Memory::int32_at(pc))) {
+ // Load from constant pool, small section.
return pc + kInstrSize * 2;
} else {
ASSERT(IsMovW(Memory::int32_at(pc)));
ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)));
- return pc + kInstrSize * 3;
+ if (IsLdrPpRegOffset(Memory::int32_at(pc + kInstrSize))) {
+ // Load from constant pool, extended section.
+ return pc + kInstrSize * 4;
+ } else {
+ // A movw / movt load immediate.
+ return pc + kInstrSize * 3;
+ }
}
}
@@ -468,20 +488,11 @@ void Assembler::deserialization_set_special_target_at(
}
-static Instr EncodeMovwImmediate(uint32_t immediate) {
- ASSERT(immediate < 0x10000);
- return ((immediate & 0xf000) << 4) | (immediate & 0xfff);
-}
-
-
-static Instr PatchMovwImmediate(Instr instruction, uint32_t immediate) {
- instruction &= ~EncodeMovwImmediate(0xffff);
- return instruction | EncodeMovwImmediate(immediate);
-}
-
-
-static bool IsConstantPoolLoad(Address pc) {
- return !Assembler::IsMovW(Memory::int32_at(pc));
+bool Assembler::is_constant_pool_load(Address pc) {
+ return !Assembler::IsMovW(Memory::int32_at(pc)) ||
+ (FLAG_enable_ool_constant_pool &&
+ Assembler::IsLdrPpRegOffset(
+ Memory::int32_at(pc + 2 * Assembler::kInstrSize)));
}
@@ -489,9 +500,21 @@ Address Assembler::constant_pool_entry_address(
Address pc, ConstantPoolArray* constant_pool) {
if (FLAG_enable_ool_constant_pool) {
ASSERT(constant_pool != NULL);
- ASSERT(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc)));
- return reinterpret_cast<Address>(constant_pool) +
- GetLdrRegisterImmediateOffset(Memory::int32_at(pc));
+ int cp_offset;
+ if (IsMovW(Memory::int32_at(pc))) {
+ ASSERT(IsMovT(Memory::int32_at(pc + kInstrSize)) &&
+ IsLdrPpRegOffset(Memory::int32_at(pc + 2 * kInstrSize)));
+ // This is an extended constant pool lookup.
+ Instruction* movw_instr = Instruction::At(pc);
+ Instruction* movt_instr = Instruction::At(pc + kInstrSize);
+ cp_offset = (movt_instr->ImmedMovwMovtValue() << 16) |
+ movw_instr->ImmedMovwMovtValue();
+ } else {
+ // This is a small constant pool lookup.
+ ASSERT(Assembler::IsLdrPpImmediateOffset(Memory::int32_at(pc)));
+ cp_offset = GetLdrRegisterImmediateOffset(Memory::int32_at(pc));
+ }
+ return reinterpret_cast<Address>(constant_pool) + cp_offset;
} else {
ASSERT(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(pc)));
Instr instr = Memory::int32_at(pc);
@@ -502,7 +525,7 @@ Address Assembler::constant_pool_entry_address(
Address Assembler::target_address_at(Address pc,
ConstantPoolArray* constant_pool) {
- if (IsConstantPoolLoad(pc)) {
+ if (is_constant_pool_load(pc)) {
// This is a constant pool lookup. Return the value in the constant pool.
return Memory::Address_at(constant_pool_entry_address(pc, constant_pool));
} else {
@@ -522,7 +545,7 @@ void Assembler::set_target_address_at(Address pc,
ConstantPoolArray* constant_pool,
Address target,
ICacheFlushMode icache_flush_mode) {
- if (IsConstantPoolLoad(pc)) {
+ if (is_constant_pool_load(pc)) {
// This is a constant pool lookup. Update the entry in the constant pool.
Memory::Address_at(constant_pool_entry_address(pc, constant_pool)) = target;
// Intuitively, we would think it is necessary to always flush the
« no previous file with comments | « src/arm/assembler-arm.cc ('k') | src/arm/code-stubs-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698