diff options
-rw-r--r-- | src/3rdparty/masm/assembler/ARMv7Assembler.h | 81 | ||||
-rw-r--r-- | src/3rdparty/masm/assembler/AbstractMacroAssembler.h | 20 | ||||
-rw-r--r-- | src/3rdparty/masm/assembler/LinkBuffer.h | 10 | ||||
-rw-r--r-- | src/3rdparty/masm/assembler/MacroAssembler.h | 15 | ||||
-rw-r--r-- | src/3rdparty/masm/assembler/MacroAssemblerARMv7.h | 79 | ||||
-rw-r--r-- | src/3rdparty/masm/assembler/MacroAssemblerX86.h | 32 | ||||
-rw-r--r-- | src/3rdparty/masm/assembler/MacroAssemblerX86_64.h | 27 | ||||
-rw-r--r-- | src/3rdparty/masm/assembler/X86Assembler.h | 40 | ||||
-rw-r--r-- | src/3rdparty/masm/stubs/ExecutableAllocator.h | 8 | ||||
-rw-r--r-- | src/qml/jit/qv4assembler.cpp | 3 | ||||
-rw-r--r-- | src/qml/jit/qv4binop.cpp | 3 | ||||
-rw-r--r-- | src/qml/jit/qv4targetplatform_p.h | 2 | ||||
-rw-r--r-- | src/qml/jit/qv4unop.cpp | 3 |
13 files changed, 295 insertions, 28 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 } } diff --git a/src/3rdparty/masm/assembler/AbstractMacroAssembler.h b/src/3rdparty/masm/assembler/AbstractMacroAssembler.h index a9035efed7..4f27e85c98 100644 --- a/src/3rdparty/masm/assembler/AbstractMacroAssembler.h +++ b/src/3rdparty/masm/assembler/AbstractMacroAssembler.h @@ -66,7 +66,9 @@ public: typedef MacroAssemblerCodePtr CodePtr; typedef MacroAssemblerCodeRef CodeRef; +#if !CPU(ARM_THUMB2) && !defined(V4_BOOTSTRAP) class Jump; +#endif typedef typename AssemblerType::RegisterID RegisterID; typedef typename AssemblerType::FPRegisterID FPRegisterID; @@ -342,6 +344,8 @@ public: } bool isSet() const { return m_label.isSet(); } + + const AssemblerLabel &label() const { return m_label; } private: AssemblerLabel m_label; }; @@ -451,6 +455,11 @@ public: AssemblerLabel m_label; }; +#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP) + using Jump = typename AssemblerType::template Jump<Label>; + friend Jump; +#endif + // Call: // // A Call object is a reference to a call instruction that has been planted @@ -501,6 +510,7 @@ public: // 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. +#if !CPU(ARM_THUMB2) && !defined(V4_BOOTSTRAP) class Jump { template<class TemplateAssemblerType> friend class AbstractMacroAssembler; @@ -512,7 +522,7 @@ public: { } -#if CPU(ARM_THUMB2) +#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP) // 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) @@ -613,10 +623,11 @@ public: private: AssemblerLabel m_label; -#if CPU(ARM_THUMB2) +#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP) ARMv7Assembler::JumpType m_type; ARMv7Assembler::Condition m_condition; -#elif CPU(ARM64) +#endif +#if CPU(ARM64) ARM64Assembler::JumpType m_type; ARM64Assembler::Condition m_condition; bool m_is64Bit; @@ -627,6 +638,7 @@ public: SH4Assembler::JumpType m_type; #endif }; +#endif struct PatchableJump { PatchableJump() @@ -871,10 +883,12 @@ protected: AssemblerType::repatchPointer(dataLabelPtr.dataLocation(), value); } +#if !defined(V4_BOOTSTRAP) static void* readPointer(CodeLocationDataLabelPtr dataLabelPtr) { return AssemblerType::readPointer(dataLabelPtr.dataLocation()); } +#endif static void replaceWithLoad(CodeLocationConvertibleLoad label) { diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h index 4d8a129e18..3a659a23ce 100644 --- a/src/3rdparty/masm/assembler/LinkBuffer.h +++ b/src/3rdparty/masm/assembler/LinkBuffer.h @@ -365,7 +365,7 @@ public: } }; -#if CPU(ARM_THUMB2) || CPU(ARM64) +#if CPU(ARM_THUMB2) || CPU(ARM64) || defined(V4_BOOTSTRAP) template <typename T> struct BranchCompactingExecutableOffsetCalculator { @@ -440,13 +440,13 @@ inline void BranchCompactingLinkBuffer<MacroAssembler>::linkCode(void* ownerUID, int readPtr = 0; int writePtr = 0; Vector<LinkRecord, 0, UnsafeVectorOverflow>& jumpsToLink = m_assembler->jumpsToLink(); - unsigned jumpCount = jumpsToLink.size(); + unsigned jumpCount = unsigned(jumpsToLink.size()); for (unsigned i = 0; i < jumpCount; ++i) { int offset = readPtr - writePtr; ASSERT(!(offset & 1)); // Copy the instructions from the last jump to the current one. - size_t regionSize = jumpsToLink[i].from() - readPtr; + unsigned regionSize = unsigned(jumpsToLink[i].from() - readPtr); uint16_t* copySource = reinterpret_cast_ptr<uint16_t*>(inData + readPtr); uint16_t* copyEnd = reinterpret_cast_ptr<uint16_t*>(inData + readPtr + regionSize); uint16_t* copyDst = reinterpret_cast_ptr<uint16_t*>(outData + writePtr); @@ -481,7 +481,7 @@ inline void BranchCompactingLinkBuffer<MacroAssembler>::linkCode(void* ownerUID, } // Copy everything after the last jump memcpy(outData + writePtr, inData + readPtr, m_initialSize - readPtr); - m_assembler->recordLinkOffsets(readPtr, m_initialSize, readPtr - writePtr); + m_assembler->recordLinkOffsets(readPtr, unsigned(m_initialSize), readPtr - writePtr); for (unsigned i = 0; i < jumpCount; ++i) { uint8_t* location = outData + jumpsToLink[i].from(); @@ -494,7 +494,7 @@ inline void BranchCompactingLinkBuffer<MacroAssembler>::linkCode(void* ownerUID, m_executableMemory->shrink(m_size); } -#if CPU(ARM_THUMB2) +#if CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP) template <> class LinkBuffer<JSC::MacroAssembler<MacroAssemblerARMv7>> : public BranchCompactingLinkBuffer<JSC::MacroAssembler<MacroAssemblerARMv7>> { diff --git a/src/3rdparty/masm/assembler/MacroAssembler.h b/src/3rdparty/masm/assembler/MacroAssembler.h index 1d0fa0003e..87794c8ef4 100644 --- a/src/3rdparty/masm/assembler/MacroAssembler.h +++ b/src/3rdparty/masm/assembler/MacroAssembler.h @@ -30,8 +30,9 @@ #if ENABLE(ASSEMBLER) -#if CPU(ARM_THUMB2) #include "MacroAssemblerARMv7.h" + +#if CPU(ARM_THUMB2) namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; }; #elif CPU(ARM64) @@ -71,6 +72,7 @@ namespace JSC { template <typename MacroAssemblerBase> class MacroAssembler : public MacroAssemblerBase { public: + using DoubleCondition = typename MacroAssemblerBase::DoubleCondition; using ResultCondition = typename MacroAssemblerBase::ResultCondition; using RelationalCondition = typename MacroAssemblerBase::RelationalCondition; @@ -102,7 +104,12 @@ public: using MacroAssemblerBase::xor32; using MacroAssemblerBase::sub32; using MacroAssemblerBase::load32; -#if CPU(X86_64) || CPU(ARM64) + + +#if defined(V4_BOOTSTRAP) + using MacroAssemblerBase::loadPtr; + using MacroAssemblerBase::storePtr; +#elif CPU(X86_64) || CPU(ARM64) using MacroAssemblerBase::add64; using MacroAssemblerBase::sub64; using MacroAssemblerBase::xor64; @@ -221,7 +228,7 @@ public: storePtr(imm, addressForPoke(index)); } -#if CPU(X86_64) || CPU(ARM64) +#if (CPU(X86_64) || CPU(ARM64)) && !defined(V4_BOOTSTRAP) void peek64(RegisterID dest, int index = 0) { load64(Address(MacroAssemblerBase::stackPointerRegister, (index * sizeof(void*))), dest); @@ -360,6 +367,7 @@ public: return !(this->random() & (BlindingModulus - 1)); } +#if !defined(V4_BOOTSTRAP) // Ptr methods // On 32-bit platforms (i.e. x86), these methods directly map onto their 32-bit equivalents. // FIXME: should this use a test for 32-bitness instead of this specific exception? @@ -884,6 +892,7 @@ public: { return branchSub64(cond, src1, src2, dest); } +#endif // !defined(V4_BOOTSTRAP) #if ENABLE(JIT_CONSTANT_BLINDING) using MacroAssemblerBase::and64; diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h index 3f6352c1db..806f2e13b6 100644 --- a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h +++ b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h @@ -27,7 +27,7 @@ #ifndef MacroAssemblerARMv7_h #define MacroAssemblerARMv7_h -#if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2) +#if ENABLE(ASSEMBLER) && (CPU(ARM_THUMB2) || defined(V4_BOOTSTRAP)) #include "ARMv7Assembler.h" #include "AbstractMacroAssembler.h" @@ -160,12 +160,41 @@ public: { add32(imm, dest, dest); } + +#if defined(V4_BOOTSTRAP) + void loadPtr(ImplicitAddress address, RegisterID dest) + { + load32(address, dest); + } + + void subPtr(TrustedImm32 imm, RegisterID dest) + { + sub32(imm, dest); + } + + void addPtr(TrustedImm32 imm, RegisterID dest) + { + add32(imm, dest); + } + + void addPtr(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + add32(imm, src, dest); + } + + void storePtr(RegisterID src, ImplicitAddress address) + { + store32(src, address); + } +#endif +#if !defined(V4_BOOTSTRAP) void add32(AbsoluteAddress src, RegisterID dest) { load32(src.m_ptr, dataTempRegister); add32(dataTempRegister, dest); } +#endif void add32(TrustedImm32 imm, RegisterID src, RegisterID dest) { @@ -206,6 +235,7 @@ public: add32(dataTempRegister, dest); } +#if !defined(V4_BOOTSTRAP) void add32(TrustedImm32 imm, AbsoluteAddress address) { load32(address.m_ptr, dataTempRegister); @@ -242,6 +272,7 @@ public: m_assembler.adc(dataTempRegister, dataTempRegister, ARMThumbImmediate::makeEncodedImm(imm.m_value >> 31)); m_assembler.str(dataTempRegister, addressTempRegister, ARMThumbImmediate::makeUInt12(4)); } +#endif void and32(RegisterID op1, RegisterID op2, RegisterID dest) { @@ -343,6 +374,7 @@ public: or32(dataTempRegister, dest); } +#if !defined(V4_BOOTSTRAP) void or32(RegisterID src, AbsoluteAddress dest) { move(TrustedImmPtr(dest.m_ptr), addressTempRegister); @@ -350,6 +382,7 @@ public: or32(src, dataTempRegister); store32(dataTempRegister, addressTempRegister); } +#endif void or32(TrustedImm32 imm, RegisterID dest) { @@ -461,6 +494,7 @@ public: sub32(dataTempRegister, dest); } +#if !defined(V4_BOOTSTRAP) void sub32(TrustedImm32 imm, AbsoluteAddress address) { load32(address.m_ptr, dataTempRegister); @@ -477,6 +511,7 @@ public: store32(dataTempRegister, address.m_ptr); } +#endif void xor32(Address src, RegisterID dest) { @@ -528,7 +563,6 @@ public: // internal function, but public because of "using load32;" in template sub-classes to pull // in the other public overloads. - void load32(ArmAddress address, RegisterID dest) { if (address.type == ArmAddress::HasIndex) @@ -649,11 +683,13 @@ public: load16(setupArmAddress(address), dest); } +#if !defined(V4_BOOTSTRAP) void load32(const void* address, RegisterID dest) { move(TrustedImmPtr(address), addressTempRegister); m_assembler.ldr(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0)); } +#endif ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest) { @@ -758,6 +794,7 @@ public: store32(dataTempRegister, setupArmAddress(address)); } +#if !defined(V4_BOOTSTRAP) void store32(RegisterID src, const void* address) { move(TrustedImmPtr(address), addressTempRegister); @@ -769,12 +806,14 @@ public: move(imm, dataTempRegister); store32(dataTempRegister, address); } +#endif void store8(RegisterID src, BaseIndex address) { store8(src, setupArmAddress(address)); } +#if !defined(V4_BOOTSTRAP) void store8(RegisterID src, void* address) { move(TrustedImmPtr(address), addressTempRegister); @@ -786,6 +825,7 @@ public: move(imm, dataTempRegister); store8(dataTempRegister, address); } +#endif void store16(RegisterID src, BaseIndex address) { @@ -883,11 +923,13 @@ public: m_assembler.vmov(dest, src); } +#if !defined(V4_BOOTSTRAP) void loadDouble(const void* address, FPRegisterID dest) { move(TrustedImmPtr(address), addressTempRegister); m_assembler.vldr(dest, addressTempRegister, 0); } +#endif void storeDouble(FPRegisterID src, ImplicitAddress address) { @@ -919,11 +961,13 @@ public: m_assembler.fsts(ARMRegisters::asSingle(src), base, offset); } +#if !defined(V4_BOOTSTRAP) void storeDouble(FPRegisterID src, const void* address) { move(TrustedImmPtr(address), addressTempRegister); storeDouble(src, addressTempRegister); } +#endif void storeDouble(FPRegisterID src, BaseIndex address) { @@ -957,11 +1001,13 @@ public: m_assembler.vadd(dest, op1, op2); } +#if !defined(V4_BOOTSTRAP) void addDouble(AbsoluteAddress address, FPRegisterID dest) { loadDouble(address.m_ptr, fpTempRegister); m_assembler.vadd(dest, dest, fpTempRegister); } +#endif void divDouble(FPRegisterID src, FPRegisterID dest) { @@ -1040,6 +1086,7 @@ public: m_assembler.vcvt_signedToFloatingPoint(dest, fpTempRegisterAsSingle()); } +#if !defined(V4_BOOTSTRAP) void convertInt32ToDouble(AbsoluteAddress address, FPRegisterID dest) { // Fixme: load directly into the fpr! @@ -1047,6 +1094,7 @@ public: m_assembler.vmov(fpTempRegister, dataTempRegister, dataTempRegister); m_assembler.vcvt_signedToFloatingPoint(dest, fpTempRegisterAsSingle()); } +#endif void convertUInt32ToDouble(RegisterID src, FPRegisterID dest, RegisterID /*scratch*/) { @@ -1200,7 +1248,7 @@ public: void push(RegisterID src) { // store preindexed with writeback - m_assembler.str(src, ARMRegisters::sp, -sizeof(void*), true, true); + m_assembler.str(src, ARMRegisters::sp, -4 /*sizeof(void*)*/, true, true); } void push(Address address) @@ -1242,10 +1290,12 @@ public: m_assembler.mov(dest, src); } +#if !defined(V4_BOOTSTRAP) void move(TrustedImmPtr imm, RegisterID dest) { move(TrustedImm32(imm), dest); } +#endif void swap(RegisterID reg1, RegisterID reg2) { @@ -1386,6 +1436,7 @@ public: return branch32(cond, addressTempRegister, right); } +#if !defined(V4_BOOTSTRAP) Jump branch32(RelationalCondition cond, AbsoluteAddress left, RegisterID right) { load32(left.m_ptr, dataTempRegister); @@ -1398,6 +1449,7 @@ public: load32(left.m_ptr, addressTempRegister); return branch32(cond, addressTempRegister, right); } +#endif Jump branch8(RelationalCondition cond, RegisterID left, TrustedImm32 right) { @@ -1454,6 +1506,7 @@ public: return branchTest32(cond, addressTempRegister, mask); } +#if !defined(V4_BOOTSTRAP) Jump branchTest8(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1)) { // use addressTempRegister incase the branchTest8 we call uses dataTempRegister. :-/ @@ -1461,6 +1514,7 @@ public: load8(Address(addressTempRegister), addressTempRegister); return branchTest32(cond, addressTempRegister, mask); } +#endif void jump(RegisterID target) { @@ -1474,12 +1528,14 @@ public: m_assembler.bx(dataTempRegister); } +#if !defined(V4_BOOTSTRAP) void jump(AbsoluteAddress address) { move(TrustedImmPtr(address.m_ptr), dataTempRegister); load32(Address(dataTempRegister), dataTempRegister); m_assembler.bx(dataTempRegister); } +#endif // Arithmetic control flow operations: @@ -1520,6 +1576,7 @@ public: return branchAdd32(cond, dest, imm, dest); } +#if !defined(V4_BOOTSTRAP) Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest) { // Move the high bits of the address into addressTempRegister, @@ -1545,6 +1602,7 @@ public: return Jump(makeBranch(cond)); } +#endif Jump branchMul32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest) { @@ -1715,6 +1773,7 @@ public: return DataLabel32(this); } +#if !defined(V4_BOOTSTRAP) ALWAYS_INLINE DataLabelPtr moveWithPatch(TrustedImmPtr imm, RegisterID dst) { padBeforePatch(); @@ -1742,7 +1801,8 @@ public: m_makeJumpPatchable = false; return PatchableJump(result); } - +#endif + PatchableJump patchableBranchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1)) { m_makeJumpPatchable = true; @@ -1759,6 +1819,7 @@ public: return PatchableJump(result); } +#if !defined(V4_BOOTSTRAP) PatchableJump patchableBranchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) { m_makeJumpPatchable = true; @@ -1766,6 +1827,7 @@ public: m_makeJumpPatchable = false; return PatchableJump(result); } +#endif PatchableJump patchableJump() { @@ -1776,6 +1838,7 @@ public: return PatchableJump(result); } +#if !defined(V4_BOOTSTRAP) ALWAYS_INLINE DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address) { DataLabelPtr label = moveWithPatch(initialValue, dataTempRegister); @@ -1783,7 +1846,7 @@ public: return label; } ALWAYS_INLINE DataLabelPtr storePtrWithPatch(ImplicitAddress address) { return storePtrWithPatch(TrustedImmPtr(0), address); } - +#endif ALWAYS_INLINE Call tailRecursiveCall() { @@ -1804,6 +1867,7 @@ public: return m_assembler.executableOffsetFor(location); } +#if !defined(V4_BOOTSTRAP) static FunctionPtr readCallTarget(CodeLocationCall call) { return FunctionPtr(reinterpret_cast<void(*)()>(ARMv7Assembler::readCallTarget(call.dataLocation()))); @@ -1816,7 +1880,8 @@ public: const unsigned twoWordOpSize = 4; return label.labelAtOffset(-twoWordOpSize * 2); } - +#endif + static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID rd, void* initialValue) { #if OS(LINUX) || OS(QNX) @@ -1933,6 +1998,7 @@ private: template <typename, template <typename> class> friend class LinkBufferBase; friend class RepatchBuffer; +#if !defined(V4_BOOTSTRAP) static void linkCall(void* code, Call call, FunctionPtr function) { ARMv7Assembler::linkCall(code, call.m_label, function.value()); @@ -1947,6 +2013,7 @@ private: { ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress()); } +#endif bool m_makeJumpPatchable; }; diff --git a/src/3rdparty/masm/assembler/MacroAssemblerX86.h b/src/3rdparty/masm/assembler/MacroAssemblerX86.h index c42100bbcb..742a4b48f7 100644 --- a/src/3rdparty/masm/assembler/MacroAssemblerX86.h +++ b/src/3rdparty/masm/assembler/MacroAssemblerX86.h @@ -54,6 +54,38 @@ public: using MacroAssemblerX86Common::convertInt32ToDouble; using MacroAssemblerX86Common::branchTest8; +#if defined(V4_BOOTSTRAP) + void loadPtr(ImplicitAddress address, RegisterID dest) + { + load32(address, dest); + } + + void subPtr(TrustedImm32 imm, RegisterID dest) + { + sub32(imm, dest); + } + + void addPtr(TrustedImm32 imm, RegisterID dest) + { + add32(imm, dest); + } + + void addPtr(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + add32(imm, src, dest); + } + + void storePtr(RegisterID src, ImplicitAddress address) + { + store32(src, address); + } + + Jump branchTest8(ResultCondition cond, ExtendedAddress address, TrustedImm32 mask = TrustedImm32(-1)) + { + return branchTest8(cond, Address(address.base, address.offset), mask); + } +#endif + void add32(TrustedImm32 imm, RegisterID src, RegisterID dest) { m_assembler.leal_mr(imm.m_value, src, dest); diff --git a/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h b/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h index 47ca952a05..3566702413 100644 --- a/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h +++ b/src/3rdparty/masm/assembler/MacroAssemblerX86_64.h @@ -52,6 +52,33 @@ public: using MacroAssemblerX86Common::loadDouble; using MacroAssemblerX86Common::convertInt32ToDouble; +#if defined(V4_BOOTSTRAP) + void loadPtr(ImplicitAddress address, RegisterID dest) + { + load64(address, dest); + } + + void subPtr(TrustedImm32 imm, RegisterID dest) + { + sub64(imm, dest); + } + + void addPtr(TrustedImm32 imm, RegisterID dest) + { + add64(imm, dest); + } + + void addPtr(TrustedImm32 imm, RegisterID src, RegisterID dest) + { + add64(imm, src, dest); + } + + void storePtr(RegisterID src, ImplicitAddress address) + { + store64(src, address); + } +#endif + void add32(TrustedImm32 imm, AbsoluteAddress address) { move(TrustedImmPtr(address.m_ptr), scratchRegister); diff --git a/src/3rdparty/masm/assembler/X86Assembler.h b/src/3rdparty/masm/assembler/X86Assembler.h index 1875ebaff0..24462ef38f 100644 --- a/src/3rdparty/masm/assembler/X86Assembler.h +++ b/src/3rdparty/masm/assembler/X86Assembler.h @@ -29,6 +29,7 @@ #if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64)) #include "AssemblerBuffer.h" +#include "AbstractMacroAssembler.h" #include "JITCompilationEffort.h" #include <stdint.h> #include <wtf/Assertions.h> @@ -252,6 +253,45 @@ public: { } + template <typename LabelType> + class Jump { + template<class TemplateAssemblerType> + friend class AbstractMacroAssembler; + friend class Call; + template <typename, template <typename> class> friend class LinkBufferBase; + public: + Jump() + { + } + + Jump(AssemblerLabel jmp) + : m_label(jmp) + { + } + + LabelType label() const + { + LabelType result; + result.m_label = m_label; + return result; + } + + void link(AbstractMacroAssembler<X86Assembler>* masm) const + { + masm->m_assembler.linkJump(m_label, masm->m_assembler.label()); + } + + void linkTo(LabelType label, AbstractMacroAssembler<X86Assembler>* masm) const + { + masm->m_assembler.linkJump(m_label, label.label()); + } + + bool isSet() const { return m_label.isSet(); } + + private: + AssemblerLabel m_label; + }; + // Stack operations: void push_r(RegisterID reg) diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h index 8617229b06..9a2a9773b5 100644 --- a/src/3rdparty/masm/stubs/ExecutableAllocator.h +++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h @@ -61,7 +61,7 @@ namespace JSC { class JSGlobalData; struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> { - ExecutableMemoryHandle(QV4::ExecutableAllocator *allocator, int size) + ExecutableMemoryHandle(QV4::ExecutableAllocator *allocator, size_t size) : m_allocator(allocator) , m_size(size) { @@ -79,14 +79,14 @@ struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> { inline bool isManaged() const { return true; } void* start() { return m_allocation->start(); } - int sizeInBytes() { return m_size; } + size_t sizeInBytes() { return m_size; } QV4::ExecutableAllocator::ChunkOfPages *chunk() const { return m_allocator->chunkForAllocation(m_allocation); } QV4::ExecutableAllocator *m_allocator; QV4::ExecutableAllocator::Allocation *m_allocation; - int m_size; + size_t m_size; }; struct ExecutableAllocator { @@ -94,7 +94,7 @@ struct ExecutableAllocator { : realAllocator(alloc) {} - PassRefPtr<ExecutableMemoryHandle> allocate(JSGlobalData&, int size, void*, int) + PassRefPtr<ExecutableMemoryHandle> allocate(JSGlobalData&, size_t size, void*, int) { return adoptRef(new ExecutableMemoryHandle(realAllocator, size)); } diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index 3ac8779508..646d9a8871 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -709,5 +709,8 @@ JSC::MacroAssemblerCodeRef Assembler<TargetConfiguration>::link(int *codeSize) } template class QV4::JIT::Assembler<DefaultAssemblerTargetConfiguration>; +#if defined(V4_BOOTSTRAP) && CPU(X86_64) +template class QV4::JIT::Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerARMv7, NoOperatingSystemSpecialization>>; +#endif #endif diff --git a/src/qml/jit/qv4binop.cpp b/src/qml/jit/qv4binop.cpp index 3a349286c6..8468bf65a6 100644 --- a/src/qml/jit/qv4binop.cpp +++ b/src/qml/jit/qv4binop.cpp @@ -577,5 +577,8 @@ typename JITAssembler::Jump Binop<JITAssembler>::genInlineBinop(IR::Expr *leftSo } template struct QV4::JIT::Binop<QV4::JIT::Assembler<DefaultAssemblerTargetConfiguration>>; +#if defined(V4_BOOTSTRAP) && CPU(X86_64) +template struct QV4::JIT::Binop<QV4::JIT::Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerARMv7, NoOperatingSystemSpecialization>>>; +#endif #endif diff --git a/src/qml/jit/qv4targetplatform_p.h b/src/qml/jit/qv4targetplatform_p.h index ca6da649c9..1c29aa2a70 100644 --- a/src/qml/jit/qv4targetplatform_p.h +++ b/src/qml/jit/qv4targetplatform_p.h @@ -310,7 +310,7 @@ public: }; #endif // Windows on x86_64 -#if CPU(ARM) +#if CPU(ARM) || defined(V4_BOOTSTRAP) template <> class TargetPlatform<JSC::MacroAssemblerARMv7, NoOperatingSystemSpecialization> { diff --git a/src/qml/jit/qv4unop.cpp b/src/qml/jit/qv4unop.cpp index cc03fa6006..31355e5dce 100644 --- a/src/qml/jit/qv4unop.cpp +++ b/src/qml/jit/qv4unop.cpp @@ -145,5 +145,8 @@ void Unop<JITAssembler>::generateCompl(IR::Expr *source, IR::Expr *target) } template struct QV4::JIT::Unop<QV4::JIT::Assembler<DefaultAssemblerTargetConfiguration>>; +#if defined(V4_BOOTSTRAP) && CPU(X86_64) +template struct QV4::JIT::Unop<QV4::JIT::Assembler<AssemblerTargetConfiguration<JSC::MacroAssemblerARMv7, NoOperatingSystemSpecialization>>>; +#endif #endif |