aboutsummaryrefslogtreecommitdiffstats
path: root/src/3rdparty/masm/assembler/ARMv7Assembler.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/masm/assembler/ARMv7Assembler.h')
-rw-r--r--src/3rdparty/masm/assembler/ARMv7Assembler.h81
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
}
}