Index: src/arm/assembler-arm.h |
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h |
index 7c80b09119fe94ea4f1e247946ac69f4aabf444e..bee35af15eed4fe96f2e0800cdb0b61945c259b4 100644 |
--- a/src/arm/assembler-arm.h |
+++ b/src/arm/assembler-arm.h |
@@ -425,7 +425,7 @@ class Operand BASE_EMBEDDED { |
// actual instruction to use is required for this calculation. For other |
// instructions instr is ignored. |
bool is_single_instruction(const Assembler* assembler, Instr instr = 0) const; |
- bool must_use_constant_pool(const Assembler* assembler) const; |
+ bool must_output_reloc_info(const Assembler* assembler) const; |
inline int32_t immediate() const { |
ASSERT(!rm_.is_valid()); |
@@ -689,13 +689,25 @@ class Assembler : public AssemblerBase { |
void label_at_put(Label* L, int at_offset); |
// Return the address in the constant pool of the code target address used by |
- // the branch/call instruction at pc. |
- INLINE(static Address target_address_address_at(Address pc)); |
+ // the branch/call instruction at pc, or the object in a mov. |
+ INLINE(static Address target_pointer_address_at(Address pc)); |
+ |
+ // Read/Modify the pointer in the branch/call/move instruction at pc. |
+ INLINE(static Address target_pointer_at(Address pc)); |
+ INLINE(static void set_target_pointer_at(Address pc, Address target)); |
// Read/Modify the code target address in the branch/call instruction at pc. |
INLINE(static Address target_address_at(Address pc)); |
INLINE(static void set_target_address_at(Address pc, Address target)); |
+ // Return the code target address at a call site from the return address |
+ // of that call in the instruction stream. |
+ INLINE(static Address target_address_from_return_address(Address pc)); |
+ |
+ // Given the address of the beginning of a call, return the address |
+ // in the instruction stream that the call will return from. |
+ INLINE(static Address return_address_from_call_start(Address pc)); |
+ |
// This sets the branch destination (which is in the constant pool on ARM). |
// This is for calls and branches within generated code. |
inline static void deserialization_set_special_target_at( |
@@ -714,22 +726,6 @@ class Assembler : public AssemblerBase { |
// Size of an instruction. |
static const int kInstrSize = sizeof(Instr); |
- // Distance between the instruction referring to the address of the call |
- // target and the return address. |
-#ifdef USE_BLX |
- // Call sequence is: |
- // ldr ip, [pc, #...] @ call address |
- // blx ip |
- // @ return address |
- static const int kCallTargetAddressOffset = 2 * kInstrSize; |
-#else |
- // Call sequence is: |
- // mov lr, pc |
- // ldr pc, [pc, #...] @ call address |
- // @ return address |
- static const int kCallTargetAddressOffset = kInstrSize; |
-#endif |
- |
// Distance between start of patched return sequence and the emitted address |
// to jump to. |
#ifdef USE_BLX |
@@ -758,6 +754,12 @@ class Assembler : public AssemblerBase { |
static const int kPatchDebugBreakSlotAddressOffset = kInstrSize; |
#endif |
+#ifdef USE_BLX |
+ static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize; |
+#else |
+ static const int kPatchDebugBreakSlotReturnOffset = kInstrSize; |
+#endif |
+ |
// Difference between address of current opcode and value read from pc |
// register. |
static const int kPcLoadDelta = 8; |
@@ -1185,6 +1187,12 @@ class Assembler : public AssemblerBase { |
bool predictable_code_size() const { return predictable_code_size_; } |
+ static bool allow_immediate_constant_pool_loads( |
+ const Assembler* assembler) { |
+ return CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) && |
+ (assembler == NULL || !assembler->predictable_code_size()); |
+ } |
+ |
// Check the code size generated from label to here. |
int SizeOfCodeGeneratedSince(Label* label) { |
return pc_offset() - label->pos(); |
@@ -1305,6 +1313,8 @@ class Assembler : public AssemblerBase { |
static Register GetCmpImmediateRegister(Instr instr); |
static int GetCmpImmediateRawImmediate(Instr instr); |
static bool IsNop(Instr instr, int type = NON_MARKING_NOP); |
+ static bool IsMovT(Instr instr); |
+ static bool IsMovW(Instr instr); |
// Constants in pools are accessed via pc relative addressing, which can |
// reach +/-4KB thereby defining a maximum distance between the instruction |
@@ -1443,6 +1453,12 @@ class Assembler : public AssemblerBase { |
void GrowBuffer(); |
inline void emit(Instr x); |
+ // 32-bit immediate values |
+ void move_32_bit_immediate(Condition cond, |
+ Register rd, |
+ SBit s, |
+ const Operand& x); |
+ |
// Instruction generation |
void addrmod1(Instr instr, Register rn, Register rd, const Operand& x); |
void addrmod2(Instr instr, Register rd, const MemOperand& x); |
@@ -1456,8 +1472,14 @@ class Assembler : public AssemblerBase { |
void link_to(Label* L, Label* appendix); |
void next(Label* L); |
+ enum UseConstantPoolMode { |
+ USE_CONSTANT_POOL, |
+ DONT_USE_CONSTANT_POOL |
+ }; |
+ |
// Record reloc info for current pc_ |
- void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0); |
+ void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0, |
+ UseConstantPoolMode mode = USE_CONSTANT_POOL); |
friend class RegExpMacroAssemblerARM; |
friend class RelocInfo; |
@@ -1482,6 +1504,26 @@ class EnsureSpace BASE_EMBEDDED { |
}; |
+class PredictableCodeSizeScope { |
+ public: |
+ explicit PredictableCodeSizeScope(Assembler* assembler) |
+ : asm_(assembler) { |
+ old_value_ = assembler->predictable_code_size(); |
+ assembler->set_predictable_code_size(true); |
+ } |
+ |
+ ~PredictableCodeSizeScope() { |
+ if (!old_value_) { |
+ asm_->set_predictable_code_size(false); |
+ } |
+ } |
+ |
+ private: |
+ Assembler* asm_; |
+ bool old_value_; |
+}; |
+ |
+ |
} } // namespace v8::internal |
#endif // V8_ARM_ASSEMBLER_ARM_H_ |