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