summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/assembler/ARMv7Assembler.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/assembler/ARMv7Assembler.h
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/assembler/ARMv7Assembler.h')
-rw-r--r--Source/JavaScriptCore/assembler/ARMv7Assembler.h336
1 files changed, 165 insertions, 171 deletions
diff --git a/Source/JavaScriptCore/assembler/ARMv7Assembler.h b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
index 6b9f305e9..5257f32a8 100644
--- a/Source/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/Source/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2010, 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
* Copyright (C) 2010 University of Szeged
*
* Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,6 @@
#if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)
#include "AssemblerBuffer.h"
-#include "AssemblerCommon.h"
#include <limits.h>
#include <wtf/Assertions.h>
#include <wtf/Vector.h>
@@ -39,83 +38,23 @@
namespace JSC {
namespace ARMRegisters {
-
- #define FOR_EACH_CPU_REGISTER(V) \
- FOR_EACH_CPU_GPREGISTER(V) \
- FOR_EACH_CPU_SPECIAL_REGISTER(V) \
- FOR_EACH_CPU_FPREGISTER(V)
-
- // The following are defined as pairs of the following value:
- // 1. type of the storage needed to save the register value by the JIT probe.
- // 2. name of the register.
- #define FOR_EACH_CPU_GPREGISTER(V) \
- V(void*, r0) \
- V(void*, r1) \
- V(void*, r2) \
- V(void*, r3) \
- V(void*, r4) \
- V(void*, r5) \
- V(void*, r6) \
- V(void*, r7) \
- V(void*, r8) \
- V(void*, r9) \
- V(void*, r10) \
- V(void*, r11) \
- V(void*, ip) \
- V(void*, sp) \
- V(void*, lr) \
- V(void*, pc)
-
- #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \
- V(void*, apsr) \
- V(void*, fpscr) \
-
- #define FOR_EACH_CPU_FPREGISTER(V) \
- V(double, d0) \
- V(double, d1) \
- V(double, d2) \
- V(double, d3) \
- V(double, d4) \
- V(double, d5) \
- V(double, d6) \
- V(double, d7) \
- V(double, d8) \
- V(double, d9) \
- V(double, d10) \
- V(double, d11) \
- V(double, d12) \
- V(double, d13) \
- V(double, d14) \
- V(double, d15) \
- V(double, d16) \
- V(double, d17) \
- V(double, d18) \
- V(double, d19) \
- V(double, d20) \
- V(double, d21) \
- V(double, d22) \
- V(double, d23) \
- V(double, d24) \
- V(double, d25) \
- V(double, d26) \
- V(double, d27) \
- V(double, d28) \
- V(double, d29) \
- V(double, d30) \
- V(double, d31)
-
typedef enum {
- #define DECLARE_REGISTER(_type, _regName) _regName,
- FOR_EACH_CPU_GPREGISTER(DECLARE_REGISTER)
- #undef DECLARE_REGISTER
-
- fp = r7, // frame pointer
- sb = r9, // static base
- sl = r10, // stack limit
- r12 = ip,
- r13 = sp,
- r14 = lr,
- r15 = pc
+ r0,
+ r1,
+ r2,
+ r3,
+ r4,
+ r5,
+ r6,
+ r7, fp = r7, // frame pointer
+ r8,
+ r9, sb = r9, // static base
+ r10, sl = r10, // stack limit
+ r11,
+ r12, ip = r12,
+ r13, sp = r13,
+ r14, lr = r14,
+ r15, pc = r15,
} RegisterID;
typedef enum {
@@ -154,9 +93,38 @@ namespace ARMRegisters {
} FPSingleRegisterID;
typedef enum {
- #define DECLARE_REGISTER(_type, _regName) _regName,
- FOR_EACH_CPU_FPREGISTER(DECLARE_REGISTER)
- #undef DECLARE_REGISTER
+ d0,
+ d1,
+ d2,
+ d3,
+ d4,
+ d5,
+ d6,
+ d7,
+ d8,
+ d9,
+ d10,
+ d11,
+ d12,
+ d13,
+ d14,
+ d15,
+ d16,
+ d17,
+ d18,
+ d19,
+ d20,
+ d21,
+ d22,
+ d23,
+ d24,
+ d25,
+ d26,
+ d27,
+ d28,
+ d29,
+ d30,
+ d31,
} FPDoubleRegisterID;
typedef enum {
@@ -206,7 +174,77 @@ namespace ARMRegisters {
return (FPDoubleRegisterID)(reg >> 1);
}
-} // namespace ARMRegisters
+#if USE(MASM_PROBE)
+ #define FOR_EACH_CPU_REGISTER(V) \
+ FOR_EACH_CPU_GPREGISTER(V) \
+ FOR_EACH_CPU_SPECIAL_REGISTER(V) \
+ FOR_EACH_CPU_FPREGISTER(V)
+
+ #define FOR_EACH_CPU_GPREGISTER(V) \
+ V(void*, r0) \
+ V(void*, r1) \
+ V(void*, r2) \
+ V(void*, r3) \
+ V(void*, r4) \
+ V(void*, r5) \
+ V(void*, r6) \
+ V(void*, r7) \
+ V(void*, r8) \
+ V(void*, r9) \
+ V(void*, r10) \
+ V(void*, r11) \
+ V(void*, ip) \
+ V(void*, sp) \
+ V(void*, lr) \
+ V(void*, pc)
+
+ #define FOR_EACH_CPU_SPECIAL_REGISTER(V) \
+ V(void*, apsr) \
+ V(void*, fpscr) \
+
+ #define FOR_EACH_CPU_FPREGISTER(V) \
+ V(double, d0) \
+ V(double, d1) \
+ V(double, d2) \
+ V(double, d3) \
+ V(double, d4) \
+ V(double, d5) \
+ V(double, d6) \
+ V(double, d7) \
+ V(double, d8) \
+ V(double, d9) \
+ V(double, d10) \
+ V(double, d11) \
+ V(double, d12) \
+ V(double, d13) \
+ V(double, d14) \
+ V(double, d15) \
+ FOR_EACH_CPU_FPREGISTER_EXTENSION(V)
+
+#if CPU(APPLE_ARMV7S)
+ #define FOR_EACH_CPU_FPREGISTER_EXTENSION(V) \
+ V(double, d16) \
+ V(double, d17) \
+ V(double, d18) \
+ V(double, d19) \
+ V(double, d20) \
+ V(double, d21) \
+ V(double, d22) \
+ V(double, d23) \
+ V(double, d24) \
+ V(double, d25) \
+ V(double, d26) \
+ V(double, d27) \
+ V(double, d28) \
+ V(double, d29) \
+ V(double, d30) \
+ V(double, d31)
+#else
+ #define FOR_EACH_CPU_FPREGISTER_EXTENSION(V) // Nothing to add.
+#endif // CPU(APPLE_ARMV7S)
+
+#endif // USE(MASM_PROBE)
+}
class ARMv7Assembler;
class ARMThumbImmediate {
@@ -454,11 +492,11 @@ public:
typedef ARMRegisters::FPQuadRegisterID FPQuadRegisterID;
typedef FPDoubleRegisterID FPRegisterID;
- static constexpr RegisterID firstRegister() { return ARMRegisters::r0; }
- static constexpr RegisterID lastRegister() { return ARMRegisters::r13; }
-
- static constexpr FPRegisterID firstFPRegister() { return ARMRegisters::d0; }
- static constexpr FPRegisterID lastFPRegister() { return ARMRegisters::d31; }
+ static RegisterID firstRegister() { return ARMRegisters::r0; }
+ static RegisterID lastRegister() { return ARMRegisters::r13; }
+
+ static FPRegisterID firstFPRegister() { return ARMRegisters::d0; }
+ static FPRegisterID lastFPRegister() { return ARMRegisters::d31; }
// (HS, LO, HI, LS) -> (AE, B, A, BE)
// (VS, VC) -> (O, NO)
@@ -545,8 +583,6 @@ public:
{
}
- AssemblerBuffer& buffer() { return m_formatter.m_buffer; }
-
private:
// ARMv7, Appx-A.6.3
@@ -610,8 +646,6 @@ private:
OP_ADD_SP_imm_T1 = 0xA800,
OP_ADD_SP_imm_T2 = 0xB000,
OP_SUB_SP_imm_T1 = 0xB080,
- OP_PUSH_T1 = 0xB400,
- OP_POP_T1 = 0xBC00,
OP_BKPT = 0xBE00,
OP_IT = 0xBF00,
OP_NOP_T1 = 0xBF00,
@@ -620,8 +654,6 @@ private:
typedef enum {
OP_B_T1 = 0xD000,
OP_B_T2 = 0xE000,
- OP_POP_T2 = 0xE8BD,
- OP_PUSH_T2 = 0xE92D,
OP_AND_reg_T2 = 0xEA00,
OP_TST_reg_T2 = 0xEA10,
OP_ORR_reg_T2 = 0xEA40,
@@ -709,7 +741,7 @@ private:
OP_ROR_reg_T2 = 0xFA60,
OP_CLZ = 0xFAB0,
OP_SMULL_T1 = 0xFB80,
-#if HAVE(ARM_IDIV_INSTRUCTIONS)
+#if CPU(APPLE_ARMV7S)
OP_SDIV_T1 = 0xFB90,
OP_UDIV_T1 = 0xFBB0,
#endif
@@ -767,11 +799,11 @@ private:
class ARMInstructionFormatter;
// false means else!
- static bool ifThenElseConditionBit(Condition condition, bool isIf)
+ bool ifThenElseConditionBit(Condition condition, bool isIf)
{
return isIf ? (condition & 1) : !(condition & 1);
}
- static uint8_t ifThenElse(Condition condition, bool inst2if, bool inst3if, bool inst4if)
+ uint8_t ifThenElse(Condition condition, bool inst2if, bool inst3if, bool inst4if)
{
int mask = (ifThenElseConditionBit(condition, inst2if) << 3)
| (ifThenElseConditionBit(condition, inst3if) << 2)
@@ -780,7 +812,7 @@ private:
ASSERT((condition != ConditionAL) || !(mask & (mask - 1)));
return (condition << 4) | mask;
}
- static uint8_t ifThenElse(Condition condition, bool inst2if, bool inst3if)
+ uint8_t ifThenElse(Condition condition, bool inst2if, bool inst3if)
{
int mask = (ifThenElseConditionBit(condition, inst2if) << 3)
| (ifThenElseConditionBit(condition, inst3if) << 2)
@@ -788,7 +820,7 @@ private:
ASSERT((condition != ConditionAL) || !(mask & (mask - 1)));
return (condition << 4) | mask;
}
- static uint8_t ifThenElse(Condition condition, bool inst2if)
+ uint8_t ifThenElse(Condition condition, bool inst2if)
{
int mask = (ifThenElseConditionBit(condition, inst2if) << 3)
| 4;
@@ -796,7 +828,7 @@ private:
return (condition << 4) | mask;
}
- static uint8_t ifThenElse(Condition condition)
+ uint8_t ifThenElse(Condition condition)
{
int mask = 8;
return (condition << 4) | mask;
@@ -823,7 +855,7 @@ public:
ASSERT(rn != ARMRegisters::pc);
ASSERT(imm.isValid());
- if (rn == ARMRegisters::sp && imm.isUInt16()) {
+ if (rn == ARMRegisters::sp) {
ASSERT(!(imm.getUInt16() & 3));
if (!(rd & 8) && imm.isUInt10()) {
m_formatter.oneWordOp5Reg3Imm8(OP_ADD_SP_imm_T1, rd, static_cast<uint8_t>(imm.getUInt10() >> 2));
@@ -862,11 +894,6 @@ public:
// NOTE: In an IT block, add doesn't modify the flags register.
ALWAYS_INLINE void add(RegisterID rd, RegisterID rn, RegisterID rm)
{
- if (rd == ARMRegisters::sp) {
- mov(rd, rn);
- rn = rd;
- }
-
if (rd == rn)
m_formatter.oneWordOp8RegReg143(OP_ADD_reg_T2, rm, rd);
else if (rd == rm)
@@ -1156,10 +1183,9 @@ public:
{
ASSERT(rn != ARMRegisters::pc); // LDR (literal)
ASSERT(imm.isUInt12());
- ASSERT(!(imm.getUInt12() & 1));
if (!((rt | rn) & 8) && imm.isUInt6())
- m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDRH_imm_T1, imm.getUInt6() >> 1, rn, rt);
+ m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDRH_imm_T1, imm.getUInt6() >> 2, rn, rt);
else
m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRH_imm_T2, rn, rt, imm.getUInt12());
}
@@ -1462,49 +1488,9 @@ public:
m_formatter.twoWordOp12Reg4FourFours(OP_ROR_reg_T2, rn, FourFours(0xf, rd, 0, rm));
}
- ALWAYS_INLINE void pop(RegisterID dest)
- {
- if (dest < ARMRegisters::r8)
- m_formatter.oneWordOp7Imm9(OP_POP_T1, 1 << dest);
- else {
- // Load postindexed with writeback.
- ldr(dest, ARMRegisters::sp, sizeof(void*), false, true);
- }
- }
-
- ALWAYS_INLINE void pop(uint32_t registerList)
- {
- ASSERT(WTF::bitCount(registerList) > 1);
- ASSERT(!((1 << ARMRegisters::pc) & registerList) || !((1 << ARMRegisters::lr) & registerList));
- ASSERT(!((1 << ARMRegisters::sp) & registerList));
- m_formatter.twoWordOp16Imm16(OP_POP_T2, registerList);
- }
-
- ALWAYS_INLINE void push(RegisterID src)
- {
- if (src < ARMRegisters::r8)
- m_formatter.oneWordOp7Imm9(OP_PUSH_T1, 1 << src);
- else if (src == ARMRegisters::lr)
- m_formatter.oneWordOp7Imm9(OP_PUSH_T1, 0x100);
- else {
- // Store preindexed with writeback.
- str(src, ARMRegisters::sp, -sizeof(void*), true, true);
- }
- }
-
- ALWAYS_INLINE void push(uint32_t registerList)
- {
- ASSERT(WTF::bitCount(registerList) > 1);
- ASSERT(!((1 << ARMRegisters::pc) & registerList));
- ASSERT(!((1 << ARMRegisters::sp) & registerList));
- m_formatter.twoWordOp16Imm16(OP_PUSH_T2, registerList);
- }
-
-#if HAVE(ARM_IDIV_INSTRUCTIONS)
- template<int datasize>
+#if CPU(APPLE_ARMV7S)
ALWAYS_INLINE void sdiv(RegisterID rd, RegisterID rn, RegisterID rm)
{
- static_assert(datasize == 32, "sdiv datasize must be 32 for armv7s");
ASSERT(!BadReg(rd));
ASSERT(!BadReg(rn));
ASSERT(!BadReg(rm));
@@ -1649,8 +1635,8 @@ public:
ASSERT(rn != ARMRegisters::pc);
ASSERT(imm.isUInt12());
- if (!((rt | rn) & 8) && imm.isUInt6())
- m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STRH_imm_T1, imm.getUInt6() >> 1, rn, rt);
+ if (!((rt | rn) & 8) && imm.isUInt7())
+ m_formatter.oneWordOp5Imm5Reg3Reg3(OP_STRH_imm_T1, imm.getUInt7() >> 2, rn, rt);
else
m_formatter.twoWordOp12Reg4Reg4Imm12(OP_STRH_imm_T2, rn, rt, imm.getUInt12());
}
@@ -1848,7 +1834,7 @@ public:
m_formatter.twoWordOp12Reg40Imm3Reg4Imm20Imm5(OP_UBFX_T1, rd, rn, (lsb & 0x1c) << 10, (lsb & 0x3) << 6, (width - 1) & 0x1f);
}
-#if HAVE(ARM_IDIV_INSTRUCTIONS)
+#if CPU(APPLE_ARMV7S)
ALWAYS_INLINE void udiv(RegisterID rd, RegisterID rn, RegisterID rm)
{
ASSERT(!BadReg(rd));
@@ -2050,7 +2036,14 @@ public:
return b.m_offset - a.m_offset;
}
- static int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return JUMP_ENUM_SIZE(jumpType) - JUMP_ENUM_SIZE(jumpLinkType); }
+ int executableOffsetFor(int location)
+ {
+ if (!location)
+ return 0;
+ return static_cast<int32_t*>(m_formatter.data())[location / sizeof(int32_t) - 1];
+ }
+
+ int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return JUMP_ENUM_SIZE(jumpType) - JUMP_ENUM_SIZE(jumpLinkType); }
// Assembler admin methods:
@@ -2059,7 +2052,7 @@ public:
return a.from() < b.from();
}
- static bool canCompact(JumpType jumpType)
+ bool canCompact(JumpType jumpType)
{
// The following cannot be compacted:
// JumpFixed: represents custom jump sequence
@@ -2068,7 +2061,7 @@ public:
return (jumpType == JumpNoCondition) || (jumpType == JumpCondition);
}
- static JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to)
+ JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to)
{
if (jumpType == JumpFixed)
return LinkInvalid;
@@ -2112,20 +2105,29 @@ public:
return LinkConditionalBX;
}
- static JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to)
+ JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to)
{
JumpLinkType linkType = computeJumpType(record.type(), from, to);
record.setLinkType(linkType);
return linkType;
}
+ void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset)
+ {
+ int32_t ptr = regionStart / sizeof(int32_t);
+ const int32_t end = regionEnd / sizeof(int32_t);
+ int32_t* offsets = static_cast<int32_t*>(m_formatter.data());
+ while (ptr < end)
+ offsets[ptr++] = offset;
+ }
+
Vector<LinkRecord, 0, UnsafeVectorOverflow>& jumpsToLink()
{
std::sort(m_jumpsToLink.begin(), m_jumpsToLink.end(), linkRecordSourceComparator);
return m_jumpsToLink;
}
- static void ALWAYS_INLINE link(LinkRecord& record, uint8_t* from, uint8_t* to)
+ void ALWAYS_INLINE link(LinkRecord& record, uint8_t* from, uint8_t* to)
{
switch (record.linkType()) {
case LinkJumpT1:
@@ -2373,6 +2375,8 @@ public:
linuxPageFlush(current, current + page);
linuxPageFlush(current, end);
+#elif OS(WINCE)
+ CacheRangeFlush(code, size, CACHE_SYNC_ALL);
#else
#error "The cacheFlush support is missing on this platform."
#endif
@@ -2574,7 +2578,7 @@ private:
return ((relative << 7) >> 7) == relative;
}
- static void linkJumpT1(Condition cond, uint16_t* instruction, void* target)
+ void linkJumpT1(Condition cond, uint16_t* instruction, void* target)
{
// FIMXE: this should be up in the MacroAssembler layer. :-(
ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
@@ -2610,7 +2614,7 @@ private:
instruction[-1] = OP_B_T2 | ((relative & 0xffe) >> 1);
}
- static void linkJumpT3(Condition cond, uint16_t* instruction, void* target)
+ void linkJumpT3(Condition cond, uint16_t* instruction, void* target)
{
// FIMXE: this should be up in the MacroAssembler layer. :-(
ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
@@ -2643,7 +2647,7 @@ private:
instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1);
}
- static void linkConditionalJumpT4(Condition cond, uint16_t* instruction, void* target)
+ void linkConditionalJumpT4(Condition cond, uint16_t* instruction, void* target)
{
// FIMXE: this should be up in the MacroAssembler layer. :-(
ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
@@ -2669,7 +2673,7 @@ private:
instruction[-1] = OP_BX | (JUMP_TEMPORARY_REGISTER << 3);
}
- static void linkConditionalBX(Condition cond, uint16_t* instruction, void* target)
+ void linkConditionalBX(Condition cond, uint16_t* instruction, void* target)
{
// FIMXE: this should be up in the MacroAssembler layer. :-(
ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
@@ -2749,11 +2753,6 @@ private:
m_buffer.putShort(op | (reg1 << 6) | (reg2 << 3) | reg3);
}
- ALWAYS_INLINE void oneWordOp7Imm9(OpcodeID op, uint16_t imm)
- {
- m_buffer.putShort(op | imm);
- }
-
ALWAYS_INLINE void oneWordOp8Imm8(OpcodeID op, uint8_t imm)
{
m_buffer.putShort(op | imm);
@@ -2792,12 +2791,6 @@ private:
m_buffer.putShort(op2);
}
- ALWAYS_INLINE void twoWordOp16Imm16(OpcodeID1 op1, uint16_t imm)
- {
- m_buffer.putShort(op1);
- m_buffer.putShort(imm);
- }
-
ALWAYS_INLINE void twoWordOp5i6Imm4Reg4EncodedImm(OpcodeID1 op, int imm4, RegisterID rd, ARMThumbImmediate imm)
{
ARMThumbImmediate newImm = imm;
@@ -2858,6 +2851,7 @@ private:
unsigned debugOffset() { return m_buffer.debugOffset(); }
+ private:
AssemblerBuffer m_buffer;
} m_formatter;