diff options
Diffstat (limited to 'src/3rdparty/masm/assembler/ARMv7Assembler.h')
-rw-r--r-- | src/3rdparty/masm/assembler/ARMv7Assembler.h | 81 |
1 files changed, 75 insertions, 6 deletions
diff --git a/src/3rdparty/masm/assembler/ARMv7Assembler.h b/src/3rdparty/masm/assembler/ARMv7Assembler.h index ba7517a750..6b32fbf487 100644 --- a/src/3rdparty/masm/assembler/ARMv7Assembler.h +++ b/src/3rdparty/masm/assembler/ARMv7Assembler.h @@ -27,10 +27,11 @@ #ifndef ARMAssembler_h #define ARMAssembler_h -#if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2) +#if ENABLE(ASSEMBLER) && (CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP)) #include "AssemblerBuffer.h" #include "MacroAssemblerCodeRef.h" +#include "AbstractMacroAssembler.h" #include <wtf/Assertions.h> #include <wtf/Vector.h> #include <stdint.h> @@ -491,8 +492,8 @@ public: private: union { struct RealTypes { - intptr_t m_from : 31; - intptr_t m_to : 31; + int32_t m_from : 31; + int32_t m_to : 31; JumpType m_type : 8; JumpLinkType m_linkType : 8; Condition m_condition : 16; @@ -510,6 +511,56 @@ public: { } + + // Jump: + // + // A jump object is a reference to a jump instruction that has been planted + // into the code buffer - it is typically used to link the jump, setting the + // relative offset such that when executed it will jump to the desired + // destination. + template <typename LabelType> + class Jump { + template<class TemplateAssemblerType> friend class AbstractMacroAssembler; + friend class Call; + template <typename, template <typename> class> friend class LinkBufferBase;; + public: + Jump() + { + } + + // Fixme: this information should be stored in the instruction stream, not in the Jump object. + Jump(AssemblerLabel jmp, ARMv7Assembler::JumpType type = ARMv7Assembler::JumpNoCondition, ARMv7Assembler::Condition condition = ARMv7Assembler::ConditionInvalid) + : m_label(jmp) + , m_type(type) + , m_condition(condition) + { + } + + LabelType label() const + { + LabelType result; + result.m_label = m_label; + return result; + } + + void link(AbstractMacroAssembler<ARMv7Assembler>* masm) const + { + masm->m_assembler.linkJump(m_label, masm->m_assembler.label(), m_type, m_condition); + } + + void linkTo(LabelType label, AbstractMacroAssembler<ARMv7Assembler>* masm) const + { + masm->m_assembler.linkJump(m_label, label.label(), m_type, m_condition); + } + + bool isSet() const { return m_label.isSet(); } + + private: + AssemblerLabel m_label; + ARMv7Assembler::JumpType m_type; + ARMv7Assembler::Condition m_condition; + }; + private: // ARMv7, Appx-A.6.3 @@ -2115,6 +2166,7 @@ public: linkJumpAbsolute(location, to); } +#if !defined(V4_BOOTSTRAP) static void linkCall(void* code, AssemblerLabel from, void* to) { ASSERT(!(reinterpret_cast<intptr_t>(code) & 1)); @@ -2123,12 +2175,14 @@ public: setPointer(reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(code) + from.m_offset) - 1, to, false); } +#endif static void linkPointer(void* code, AssemblerLabel where, void* value) { setPointer(reinterpret_cast<char*>(code) + where.m_offset, value, false); } +#if !defined(V4_BOOTSTRAP) static void relinkJump(void* from, void* to) { ASSERT(!(reinterpret_cast<intptr_t>(from) & 1)); @@ -2146,11 +2200,12 @@ public: setPointer(reinterpret_cast<uint16_t*>(from) - 1, to, true); } - + static void* readCallTarget(void* from) { return readPointer(reinterpret_cast<uint16_t*>(from) - 1); } +#endif static void repatchInt32(void* where, int32_t value) { @@ -2179,6 +2234,7 @@ public: cacheFlush(location, sizeof(uint16_t) * 2); } +#if !defined(V4_BOOTSTRAP) static void repatchPointer(void* where, void* value) { ASSERT(!(reinterpret_cast<intptr_t>(where) & 1)); @@ -2190,7 +2246,8 @@ public: { return reinterpret_cast<void*>(readInt32(where)); } - +#endif + static void replaceWithJump(void* instructionStart, void* to) { ASSERT(!(bitwise_cast<uintptr_t>(instructionStart) & 1)); @@ -2433,7 +2490,9 @@ private: static void setPointer(void* code, void* value, bool flush) { - setInt32(code, reinterpret_cast<uint32_t>(value), flush); + // ### Deliberate "loss" of precision here. On 64-bit hosts void* is wider + // than uint32_t, but the target is 32-bit ARM anyway. + setInt32(code, static_cast<uint32_t>(reinterpret_cast<uintptr_t>(value)), flush); } static bool isB(void* address) @@ -2597,6 +2656,11 @@ private: static void linkBX(uint16_t* instruction, void* target) { +#if defined(V4_BOOTSTRAP) + UNUSED_PARAM(instruction); + UNUSED_PARAM(target); + RELEASE_ASSERT_NOT_REACHED(); +#else // FIMXE: this should be up in the MacroAssembler layer. :-( ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); @@ -2609,6 +2673,7 @@ private: instruction[-3] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16); instruction[-2] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, hi16); instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3); +#endif } void linkConditionalBX(Condition cond, uint16_t* instruction, void* target) @@ -2641,6 +2706,9 @@ private: instruction[-3] = OP_NOP_T2b; linkJumpT4(instruction, target); } else { +#if defined(V4_BOOTSTRAP) + RELEASE_ASSERT_NOT_REACHED(); +#else const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip; ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1)); ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) >> 16)); @@ -2649,6 +2717,7 @@ private: instruction[-3] = twoWordOp5i6Imm4Reg4EncodedImmFirst(OP_MOVT, hi16); instruction[-2] = twoWordOp5i6Imm4Reg4EncodedImmSecond(JUMP_TEMPORARY_REGISTER, hi16); instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3); +#endif } } |