18f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian/* 28f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2008 Apple Inc. All rights reserved. 38f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * 48f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Redistribution and use in source and binary forms, with or without 58f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * modification, are permitted provided that the following conditions 68f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * are met: 78f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * 1. Redistributions of source code must retain the above copyright 88f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * notice, this list of conditions and the following disclaimer. 98f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * 2. Redistributions in binary form must reproduce the above copyright 108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * notice, this list of conditions and the following disclaimer in the 118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * documentation and/or other materials provided with the distribution. 128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * 138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian */ 258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#ifndef AbstractMacroAssembler_h 278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#define AbstractMacroAssembler_h 288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 296b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "CodeLocation.h" 306b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#include "MacroAssemblerCodeRef.h" 315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <wtf/Noncopyable.h> 325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include <wtf/UnusedParam.h> 335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if ENABLE(ASSEMBLER) 358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiannamespace JSC { 378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochclass LinkBuffer; 390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochclass RepatchBuffer; 400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qiantemplate <class AssemblerType> 428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianclass AbstractMacroAssembler { 438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianpublic: 440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch typedef AssemblerType AssemblerType_T; 450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian typedef MacroAssemblerCodePtr CodePtr; 475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian typedef MacroAssemblerCodeRef CodeRef; 485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian class Jump; 508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian typedef typename AssemblerType::RegisterID RegisterID; 528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian typedef typename AssemblerType::JmpSrc JmpSrc; 538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian typedef typename AssemblerType::JmpDst JmpDst; 548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Section 1: MacroAssembler operand types 578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // The following types are used as operands to MacroAssembler operations, 598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // describing immediate and memory operands to the instructions to be planted. 608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian enum Scale { 638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TimesOne, 648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TimesTwo, 658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TimesFour, 668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian TimesEight, 678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Address: 708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Describes a simple base-offset address. 728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian struct Address { 738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian explicit Address(RegisterID base, int32_t offset = 0) 748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : base(base) 758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , offset(offset) 768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RegisterID base; 808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int32_t offset; 818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 83dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block struct ExtendedAddress { 84dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block explicit ExtendedAddress(RegisterID base, intptr_t offset = 0) 85dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block : base(base) 86dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block , offset(offset) 87dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block { 88dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block } 89dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 90dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block RegisterID base; 91dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block intptr_t offset; 92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block }; 93dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block 948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // ImplicitAddress: 958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // This class is used for explicit 'load' and 'store' operations 978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // (as opposed to situations in which a memory operand is provided 988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // to a generic operation, such as an integer arithmetic instruction). 998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 1008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // In the case of a load (or store) operation we want to permit 1018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // addresses to be implicitly constructed, e.g. the two calls: 1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 1038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // load32(Address(addrReg), destReg); 1048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // load32(addrReg, destReg); 1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 1068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Are equivalent, and the explicit wrapping of the Address in the former 1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // is unnecessary. 1088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian struct ImplicitAddress { 1098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ImplicitAddress(RegisterID base) 1108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : base(base) 1118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , offset(0) 1128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ImplicitAddress(Address address) 1168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : base(address.base) 1178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , offset(address.offset) 1188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 1198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RegisterID base; 1228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int32_t offset; 1238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 1248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // BaseIndex: 1268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 1278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Describes a complex addressing mode. 1288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian struct BaseIndex { 1298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian BaseIndex(RegisterID base, RegisterID index, Scale scale, int32_t offset = 0) 1308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : base(base) 1318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , index(index) 1328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , scale(scale) 1338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , offset(offset) 1348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 1358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RegisterID base; 1388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian RegisterID index; 1398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Scale scale; 1408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int32_t offset; 1418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 1428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // AbsoluteAddress: 1448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 1458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Describes an memory operand given by a pointer. For regular load & store 1468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // operations an unwrapped void* will be used, rather than using this. 1478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian struct AbsoluteAddress { 1482bde8e466a4451c7319e3a072d118917957d6554Steve Block explicit AbsoluteAddress(const void* ptr) 1498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : m_ptr(ptr) 1508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 1518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1532bde8e466a4451c7319e3a072d118917957d6554Steve Block const void* m_ptr; 1548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 1558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1562bde8e466a4451c7319e3a072d118917957d6554Steve Block // TrustedImmPtr: 1578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 1588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // A pointer sized immediate operand to an instruction - this is wrapped 1598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // in a class requiring explicit construction in order to differentiate 1608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // from pointers used as absolute addresses to memory operations 1612bde8e466a4451c7319e3a072d118917957d6554Steve Block struct TrustedImmPtr { 1622bde8e466a4451c7319e3a072d118917957d6554Steve Block explicit TrustedImmPtr(const void* value) 1638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : m_value(value) 1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian intptr_t asIntptr() 1688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return reinterpret_cast<intptr_t>(m_value); 1708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 17221939df44de1705786c545cd1bf519d47250322dBen Murdoch const void* m_value; 1738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 1748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1752bde8e466a4451c7319e3a072d118917957d6554Steve Block struct ImmPtr : public TrustedImmPtr { 1762bde8e466a4451c7319e3a072d118917957d6554Steve Block explicit ImmPtr(const void* value) 1772bde8e466a4451c7319e3a072d118917957d6554Steve Block : TrustedImmPtr(value) 1782bde8e466a4451c7319e3a072d118917957d6554Steve Block { 1792bde8e466a4451c7319e3a072d118917957d6554Steve Block } 1802bde8e466a4451c7319e3a072d118917957d6554Steve Block }; 1812bde8e466a4451c7319e3a072d118917957d6554Steve Block 1822bde8e466a4451c7319e3a072d118917957d6554Steve Block // TrustedImm32: 1838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 1848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // A 32bit immediate operand to an instruction - this is wrapped in a 1858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // class requiring explicit construction in order to prevent RegisterIDs 1868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // (which are implemented as an enum) from accidentally being passed as 1878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // immediate values. 1882bde8e466a4451c7319e3a072d118917957d6554Steve Block struct TrustedImm32 { 1892bde8e466a4451c7319e3a072d118917957d6554Steve Block explicit TrustedImm32(int32_t value) 1908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : m_value(value) 191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if CPU(ARM) || CPU(MIPS) 1925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian , m_isPointer(false) 1935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif 1948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 1958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 1968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 197d0825bca7fe65beaee391d30da42e937db621564Steve Block#if !CPU(X86_64) 1982bde8e466a4451c7319e3a072d118917957d6554Steve Block explicit TrustedImm32(TrustedImmPtr ptr) 1998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : m_value(ptr.asIntptr()) 200dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if CPU(ARM) || CPU(MIPS) 2015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian , m_isPointer(true) 2025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif 2038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 2048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 2058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif 2068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian int32_t m_value; 208dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#if CPU(ARM) || CPU(MIPS) 2095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // We rely on being able to regenerate code to recover exception handling 2105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // information. Since ARMv7 supports 16-bit immediates there is a danger 2115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // that if pointer values change the layout of the generated code will change. 2125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // To avoid this problem, always generate pointers (and thus Imm32s constructed 2135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // from ImmPtrs) with a code sequence that is able to represent any pointer 2145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // value - don't use a more compact form in these cases. 215dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block // Same for MIPS. 2165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian bool m_isPointer; 2175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif 2188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 2198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2212bde8e466a4451c7319e3a072d118917957d6554Steve Block struct Imm32 : public TrustedImm32 { 2222bde8e466a4451c7319e3a072d118917957d6554Steve Block explicit Imm32(int32_t value) 2232bde8e466a4451c7319e3a072d118917957d6554Steve Block : TrustedImm32(value) 2242bde8e466a4451c7319e3a072d118917957d6554Steve Block { 2252bde8e466a4451c7319e3a072d118917957d6554Steve Block } 2262bde8e466a4451c7319e3a072d118917957d6554Steve Block#if !CPU(X86_64) 2272bde8e466a4451c7319e3a072d118917957d6554Steve Block explicit Imm32(TrustedImmPtr ptr) 2282bde8e466a4451c7319e3a072d118917957d6554Steve Block : TrustedImm32(ptr) 2292bde8e466a4451c7319e3a072d118917957d6554Steve Block { 2302bde8e466a4451c7319e3a072d118917957d6554Steve Block } 2312bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif 2322bde8e466a4451c7319e3a072d118917957d6554Steve Block }; 2332bde8e466a4451c7319e3a072d118917957d6554Steve Block 2348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Section 2: MacroAssembler code buffer handles 2358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 2368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // The following types are used to reference items in the code buffer 2378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // during JIT code generation. For example, the type Jump is used to 2388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // track the location of a jump instruction so that it may later be 2398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // linked to a label marking its destination. 2408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Label: 2438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 2448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // A Label records a point in the generated instruction stream, typically such that 2458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // it may be used as a destination for a jump. 2468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian class Label { 2475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian template<class TemplateAssemblerType> 2488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian friend class AbstractMacroAssembler; 2495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian friend class Jump; 2505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian friend class MacroAssemblerCodeRef; 2510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch friend class LinkBuffer; 2525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian public: 2548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Label() 2558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 2568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 2578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Label(AbstractMacroAssembler<AssemblerType>* masm) 2598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : m_label(masm->m_assembler.label()) 2608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 2618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 2628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool isUsed() const { return m_label.isUsed(); } 264f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch bool isSet() const { return m_label.isSet(); } 2658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void used() { m_label.used(); } 2668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian private: 2678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian JmpDst m_label; 2688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 2698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // DataLabelPtr: 2718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 2728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // A DataLabelPtr is used to refer to a location in the code containing a pointer to be 2738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // patched after the code has been generated. 2748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian class DataLabelPtr { 2755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian template<class TemplateAssemblerType> 2768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian friend class AbstractMacroAssembler; 2770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch friend class LinkBuffer; 2788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian public: 2798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian DataLabelPtr() 2808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 2818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 2828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian DataLabelPtr(AbstractMacroAssembler<AssemblerType>* masm) 2848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : m_label(masm->m_assembler.label()) 2858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 2868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 2878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 288f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch bool isSet() const { return m_label.isSet(); } 289f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 2908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian private: 2918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian JmpDst m_label; 2928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 2938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 2948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // DataLabel32: 2958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 2968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // A DataLabelPtr is used to refer to a location in the code containing a pointer to be 2978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // patched after the code has been generated. 2988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian class DataLabel32 { 2995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian template<class TemplateAssemblerType> 3008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian friend class AbstractMacroAssembler; 3010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch friend class LinkBuffer; 3028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian public: 3038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian DataLabel32() 3048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3068f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian DataLabel32(AbstractMacroAssembler<AssemblerType>* masm) 3088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : m_label(masm->m_assembler.label()) 3098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian private: 3138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian JmpDst m_label; 3148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 3158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Call: 3178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 3188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // A Call object is a reference to a call instruction that has been planted 3198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // into the code buffer - it is typically used to link the call, setting the 3208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // relative offset such that when executed it will call to the desired 3218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // destination. 3228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian class Call { 3235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian template<class TemplateAssemblerType> 3248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian friend class AbstractMacroAssembler; 3250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian public: 3278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian enum Flags { 3288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian None = 0x0, 3298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Linkable = 0x1, 3308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Near = 0x2, 3318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian LinkableNear = 0x3, 3328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 3338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Call() 3358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : m_flags(None) 3368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Call(JmpSrc jmp, Flags flags) 3408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : m_jmp(jmp) 3418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian , m_flags(flags) 3428f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool isFlagSet(Flags flag) 3468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return m_flags & flag; 3488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian static Call fromTailJump(Jump jump) 3518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return Call(jump.m_jmp, Linkable); 3538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian JmpSrc m_jmp; 3560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch private: 3578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Flags m_flags; 3588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 3598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Jump: 3618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 3628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // A jump object is a reference to a jump instruction that has been planted 3638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // into the code buffer - it is typically used to link the jump, setting the 3648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // relative offset such that when executed it will jump to the desired 3658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // destination. 3668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian class Jump { 3675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian template<class TemplateAssemblerType> 3688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian friend class AbstractMacroAssembler; 3698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian friend class Call; 3700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch friend class LinkBuffer; 3718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian public: 3728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Jump() 3738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Jump(JmpSrc jmp) 3778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian : m_jmp(jmp) 3788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3812bde8e466a4451c7319e3a072d118917957d6554Steve Block void link(AbstractMacroAssembler<AssemblerType>* masm) const 3828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian masm->m_assembler.linkJump(m_jmp, masm->m_assembler.label()); 3848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3862bde8e466a4451c7319e3a072d118917957d6554Steve Block void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) const 3878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 3888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian masm->m_assembler.linkJump(m_jmp, label.m_label); 3898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 3908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3912bde8e466a4451c7319e3a072d118917957d6554Steve Block bool isSet() const { return m_jmp.isSet(); } 3922bde8e466a4451c7319e3a072d118917957d6554Steve Block 3938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian private: 3948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian JmpSrc m_jmp; 3958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 3968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 3978f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // JumpList: 3988f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 3998f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // A JumpList is a set of Jump objects. 4008f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // All jumps in the set will be linked to the same destination. 4018f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian class JumpList { 4020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch friend class LinkBuffer; 4038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian public: 4050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch typedef Vector<Jump, 16> JumpVector; 4060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 4078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void link(AbstractMacroAssembler<AssemblerType>* masm) 4088f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4098f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian size_t size = m_jumps.size(); 4108f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian for (size_t i = 0; i < size; ++i) 4118f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_jumps[i].link(masm); 4128f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_jumps.clear(); 4138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4158f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void linkTo(Label label, AbstractMacroAssembler<AssemblerType>* masm) 4168f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4178f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian size_t size = m_jumps.size(); 4188f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian for (size_t i = 0; i < size; ++i) 4198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_jumps[i].linkTo(label, masm); 4208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_jumps.clear(); 4218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4228f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4238f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void append(Jump jump) 4248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4258f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_jumps.append(jump); 4268f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4278f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4288f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian void append(JumpList& other) 4298f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_jumps.append(other.m_jumps.begin(), other.m_jumps.size()); 4318f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4338f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian bool empty() 4348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return !m_jumps.size(); 4368f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4378f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 438f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch void clear() 439f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch { 440f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_jumps.clear(); 441f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 442f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 4430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch const JumpVector& jumps() { return m_jumps; } 4448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian private: 4460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch JumpVector m_jumps; 4478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian }; 4488f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // Section 3: Misc admin methods 4518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian size_t size() 4528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4538f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return m_assembler.size(); 4548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4558f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4568f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Label label() 4578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4588f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return Label(this); 4598f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4608f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4618f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian Label align() 4628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian m_assembler.align(16); 4648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return Label(this); 4658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ptrdiff_t differenceBetween(Label from, Jump to) 4688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); 4708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ptrdiff_t differenceBetween(Label from, Call to) 4738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); 4758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4778f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ptrdiff_t differenceBetween(Label from, Label to) 4788f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4798f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); 4808f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4818f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4828f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ptrdiff_t differenceBetween(Label from, DataLabelPtr to) 4838f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4848f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); 4858f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4868f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4878f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ptrdiff_t differenceBetween(Label from, DataLabel32 to) 4888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); 4908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4918f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4928f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ptrdiff_t differenceBetween(DataLabelPtr from, Jump to) 4938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 4948f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); 4958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 4968f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 4975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ptrdiff_t differenceBetween(DataLabelPtr from, DataLabelPtr to) 4985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian { 4995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_label); 5005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 5015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian ptrdiff_t differenceBetween(DataLabelPtr from, Call to) 5038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian { 5048f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); 5058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 5062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5072daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch // Temporary interface; likely to be removed, since may be hard to port to all architectures. 5082daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if CPU(X86) || CPU(X86_64) 5092daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch void rewindToLabel(Label rewindTo) { m_assembler.rewindToLabel(rewindTo.m_label); } 5102daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif 5112daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 512dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch void beginUninterruptedSequence() { } 513dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch void endUninterruptedSequence() { } 5148f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#ifndef NDEBUG 5162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch unsigned debugOffset() { return m_assembler.debugOffset(); } 5172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif 5182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch 5198f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianprotected: 5208f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian AssemblerType m_assembler; 5218f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch friend class LinkBuffer; 5230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch friend class RepatchBuffer; 5248f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static void linkJump(void* code, Jump jump, CodeLocationLabel target) 5260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 5270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch AssemblerType::linkJump(code, jump.m_jmp, target.dataLocation()); 5280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 5295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static void linkPointer(void* code, typename AssemblerType::JmpDst label, void* value) 5310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 5320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch AssemblerType::linkPointer(code, label, value); 5330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 5348f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static void* getLinkerAddress(void* code, typename AssemblerType::JmpSrc label) 5360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 5370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return AssemblerType::getRelocatedAddress(code, label); 5380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 5398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static void* getLinkerAddress(void* code, typename AssemblerType::JmpDst label) 5410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 5420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return AssemblerType::getRelocatedAddress(code, label); 5430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 5445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 5450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static unsigned getLinkerCallReturnOffset(Call call) 5460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 5470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch return AssemblerType::getCallReturnOffset(call.m_jmp); 5480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 5498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static void repatchJump(CodeLocationJump jump, CodeLocationLabel destination) 5510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 5520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch AssemblerType::relinkJump(jump.dataLocation(), destination.dataLocation()); 5530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 5548f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static void repatchNearCall(CodeLocationNearCall nearCall, CodeLocationLabel destination) 5560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 5570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch AssemblerType::relinkCall(nearCall.dataLocation(), destination.executableAddress()); 5580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 5590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 5600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static void repatchInt32(CodeLocationDataLabel32 dataLabel32, int32_t value) 5610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 5620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch AssemblerType::repatchInt32(dataLabel32.dataLocation(), value); 5630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 5640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 5650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch static void repatchPointer(CodeLocationDataLabelPtr dataLabelPtr, void* value) 5660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch { 5670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch AssemblerType::repatchPointer(dataLabelPtr.dataLocation(), value); 5680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 5690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}; 5708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian} // namespace JSC 5728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif // ENABLE(ASSEMBLER) 5748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 5758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif // AbstractMacroAssembler_h 576