summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h')
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h391
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