Chromium Code Reviews| Index: src/arm/assembler-arm.h |
| diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h |
| index 7c80b09119fe94ea4f1e247946ac69f4aabf444e..1b882b1bacae2331e666227ffc1a0327663d1389 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,8 @@ class Assembler : public AssemblerBase { |
| static const int kPatchDebugBreakSlotAddressOffset = kInstrSize; |
| #endif |
| + static const int kPatchDebugBreakSlotReturnOffset = 2 * kInstrSize; |
|
ulan
2012/10/18 09:07:53
Is the offset correct when we don't use BLX?
danno
2012/10/18 12:22:10
Done.
|
| + |
| // Difference between address of current opcode and value read from pc |
| // register. |
| static const int kPcLoadDelta = 8; |
| @@ -1185,6 +1183,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 +1309,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 +1449,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 +1468,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 +1500,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_ |