diff options
Diffstat (limited to 'Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h')
-rw-r--r-- | Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h | 391 |
1 files changed, 279 insertions, 112 deletions
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h index 68a04fd22..3c95f2802 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2009-2010, 2014-2016 Apple Inc. All rights reserved. * Copyright (C) 2010 University of Szeged * * Redistribution and use in source and binary forms, with or without @@ -24,8 +24,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef MacroAssemblerARMv7_h -#define MacroAssemblerARMv7_h +#pragma once #if ENABLE(ASSEMBLER) @@ -34,7 +33,7 @@ namespace JSC { -class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> { +class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler, MacroAssemblerARMv7> { static const RegisterID dataTempRegister = ARMRegisters::ip; static const RegisterID addressTempRegister = ARMRegisters::r6; @@ -42,6 +41,9 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> { inline ARMRegisters::FPSingleRegisterID fpTempRegisterAsSingle() { return ARMRegisters::asSingle(fpTempRegister); } public: + static const unsigned numGPRs = 16; + static const unsigned numFPRs = 16; + MacroAssemblerARMv7() : m_makeJumpPatchable(false) { @@ -62,12 +64,11 @@ public: Vector<LinkRecord, 0, UnsafeVectorOverflow>& jumpsToLink() { return m_assembler.jumpsToLink(); } void* unlinkedCode() { return m_assembler.unlinkedCode(); } - bool canCompact(JumpType jumpType) { return m_assembler.canCompact(jumpType); } - JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to) { return m_assembler.computeJumpType(jumpType, from, to); } - JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to) { return m_assembler.computeJumpType(record, from, to); } - void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset) {return m_assembler.recordLinkOffsets(regionStart, regionEnd, offset); } - int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return m_assembler.jumpSizeDelta(jumpType, jumpLinkType); } - void link(LinkRecord& record, uint8_t* from, uint8_t* to) { return m_assembler.link(record, from, to); } + static bool canCompact(JumpType jumpType) { return ARMv7Assembler::canCompact(jumpType); } + static JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to) { return ARMv7Assembler::computeJumpType(jumpType, from, to); } + static JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to) { return ARMv7Assembler::computeJumpType(record, from, to); } + static int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return ARMv7Assembler::jumpSizeDelta(jumpType, jumpLinkType); } + static void link(LinkRecord& record, uint8_t* from, const uint8_t* fromInstruction, uint8_t* to) { return ARMv7Assembler::link(record, from, fromInstruction, to); } struct ArmAddress { enum AddressType { @@ -156,6 +157,11 @@ public: m_assembler.add(dest, dest, src); } + void add32(RegisterID left, RegisterID right, RegisterID dest) + { + m_assembler.add(dest, left, right); + } + void add32(TrustedImm32 imm, RegisterID dest) { add32(imm, dest, dest); @@ -170,6 +176,14 @@ public: void add32(TrustedImm32 imm, RegisterID src, RegisterID dest) { ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value); + + // For adds with stack pointer destination, moving the src first to sp is + // needed to avoid unpredictable instruction + if (dest == ARMRegisters::sp && src != dest) { + move(src, ARMRegisters::sp); + src = ARMRegisters::sp; + } + if (armImm.isValid()) m_assembler.add(dest, src, armImm); else { @@ -218,6 +232,11 @@ public: store32(dataTempRegister, address.m_ptr); } + void addPtrNoFlags(TrustedImm32 imm, RegisterID srcDest) + { + add32(imm, srcDest); + } + void add64(TrustedImm32 imm, AbsoluteAddress address) { move(TrustedImmPtr(address.m_ptr), addressTempRegister); @@ -305,6 +324,11 @@ public: m_assembler.smull(dest, dataTempRegister, dest, src); } + void mul32(RegisterID left, RegisterID right, RegisterID dest) + { + m_assembler.smull(dest, dataTempRegister, left, right); + } + void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest) { move(imm, dataTempRegister); @@ -329,6 +353,31 @@ public: store32(dataTempRegister, addressTempRegister); } + void or32(TrustedImm32 imm, AbsoluteAddress address) + { + ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value); + if (armImm.isValid()) { + move(TrustedImmPtr(address.m_ptr), addressTempRegister); + load32(addressTempRegister, dataTempRegister); + m_assembler.orr(dataTempRegister, dataTempRegister, armImm); + store32(dataTempRegister, addressTempRegister); + } else { + move(TrustedImmPtr(address.m_ptr), addressTempRegister); + load32(addressTempRegister, dataTempRegister); + move(imm, addressTempRegister); + m_assembler.orr(dataTempRegister, dataTempRegister, addressTempRegister); + move(TrustedImmPtr(address.m_ptr), addressTempRegister); + store32(dataTempRegister, addressTempRegister); + } + } + + void or32(TrustedImm32 imm, Address address) + { + load32(address, dataTempRegister); + or32(imm, dataTempRegister, dataTempRegister); + store32(dataTempRegister, address); + } + void or32(TrustedImm32 imm, RegisterID dest) { or32(imm, dest, dest); @@ -345,6 +394,7 @@ public: if (armImm.isValid()) m_assembler.orr(dest, src, armImm); else { + ASSERT(src != dataTempRegister); move(imm, dataTempRegister); m_assembler.orr(dest, src, dataTempRegister); } @@ -362,7 +412,10 @@ public: void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) { - m_assembler.asr(dest, src, imm.m_value & 0x1f); + if (!imm.m_value) + move(src, dest); + else + m_assembler.asr(dest, src, imm.m_value & 0x1f); } void rshift32(RegisterID shiftAmount, RegisterID dest) @@ -387,7 +440,10 @@ public: void urshift32(RegisterID src, TrustedImm32 imm, RegisterID dest) { - m_assembler.lsr(dest, src, imm.m_value & 0x1f); + if (!imm.m_value) + move(src, dest); + else + m_assembler.lsr(dest, src, imm.m_value & 0x1f); } void urshift32(RegisterID shiftAmount, RegisterID dest) @@ -405,6 +461,11 @@ public: m_assembler.sub(dest, dest, src); } + void sub32(RegisterID left, RegisterID right, RegisterID dest) + { + m_assembler.sub(dest, left, right); + } + void sub32(TrustedImm32 imm, RegisterID dest) { ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value); @@ -527,7 +588,7 @@ private: } } - void load16Signed(ArmAddress address, RegisterID dest) + void load16SignedExtendTo32(ArmAddress address, RegisterID dest) { ASSERT(address.type == ArmAddress::HasIndex); m_assembler.ldrsh(dest, address.base, address.u.index, address.u.scale); @@ -547,7 +608,7 @@ private: } } - void load8Signed(ArmAddress address, RegisterID dest) + void load8SignedExtendTo32(ArmAddress address, RegisterID dest) { ASSERT(address.type == ArmAddress::HasIndex); m_assembler.ldrsb(dest, address.base, address.u.index, address.u.scale); @@ -624,6 +685,18 @@ public: m_assembler.ldr(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0)); } + void abortWithReason(AbortReason reason) + { + move(TrustedImm32(reason), dataTempRegister); + breakpoint(); + } + + void abortWithReason(AbortReason reason, intptr_t misc) + { + move(TrustedImm32(misc), addressTempRegister); + abortWithReason(reason); + } + ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest) { ConvertibleLoadLabel result(this); @@ -637,7 +710,7 @@ public: load8(setupArmAddress(address), dest); } - void load8Signed(ImplicitAddress, RegisterID) + void load8SignedExtendTo32(ImplicitAddress, RegisterID) { UNREACHABLE_FOR_PLATFORM(); } @@ -647,9 +720,9 @@ public: load8(setupArmAddress(address), dest); } - void load8Signed(BaseIndex address, RegisterID dest) + void load8SignedExtendTo32(BaseIndex address, RegisterID dest) { - load8Signed(setupArmAddress(address), dest); + load8SignedExtendTo32(setupArmAddress(address), dest); } void load8(const void* address, RegisterID dest) @@ -683,9 +756,9 @@ public: m_assembler.ldrh(dest, makeBaseIndexBase(address), address.index, address.scale); } - void load16Signed(BaseIndex address, RegisterID dest) + void load16SignedExtendTo32(BaseIndex address, RegisterID dest) { - load16Signed(setupArmAddress(address), dest); + load16SignedExtendTo32(setupArmAddress(address), dest); } void load16(ImplicitAddress address, RegisterID dest) @@ -699,7 +772,7 @@ public: } } - void load16Signed(ImplicitAddress, RegisterID) + void load16SignedExtendTo32(ImplicitAddress, RegisterID) { UNREACHABLE_FOR_PLATFORM(); } @@ -745,6 +818,11 @@ public: store32(dataTempRegister, address); } + void store8(RegisterID src, Address address) + { + store8(src, setupArmAddress(address)); + } + void store8(RegisterID src, BaseIndex address) { store8(src, setupArmAddress(address)); @@ -758,7 +836,15 @@ public: void store8(TrustedImm32 imm, void* address) { - move(imm, dataTempRegister); + TrustedImm32 imm8(static_cast<int8_t>(imm.m_value)); + move(imm8, dataTempRegister); + store8(dataTempRegister, address); + } + + void store8(TrustedImm32 imm, Address address) + { + TrustedImm32 imm8(static_cast<int8_t>(imm.m_value)); + move(imm8, dataTempRegister); store8(dataTempRegister, address); } @@ -803,6 +889,7 @@ public: static bool supportsFloatingPointTruncate() { return true; } static bool supportsFloatingPointSqrt() { return true; } static bool supportsFloatingPointAbs() { return true; } + static bool supportsFloatingPointRounding() { return false; } void loadDouble(ImplicitAddress address, FPRegisterID dest) { @@ -856,9 +943,15 @@ public: m_assembler.vmov(dest, src); } - void loadDouble(const void* address, FPRegisterID dest) + void moveZeroToDouble(FPRegisterID reg) { - move(TrustedImmPtr(address), addressTempRegister); + static double zeroConstant = 0.; + loadDouble(TrustedImmPtr(&zeroConstant), reg); + } + + void loadDouble(TrustedImmPtr address, FPRegisterID dest) + { + move(address, addressTempRegister); m_assembler.vldr(dest, addressTempRegister, 0); } @@ -892,9 +985,9 @@ public: m_assembler.fsts(ARMRegisters::asSingle(src), base, offset); } - void storeDouble(FPRegisterID src, const void* address) + void storeDouble(FPRegisterID src, TrustedImmPtr address) { - move(TrustedImmPtr(address), addressTempRegister); + move(address, addressTempRegister); storeDouble(src, addressTempRegister); } @@ -932,7 +1025,7 @@ public: void addDouble(AbsoluteAddress address, FPRegisterID dest) { - loadDouble(address.m_ptr, fpTempRegister); + loadDouble(TrustedImmPtr(address.m_ptr), fpTempRegister); m_assembler.vadd(dest, dest, fpTempRegister); } @@ -993,6 +1086,24 @@ public: m_assembler.vneg(dest, src); } + NO_RETURN_DUE_TO_CRASH void ceilDouble(FPRegisterID, FPRegisterID) + { + ASSERT(!supportsFloatingPointRounding()); + CRASH(); + } + + NO_RETURN_DUE_TO_CRASH void floorDouble(FPRegisterID, FPRegisterID) + { + ASSERT(!supportsFloatingPointRounding()); + CRASH(); + } + + NO_RETURN_DUE_TO_CRASH void roundTowardZeroDouble(FPRegisterID, FPRegisterID) + { + ASSERT(!supportsFloatingPointRounding()); + CRASH(); + } + void convertInt32ToDouble(RegisterID src, FPRegisterID dest) { m_assembler.vmov(fpTempRegister, src, src); @@ -1138,14 +1249,12 @@ public: void pop(RegisterID dest) { - // store postindexed with writeback - m_assembler.ldr(dest, ARMRegisters::sp, sizeof(void*), false, true); + m_assembler.pop(dest); } void push(RegisterID src) { - // store preindexed with writeback - m_assembler.str(src, ARMRegisters::sp, -sizeof(void*), true, true); + m_assembler.push(src); } void push(Address address) @@ -1160,6 +1269,16 @@ public: push(dataTempRegister); } + void popPair(RegisterID dest1, RegisterID dest2) + { + m_assembler.pop(1 << dest1 | 1 << dest2); + } + + void pushPair(RegisterID src1, RegisterID src2) + { + m_assembler.push(1 << src1 | 1 << src2); + } + // Register move operations: // // Move values in registers. @@ -1225,6 +1344,11 @@ public: m_assembler.dmbSY(); } + void storeFence() + { + m_assembler.dmbISHST(); + } + static void replaceWithJump(CodeLocationLabel instructionStart, CodeLocationLabel destination) { ARMv7Assembler::replaceWithJump(instructionStart.dataLocation(), destination.dataLocation()); @@ -1235,6 +1359,11 @@ public: return ARMv7Assembler::maxJumpReplacementSize(); } + static ptrdiff_t patchableJumpSize() + { + return ARMv7Assembler::patchableJumpSize(); + } + // Forwards / external control flow operations: // // This set of jump and conditional branch operations return a Jump @@ -1255,25 +1384,22 @@ public: private: // Should we be using TEQ for equal/not-equal? - void compare32(RegisterID left, TrustedImm32 right) + void compare32AndSetFlags(RegisterID left, TrustedImm32 right) { int32_t imm = right.m_value; - if (!imm) - m_assembler.tst(left, left); + ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm); + if (armImm.isValid()) + m_assembler.cmp(left, armImm); + else if ((armImm = ARMThumbImmediate::makeEncodedImm(-imm)).isValid()) + m_assembler.cmn(left, armImm); else { - ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm); - if (armImm.isValid()) - m_assembler.cmp(left, armImm); - else if ((armImm = ARMThumbImmediate::makeEncodedImm(-imm)).isValid()) - m_assembler.cmn(left, armImm); - else { - move(TrustedImm32(imm), dataTempRegister); - m_assembler.cmp(left, dataTempRegister); - } + move(TrustedImm32(imm), dataTempRegister); + m_assembler.cmp(left, dataTempRegister); } } - void test32(RegisterID reg, TrustedImm32 mask) +public: + void test32(RegisterID reg, TrustedImm32 mask = TrustedImm32(-1)) { int32_t imm = mask.m_value; @@ -1281,16 +1407,28 @@ private: m_assembler.tst(reg, reg); else { ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm); - if (armImm.isValid()) - m_assembler.tst(reg, armImm); - else { + if (armImm.isValid()) { + if (reg == ARMRegisters::sp) { + move(reg, addressTempRegister); + m_assembler.tst(addressTempRegister, armImm); + } else + m_assembler.tst(reg, armImm); + } else { move(mask, dataTempRegister); - m_assembler.tst(reg, dataTempRegister); + if (reg == ARMRegisters::sp) { + move(reg, addressTempRegister); + m_assembler.tst(addressTempRegister, dataTempRegister); + } else + m_assembler.tst(reg, dataTempRegister); } } } + + Jump branch(ResultCondition cond) + { + return Jump(makeBranch(cond)); + } -public: Jump branch32(RelationalCondition cond, RegisterID left, RegisterID right) { m_assembler.cmp(left, right); @@ -1299,7 +1437,7 @@ public: Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right) { - compare32(left, right); + compare32AndSetFlags(left, right); return Jump(makeBranch(cond)); } @@ -1349,44 +1487,54 @@ public: return branch32(cond, addressTempRegister, right); } + Jump branchPtr(RelationalCondition cond, BaseIndex left, RegisterID right) + { + load32(left, dataTempRegister); + return branch32(cond, dataTempRegister, right); + } + Jump branch8(RelationalCondition cond, RegisterID left, TrustedImm32 right) { - compare32(left, right); + TrustedImm32 right8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, right); + compare32AndSetFlags(left, right8); return Jump(makeBranch(cond)); } Jump branch8(RelationalCondition cond, Address left, TrustedImm32 right) { - ASSERT(!(0xffffff00 & right.m_value)); // use addressTempRegister incase the branch8 we call uses dataTempRegister. :-/ - load8(left, addressTempRegister); - return branch8(cond, addressTempRegister, right); + TrustedImm32 right8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, right); + MacroAssemblerHelpers::load8OnCondition(*this, cond, left, addressTempRegister); + return branch8(cond, addressTempRegister, right8); } Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right) { - ASSERT(!(0xffffff00 & right.m_value)); // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/ - load8(left, addressTempRegister); - return branch32(cond, addressTempRegister, right); + TrustedImm32 right8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, right); + MacroAssemblerHelpers::load8OnCondition(*this, cond, left, addressTempRegister); + return branch32(cond, addressTempRegister, right8); } Jump branch8(RelationalCondition cond, AbsoluteAddress address, TrustedImm32 right) { // Use addressTempRegister instead of dataTempRegister, since branch32 uses dataTempRegister. + TrustedImm32 right8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, right); move(TrustedImmPtr(address.m_ptr), addressTempRegister); - load8(Address(addressTempRegister), addressTempRegister); - return branch32(cond, addressTempRegister, right); + MacroAssemblerHelpers::load8OnCondition(*this, cond, Address(addressTempRegister), addressTempRegister); + return branch32(cond, addressTempRegister, right8); } Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask) { + ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == PositiveOrZero); m_assembler.tst(reg, mask); return Jump(makeBranch(cond)); } Jump branchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1)) { + ASSERT(cond == Zero || cond == NonZero || cond == Signed || cond == PositiveOrZero); test32(reg, mask); return Jump(makeBranch(cond)); } @@ -1408,23 +1556,26 @@ public: Jump branchTest8(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1)) { // use addressTempRegister incase the branchTest8 we call uses dataTempRegister. :-/ - load8(address, addressTempRegister); - return branchTest32(cond, addressTempRegister, mask); + TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask); + MacroAssemblerHelpers::load8OnCondition(*this, cond, address, addressTempRegister); + return branchTest32(cond, addressTempRegister, mask8); } Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1)) { // use addressTempRegister incase the branchTest8 we call uses dataTempRegister. :-/ - load8(address, addressTempRegister); - return branchTest32(cond, addressTempRegister, mask); + TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask); + MacroAssemblerHelpers::load8OnCondition(*this, cond, address, addressTempRegister); + return branchTest32(cond, addressTempRegister, mask8); } Jump branchTest8(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1)) { // use addressTempRegister incase the branchTest8 we call uses dataTempRegister. :-/ + TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask); move(TrustedImmPtr(address.m_ptr), addressTempRegister); - load8(Address(addressTempRegister), addressTempRegister); - return branchTest32(cond, addressTempRegister, mask); + MacroAssemblerHelpers::load8OnCondition(*this, cond, Address(addressTempRegister), addressTempRegister); + return branchTest32(cond, addressTempRegister, mask8); } void jump(RegisterID target) @@ -1534,7 +1685,7 @@ public: return branchMul32(cond, src, dest, dest); } - Jump branchMul32(ResultCondition cond, TrustedImm32 imm, RegisterID src, RegisterID dest) + Jump branchMul32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest) { move(imm, dataTempRegister); return branchMul32(cond, dataTempRegister, src, dest); @@ -1607,6 +1758,12 @@ public: return Call(m_assembler.blx(dataTempRegister), Call::LinkableNear); } + ALWAYS_INLINE Call nearTailCall() + { + moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister); + return Call(m_assembler.bx(dataTempRegister), Call::LinkableNearTail); + } + ALWAYS_INLINE Call call() { moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister); @@ -1645,13 +1802,14 @@ public: void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest) { - load8(left, addressTempRegister); - compare32(cond, addressTempRegister, right, dest); + TrustedImm32 right8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, right); + MacroAssemblerHelpers::load8OnCondition(*this, cond, left, addressTempRegister); + compare32(cond, addressTempRegister, right8, dest); } void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest) { - compare32(left, right); + compare32AndSetFlags(left, right); m_assembler.it(armV7Condition(cond), false); m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1)); m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0)); @@ -1672,8 +1830,9 @@ public: void test8(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest) { - load8(address, dataTempRegister); - test32(dataTempRegister, mask); + TrustedImm32 mask8 = MacroAssemblerHelpers::mask8OnCondition(*this, cond, mask); + MacroAssemblerHelpers::load8OnCondition(*this, cond, address, dataTempRegister); + test32(dataTempRegister, mask8); m_assembler.it(armV7Condition(cond), false); m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1)); m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0)); @@ -1706,6 +1865,13 @@ public: return branch32(cond, addressTempRegister, dataTempRegister); } + ALWAYS_INLINE Jump branch32WithPatch(RelationalCondition cond, Address left, DataLabel32& dataLabel, TrustedImm32 initialRightValue = TrustedImm32(0)) + { + load32(left, addressTempRegister); + dataLabel = moveWithPatch(initialRightValue, dataTempRegister); + return branch32(cond, addressTempRegister, dataTempRegister); + } + PatchableJump patchableBranchPtr(RelationalCondition cond, Address left, TrustedImmPtr right = TrustedImmPtr(0)) { m_makeJumpPatchable = true; @@ -1730,6 +1896,14 @@ public: return PatchableJump(result); } + PatchableJump patchableBranch32(RelationalCondition cond, Address left, TrustedImm32 imm) + { + m_makeJumpPatchable = true; + Jump result = branch32(cond, left, imm); + m_makeJumpPatchable = false; + return PatchableJump(result); + } + PatchableJump patchableBranchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0)) { m_makeJumpPatchable = true; @@ -1738,6 +1912,14 @@ public: return PatchableJump(result); } + PatchableJump patchableBranch32WithPatch(RelationalCondition cond, Address left, DataLabel32& dataLabel, TrustedImm32 initialRightValue = TrustedImm32(0)) + { + m_makeJumpPatchable = true; + Jump result = branch32WithPatch(cond, left, dataLabel, initialRightValue); + m_makeJumpPatchable = false; + return PatchableJump(result); + } + PatchableJump patchableJump() { padBeforePatch(); @@ -1770,17 +1952,13 @@ public: } - int executableOffsetFor(int location) - { - return m_assembler.executableOffsetFor(location); - } - static FunctionPtr readCallTarget(CodeLocationCall call) { return FunctionPtr(reinterpret_cast<void(*)()>(ARMv7Assembler::readCallTarget(call.dataLocation()))); } static bool canJumpReplacePatchableBranchPtrWithPatch() { return false; } + static bool canJumpReplacePatchableBranch32WithPatch() { return false; } static CodeLocationLabel startOfBranchPtrWithPatchOnRegister(CodeLocationDataLabelPtr label) { @@ -1804,36 +1982,35 @@ public: return CodeLocationLabel(); } + static CodeLocationLabel startOfPatchableBranch32WithPatchOnAddress(CodeLocationDataLabel32) + { + UNREACHABLE_FOR_PLATFORM(); + return CodeLocationLabel(); + } + static void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel, Address, void*) { UNREACHABLE_FOR_PLATFORM(); } -#if USE(MASM_PROBE) - struct CPUState { - #define DECLARE_REGISTER(_type, _regName) \ - _type _regName; - FOR_EACH_CPU_REGISTER(DECLARE_REGISTER) - #undef DECLARE_REGISTER - }; - - struct ProbeContext; - typedef void (*ProbeFunction)(struct ProbeContext*); + static void revertJumpReplacementToPatchableBranch32WithPatch(CodeLocationLabel, Address, int32_t) + { + UNREACHABLE_FOR_PLATFORM(); + } - struct ProbeContext { - ProbeFunction probeFunction; - void* arg1; - void* arg2; - CPUState cpu; + static void repatchCall(CodeLocationCall call, CodeLocationLabel destination) + { + ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress()); + } - void dump(const char* indentation = 0); - private: - void dumpCPURegisters(const char* indentation); - }; + static void repatchCall(CodeLocationCall call, FunctionPtr destination) + { + ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress()); + } - // For details about probe(), see comment in MacroAssemblerX86_64.h. - void probe(ProbeFunction, void* arg1 = 0, void* arg2 = 0); -#endif // USE(MASM_PROBE) +#if ENABLE(MASM_PROBE) + void probe(ProbeFunction, void* arg1, void* arg2); +#endif // ENABLE(MASM_PROBE) protected: ALWAYS_INLINE Jump jump() @@ -1928,24 +2105,16 @@ protected: private: friend class LinkBuffer; - friend class RepatchBuffer; static void linkCall(void* code, Call call, FunctionPtr function) { - ARMv7Assembler::linkCall(code, call.m_label, function.value()); - } - - static void repatchCall(CodeLocationCall call, CodeLocationLabel destination) - { - ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress()); - } - - static void repatchCall(CodeLocationCall call, FunctionPtr destination) - { - ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress()); + if (call.isFlagSet(Call::Tail)) + ARMv7Assembler::linkJump(code, call.m_label, function.value()); + else + ARMv7Assembler::linkCall(code, call.m_label, function.value()); } -#if USE(MASM_PROBE) +#if ENABLE(MASM_PROBE) inline TrustedImm32 trustedImm32FromPtr(void* ptr) { return TrustedImm32(TrustedImmPtr(ptr)); @@ -1968,5 +2137,3 @@ private: } // namespace JSC #endif // ENABLE(ASSEMBLER) - -#endif // MacroAssemblerARMv7_h |