aboutsummaryrefslogtreecommitdiffstats
path: root/src/3rdparty
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-08-08 10:41:54 +0200
committerLars Knoll <lars.knoll@qt.io>2018-08-11 13:11:16 +0000
commitd6d659a04832217d05930063a2aa484a5f0ec7ee (patch)
tree7b635580834d659dc6150f59467359cbf5706ba7 /src/3rdparty
parentc7686a6c00146860fa6466fc17eb13e91c1eb22d (diff)
Get rid of the Macro assembler for ARMv6 and earlier
We've not been using it for quite some time, and the interpreter is the better fallback option there. Change-Id: If4d698115eec6038b369586ebdd8c1e4b88ea0ba Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/3rdparty')
-rw-r--r--src/3rdparty/masm/assembler/ARMAssembler.cpp444
-rw-r--r--src/3rdparty/masm/assembler/ARMAssembler.h1129
-rw-r--r--src/3rdparty/masm/assembler/LinkBuffer.cpp17
-rw-r--r--src/3rdparty/masm/assembler/LinkBuffer.h2
-rw-r--r--src/3rdparty/masm/assembler/MacroAssembler.h6
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerARM.cpp99
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerARM.h1386
7 files changed, 0 insertions, 3083 deletions
diff --git a/src/3rdparty/masm/assembler/ARMAssembler.cpp b/src/3rdparty/masm/assembler/ARMAssembler.cpp
deleted file mode 100644
index 6912d1ea39..0000000000
--- a/src/3rdparty/masm/assembler/ARMAssembler.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright (C) 2009 University of Szeged
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
-
-#include "ARMAssembler.h"
-
-namespace JSC {
-
-// Patching helpers
-
-void ARMAssembler::patchConstantPoolLoad(void* loadAddr, void* constPoolAddr)
-{
- ARMWord *ldr = reinterpret_cast<ARMWord*>(loadAddr);
- ARMWord diff = reinterpret_cast<ARMWord*>(constPoolAddr) - ldr;
- ARMWord index = (*ldr & 0xfff) >> 1;
-
- ASSERT(diff >= 1);
- if (diff >= 2 || index > 0) {
- diff = (diff + index - 2) * sizeof(ARMWord);
- ASSERT(diff <= 0xfff);
- *ldr = (*ldr & ~0xfff) | diff;
- } else
- *ldr = (*ldr & ~(0xfff | ARMAssembler::DataTransferUp)) | sizeof(ARMWord);
-}
-
-// Handle immediates
-
-ARMWord ARMAssembler::getOp2(ARMWord imm)
-{
- int rol;
-
- if (imm <= 0xff)
- return Op2Immediate | imm;
-
- if ((imm & 0xff000000) == 0) {
- imm <<= 8;
- rol = 8;
- }
- else {
- imm = (imm << 24) | (imm >> 8);
- rol = 0;
- }
-
- if ((imm & 0xff000000) == 0) {
- imm <<= 8;
- rol += 4;
- }
-
- if ((imm & 0xf0000000) == 0) {
- imm <<= 4;
- rol += 2;
- }
-
- if ((imm & 0xc0000000) == 0) {
- imm <<= 2;
- rol += 1;
- }
-
- if ((imm & 0x00ffffff) == 0)
- return Op2Immediate | (imm >> 24) | (rol << 8);
-
- return InvalidImmediate;
-}
-
-int ARMAssembler::genInt(int reg, ARMWord imm, bool positive)
-{
- // Step1: Search a non-immediate part
- ARMWord mask;
- ARMWord imm1;
- ARMWord imm2;
- int rol;
-
- mask = 0xff000000;
- rol = 8;
- while(1) {
- if ((imm & mask) == 0) {
- imm = (imm << rol) | (imm >> (32 - rol));
- rol = 4 + (rol >> 1);
- break;
- }
- rol += 2;
- mask >>= 2;
- if (mask & 0x3) {
- // rol 8
- imm = (imm << 8) | (imm >> 24);
- mask = 0xff00;
- rol = 24;
- while (1) {
- if ((imm & mask) == 0) {
- imm = (imm << rol) | (imm >> (32 - rol));
- rol = (rol >> 1) - 8;
- break;
- }
- rol += 2;
- mask >>= 2;
- if (mask & 0x3)
- return 0;
- }
- break;
- }
- }
-
- ASSERT((imm & 0xff) == 0);
-
- if ((imm & 0xff000000) == 0) {
- imm1 = Op2Immediate | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8);
- imm2 = Op2Immediate | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8);
- } else if (imm & 0xc0000000) {
- imm1 = Op2Immediate | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
- imm <<= 8;
- rol += 4;
-
- if ((imm & 0xff000000) == 0) {
- imm <<= 8;
- rol += 4;
- }
-
- if ((imm & 0xf0000000) == 0) {
- imm <<= 4;
- rol += 2;
- }
-
- if ((imm & 0xc0000000) == 0) {
- imm <<= 2;
- rol += 1;
- }
-
- if ((imm & 0x00ffffff) == 0)
- imm2 = Op2Immediate | (imm >> 24) | ((rol & 0xf) << 8);
- else
- return 0;
- } else {
- if ((imm & 0xf0000000) == 0) {
- imm <<= 4;
- rol += 2;
- }
-
- if ((imm & 0xc0000000) == 0) {
- imm <<= 2;
- rol += 1;
- }
-
- imm1 = Op2Immediate | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8);
- imm <<= 8;
- rol += 4;
-
- if ((imm & 0xf0000000) == 0) {
- imm <<= 4;
- rol += 2;
- }
-
- if ((imm & 0xc0000000) == 0) {
- imm <<= 2;
- rol += 1;
- }
-
- if ((imm & 0x00ffffff) == 0)
- imm2 = Op2Immediate | (imm >> 24) | ((rol & 0xf) << 8);
- else
- return 0;
- }
-
- if (positive) {
- mov(reg, imm1);
- orr(reg, reg, imm2);
- } else {
- mvn(reg, imm1);
- bic(reg, reg, imm2);
- }
-
- return 1;
-}
-
-ARMWord ARMAssembler::getImm(ARMWord imm, int tmpReg, bool invert)
-{
- ARMWord tmp;
-
- // Do it by 1 instruction
- tmp = getOp2(imm);
- if (tmp != InvalidImmediate)
- return tmp;
-
- tmp = getOp2(~imm);
- if (tmp != InvalidImmediate) {
- if (invert)
- return tmp | Op2InvertedImmediate;
- mvn(tmpReg, tmp);
- return tmpReg;
- }
-
- return encodeComplexImm(imm, tmpReg);
-}
-
-void ARMAssembler::moveImm(ARMWord imm, int dest)
-{
- ARMWord tmp;
-
- // Do it by 1 instruction
- tmp = getOp2(imm);
- if (tmp != InvalidImmediate) {
- mov(dest, tmp);
- return;
- }
-
- tmp = getOp2(~imm);
- if (tmp != InvalidImmediate) {
- mvn(dest, tmp);
- return;
- }
-
- encodeComplexImm(imm, dest);
-}
-
-ARMWord ARMAssembler::encodeComplexImm(ARMWord imm, int dest)
-{
-#if WTF_ARM_ARCH_AT_LEAST(7)
- ARMWord tmp = getImm16Op2(imm);
- if (tmp != InvalidImmediate) {
- movw(dest, tmp);
- return dest;
- }
- movw(dest, getImm16Op2(imm & 0xffff));
- movt(dest, getImm16Op2(imm >> 16));
- return dest;
-#else
- // Do it by 2 instruction
- if (genInt(dest, imm, true))
- return dest;
- if (genInt(dest, ~imm, false))
- return dest;
-
- ldrImmediate(dest, imm);
- return dest;
-#endif
-}
-
-// Memory load/store helpers
-
-void ARMAssembler::dataTransfer32(DataTransferTypeA transferType, RegisterID srcDst, RegisterID base, int32_t offset)
-{
- if (offset >= 0) {
- if (offset <= 0xfff)
- dtrUp(transferType, srcDst, base, offset);
- else if (offset <= 0xfffff) {
- add(ARMRegisters::S0, base, Op2Immediate | (offset >> 12) | (10 << 8));
- dtrUp(transferType, srcDst, ARMRegisters::S0, (offset & 0xfff));
- } else {
- moveImm(offset, ARMRegisters::S0);
- dtrUpRegister(transferType, srcDst, base, ARMRegisters::S0);
- }
- } else {
- if (offset >= -0xfff)
- dtrDown(transferType, srcDst, base, -offset);
- else if (offset >= -0xfffff) {
- sub(ARMRegisters::S0, base, Op2Immediate | (-offset >> 12) | (10 << 8));
- dtrDown(transferType, srcDst, ARMRegisters::S0, (-offset & 0xfff));
- } else {
- moveImm(offset, ARMRegisters::S0);
- dtrUpRegister(transferType, srcDst, base, ARMRegisters::S0);
- }
- }
-}
-
-void ARMAssembler::baseIndexTransfer32(DataTransferTypeA transferType, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset)
-{
- ASSERT(scale >= 0 && scale <= 3);
- ARMWord op2 = lsl(index, scale);
-
- if (!offset) {
- dtrUpRegister(transferType, srcDst, base, op2);
- return;
- }
-
- if (offset <= 0xfffff && offset >= -0xfffff) {
- add(ARMRegisters::S0, base, op2);
- dataTransfer32(transferType, srcDst, ARMRegisters::S0, offset);
- return;
- }
-
- moveImm(offset, ARMRegisters::S0);
- add(ARMRegisters::S0, ARMRegisters::S0, op2);
- dtrUpRegister(transferType, srcDst, base, ARMRegisters::S0);
-}
-
-void ARMAssembler::dataTransfer16(DataTransferTypeB transferType, RegisterID srcDst, RegisterID base, int32_t offset)
-{
- if (offset >= 0) {
- if (offset <= 0xff)
- halfDtrUp(transferType, srcDst, base, getOp2Half(offset));
- else if (offset <= 0xffff) {
- add(ARMRegisters::S0, base, Op2Immediate | (offset >> 8) | (12 << 8));
- halfDtrUp(transferType, srcDst, ARMRegisters::S0, getOp2Half(offset & 0xff));
- } else {
- moveImm(offset, ARMRegisters::S0);
- halfDtrUpRegister(transferType, srcDst, base, ARMRegisters::S0);
- }
- } else {
- if (offset >= -0xff)
- halfDtrDown(transferType, srcDst, base, getOp2Half(-offset));
- else if (offset >= -0xffff) {
- sub(ARMRegisters::S0, base, Op2Immediate | (-offset >> 8) | (12 << 8));
- halfDtrDown(transferType, srcDst, ARMRegisters::S0, getOp2Half(-offset & 0xff));
- } else {
- moveImm(offset, ARMRegisters::S0);
- halfDtrUpRegister(transferType, srcDst, base, ARMRegisters::S0);
- }
- }
-}
-
-void ARMAssembler::baseIndexTransfer16(DataTransferTypeB transferType, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset)
-{
- if (!scale && !offset) {
- halfDtrUpRegister(transferType, srcDst, base, index);
- return;
- }
-
- ARMWord op2 = lsl(index, scale);
-
- if (offset <= 0xffff && offset >= -0xffff) {
- add(ARMRegisters::S0, base, op2);
- dataTransfer16(transferType, srcDst, ARMRegisters::S0, offset);
- return;
- }
-
- moveImm(offset, ARMRegisters::S0);
- add(ARMRegisters::S0, ARMRegisters::S0, op2);
- halfDtrUpRegister(transferType, srcDst, base, ARMRegisters::S0);
-}
-
-void ARMAssembler::dataTransferFloat(DataTransferTypeFloat transferType, FPRegisterID srcDst, RegisterID base, int32_t offset)
-{
- // VFP cannot directly access memory that is not four-byte-aligned
- if (!(offset & 0x3)) {
- if (offset <= 0x3ff && offset >= 0) {
- doubleDtrUp(transferType, srcDst, base, offset >> 2);
- return;
- }
- if (offset <= 0x3ffff && offset >= 0) {
- add(ARMRegisters::S0, base, Op2Immediate | (offset >> 10) | (11 << 8));
- doubleDtrUp(transferType, srcDst, ARMRegisters::S0, (offset >> 2) & 0xff);
- return;
- }
- offset = -offset;
-
- if (offset <= 0x3ff && offset >= 0) {
- doubleDtrDown(transferType, srcDst, base, offset >> 2);
- return;
- }
- if (offset <= 0x3ffff && offset >= 0) {
- sub(ARMRegisters::S0, base, Op2Immediate | (offset >> 10) | (11 << 8));
- doubleDtrDown(transferType, srcDst, ARMRegisters::S0, (offset >> 2) & 0xff);
- return;
- }
- offset = -offset;
- }
-
- moveImm(offset, ARMRegisters::S0);
- add(ARMRegisters::S0, ARMRegisters::S0, base);
- doubleDtrUp(transferType, srcDst, ARMRegisters::S0, 0);
-}
-
-void ARMAssembler::baseIndexTransferFloat(DataTransferTypeFloat transferType, FPRegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset)
-{
- add(ARMRegisters::S1, base, lsl(index, scale));
- dataTransferFloat(transferType, srcDst, ARMRegisters::S1, offset);
-}
-
-PassRefPtr<ExecutableMemoryHandle> ARMAssembler::executableCopy(JSGlobalData& globalData, void* ownerUID, JITCompilationEffort effort)
-{
- // 64-bit alignment is required for next constant pool and JIT code as well
- m_buffer.flushWithoutBarrier(true);
- if (!m_buffer.isAligned(8))
- bkpt(0);
-
- RefPtr<ExecutableMemoryHandle> result = m_buffer.executableCopy(globalData, ownerUID, effort);
- char* data = reinterpret_cast<char*>(result->start());
-
- for (Jumps::Iterator iter = m_jumps.begin(); iter != m_jumps.end(); ++iter) {
- // The last bit is set if the constant must be placed on constant pool.
- int pos = (iter->m_offset) & (~0x1);
- ARMWord* ldrAddr = reinterpret_cast_ptr<ARMWord*>(data + pos);
- ARMWord* addr = getLdrImmAddress(ldrAddr);
- if (*addr != InvalidBranchTarget) {
- if (!(iter->m_offset & 1)) {
- intptr_t difference = reinterpret_cast_ptr<ARMWord*>(data + *addr) - (ldrAddr + DefaultPrefetchOffset);
-
- if ((difference <= MaximumBranchOffsetDistance && difference >= MinimumBranchOffsetDistance)) {
- *ldrAddr = B | getConditionalField(*ldrAddr) | (difference & BranchOffsetMask);
- continue;
- }
- }
- *addr = reinterpret_cast<ARMWord>(data + *addr);
- }
- }
-
- return result;
-}
-
-#if OS(LINUX) && COMPILER(RVCT)
-
-__asm void ARMAssembler::cacheFlush(void* code, size_t size)
-{
- ARM
- push {r7}
- add r1, r1, r0
- mov r7, #0xf0000
- add r7, r7, #0x2
- mov r2, #0x0
- svc #0x0
- pop {r7}
- bx lr
-}
-
-#endif
-
-} // namespace JSC
-
-#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
diff --git a/src/3rdparty/masm/assembler/ARMAssembler.h b/src/3rdparty/masm/assembler/ARMAssembler.h
deleted file mode 100644
index 16cc25d4db..0000000000
--- a/src/3rdparty/masm/assembler/ARMAssembler.h
+++ /dev/null
@@ -1,1129 +0,0 @@
-/*
- * Copyright (C) 2009, 2010 University of Szeged
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ARMAssembler_h
-#define ARMAssembler_h
-
-#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
-
-#include "AssemblerBufferWithConstantPool.h"
-#include "JITCompilationEffort.h"
-#include <wtf/Assertions.h>
-namespace JSC {
-
- typedef uint32_t ARMWord;
-
- namespace ARMRegisters {
- typedef enum {
- r0 = 0,
- r1,
- r2,
- r3,
- r4,
- r5,
- r6, S0 = r6,
- r7,
- r8,
- r9,
- r10,
- r11,
- r12, S1 = r12,
- r13, sp = r13,
- r14, lr = r14,
- r15, pc = r15
- } RegisterID;
-
- typedef enum {
- d0,
- d1,
- d2,
- d3,
- d4,
- d5,
- d6,
- d7, SD0 = d7, /* Same as thumb assembler. */
- d8,
- d9,
- d10,
- d11,
- d12,
- d13,
- d14,
- d15,
- d16,
- d17,
- d18,
- d19,
- d20,
- d21,
- d22,
- d23,
- d24,
- d25,
- d26,
- d27,
- d28,
- d29,
- d30,
- d31
- } FPRegisterID;
-
- } // namespace ARMRegisters
-
- class ARMAssembler {
- public:
- typedef ARMRegisters::RegisterID RegisterID;
- typedef ARMRegisters::FPRegisterID FPRegisterID;
- typedef AssemblerBufferWithConstantPool<2048, 4, 4, ARMAssembler> ARMBuffer;
- typedef SegmentedVector<AssemblerLabel, 64> Jumps;
-
- ARMAssembler()
- : m_indexOfTailOfLastWatchpoint(1)
- {
- }
-
- // ARM conditional constants
- typedef enum {
- EQ = 0x00000000, // Zero
- NE = 0x10000000, // Non-zero
- CS = 0x20000000,
- CC = 0x30000000,
- MI = 0x40000000,
- PL = 0x50000000,
- VS = 0x60000000,
- VC = 0x70000000,
- HI = 0x80000000,
- LS = 0x90000000,
- GE = 0xa0000000,
- LT = 0xb0000000,
- GT = 0xc0000000,
- LE = 0xd0000000,
- AL = 0xe0000000
- } Condition;
-
- // ARM instruction constants
- enum {
- AND = (0x0 << 21),
- EOR = (0x1 << 21),
- SUB = (0x2 << 21),
- RSB = (0x3 << 21),
- ADD = (0x4 << 21),
- ADC = (0x5 << 21),
- SBC = (0x6 << 21),
- RSC = (0x7 << 21),
- TST = (0x8 << 21),
- TEQ = (0x9 << 21),
- CMP = (0xa << 21),
- CMN = (0xb << 21),
- ORR = (0xc << 21),
- MOV = (0xd << 21),
- BIC = (0xe << 21),
- MVN = (0xf << 21),
- MUL = 0x00000090,
- MULL = 0x00c00090,
- VMOV_F64 = 0x0eb00b40,
- VADD_F64 = 0x0e300b00,
- VDIV_F64 = 0x0e800b00,
- VSUB_F64 = 0x0e300b40,
- VMUL_F64 = 0x0e200b00,
- VCMP_F64 = 0x0eb40b40,
- VSQRT_F64 = 0x0eb10bc0,
- VABS_F64 = 0x0eb00bc0,
- VNEG_F64 = 0x0eb10b40,
- STMDB = 0x09200000,
- LDMIA = 0x08b00000,
- B = 0x0a000000,
- BL = 0x0b000000,
- BX = 0x012fff10,
- VMOV_VFP64 = 0x0c400a10,
- VMOV_ARM64 = 0x0c500a10,
- VMOV_VFP32 = 0x0e000a10,
- VMOV_ARM32 = 0x0e100a10,
- VCVT_F64_S32 = 0x0eb80bc0,
- VCVT_S32_F64 = 0x0ebd0b40,
- VCVT_U32_F64 = 0x0ebc0b40,
- VCVT_F32_F64 = 0x0eb70bc0,
- VCVT_F64_F32 = 0x0eb70ac0,
- VMRS_APSR = 0x0ef1fa10,
- CLZ = 0x016f0f10,
- BKPT = 0xe1200070,
- BLX = 0x012fff30,
-#if WTF_ARM_ARCH_AT_LEAST(7)
- MOVW = 0x03000000,
- MOVT = 0x03400000,
-#endif
- NOP = 0xe1a00000,
- };
-
- enum {
- Op2Immediate = (1 << 25),
- ImmediateForHalfWordTransfer = (1 << 22),
- Op2InvertedImmediate = (1 << 26),
- SetConditionalCodes = (1 << 20),
- Op2IsRegisterArgument = (1 << 25),
- // Data transfer flags.
- DataTransferUp = (1 << 23),
- DataTransferWriteBack = (1 << 21),
- DataTransferPostUpdate = (1 << 24),
- DataTransferLoad = (1 << 20),
- ByteDataTransfer = (1 << 22),
- };
-
- enum DataTransferTypeA {
- LoadUint32 = 0x05000000 | DataTransferLoad,
- LoadUint8 = 0x05400000 | DataTransferLoad,
- StoreUint32 = 0x05000000,
- StoreUint8 = 0x05400000,
- };
-
- enum DataTransferTypeB {
- LoadUint16 = 0x010000b0 | DataTransferLoad,
- LoadInt16 = 0x010000f0 | DataTransferLoad,
- LoadInt8 = 0x010000d0 | DataTransferLoad,
- StoreUint16 = 0x010000b0,
- };
-
- enum DataTransferTypeFloat {
- LoadFloat = 0x0d000a00 | DataTransferLoad,
- LoadDouble = 0x0d000b00 | DataTransferLoad,
- StoreFloat = 0x0d000a00,
- StoreDouble = 0x0d000b00,
- };
-
- // Masks of ARM instructions
- enum {
- BranchOffsetMask = 0x00ffffff,
- ConditionalFieldMask = 0xf0000000,
- DataTransferOffsetMask = 0xfff,
- };
-
- enum {
- MinimumBranchOffsetDistance = -0x00800000,
- MaximumBranchOffsetDistance = 0x007fffff,
- };
-
- enum {
- padForAlign8 = 0x00,
- padForAlign16 = 0x0000,
- padForAlign32 = 0xe12fff7f // 'bkpt 0xffff' instruction.
- };
-
- static const ARMWord InvalidImmediate = 0xf0000000;
- static const ARMWord InvalidBranchTarget = 0xffffffff;
- static const int DefaultPrefetchOffset = 2;
-
- static const ARMWord BlxInstructionMask = 0x012fff30;
- static const ARMWord LdrOrAddInstructionMask = 0x0ff00000;
- static const ARMWord LdrPcImmediateInstructionMask = 0x0f7f0000;
-
- static const ARMWord AddImmediateInstruction = 0x02800000;
- static const ARMWord BlxInstruction = 0x012fff30;
- static const ARMWord LdrImmediateInstruction = 0x05900000;
- static const ARMWord LdrPcImmediateInstruction = 0x051f0000;
-
- // Instruction formating
-
- void emitInstruction(ARMWord op, int rd, int rn, ARMWord op2)
- {
- ASSERT(((op2 & ~Op2Immediate) <= 0xfff) || (((op2 & ~ImmediateForHalfWordTransfer) <= 0xfff)));
- m_buffer.putInt(op | RN(rn) | RD(rd) | op2);
- }
-
- void emitDoublePrecisionInstruction(ARMWord op, int dd, int dn, int dm)
- {
- ASSERT((dd >= 0 && dd <= 31) && (dn >= 0 && dn <= 31) && (dm >= 0 && dm <= 31));
- m_buffer.putInt(op | ((dd & 0xf) << 12) | ((dd & 0x10) << (22 - 4))
- | ((dn & 0xf) << 16) | ((dn & 0x10) << (7 - 4))
- | (dm & 0xf) | ((dm & 0x10) << (5 - 4)));
- }
-
- void emitSinglePrecisionInstruction(ARMWord op, int sd, int sn, int sm)
- {
- ASSERT((sd >= 0 && sd <= 31) && (sn >= 0 && sn <= 31) && (sm >= 0 && sm <= 31));
- m_buffer.putInt(op | ((sd >> 1) << 12) | ((sd & 0x1) << 22)
- | ((sn >> 1) << 16) | ((sn & 0x1) << 7)
- | (sm >> 1) | ((sm & 0x1) << 5));
- }
-
- void bitAnd(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | AND, rd, rn, op2);
- }
-
- void bitAnds(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | AND | SetConditionalCodes, rd, rn, op2);
- }
-
- void eor(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | EOR, rd, rn, op2);
- }
-
- void eors(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | EOR | SetConditionalCodes, rd, rn, op2);
- }
-
- void sub(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | SUB, rd, rn, op2);
- }
-
- void subs(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | SUB | SetConditionalCodes, rd, rn, op2);
- }
-
- void rsb(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | RSB, rd, rn, op2);
- }
-
- void rsbs(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | RSB | SetConditionalCodes, rd, rn, op2);
- }
-
- void add(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | ADD, rd, rn, op2);
- }
-
- void adds(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | ADD | SetConditionalCodes, rd, rn, op2);
- }
-
- void adc(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | ADC, rd, rn, op2);
- }
-
- void adcs(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | ADC | SetConditionalCodes, rd, rn, op2);
- }
-
- void sbc(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | SBC, rd, rn, op2);
- }
-
- void sbcs(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | SBC | SetConditionalCodes, rd, rn, op2);
- }
-
- void rsc(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | RSC, rd, rn, op2);
- }
-
- void rscs(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | RSC | SetConditionalCodes, rd, rn, op2);
- }
-
- void tst(int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | TST | SetConditionalCodes, 0, rn, op2);
- }
-
- void teq(int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | TEQ | SetConditionalCodes, 0, rn, op2);
- }
-
- void cmp(int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | CMP | SetConditionalCodes, 0, rn, op2);
- }
-
- void cmn(int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | CMN | SetConditionalCodes, 0, rn, op2);
- }
-
- void orr(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | ORR, rd, rn, op2);
- }
-
- void orrs(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | ORR | SetConditionalCodes, rd, rn, op2);
- }
-
- void mov(int rd, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | MOV, rd, ARMRegisters::r0, op2);
- }
-
-#if WTF_ARM_ARCH_AT_LEAST(7)
- void movw(int rd, ARMWord op2, Condition cc = AL)
- {
- ASSERT((op2 | 0xf0fff) == 0xf0fff);
- m_buffer.putInt(toARMWord(cc) | MOVW | RD(rd) | op2);
- }
-
- void movt(int rd, ARMWord op2, Condition cc = AL)
- {
- ASSERT((op2 | 0xf0fff) == 0xf0fff);
- m_buffer.putInt(toARMWord(cc) | MOVT | RD(rd) | op2);
- }
-#endif
-
- void movs(int rd, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | MOV | SetConditionalCodes, rd, ARMRegisters::r0, op2);
- }
-
- void bic(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | BIC, rd, rn, op2);
- }
-
- void bics(int rd, int rn, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | BIC | SetConditionalCodes, rd, rn, op2);
- }
-
- void mvn(int rd, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | MVN, rd, ARMRegisters::r0, op2);
- }
-
- void mvns(int rd, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | MVN | SetConditionalCodes, rd, ARMRegisters::r0, op2);
- }
-
- void mul(int rd, int rn, int rm, Condition cc = AL)
- {
- m_buffer.putInt(toARMWord(cc) | MUL | RN(rd) | RS(rn) | RM(rm));
- }
-
- void muls(int rd, int rn, int rm, Condition cc = AL)
- {
- m_buffer.putInt(toARMWord(cc) | MUL | SetConditionalCodes | RN(rd) | RS(rn) | RM(rm));
- }
-
- void mull(int rdhi, int rdlo, int rn, int rm, Condition cc = AL)
- {
- m_buffer.putInt(toARMWord(cc) | MULL | RN(rdhi) | RD(rdlo) | RS(rn) | RM(rm));
- }
-
- void vmov_f64(int dd, int dm, Condition cc = AL)
- {
- emitDoublePrecisionInstruction(toARMWord(cc) | VMOV_F64, dd, 0, dm);
- }
-
- void vadd_f64(int dd, int dn, int dm, Condition cc = AL)
- {
- emitDoublePrecisionInstruction(toARMWord(cc) | VADD_F64, dd, dn, dm);
- }
-
- void vdiv_f64(int dd, int dn, int dm, Condition cc = AL)
- {
- emitDoublePrecisionInstruction(toARMWord(cc) | VDIV_F64, dd, dn, dm);
- }
-
- void vsub_f64(int dd, int dn, int dm, Condition cc = AL)
- {
- emitDoublePrecisionInstruction(toARMWord(cc) | VSUB_F64, dd, dn, dm);
- }
-
- void vmul_f64(int dd, int dn, int dm, Condition cc = AL)
- {
- emitDoublePrecisionInstruction(toARMWord(cc) | VMUL_F64, dd, dn, dm);
- }
-
- void vcmp_f64(int dd, int dm, Condition cc = AL)
- {
- emitDoublePrecisionInstruction(toARMWord(cc) | VCMP_F64, dd, 0, dm);
- }
-
- void vsqrt_f64(int dd, int dm, Condition cc = AL)
- {
- emitDoublePrecisionInstruction(toARMWord(cc) | VSQRT_F64, dd, 0, dm);
- }
-
- void vabs_f64(int dd, int dm, Condition cc = AL)
- {
- emitDoublePrecisionInstruction(toARMWord(cc) | VABS_F64, dd, 0, dm);
- }
-
- void vneg_f64(int dd, int dm, Condition cc = AL)
- {
- emitDoublePrecisionInstruction(toARMWord(cc) | VNEG_F64, dd, 0, dm);
- }
-
- void ldrImmediate(int rd, ARMWord imm, Condition cc = AL)
- {
- m_buffer.putIntWithConstantInt(toARMWord(cc) | LoadUint32 | DataTransferUp | RN(ARMRegisters::pc) | RD(rd), imm, true);
- }
-
- void ldrUniqueImmediate(int rd, ARMWord imm, Condition cc = AL)
- {
- m_buffer.putIntWithConstantInt(toARMWord(cc) | LoadUint32 | DataTransferUp | RN(ARMRegisters::pc) | RD(rd), imm);
- }
-
- void dtrUp(DataTransferTypeA transferType, int rd, int rb, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | transferType | DataTransferUp, rd, rb, op2);
- }
-
- void dtrUpRegister(DataTransferTypeA transferType, int rd, int rb, int rm, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | transferType | DataTransferUp | Op2IsRegisterArgument, rd, rb, rm);
- }
-
- void dtrDown(DataTransferTypeA transferType, int rd, int rb, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | transferType, rd, rb, op2);
- }
-
- void dtrDownRegister(DataTransferTypeA transferType, int rd, int rb, int rm, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | transferType | Op2IsRegisterArgument, rd, rb, rm);
- }
-
- void halfDtrUp(DataTransferTypeB transferType, int rd, int rb, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | transferType | DataTransferUp, rd, rb, op2);
- }
-
- void halfDtrUpRegister(DataTransferTypeB transferType, int rd, int rn, int rm, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | transferType | DataTransferUp, rd, rn, rm);
- }
-
- void halfDtrDown(DataTransferTypeB transferType, int rd, int rb, ARMWord op2, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | transferType, rd, rb, op2);
- }
-
- void halfDtrDownRegister(DataTransferTypeB transferType, int rd, int rn, int rm, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | transferType, rd, rn, rm);
- }
-
- void doubleDtrUp(DataTransferTypeFloat type, int rd, int rb, ARMWord op2, Condition cc = AL)
- {
- ASSERT(op2 <= 0xff && rd <= 15);
- /* Only d0-d15 and s0, s2, s4 ... s30 are supported. */
- m_buffer.putInt(toARMWord(cc) | DataTransferUp | type | (rd << 12) | RN(rb) | op2);
- }
-
- void doubleDtrDown(DataTransferTypeFloat type, int rd, int rb, ARMWord op2, Condition cc = AL)
- {
- ASSERT(op2 <= 0xff && rd <= 15);
- /* Only d0-d15 and s0, s2, s4 ... s30 are supported. */
- m_buffer.putInt(toARMWord(cc) | type | (rd << 12) | RN(rb) | op2);
- }
-
- void push(int reg, Condition cc = AL)
- {
- ASSERT(ARMWord(reg) <= 0xf);
- m_buffer.putInt(toARMWord(cc) | StoreUint32 | DataTransferWriteBack | RN(ARMRegisters::sp) | RD(reg) | 0x4);
- }
-
- void pop(int reg, Condition cc = AL)
- {
- ASSERT(ARMWord(reg) <= 0xf);
- m_buffer.putInt(toARMWord(cc) | (LoadUint32 ^ DataTransferPostUpdate) | DataTransferUp | RN(ARMRegisters::sp) | RD(reg) | 0x4);
- }
-
- inline void poke(int reg, Condition cc = AL)
- {
- dtrDown(StoreUint32, ARMRegisters::sp, 0, reg, cc);
- }
-
- inline void peek(int reg, Condition cc = AL)
- {
- dtrUp(LoadUint32, reg, ARMRegisters::sp, 0, cc);
- }
-
- void vmov_vfp64(int sm, int rt, int rt2, Condition cc = AL)
- {
- ASSERT(rt != rt2);
- m_buffer.putInt(toARMWord(cc) | VMOV_VFP64 | RN(rt2) | RD(rt) | (sm & 0xf) | ((sm & 0x10) << (5 - 4)));
- }
-
- void vmov_arm64(int rt, int rt2, int sm, Condition cc = AL)
- {
- ASSERT(rt != rt2);
- m_buffer.putInt(toARMWord(cc) | VMOV_ARM64 | RN(rt2) | RD(rt) | (sm & 0xf) | ((sm & 0x10) << (5 - 4)));
- }
-
- void vmov_vfp32(int sn, int rt, Condition cc = AL)
- {
- ASSERT(rt <= 15);
- emitSinglePrecisionInstruction(toARMWord(cc) | VMOV_VFP32, rt << 1, sn, 0);
- }
-
- void vmov_arm32(int rt, int sn, Condition cc = AL)
- {
- ASSERT(rt <= 15);
- emitSinglePrecisionInstruction(toARMWord(cc) | VMOV_ARM32, rt << 1, sn, 0);
- }
-
- void vcvt_f64_s32(int dd, int sm, Condition cc = AL)
- {
- ASSERT(!(sm & 0x1)); // sm must be divisible by 2
- emitDoublePrecisionInstruction(toARMWord(cc) | VCVT_F64_S32, dd, 0, (sm >> 1));
- }
-
- void vcvt_s32_f64(int sd, int dm, Condition cc = AL)
- {
- ASSERT(!(sd & 0x1)); // sd must be divisible by 2
- emitDoublePrecisionInstruction(toARMWord(cc) | VCVT_S32_F64, (sd >> 1), 0, dm);
- }
-
- void vcvt_u32_f64(int sd, int dm, Condition cc = AL)
- {
- ASSERT(!(sd & 0x1)); // sd must be divisible by 2
- emitDoublePrecisionInstruction(toARMWord(cc) | VCVT_U32_F64, (sd >> 1), 0, dm);
- }
-
- void vcvt_f64_f32(int dd, int sm, Condition cc = AL)
- {
- ASSERT(dd <= 15 && sm <= 15);
- emitDoublePrecisionInstruction(toARMWord(cc) | VCVT_F64_F32, dd, 0, sm);
- }
-
- void vcvt_f32_f64(int dd, int sm, Condition cc = AL)
- {
- ASSERT(dd <= 15 && sm <= 15);
- emitDoublePrecisionInstruction(toARMWord(cc) | VCVT_F32_F64, dd, 0, sm);
- }
-
- void vmrs_apsr(Condition cc = AL)
- {
- m_buffer.putInt(toARMWord(cc) | VMRS_APSR);
- }
-
- void clz(int rd, int rm, Condition cc = AL)
- {
- m_buffer.putInt(toARMWord(cc) | CLZ | RD(rd) | RM(rm));
- }
-
- void bkpt(ARMWord value)
- {
- m_buffer.putInt(BKPT | ((value & 0xff0) << 4) | (value & 0xf));
- }
-
- void nop()
- {
- m_buffer.putInt(NOP);
- }
-
- void bx(int rm, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | BX, 0, 0, RM(rm));
- }
-
- AssemblerLabel blx(int rm, Condition cc = AL)
- {
- emitInstruction(toARMWord(cc) | BLX, 0, 0, RM(rm));
- return m_buffer.label();
- }
-
- static ARMWord lsl(int reg, ARMWord value)
- {
- ASSERT(reg <= ARMRegisters::pc);
- ASSERT(value <= 0x1f);
- return reg | (value << 7) | 0x00;
- }
-
- static ARMWord lsr(int reg, ARMWord value)
- {
- ASSERT(reg <= ARMRegisters::pc);
- ASSERT(value <= 0x1f);
- return reg | (value << 7) | 0x20;
- }
-
- static ARMWord asr(int reg, ARMWord value)
- {
- ASSERT(reg <= ARMRegisters::pc);
- ASSERT(value <= 0x1f);
- return reg | (value << 7) | 0x40;
- }
-
- static ARMWord lslRegister(int reg, int shiftReg)
- {
- ASSERT(reg <= ARMRegisters::pc);
- ASSERT(shiftReg <= ARMRegisters::pc);
- return reg | (shiftReg << 8) | 0x10;
- }
-
- static ARMWord lsrRegister(int reg, int shiftReg)
- {
- ASSERT(reg <= ARMRegisters::pc);
- ASSERT(shiftReg <= ARMRegisters::pc);
- return reg | (shiftReg << 8) | 0x30;
- }
-
- static ARMWord asrRegister(int reg, int shiftReg)
- {
- ASSERT(reg <= ARMRegisters::pc);
- ASSERT(shiftReg <= ARMRegisters::pc);
- return reg | (shiftReg << 8) | 0x50;
- }
-
- // General helpers
-
- size_t codeSize() const
- {
- return m_buffer.codeSize();
- }
-
- void ensureSpace(int insnSpace, int constSpace)
- {
- m_buffer.ensureSpace(insnSpace, constSpace);
- }
-
- int sizeOfConstantPool()
- {
- return m_buffer.sizeOfConstantPool();
- }
-
- AssemblerLabel labelIgnoringWatchpoints()
- {
- m_buffer.ensureSpaceForAnyInstruction();
- return m_buffer.label();
- }
-
- AssemblerLabel labelForWatchpoint()
- {
- m_buffer.ensureSpaceForAnyInstruction(maxJumpReplacementSize() / sizeof(ARMWord));
- AssemblerLabel result = m_buffer.label();
- if (result.m_offset != (m_indexOfTailOfLastWatchpoint - maxJumpReplacementSize()))
- result = label();
- m_indexOfTailOfLastWatchpoint = result.m_offset + maxJumpReplacementSize();
- return label();
- }
-
- AssemblerLabel label()
- {
- AssemblerLabel result = labelIgnoringWatchpoints();
- while (result.m_offset + 1 < m_indexOfTailOfLastWatchpoint) {
- nop();
- // The available number of instructions are ensured by labelForWatchpoint.
- result = m_buffer.label();
- }
- return result;
- }
-
- AssemblerLabel align(int alignment)
- {
- while (!m_buffer.isAligned(alignment))
- mov(ARMRegisters::r0, ARMRegisters::r0);
-
- return label();
- }
-
- AssemblerLabel loadBranchTarget(int rd, Condition cc = AL, int useConstantPool = 0)
- {
- ensureSpace(sizeof(ARMWord), sizeof(ARMWord));
- m_jumps.append(m_buffer.codeSize() | (useConstantPool & 0x1));
- ldrUniqueImmediate(rd, InvalidBranchTarget, cc);
- return m_buffer.label();
- }
-
- AssemblerLabel jmp(Condition cc = AL, int useConstantPool = 0)
- {
- return loadBranchTarget(ARMRegisters::pc, cc, useConstantPool);
- }
-
- PassRefPtr<ExecutableMemoryHandle> executableCopy(JSGlobalData&, void* ownerUID, JITCompilationEffort);
-
- unsigned debugOffset() { return m_buffer.debugOffset(); }
-
- // DFG assembly helpers for moving data between fp and registers.
- void vmov(RegisterID rd1, RegisterID rd2, FPRegisterID rn)
- {
- vmov_arm64(rd1, rd2, rn);
- }
-
- void vmov(FPRegisterID rd, RegisterID rn1, RegisterID rn2)
- {
- vmov_vfp64(rd, rn1, rn2);
- }
-
- // Patching helpers
-
- static ARMWord* getLdrImmAddress(ARMWord* insn)
- {
- // Check for call
- if ((*insn & LdrPcImmediateInstructionMask) != LdrPcImmediateInstruction) {
- // Must be BLX
- ASSERT((*insn & BlxInstructionMask) == BlxInstruction);
- insn--;
- }
-
- // Must be an ldr ..., [pc +/- imm]
- ASSERT((*insn & LdrPcImmediateInstructionMask) == LdrPcImmediateInstruction);
-
- ARMWord addr = reinterpret_cast<ARMWord>(insn) + DefaultPrefetchOffset * sizeof(ARMWord);
- if (*insn & DataTransferUp)
- return reinterpret_cast<ARMWord*>(addr + (*insn & DataTransferOffsetMask));
- return reinterpret_cast<ARMWord*>(addr - (*insn & DataTransferOffsetMask));
- }
-
- static ARMWord* getLdrImmAddressOnPool(ARMWord* insn, uint32_t* constPool)
- {
- // Must be an ldr ..., [pc +/- imm]
- ASSERT((*insn & LdrPcImmediateInstructionMask) == LdrPcImmediateInstruction);
-
- if (*insn & 0x1)
- return reinterpret_cast<ARMWord*>(constPool + ((*insn & DataTransferOffsetMask) >> 1));
- return getLdrImmAddress(insn);
- }
-
- static void patchPointerInternal(intptr_t from, void* to)
- {
- ARMWord* insn = reinterpret_cast<ARMWord*>(from);
- ARMWord* addr = getLdrImmAddress(insn);
- *addr = reinterpret_cast<ARMWord>(to);
- }
-
- static ARMWord patchConstantPoolLoad(ARMWord load, ARMWord value)
- {
- value = (value << 1) + 1;
- ASSERT(!(value & ~DataTransferOffsetMask));
- return (load & ~DataTransferOffsetMask) | value;
- }
-
- static void patchConstantPoolLoad(void* loadAddr, void* constPoolAddr);
-
- // Read pointers
- static void* readPointer(void* from)
- {
- ARMWord* instruction = reinterpret_cast<ARMWord*>(from);
- ARMWord* address = getLdrImmAddress(instruction);
- return *reinterpret_cast<void**>(address);
- }
-
- // Patch pointers
-
- static void linkPointer(void* code, AssemblerLabel from, void* to)
- {
- patchPointerInternal(reinterpret_cast<intptr_t>(code) + from.m_offset, to);
- }
-
- static void repatchInt32(void* where, int32_t to)
- {
- patchPointerInternal(reinterpret_cast<intptr_t>(where), reinterpret_cast<void*>(to));
- }
-
- static void repatchCompact(void* where, int32_t value)
- {
- ARMWord* instruction = reinterpret_cast<ARMWord*>(where);
- ASSERT((*instruction & 0x0f700000) == LoadUint32);
- if (value >= 0)
- *instruction = (*instruction & 0xff7ff000) | DataTransferUp | value;
- else
- *instruction = (*instruction & 0xff7ff000) | -value;
- cacheFlush(instruction, sizeof(ARMWord));
- }
-
- static void repatchPointer(void* from, void* to)
- {
- patchPointerInternal(reinterpret_cast<intptr_t>(from), to);
- }
-
- // Linkers
- static intptr_t getAbsoluteJumpAddress(void* base, int offset = 0)
- {
- return reinterpret_cast<intptr_t>(base) + offset - sizeof(ARMWord);
- }
-
- void linkJump(AssemblerLabel from, AssemblerLabel to)
- {
- ARMWord* insn = reinterpret_cast<ARMWord*>(getAbsoluteJumpAddress(m_buffer.data(), from.m_offset));
- ARMWord* addr = getLdrImmAddressOnPool(insn, m_buffer.poolAddress());
- *addr = toARMWord(to.m_offset);
- }
-
- static void linkJump(void* code, AssemblerLabel from, void* to)
- {
- patchPointerInternal(getAbsoluteJumpAddress(code, from.m_offset), to);
- }
-
- static void relinkJump(void* from, void* to)
- {
- patchPointerInternal(getAbsoluteJumpAddress(from), to);
- }
-
- static void linkCall(void* code, AssemblerLabel from, void* to)
- {
- patchPointerInternal(getAbsoluteJumpAddress(code, from.m_offset), to);
- }
-
- static void relinkCall(void* from, void* to)
- {
- patchPointerInternal(getAbsoluteJumpAddress(from), to);
- }
-
- static void* readCallTarget(void* from)
- {
- return reinterpret_cast<void*>(readPointer(reinterpret_cast<void*>(getAbsoluteJumpAddress(from))));
- }
-
- static void replaceWithJump(void* instructionStart, void* to)
- {
- ARMWord* instruction = reinterpret_cast<ARMWord*>(instructionStart);
- intptr_t difference = reinterpret_cast<intptr_t>(to) - (reinterpret_cast<intptr_t>(instruction) + DefaultPrefetchOffset * sizeof(ARMWord));
-
- if (!(difference & 1)) {
- difference >>= 2;
- if ((difference <= MaximumBranchOffsetDistance && difference >= MinimumBranchOffsetDistance)) {
- // Direct branch.
- instruction[0] = B | AL | (difference & BranchOffsetMask);
- cacheFlush(instruction, sizeof(ARMWord));
- return;
- }
- }
-
- // Load target.
- instruction[0] = LoadUint32 | AL | RN(ARMRegisters::pc) | RD(ARMRegisters::pc) | 4;
- instruction[1] = reinterpret_cast<ARMWord>(to);
- cacheFlush(instruction, sizeof(ARMWord) * 2);
- }
-
- static ptrdiff_t maxJumpReplacementSize()
- {
- return sizeof(ARMWord) * 2;
- }
-
- static void replaceWithLoad(void* instructionStart)
- {
- ARMWord* instruction = reinterpret_cast<ARMWord*>(instructionStart);
- cacheFlush(instruction, sizeof(ARMWord));
-
- ASSERT((*instruction & LdrOrAddInstructionMask) == AddImmediateInstruction || (*instruction & LdrOrAddInstructionMask) == LdrImmediateInstruction);
- if ((*instruction & LdrOrAddInstructionMask) == AddImmediateInstruction) {
- *instruction = (*instruction & ~LdrOrAddInstructionMask) | LdrImmediateInstruction;
- cacheFlush(instruction, sizeof(ARMWord));
- }
- }
-
- static void replaceWithAddressComputation(void* instructionStart)
- {
- ARMWord* instruction = reinterpret_cast<ARMWord*>(instructionStart);
- cacheFlush(instruction, sizeof(ARMWord));
-
- ASSERT((*instruction & LdrOrAddInstructionMask) == AddImmediateInstruction || (*instruction & LdrOrAddInstructionMask) == LdrImmediateInstruction);
- if ((*instruction & LdrOrAddInstructionMask) == LdrImmediateInstruction) {
- *instruction = (*instruction & ~LdrOrAddInstructionMask) | AddImmediateInstruction;
- cacheFlush(instruction, sizeof(ARMWord));
- }
- }
-
- static void revertBranchPtrWithPatch(void* instructionStart, RegisterID rn, ARMWord imm)
- {
- ARMWord* instruction = reinterpret_cast<ARMWord*>(instructionStart);
-
- ASSERT((instruction[2] & LdrPcImmediateInstructionMask) == LdrPcImmediateInstruction);
- instruction[0] = toARMWord(AL) | ((instruction[2] & 0x0fff0fff) + sizeof(ARMWord)) | RD(ARMRegisters::S1);
- *getLdrImmAddress(instruction) = imm;
- instruction[1] = toARMWord(AL) | CMP | SetConditionalCodes | RN(rn) | RM(ARMRegisters::S1);
- cacheFlush(instruction, 2 * sizeof(ARMWord));
- }
-
- // Address operations
-
- static void* getRelocatedAddress(void* code, AssemblerLabel label)
- {
- return reinterpret_cast<void*>(reinterpret_cast<char*>(code) + label.m_offset);
- }
-
- // Address differences
-
- static int getDifferenceBetweenLabels(AssemblerLabel a, AssemblerLabel b)
- {
- return b.m_offset - a.m_offset;
- }
-
- static unsigned getCallReturnOffset(AssemblerLabel call)
- {
- return call.m_offset;
- }
-
- // Handle immediates
-
- static ARMWord getOp2(ARMWord imm);
-
- // Fast case if imm is known to be between 0 and 0xff
- static ARMWord getOp2Byte(ARMWord imm)
- {
- ASSERT(imm <= 0xff);
- return Op2Immediate | imm;
- }
-
- static ARMWord getOp2Half(ARMWord imm)
- {
- ASSERT(imm <= 0xff);
- return ImmediateForHalfWordTransfer | (imm & 0x0f) | ((imm & 0xf0) << 4);
- }
-
-#if WTF_ARM_ARCH_AT_LEAST(7)
- static ARMWord getImm16Op2(ARMWord imm)
- {
- if (imm <= 0xffff)
- return (imm & 0xf000) << 4 | (imm & 0xfff);
- return InvalidImmediate;
- }
-#endif
- ARMWord getImm(ARMWord imm, int tmpReg, bool invert = false);
- void moveImm(ARMWord imm, int dest);
- ARMWord encodeComplexImm(ARMWord imm, int dest);
-
- // Memory load/store helpers
-
- void dataTransfer32(DataTransferTypeA, RegisterID srcDst, RegisterID base, int32_t offset);
- void baseIndexTransfer32(DataTransferTypeA, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset);
- void dataTransfer16(DataTransferTypeB, RegisterID srcDst, RegisterID base, int32_t offset);
- void baseIndexTransfer16(DataTransferTypeB, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset);
- void dataTransferFloat(DataTransferTypeFloat, FPRegisterID srcDst, RegisterID base, int32_t offset);
- void baseIndexTransferFloat(DataTransferTypeFloat, FPRegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset);
-
- // Constant pool hnadlers
-
- static ARMWord placeConstantPoolBarrier(int offset)
- {
- offset = (offset - sizeof(ARMWord)) >> 2;
- ASSERT((offset <= MaximumBranchOffsetDistance && offset >= MinimumBranchOffsetDistance));
- return AL | B | (offset & BranchOffsetMask);
- }
-
-#if OS(LINUX) && COMPILER(GCC)
- static inline void linuxPageFlush(uintptr_t begin, uintptr_t end)
- {
- asm volatile(
- "push {r7}\n"
- "mov r0, %0\n"
- "mov r1, %1\n"
- "mov r7, #0xf0000\n"
- "add r7, r7, #0x2\n"
- "mov r2, #0x0\n"
- "svc 0x0\n"
- "pop {r7}\n"
- :
- : "r" (begin), "r" (end)
- : "r0", "r1", "r2");
- }
-#endif
-
-#if OS(LINUX) && COMPILER(RVCT)
- static __asm void cacheFlush(void* code, size_t);
-#else
- static void cacheFlush(void* code, size_t size)
- {
-#if OS(LINUX) && COMPILER(GCC)
- size_t page = pageSize();
- uintptr_t current = reinterpret_cast<uintptr_t>(code);
- uintptr_t end = current + size;
- uintptr_t firstPageEnd = (current & ~(page - 1)) + page;
-
- if (end <= firstPageEnd) {
- linuxPageFlush(current, end);
- return;
- }
-
- linuxPageFlush(current, firstPageEnd);
-
- for (current = firstPageEnd; current + page < end; current += page)
- linuxPageFlush(current, current + page);
-
- linuxPageFlush(current, end);
-#elif OS(WINCE)
- CacheRangeFlush(code, size, CACHE_SYNC_ALL);
-#elif OS(QNX) && ENABLE(ASSEMBLER_WX_EXCLUSIVE)
- UNUSED_PARAM(code);
- UNUSED_PARAM(size);
-#elif OS(QNX)
- msync(code, size, MS_INVALIDATE_ICACHE);
-#else
-#error "The cacheFlush support is missing on this platform."
-#endif
- }
-#endif
-
- private:
- static ARMWord RM(int reg)
- {
- ASSERT(reg <= ARMRegisters::pc);
- return reg;
- }
-
- static ARMWord RS(int reg)
- {
- ASSERT(reg <= ARMRegisters::pc);
- return reg << 8;
- }
-
- static ARMWord RD(int reg)
- {
- ASSERT(reg <= ARMRegisters::pc);
- return reg << 12;
- }
-
- static ARMWord RN(int reg)
- {
- ASSERT(reg <= ARMRegisters::pc);
- return reg << 16;
- }
-
- static ARMWord getConditionalField(ARMWord i)
- {
- return i & ConditionalFieldMask;
- }
-
- static ARMWord toARMWord(Condition cc)
- {
- return static_cast<ARMWord>(cc);
- }
-
- static ARMWord toARMWord(uint32_t u)
- {
- return static_cast<ARMWord>(u);
- }
-
- int genInt(int reg, ARMWord imm, bool positive);
-
- ARMBuffer m_buffer;
- Jumps m_jumps;
- uint32_t m_indexOfTailOfLastWatchpoint;
- };
-
-} // namespace JSC
-
-#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
-
-#endif // ARMAssembler_h
diff --git a/src/3rdparty/masm/assembler/LinkBuffer.cpp b/src/3rdparty/masm/assembler/LinkBuffer.cpp
index 74c278135b..44a11706c9 100644
--- a/src/3rdparty/masm/assembler/LinkBuffer.cpp
+++ b/src/3rdparty/masm/assembler/LinkBuffer.cpp
@@ -75,23 +75,6 @@ void LinkBuffer::dumpCode(void* code, size_t size)
for (unsigned i = 0; i < tsize; i++)
dataLogF("\t.short\t0x%x\n", tcode[i]);
-#elif CPU(ARM_TRADITIONAL)
- // gcc -c jit.s
- // objdump -D jit.o
- static unsigned codeCount = 0;
- unsigned int* tcode = static_cast<unsigned int*>(code);
- size_t tsize = size / sizeof(unsigned int);
- char nameBuf[128];
- snprintf(nameBuf, sizeof(nameBuf), "_jsc_jit%u", codeCount++);
- dataLogF("\t.globl\t%s\n"
- "\t.align 4\n"
- "\t.code 32\n"
- "\t.text\n"
- "# %p\n"
- "%s:\n", nameBuf, code, nameBuf);
-
- for (unsigned i = 0; i < tsize; i++)
- dataLogF("\t.long\t0x%x\n", tcode[i]);
#endif
}
#endif
diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h
index 8af084c330..9b0016e96a 100644
--- a/src/3rdparty/masm/assembler/LinkBuffer.h
+++ b/src/3rdparty/masm/assembler/LinkBuffer.h
@@ -524,8 +524,6 @@ public:
typedef LinkBuffer<MacroAssembler<MacroAssemblerARMv7>> DefaultLinkBuffer;
#elif CPU(ARM64)
typedef LinkBuffer<MacroAssembler<MacroAssemblerARM64>> DefaultLinkBuffer;
-#elif CPU(ARM_TRADITIONAL)
-typedef LinkBuffer<MacroAssembler<MacroAssemblerARM>> DefaultLinkBuffer;
#elif CPU(MIPS)
typedef LinkBuffer<MacroAssembler<MacroAssemblerMIPS>> DefaultLinkBuffer;
#elif CPU(X86)
diff --git a/src/3rdparty/masm/assembler/MacroAssembler.h b/src/3rdparty/masm/assembler/MacroAssembler.h
index 99d0bff59d..b442a81bd0 100644
--- a/src/3rdparty/masm/assembler/MacroAssembler.h
+++ b/src/3rdparty/masm/assembler/MacroAssembler.h
@@ -39,10 +39,6 @@ namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; };
#elif CPU(ARM64)
namespace JSC { typedef MacroAssemblerARM64 MacroAssemblerBase; };
-#elif CPU(ARM_TRADITIONAL)
-#include "MacroAssemblerARM.h"
-namespace JSC { typedef MacroAssemblerARM MacroAssemblerBase; };
-
#elif CPU(MIPS)
#include "MacroAssemblerMIPS.h"
namespace JSC {
@@ -1483,8 +1479,6 @@ public:
typedef MacroAssembler<MacroAssemblerARMv7> DefaultMacroAssembler;
#elif CPU(ARM64)
typedef MacroAssembler<MacroAssemblerARM64> DefaultMacroAssembler;
-#elif CPU(ARM_TRADITIONAL)
-typedef MacroAssembler<MacroAssemblerARM> DefaultMacroAssembler;
#elif CPU(MIPS)
typedef MacroAssembler<MacroAssemblerMIPS> DefaultMacroAssembler;
#elif CPU(X86)
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARM.cpp b/src/3rdparty/masm/assembler/MacroAssemblerARM.cpp
deleted file mode 100644
index 3ca9c7da80..0000000000
--- a/src/3rdparty/masm/assembler/MacroAssemblerARM.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2009 University of Szeged
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
-
-#include "MacroAssemblerARM.h"
-
-#if OS(LINUX)
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <elf.h>
-#define HWCAP_VFP (1 << 6)
-#endif
-
-namespace JSC {
-
-static bool isVFPPresent()
-{
-#if OS(LINUX)
- int fd = open("/proc/self/auxv", O_RDONLY);
- if (fd > 0) {
- Elf32_auxv_t aux;
- while (read(fd, &aux, sizeof(Elf32_auxv_t))) {
- if (aux.a_type == AT_HWCAP) {
- close(fd);
- return aux.a_un.a_val & HWCAP_VFP;
- }
- }
- close(fd);
- }
-#endif
-
-#if (COMPILER(RVCT) && defined(__TARGET_FPU_VFP)) || (COMPILER(GCC) && defined(__VFP_FP__))
- return true;
-#else
- return false;
-#endif
-}
-
-const bool MacroAssemblerARM::s_isVFPPresent = isVFPPresent();
-
-#if CPU(ARMV5_OR_LOWER)
-/* On ARMv5 and below, natural alignment is required. */
-void MacroAssemblerARM::load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
-{
- ARMWord op2;
-
- ASSERT(address.scale >= 0 && address.scale <= 3);
- op2 = m_assembler.lsl(address.index, static_cast<int>(address.scale));
-
- if (address.offset >= 0 && address.offset + 0x2 <= 0xff) {
- m_assembler.add(ARMRegisters::S0, address.base, op2);
- m_assembler.halfDtrUp(ARMAssembler::LoadUint16, dest, ARMRegisters::S0, ARMAssembler::getOp2Half(address.offset));
- m_assembler.halfDtrUp(ARMAssembler::LoadUint16, ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::getOp2Half(address.offset + 0x2));
- } else if (address.offset < 0 && address.offset >= -0xff) {
- m_assembler.add(ARMRegisters::S0, address.base, op2);
- m_assembler.halfDtrDown(ARMAssembler::LoadUint16, dest, ARMRegisters::S0, ARMAssembler::getOp2Half(-address.offset));
- m_assembler.halfDtrDown(ARMAssembler::LoadUint16, ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::getOp2Half(-address.offset - 0x2));
- } else {
- m_assembler.moveImm(address.offset, ARMRegisters::S0);
- m_assembler.add(ARMRegisters::S0, ARMRegisters::S0, op2);
- m_assembler.halfDtrUpRegister(ARMAssembler::LoadUint16, dest, address.base, ARMRegisters::S0);
- m_assembler.add(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::Op2Immediate | 0x2);
- m_assembler.halfDtrUpRegister(ARMAssembler::LoadUint16, ARMRegisters::S0, address.base, ARMRegisters::S0);
- }
- m_assembler.orr(dest, dest, m_assembler.lsl(ARMRegisters::S0, 16));
-}
-#endif
-
-}
-
-#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARM.h b/src/3rdparty/masm/assembler/MacroAssemblerARM.h
deleted file mode 100644
index 268fe5fe73..0000000000
--- a/src/3rdparty/masm/assembler/MacroAssemblerARM.h
+++ /dev/null
@@ -1,1386 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc.
- * Copyright (C) 2009, 2010 University of Szeged
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MacroAssemblerARM_h
-#define MacroAssemblerARM_h
-
-#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
-
-#include "ARMAssembler.h"
-#include "AbstractMacroAssembler.h"
-
-namespace JSC {
-
-class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler> {
- static const int DoubleConditionMask = 0x0f;
- static const int DoubleConditionBitSpecial = 0x10;
- COMPILE_ASSERT(!(DoubleConditionBitSpecial & DoubleConditionMask), DoubleConditionBitSpecial_should_not_interfere_with_ARMAssembler_Condition_codes);
-public:
- typedef ARMRegisters::FPRegisterID FPRegisterID;
-
- enum RelationalCondition {
- Equal = ARMAssembler::EQ,
- NotEqual = ARMAssembler::NE,
- Above = ARMAssembler::HI,
- AboveOrEqual = ARMAssembler::CS,
- Below = ARMAssembler::CC,
- BelowOrEqual = ARMAssembler::LS,
- GreaterThan = ARMAssembler::GT,
- GreaterThanOrEqual = ARMAssembler::GE,
- LessThan = ARMAssembler::LT,
- LessThanOrEqual = ARMAssembler::LE
- };
-
- enum ResultCondition {
- Overflow = ARMAssembler::VS,
- Signed = ARMAssembler::MI,
- Zero = ARMAssembler::EQ,
- NonZero = ARMAssembler::NE
- };
-
- enum DoubleCondition {
- // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
- DoubleEqual = ARMAssembler::EQ,
- DoubleNotEqual = ARMAssembler::NE | DoubleConditionBitSpecial,
- DoubleGreaterThan = ARMAssembler::GT,
- DoubleGreaterThanOrEqual = ARMAssembler::GE,
- DoubleLessThan = ARMAssembler::CC,
- DoubleLessThanOrEqual = ARMAssembler::LS,
- // If either operand is NaN, these conditions always evaluate to true.
- DoubleEqualOrUnordered = ARMAssembler::EQ | DoubleConditionBitSpecial,
- DoubleNotEqualOrUnordered = ARMAssembler::NE,
- DoubleGreaterThanOrUnordered = ARMAssembler::HI,
- DoubleGreaterThanOrEqualOrUnordered = ARMAssembler::CS,
- DoubleLessThanOrUnordered = ARMAssembler::LT,
- DoubleLessThanOrEqualOrUnordered = ARMAssembler::LE,
- };
-
- static const RegisterID stackPointerRegister = ARMRegisters::sp;
- static const RegisterID linkRegister = ARMRegisters::lr;
-
- static const Scale ScalePtr = TimesFour;
-
- void add32(RegisterID src, RegisterID dest)
- {
- m_assembler.adds(dest, dest, src);
- }
-
- void add32(RegisterID op1, RegisterID op2, RegisterID dest)
- {
- m_assembler.adds(dest, op1, op2);
- }
-
- void add32(TrustedImm32 imm, Address address)
- {
- load32(address, ARMRegisters::S1);
- add32(imm, ARMRegisters::S1);
- store32(ARMRegisters::S1, address);
- }
-
- void add32(TrustedImm32 imm, RegisterID dest)
- {
- m_assembler.adds(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
- }
-
- void add32(AbsoluteAddress src, RegisterID dest)
- {
- move(TrustedImmPtr(src.m_ptr), ARMRegisters::S1);
- m_assembler.dtrUp(ARMAssembler::LoadUint32, ARMRegisters::S1, ARMRegisters::S1, 0);
- add32(ARMRegisters::S1, dest);
- }
-
- void add32(Address src, RegisterID dest)
- {
- load32(src, ARMRegisters::S1);
- add32(ARMRegisters::S1, dest);
- }
-
- void add32(RegisterID src, TrustedImm32 imm, RegisterID dest)
- {
- m_assembler.adds(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
- }
-
- void and32(RegisterID src, RegisterID dest)
- {
- m_assembler.bitAnds(dest, dest, src);
- }
-
- void and32(RegisterID op1, RegisterID op2, RegisterID dest)
- {
- m_assembler.bitAnds(dest, op1, op2);
- }
-
- void and32(TrustedImm32 imm, RegisterID dest)
- {
- ARMWord w = m_assembler.getImm(imm.m_value, ARMRegisters::S0, true);
- if (w & ARMAssembler::Op2InvertedImmediate)
- m_assembler.bics(dest, dest, w & ~ARMAssembler::Op2InvertedImmediate);
- else
- m_assembler.bitAnds(dest, dest, w);
- }
-
- void and32(TrustedImm32 imm, RegisterID src, RegisterID dest)
- {
- ARMWord w = m_assembler.getImm(imm.m_value, ARMRegisters::S0, true);
- if (w & ARMAssembler::Op2InvertedImmediate)
- m_assembler.bics(dest, src, w & ~ARMAssembler::Op2InvertedImmediate);
- else
- m_assembler.bitAnds(dest, src, w);
- }
-
- void and32(Address src, RegisterID dest)
- {
- load32(src, ARMRegisters::S1);
- and32(ARMRegisters::S1, dest);
- }
-
- void lshift32(RegisterID shiftAmount, RegisterID dest)
- {
- lshift32(dest, shiftAmount, dest);
- }
-
- void lshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
- {
- ARMWord w = ARMAssembler::getOp2Byte(0x1f);
- m_assembler.bitAnd(ARMRegisters::S0, shiftAmount, w);
-
- m_assembler.movs(dest, m_assembler.lslRegister(src, ARMRegisters::S0));
- }
-
- void lshift32(TrustedImm32 imm, RegisterID dest)
- {
- m_assembler.movs(dest, m_assembler.lsl(dest, imm.m_value & 0x1f));
- }
-
- void lshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
- {
- m_assembler.movs(dest, m_assembler.lsl(src, imm.m_value & 0x1f));
- }
-
- void mul32(RegisterID op1, RegisterID op2, RegisterID dest)
- {
- if (op2 == dest) {
- if (op1 == dest) {
- move(op2, ARMRegisters::S0);
- op2 = ARMRegisters::S0;
- } else {
- // Swap the operands.
- RegisterID tmp = op1;
- op1 = op2;
- op2 = tmp;
- }
- }
- m_assembler.muls(dest, op1, op2);
- }
-
- void mul32(RegisterID src, RegisterID dest)
- {
- mul32(src, dest, dest);
- }
-
- void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
- {
- move(imm, ARMRegisters::S0);
- m_assembler.muls(dest, src, ARMRegisters::S0);
- }
-
- void neg32(RegisterID srcDest)
- {
- m_assembler.rsbs(srcDest, srcDest, ARMAssembler::getOp2Byte(0));
- }
-
- void or32(RegisterID src, RegisterID dest)
- {
- m_assembler.orrs(dest, dest, src);
- }
-
- void or32(RegisterID src, AbsoluteAddress dest)
- {
- move(TrustedImmPtr(dest.m_ptr), ARMRegisters::S0);
- load32(Address(ARMRegisters::S0), ARMRegisters::S1);
- or32(src, ARMRegisters::S1);
- store32(ARMRegisters::S1, ARMRegisters::S0);
- }
-
- void or32(TrustedImm32 imm, RegisterID dest)
- {
- m_assembler.orrs(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
- }
-
- void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
- {
- m_assembler.orrs(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
- }
-
- void or32(RegisterID op1, RegisterID op2, RegisterID dest)
- {
- m_assembler.orrs(dest, op1, op2);
- }
-
- void rshift32(RegisterID shiftAmount, RegisterID dest)
- {
- rshift32(dest, shiftAmount, dest);
- }
-
- void rshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
- {
- ARMWord w = ARMAssembler::getOp2Byte(0x1f);
- m_assembler.bitAnd(ARMRegisters::S0, shiftAmount, w);
-
- m_assembler.movs(dest, m_assembler.asrRegister(src, ARMRegisters::S0));
- }
-
- void rshift32(TrustedImm32 imm, RegisterID dest)
- {
- rshift32(dest, imm, dest);
- }
-
- void rshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
- {
- m_assembler.movs(dest, m_assembler.asr(src, imm.m_value & 0x1f));
- }
-
- void urshift32(RegisterID shiftAmount, RegisterID dest)
- {
- urshift32(dest, shiftAmount, dest);
- }
-
- void urshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
- {
- ARMWord w = ARMAssembler::getOp2Byte(0x1f);
- m_assembler.bitAnd(ARMRegisters::S0, shiftAmount, w);
-
- m_assembler.movs(dest, m_assembler.lsrRegister(src, ARMRegisters::S0));
- }
-
- void urshift32(TrustedImm32 imm, RegisterID dest)
- {
- m_assembler.movs(dest, m_assembler.lsr(dest, imm.m_value & 0x1f));
- }
-
- void urshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
- {
- m_assembler.movs(dest, m_assembler.lsr(src, imm.m_value & 0x1f));
- }
-
- void sub32(RegisterID src, RegisterID dest)
- {
- m_assembler.subs(dest, dest, src);
- }
-
- void sub32(TrustedImm32 imm, RegisterID dest)
- {
- m_assembler.subs(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
- }
-
- void sub32(TrustedImm32 imm, Address address)
- {
- load32(address, ARMRegisters::S1);
- sub32(imm, ARMRegisters::S1);
- store32(ARMRegisters::S1, address);
- }
-
- void sub32(Address src, RegisterID dest)
- {
- load32(src, ARMRegisters::S1);
- sub32(ARMRegisters::S1, dest);
- }
-
- void sub32(RegisterID src, TrustedImm32 imm, RegisterID dest)
- {
- m_assembler.subs(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
- }
-
- void xor32(RegisterID src, RegisterID dest)
- {
- m_assembler.eors(dest, dest, src);
- }
-
- void xor32(RegisterID op1, RegisterID op2, RegisterID dest)
- {
- m_assembler.eors(dest, op1, op2);
- }
-
- void xor32(TrustedImm32 imm, RegisterID dest)
- {
- if (imm.m_value == -1)
- m_assembler.mvns(dest, dest);
- else
- m_assembler.eors(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
- }
-
- void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest)
- {
- if (imm.m_value == -1)
- m_assembler.mvns(dest, src);
- else
- m_assembler.eors(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
- }
-
- void countLeadingZeros32(RegisterID src, RegisterID dest)
- {
-#if WTF_ARM_ARCH_AT_LEAST(5)
- m_assembler.clz(dest, src);
-#else
- UNUSED_PARAM(src);
- UNUSED_PARAM(dest);
- RELEASE_ASSERT_NOT_REACHED();
-#endif
- }
-
- void load8(ImplicitAddress address, RegisterID dest)
- {
- m_assembler.dataTransfer32(ARMAssembler::LoadUint8, dest, address.base, address.offset);
- }
-
- void load8(BaseIndex address, RegisterID dest)
- {
- m_assembler.baseIndexTransfer32(ARMAssembler::LoadUint8, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void load8Signed(BaseIndex address, RegisterID dest)
- {
- m_assembler.baseIndexTransfer16(ARMAssembler::LoadInt8, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void load16(ImplicitAddress address, RegisterID dest)
- {
- m_assembler.dataTransfer16(ARMAssembler::LoadUint16, dest, address.base, address.offset);
- }
-
- void load16(BaseIndex address, RegisterID dest)
- {
- m_assembler.baseIndexTransfer16(ARMAssembler::LoadUint16, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void load16Signed(BaseIndex address, RegisterID dest)
- {
- m_assembler.baseIndexTransfer16(ARMAssembler::LoadInt16, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void load32(ImplicitAddress address, RegisterID dest)
- {
- m_assembler.dataTransfer32(ARMAssembler::LoadUint32, dest, address.base, address.offset);
- }
-
- void load32(BaseIndex address, RegisterID dest)
- {
- m_assembler.baseIndexTransfer32(ARMAssembler::LoadUint32, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
-#if CPU(ARMV5_OR_LOWER)
- void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest);
-#else
- void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
- {
- load32(address, dest);
- }
-#endif
-
- void load16Unaligned(BaseIndex address, RegisterID dest)
- {
- load16(address, dest);
- }
-
- ConvertibleLoadLabel convertibleLoadPtr(Address address, RegisterID dest)
- {
- ConvertibleLoadLabel result(this);
- ASSERT(address.offset >= 0 && address.offset <= 255);
- m_assembler.dtrUp(ARMAssembler::LoadUint32, dest, address.base, address.offset);
- return result;
- }
-
- DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
- {
- DataLabel32 dataLabel(this);
- m_assembler.ldrUniqueImmediate(ARMRegisters::S0, 0);
- m_assembler.dtrUpRegister(ARMAssembler::LoadUint32, dest, address.base, ARMRegisters::S0);
- return dataLabel;
- }
-
- static bool isCompactPtrAlignedAddressOffset(ptrdiff_t value)
- {
- return value >= -4095 && value <= 4095;
- }
-
- DataLabelCompact load32WithCompactAddressOffsetPatch(Address address, RegisterID dest)
- {
- DataLabelCompact dataLabel(this);
- ASSERT(isCompactPtrAlignedAddressOffset(address.offset));
- if (address.offset >= 0)
- m_assembler.dtrUp(ARMAssembler::LoadUint32, dest, address.base, address.offset);
- else
- m_assembler.dtrDown(ARMAssembler::LoadUint32, dest, address.base, address.offset);
- return dataLabel;
- }
-
- DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
- {
- DataLabel32 dataLabel(this);
- m_assembler.ldrUniqueImmediate(ARMRegisters::S0, 0);
- m_assembler.dtrUpRegister(ARMAssembler::StoreUint32, src, address.base, ARMRegisters::S0);
- return dataLabel;
- }
-
- void store8(RegisterID src, BaseIndex address)
- {
- m_assembler.baseIndexTransfer32(ARMAssembler::StoreUint8, src, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void store8(TrustedImm32 imm, const void* address)
- {
- move(TrustedImm32(reinterpret_cast<ARMWord>(address)), ARMRegisters::S0);
- move(imm, ARMRegisters::S1);
- m_assembler.dtrUp(ARMAssembler::StoreUint8, ARMRegisters::S1, ARMRegisters::S0, 0);
- }
-
- void store16(RegisterID src, BaseIndex address)
- {
- m_assembler.baseIndexTransfer16(ARMAssembler::StoreUint16, src, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void store32(RegisterID src, ImplicitAddress address)
- {
- m_assembler.dataTransfer32(ARMAssembler::StoreUint32, src, address.base, address.offset);
- }
-
- void store32(RegisterID src, BaseIndex address)
- {
- m_assembler.baseIndexTransfer32(ARMAssembler::StoreUint32, src, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void store32(TrustedImm32 imm, ImplicitAddress address)
- {
- move(imm, ARMRegisters::S1);
- store32(ARMRegisters::S1, address);
- }
-
- void store32(TrustedImm32 imm, BaseIndex address)
- {
- move(imm, ARMRegisters::S1);
- m_assembler.baseIndexTransfer32(ARMAssembler::StoreUint32, ARMRegisters::S1, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void store32(RegisterID src, const void* address)
- {
- m_assembler.ldrUniqueImmediate(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
- m_assembler.dtrUp(ARMAssembler::StoreUint32, src, ARMRegisters::S0, 0);
- }
-
- void store32(TrustedImm32 imm, const void* address)
- {
- m_assembler.ldrUniqueImmediate(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
- m_assembler.moveImm(imm.m_value, ARMRegisters::S1);
- m_assembler.dtrUp(ARMAssembler::StoreUint32, ARMRegisters::S1, ARMRegisters::S0, 0);
- }
-
- void pop(RegisterID dest)
- {
- m_assembler.pop(dest);
- }
-
- void push(RegisterID src)
- {
- m_assembler.push(src);
- }
-
- void push(Address address)
- {
- load32(address, ARMRegisters::S1);
- push(ARMRegisters::S1);
- }
-
- void push(TrustedImm32 imm)
- {
- move(imm, ARMRegisters::S0);
- push(ARMRegisters::S0);
- }
-
- void move(TrustedImm32 imm, RegisterID dest)
- {
- m_assembler.moveImm(imm.m_value, dest);
- }
-
- void move(RegisterID src, RegisterID dest)
- {
- if (src != dest)
- m_assembler.mov(dest, src);
- }
-
- void move(TrustedImmPtr imm, RegisterID dest)
- {
- move(TrustedImm32(imm), dest);
- }
-
- void swap(RegisterID reg1, RegisterID reg2)
- {
- move(reg1, ARMRegisters::S0);
- move(reg2, reg1);
- move(ARMRegisters::S0, reg2);
- }
-
- void signExtend32ToPtr(RegisterID src, RegisterID dest)
- {
- if (src != dest)
- move(src, dest);
- }
-
- void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
- {
- if (src != dest)
- move(src, dest);
- }
-
- Jump branch8(RelationalCondition cond, Address left, TrustedImm32 right)
- {
- load8(left, ARMRegisters::S1);
- return branch32(cond, ARMRegisters::S1, right);
- }
-
- Jump branch8(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
- {
- ASSERT(!(right.m_value & 0xFFFFFF00));
- load8(left, ARMRegisters::S1);
- return branch32(cond, ARMRegisters::S1, right);
- }
-
- Jump branch32(RelationalCondition cond, RegisterID left, RegisterID right, int useConstantPool = 0)
- {
- m_assembler.cmp(left, right);
- return Jump(m_assembler.jmp(ARMCondition(cond), useConstantPool));
- }
-
- Jump branch32(RelationalCondition cond, RegisterID left, TrustedImm32 right, int useConstantPool = 0)
- {
- internalCompare32(left, right);
- return Jump(m_assembler.jmp(ARMCondition(cond), useConstantPool));
- }
-
- Jump branch32(RelationalCondition cond, RegisterID left, Address right)
- {
- load32(right, ARMRegisters::S1);
- return branch32(cond, left, ARMRegisters::S1);
- }
-
- Jump branch32(RelationalCondition cond, Address left, RegisterID right)
- {
- load32(left, ARMRegisters::S1);
- return branch32(cond, ARMRegisters::S1, right);
- }
-
- Jump branch32(RelationalCondition cond, Address left, TrustedImm32 right)
- {
- load32(left, ARMRegisters::S1);
- return branch32(cond, ARMRegisters::S1, right);
- }
-
- Jump branch32(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
- {
- load32(left, ARMRegisters::S1);
- return branch32(cond, ARMRegisters::S1, right);
- }
-
- Jump branch32WithUnalignedHalfWords(RelationalCondition cond, BaseIndex left, TrustedImm32 right)
- {
- load32WithUnalignedHalfWords(left, ARMRegisters::S1);
- return branch32(cond, ARMRegisters::S1, right);
- }
-
- Jump branchTest8(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
- {
- load8(address, ARMRegisters::S1);
- return branchTest32(cond, ARMRegisters::S1, mask);
- }
-
- Jump branchTest8(ResultCondition cond, AbsoluteAddress address, TrustedImm32 mask = TrustedImm32(-1))
- {
- move(TrustedImmPtr(address.m_ptr), ARMRegisters::S1);
- load8(Address(ARMRegisters::S1), ARMRegisters::S1);
- return branchTest32(cond, ARMRegisters::S1, mask);
- }
-
- Jump branchTest32(ResultCondition cond, RegisterID reg, RegisterID mask)
- {
- ASSERT((cond == Zero) || (cond == NonZero));
- m_assembler.tst(reg, mask);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
- {
- ASSERT((cond == Zero) || (cond == NonZero));
- ARMWord w = m_assembler.getImm(mask.m_value, ARMRegisters::S0, true);
- if (w & ARMAssembler::Op2InvertedImmediate)
- m_assembler.bics(ARMRegisters::S0, reg, w & ~ARMAssembler::Op2InvertedImmediate);
- else
- m_assembler.tst(reg, w);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchTest32(ResultCondition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
- {
- load32(address, ARMRegisters::S1);
- return branchTest32(cond, ARMRegisters::S1, mask);
- }
-
- Jump branchTest32(ResultCondition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
- {
- load32(address, ARMRegisters::S1);
- return branchTest32(cond, ARMRegisters::S1, mask);
- }
-
- Jump jump()
- {
- return Jump(m_assembler.jmp());
- }
-
- void jump(RegisterID target)
- {
- m_assembler.bx(target);
- }
-
- void jump(Address address)
- {
- load32(address, ARMRegisters::pc);
- }
-
- void jump(AbsoluteAddress address)
- {
- move(TrustedImmPtr(address.m_ptr), ARMRegisters::S0);
- load32(Address(ARMRegisters::S0, 0), ARMRegisters::pc);
- }
-
- void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2)
- {
- m_assembler.vmov(dest1, dest2, src);
- }
-
- void moveIntsToDouble(RegisterID src1, RegisterID src2, FPRegisterID dest, FPRegisterID)
- {
- m_assembler.vmov(dest, src1, src2);
- }
-
- Jump branchAdd32(ResultCondition cond, RegisterID src, RegisterID dest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- add32(src, dest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchAdd32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- add32(op1, op2, dest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- add32(imm, dest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchAdd32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- add32(src, imm, dest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- add32(imm, dest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- void mull32(RegisterID op1, RegisterID op2, RegisterID dest)
- {
- if (op2 == dest) {
- if (op1 == dest) {
- move(op2, ARMRegisters::S0);
- op2 = ARMRegisters::S0;
- } else {
- // Swap the operands.
- RegisterID tmp = op1;
- op1 = op2;
- op2 = tmp;
- }
- }
- m_assembler.mull(ARMRegisters::S1, dest, op1, op2);
- m_assembler.cmp(ARMRegisters::S1, m_assembler.asr(dest, 31));
- }
-
- Jump branchMul32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- if (cond == Overflow) {
- mull32(src1, src2, dest);
- cond = NonZero;
- }
- else
- mul32(src1, src2, dest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest)
- {
- return branchMul32(cond, src, dest, dest);
- }
-
- Jump branchMul32(ResultCondition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- if (cond == Overflow) {
- move(imm, ARMRegisters::S0);
- mull32(ARMRegisters::S0, src, dest);
- cond = NonZero;
- }
- else
- mul32(imm, src, dest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchSub32(ResultCondition cond, RegisterID src, RegisterID dest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- sub32(src, dest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchSub32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- sub32(imm, dest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- sub32(src, imm, dest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchSub32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- m_assembler.subs(dest, op1, op2);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchNeg32(ResultCondition cond, RegisterID srcDest)
- {
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
- neg32(srcDest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest)
- {
- ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
- or32(src, dest);
- return Jump(m_assembler.jmp(ARMCondition(cond)));
- }
-
- PatchableJump patchableBranch32(RelationalCondition cond, RegisterID reg, TrustedImm32 imm)
- {
- internalCompare32(reg, imm);
- Jump jump(m_assembler.loadBranchTarget(ARMRegisters::S1, ARMCondition(cond), true));
- m_assembler.bx(ARMRegisters::S1, ARMCondition(cond));
- return PatchableJump(jump);
- }
-
- void breakpoint()
- {
- m_assembler.bkpt(0);
- }
-
- Call nearCall()
- {
- m_assembler.loadBranchTarget(ARMRegisters::S1, ARMAssembler::AL, true);
- return Call(m_assembler.blx(ARMRegisters::S1), Call::LinkableNear);
- }
-
- Call call(RegisterID target)
- {
- return Call(m_assembler.blx(target), Call::None);
- }
-
- void call(Address address)
- {
- call32(address.base, address.offset);
- }
-
- void ret()
- {
- m_assembler.bx(linkRegister);
- }
-
- void compare32(RelationalCondition cond, RegisterID left, RegisterID right, RegisterID dest)
- {
- m_assembler.cmp(left, right);
- m_assembler.mov(dest, ARMAssembler::getOp2Byte(0));
- m_assembler.mov(dest, ARMAssembler::getOp2Byte(1), ARMCondition(cond));
- }
-
- void compare32(RelationalCondition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
- {
- m_assembler.cmp(left, m_assembler.getImm(right.m_value, ARMRegisters::S0));
- m_assembler.mov(dest, ARMAssembler::getOp2Byte(0));
- m_assembler.mov(dest, ARMAssembler::getOp2Byte(1), ARMCondition(cond));
- }
-
- void compare8(RelationalCondition cond, Address left, TrustedImm32 right, RegisterID dest)
- {
- load8(left, ARMRegisters::S1);
- compare32(cond, ARMRegisters::S1, right, dest);
- }
-
- void test32(ResultCondition cond, RegisterID reg, TrustedImm32 mask, RegisterID dest)
- {
- if (mask.m_value == -1)
- m_assembler.cmp(0, reg);
- else
- m_assembler.tst(reg, m_assembler.getImm(mask.m_value, ARMRegisters::S0));
- m_assembler.mov(dest, ARMAssembler::getOp2Byte(0));
- m_assembler.mov(dest, ARMAssembler::getOp2Byte(1), ARMCondition(cond));
- }
-
- void test32(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest)
- {
- load32(address, ARMRegisters::S1);
- test32(cond, ARMRegisters::S1, mask, dest);
- }
-
- void test8(ResultCondition cond, Address address, TrustedImm32 mask, RegisterID dest)
- {
- load8(address, ARMRegisters::S1);
- test32(cond, ARMRegisters::S1, mask, dest);
- }
-
- void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
- {
- m_assembler.add(dest, src, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
- }
-
- void add32(TrustedImm32 imm, AbsoluteAddress address)
- {
- load32(address.m_ptr, ARMRegisters::S1);
- add32(imm, ARMRegisters::S1);
- store32(ARMRegisters::S1, address.m_ptr);
- }
-
- void add64(TrustedImm32 imm, AbsoluteAddress address)
- {
- ARMWord tmp;
-
- move(TrustedImmPtr(address.m_ptr), ARMRegisters::S1);
- m_assembler.dtrUp(ARMAssembler::LoadUint32, ARMRegisters::S0, ARMRegisters::S1, 0);
-
- if ((tmp = ARMAssembler::getOp2(imm.m_value)) != ARMAssembler::InvalidImmediate)
- m_assembler.adds(ARMRegisters::S0, ARMRegisters::S0, tmp);
- else if ((tmp = ARMAssembler::getOp2(-imm.m_value)) != ARMAssembler::InvalidImmediate)
- m_assembler.subs(ARMRegisters::S0, ARMRegisters::S0, tmp);
- else {
- m_assembler.adds(ARMRegisters::S0, ARMRegisters::S0, m_assembler.getImm(imm.m_value, ARMRegisters::S1));
- move(TrustedImmPtr(address.m_ptr), ARMRegisters::S1);
- }
- m_assembler.dtrUp(ARMAssembler::StoreUint32, ARMRegisters::S0, ARMRegisters::S1, 0);
-
- m_assembler.dtrUp(ARMAssembler::LoadUint32, ARMRegisters::S0, ARMRegisters::S1, sizeof(ARMWord));
- if (imm.m_value >= 0)
- m_assembler.adc(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::getOp2Byte(0));
- else
- m_assembler.sbc(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::getOp2Byte(0));
- m_assembler.dtrUp(ARMAssembler::StoreUint32, ARMRegisters::S0, ARMRegisters::S1, sizeof(ARMWord));
- }
-
- void sub32(TrustedImm32 imm, AbsoluteAddress address)
- {
- load32(address.m_ptr, ARMRegisters::S1);
- sub32(imm, ARMRegisters::S1);
- store32(ARMRegisters::S1, address.m_ptr);
- }
-
- void load32(const void* address, RegisterID dest)
- {
- m_assembler.ldrUniqueImmediate(ARMRegisters::S0, reinterpret_cast<ARMWord>(address));
- m_assembler.dtrUp(ARMAssembler::LoadUint32, dest, ARMRegisters::S0, 0);
- }
-
- Jump branch32(RelationalCondition cond, AbsoluteAddress left, RegisterID right)
- {
- load32(left.m_ptr, ARMRegisters::S1);
- return branch32(cond, ARMRegisters::S1, right);
- }
-
- Jump branch32(RelationalCondition cond, AbsoluteAddress left, TrustedImm32 right)
- {
- load32(left.m_ptr, ARMRegisters::S1);
- return branch32(cond, ARMRegisters::S1, right);
- }
-
- void relativeTableJump(RegisterID index, int scale)
- {
- ASSERT(scale >= 0 && scale <= 31);
- m_assembler.add(ARMRegisters::pc, ARMRegisters::pc, m_assembler.lsl(index, scale));
-
- // NOP the default prefetching
- m_assembler.mov(ARMRegisters::r0, ARMRegisters::r0);
- }
-
- Call call()
- {
- ensureSpace(2 * sizeof(ARMWord), sizeof(ARMWord));
- m_assembler.loadBranchTarget(ARMRegisters::S1, ARMAssembler::AL, true);
- return Call(m_assembler.blx(ARMRegisters::S1), Call::Linkable);
- }
-
- Call tailRecursiveCall()
- {
- return Call::fromTailJump(jump());
- }
-
- Call makeTailRecursiveCall(Jump oldJump)
- {
- return Call::fromTailJump(oldJump);
- }
-
- DataLabelPtr moveWithPatch(TrustedImmPtr initialValue, RegisterID dest)
- {
- DataLabelPtr dataLabel(this);
- m_assembler.ldrUniqueImmediate(dest, reinterpret_cast<ARMWord>(initialValue.m_value));
- return dataLabel;
- }
-
- Jump branchPtrWithPatch(RelationalCondition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
- {
- ensureSpace(3 * sizeof(ARMWord), 2 * sizeof(ARMWord));
- dataLabel = moveWithPatch(initialRightValue, ARMRegisters::S1);
- Jump jump = branch32(cond, left, ARMRegisters::S1, true);
- return jump;
- }
-
- Jump branchPtrWithPatch(RelationalCondition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
- {
- load32(left, ARMRegisters::S1);
- ensureSpace(3 * sizeof(ARMWord), 2 * sizeof(ARMWord));
- dataLabel = moveWithPatch(initialRightValue, ARMRegisters::S0);
- Jump jump = branch32(cond, ARMRegisters::S0, ARMRegisters::S1, true);
- return jump;
- }
-
- DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
- {
- DataLabelPtr dataLabel = moveWithPatch(initialValue, ARMRegisters::S1);
- store32(ARMRegisters::S1, address);
- return dataLabel;
- }
-
- DataLabelPtr storePtrWithPatch(ImplicitAddress address)
- {
- return storePtrWithPatch(TrustedImmPtr(0), address);
- }
-
- // Floating point operators
- static bool supportsFloatingPoint()
- {
- return s_isVFPPresent;
- }
-
- static bool supportsFloatingPointTruncate()
- {
- return false;
- }
-
- static bool supportsFloatingPointSqrt()
- {
- return s_isVFPPresent;
- }
- static bool supportsFloatingPointAbs() { return false; }
-
- void loadFloat(BaseIndex address, FPRegisterID dest)
- {
- m_assembler.baseIndexTransferFloat(ARMAssembler::LoadFloat, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void loadDouble(ImplicitAddress address, FPRegisterID dest)
- {
- m_assembler.dataTransferFloat(ARMAssembler::LoadDouble, dest, address.base, address.offset);
- }
-
- void loadDouble(BaseIndex address, FPRegisterID dest)
- {
- m_assembler.baseIndexTransferFloat(ARMAssembler::LoadDouble, dest, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void loadDouble(const void* address, FPRegisterID dest)
- {
- move(TrustedImm32(reinterpret_cast<ARMWord>(address)), ARMRegisters::S0);
- m_assembler.doubleDtrUp(ARMAssembler::LoadDouble, dest, ARMRegisters::S0, 0);
- }
-
- void storeFloat(FPRegisterID src, BaseIndex address)
- {
- m_assembler.baseIndexTransferFloat(ARMAssembler::StoreFloat, src, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void storeDouble(FPRegisterID src, ImplicitAddress address)
- {
- m_assembler.dataTransferFloat(ARMAssembler::StoreDouble, src, address.base, address.offset);
- }
-
- void storeDouble(FPRegisterID src, BaseIndex address)
- {
- m_assembler.baseIndexTransferFloat(ARMAssembler::StoreDouble, src, address.base, address.index, static_cast<int>(address.scale), address.offset);
- }
-
- void storeDouble(FPRegisterID src, const void* address)
- {
- move(TrustedImm32(reinterpret_cast<ARMWord>(address)), ARMRegisters::S0);
- m_assembler.dataTransferFloat(ARMAssembler::StoreDouble, src, ARMRegisters::S0, 0);
- }
-
- void moveDouble(FPRegisterID src, FPRegisterID dest)
- {
- if (src != dest)
- m_assembler.vmov_f64(dest, src);
- }
-
- void addDouble(FPRegisterID src, FPRegisterID dest)
- {
- m_assembler.vadd_f64(dest, dest, src);
- }
-
- void addDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
- {
- m_assembler.vadd_f64(dest, op1, op2);
- }
-
- void addDouble(Address src, FPRegisterID dest)
- {
- loadDouble(src, ARMRegisters::SD0);
- addDouble(ARMRegisters::SD0, dest);
- }
-
- void addDouble(AbsoluteAddress address, FPRegisterID dest)
- {
- loadDouble(address.m_ptr, ARMRegisters::SD0);
- addDouble(ARMRegisters::SD0, dest);
- }
-
- void divDouble(FPRegisterID src, FPRegisterID dest)
- {
- m_assembler.vdiv_f64(dest, dest, src);
- }
-
- void divDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
- {
- m_assembler.vdiv_f64(dest, op1, op2);
- }
-
- void divDouble(Address src, FPRegisterID dest)
- {
- RELEASE_ASSERT_NOT_REACHED(); // Untested
- loadDouble(src, ARMRegisters::SD0);
- divDouble(ARMRegisters::SD0, dest);
- }
-
- void subDouble(FPRegisterID src, FPRegisterID dest)
- {
- m_assembler.vsub_f64(dest, dest, src);
- }
-
- void subDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
- {
- m_assembler.vsub_f64(dest, op1, op2);
- }
-
- void subDouble(Address src, FPRegisterID dest)
- {
- loadDouble(src, ARMRegisters::SD0);
- subDouble(ARMRegisters::SD0, dest);
- }
-
- void mulDouble(FPRegisterID src, FPRegisterID dest)
- {
- m_assembler.vmul_f64(dest, dest, src);
- }
-
- void mulDouble(Address src, FPRegisterID dest)
- {
- loadDouble(src, ARMRegisters::SD0);
- mulDouble(ARMRegisters::SD0, dest);
- }
-
- void mulDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
- {
- m_assembler.vmul_f64(dest, op1, op2);
- }
-
- void sqrtDouble(FPRegisterID src, FPRegisterID dest)
- {
- m_assembler.vsqrt_f64(dest, src);
- }
-
- void absDouble(FPRegisterID src, FPRegisterID dest)
- {
- m_assembler.vabs_f64(dest, src);
- }
-
- void negateDouble(FPRegisterID src, FPRegisterID dest)
- {
- m_assembler.vneg_f64(dest, src);
- }
-
- void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
- {
- m_assembler.vmov_vfp32(dest << 1, src);
- m_assembler.vcvt_f64_s32(dest, dest << 1);
- }
-
- void convertInt32ToDouble(Address src, FPRegisterID dest)
- {
- load32(src, ARMRegisters::S1);
- convertInt32ToDouble(ARMRegisters::S1, dest);
- }
-
- void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
- {
- move(TrustedImmPtr(src.m_ptr), ARMRegisters::S1);
- load32(Address(ARMRegisters::S1), ARMRegisters::S1);
- convertInt32ToDouble(ARMRegisters::S1, dest);
- }
-
- void convertFloatToDouble(FPRegisterID src, FPRegisterID dst)
- {
- m_assembler.vcvt_f64_f32(dst, src);
- }
-
- void convertDoubleToFloat(FPRegisterID src, FPRegisterID dst)
- {
- m_assembler.vcvt_f32_f64(dst, src);
- }
-
- Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
- {
- m_assembler.vcmp_f64(left, right);
- m_assembler.vmrs_apsr();
- if (cond & DoubleConditionBitSpecial)
- m_assembler.cmp(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::VS);
- return Jump(m_assembler.jmp(static_cast<ARMAssembler::Condition>(cond & ~DoubleConditionMask)));
- }
-
- // Truncates 'src' to an integer, and places the resulting 'dest'.
- // If the result is not representable as a 32 bit value, branch.
- // May also branch for some values that are representable in 32 bits
- // (specifically, in this case, INT_MIN).
- enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful };
- Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed)
- {
- truncateDoubleToInt32(src, dest);
-
- m_assembler.add(ARMRegisters::S0, dest, ARMAssembler::getOp2Byte(1));
- m_assembler.bic(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::getOp2Byte(1));
-
- ARMWord w = ARMAssembler::getOp2(0x80000000);
- ASSERT(w != ARMAssembler::InvalidImmediate);
- m_assembler.cmp(ARMRegisters::S0, w);
- return Jump(m_assembler.jmp(branchType == BranchIfTruncateFailed ? ARMAssembler::EQ : ARMAssembler::NE));
- }
-
- Jump branchTruncateDoubleToUint32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed)
- {
- truncateDoubleToUint32(src, dest);
-
- m_assembler.add(ARMRegisters::S0, dest, ARMAssembler::getOp2Byte(1));
- m_assembler.bic(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::getOp2Byte(1));
-
- m_assembler.cmp(ARMRegisters::S0, ARMAssembler::getOp2Byte(0));
- return Jump(m_assembler.jmp(branchType == BranchIfTruncateFailed ? ARMAssembler::EQ : ARMAssembler::NE));
- }
-
- // Result is undefined if the value is outside of the integer range.
- void truncateDoubleToInt32(FPRegisterID src, RegisterID dest)
- {
- m_assembler.vcvt_s32_f64(ARMRegisters::SD0 << 1, src);
- m_assembler.vmov_arm32(dest, ARMRegisters::SD0 << 1);
- }
-
- void truncateDoubleToUint32(FPRegisterID src, RegisterID dest)
- {
- m_assembler.vcvt_u32_f64(ARMRegisters::SD0 << 1, src);
- m_assembler.vmov_arm32(dest, ARMRegisters::SD0 << 1);
- }
-
- // Convert 'src' to an integer, and places the resulting 'dest'.
- // If the result is not representable as a 32 bit value, branch.
- // May also branch for some values that are representable in 32 bits
- // (specifically, in this case, 0).
- void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID)
- {
- m_assembler.vcvt_s32_f64(ARMRegisters::SD0 << 1, src);
- m_assembler.vmov_arm32(dest, ARMRegisters::SD0 << 1);
-
- // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
- m_assembler.vcvt_f64_s32(ARMRegisters::SD0, ARMRegisters::SD0 << 1);
- failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, ARMRegisters::SD0));
-
- // If the result is zero, it might have been -0.0, and 0.0 equals to -0.0
- failureCases.append(branchTest32(Zero, dest));
- }
-
- Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID scratch)
- {
- m_assembler.mov(ARMRegisters::S0, ARMAssembler::getOp2Byte(0));
- convertInt32ToDouble(ARMRegisters::S0, scratch);
- return branchDouble(DoubleNotEqual, reg, scratch);
- }
-
- Jump branchDoubleZeroOrNaN(FPRegisterID reg, FPRegisterID scratch)
- {
- m_assembler.mov(ARMRegisters::S0, ARMAssembler::getOp2Byte(0));
- convertInt32ToDouble(ARMRegisters::S0, scratch);
- return branchDouble(DoubleEqualOrUnordered, reg, scratch);
- }
-
- // Invert a relational condition, e.g. == becomes !=, < becomes >=, etc.
- static RelationalCondition invert(RelationalCondition cond)
- {
- ASSERT((static_cast<uint32_t>(cond & 0x0fffffff)) == 0 && static_cast<uint32_t>(cond) < static_cast<uint32_t>(ARMAssembler::AL));
- return static_cast<RelationalCondition>(cond ^ 0x10000000);
- }
-
- void nop()
- {
- m_assembler.nop();
- }
-
- static FunctionPtr readCallTarget(CodeLocationCall call)
- {
- return FunctionPtr(reinterpret_cast<void(*)()>(ARMAssembler::readCallTarget(call.dataLocation())));
- }
-
- static void replaceWithJump(CodeLocationLabel instructionStart, CodeLocationLabel destination)
- {
- ARMAssembler::replaceWithJump(instructionStart.dataLocation(), destination.dataLocation());
- }
-
- static ptrdiff_t maxJumpReplacementSize()
- {
- ARMAssembler::maxJumpReplacementSize();
- return 0;
- }
-
- static bool canJumpReplacePatchableBranchPtrWithPatch() { return false; }
-
- static CodeLocationLabel startOfPatchableBranchPtrWithPatchOnAddress(CodeLocationDataLabelPtr)
- {
- UNREACHABLE_FOR_PLATFORM();
- return CodeLocationLabel();
- }
-
- static CodeLocationLabel startOfBranchPtrWithPatchOnRegister(CodeLocationDataLabelPtr label)
- {
- return label.labelAtOffset(0);
- }
-
- static void revertJumpReplacementToBranchPtrWithPatch(CodeLocationLabel instructionStart, RegisterID reg, void* initialValue)
- {
- ARMAssembler::revertBranchPtrWithPatch(instructionStart.dataLocation(), reg, reinterpret_cast<uintptr_t>(initialValue) & 0xffff);
- }
-
- static void revertJumpReplacementToPatchableBranchPtrWithPatch(CodeLocationLabel, Address, void*)
- {
- UNREACHABLE_FOR_PLATFORM();
- }
-
-protected:
- ARMAssembler::Condition ARMCondition(RelationalCondition cond)
- {
- return static_cast<ARMAssembler::Condition>(cond);
- }
-
- ARMAssembler::Condition ARMCondition(ResultCondition cond)
- {
- return static_cast<ARMAssembler::Condition>(cond);
- }
-
- void ensureSpace(int insnSpace, int constSpace)
- {
- m_assembler.ensureSpace(insnSpace, constSpace);
- }
-
- int sizeOfConstantPool()
- {
- return m_assembler.sizeOfConstantPool();
- }
-
- void call32(RegisterID base, int32_t offset)
- {
- load32(Address(base, offset), ARMRegisters::S1);
- m_assembler.blx(ARMRegisters::S1);
- }
-
-private:
- template <typename, template <typename> class> friend class LinkBufferBase;
- friend class RepatchBuffer;
-
- void internalCompare32(RegisterID left, TrustedImm32 right)
- {
- ARMWord tmp = (static_cast<unsigned>(right.m_value) == 0x80000000) ? ARMAssembler::InvalidImmediate : m_assembler.getOp2(-right.m_value);
- if (tmp != ARMAssembler::InvalidImmediate)
- m_assembler.cmn(left, tmp);
- else
- m_assembler.cmp(left, m_assembler.getImm(right.m_value, ARMRegisters::S0));
- }
-
- static void linkCall(void* code, Call call, FunctionPtr function)
- {
- ARMAssembler::linkCall(code, call.m_label, function.value());
- }
-
- static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
- {
- ARMAssembler::relinkCall(call.dataLocation(), destination.executableAddress());
- }
-
- static void repatchCall(CodeLocationCall call, FunctionPtr destination)
- {
- ARMAssembler::relinkCall(call.dataLocation(), destination.executableAddress());
- }
-
- static const bool s_isVFPPresent;
-};
-
-}
-
-#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
-
-#endif // MacroAssemblerARM_h