10bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch/*
221939df44de1705786c545cd1bf519d47250322dBen Murdoch * Copyright (C) 2009, 2010 University of Szeged
30bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * All rights reserved.
40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
50bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Redistribution and use in source and binary forms, with or without
60bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * modification, are permitted provided that the following conditions
70bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * are met:
80bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 1. Redistributions of source code must retain the above copyright
90bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    notice, this list of conditions and the following disclaimer.
100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright
110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    notice, this list of conditions and the following disclaimer in the
120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *    documentation and/or other materials provided with the distribution.
130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch *
140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch */
260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#ifndef ARMAssembler_h
280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#define ARMAssembler_h
290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
30d0825bca7fe65beaee391d30da42e937db621564Steve Block#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "AssemblerBufferWithConstantPool.h"
330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <wtf/Assertions.h>
340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochnamespace JSC {
350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    typedef uint32_t ARMWord;
37231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
38231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    namespace ARMRegisters {
39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        typedef enum {
40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            r0 = 0,
41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            r1,
42231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            r2,
43f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            r3, S0 = r3,
44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            r4,
45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            r5,
46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            r6,
47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            r7,
48f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            r8, S1 = r8,
49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            r9,
50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            r10,
51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            r11,
52231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            r12,
53f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            r13, sp = r13,
54f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            r14, lr = r14,
55f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            r15, pc = r15
56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } RegisterID;
57231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        typedef enum {
59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            d0,
60231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            d1,
61231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            d2,
62f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d3, SD0 = d3,
63f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d4,
64f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d5,
65f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d6,
66f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d7,
67f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d8,
68f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d9,
69f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d10,
70f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d11,
71f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d12,
72f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d13,
73f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d14,
74f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d15,
75f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d16,
76f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d17,
77f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d18,
78f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d19,
79f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d20,
80f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d21,
81f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d22,
82f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d23,
83f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d24,
84f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d25,
85f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d26,
86f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d27,
87f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d28,
88f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d29,
89f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d30,
90f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            d31
91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } FPRegisterID;
92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    } // namespace ARMRegisters
940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    class ARMAssembler {
960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    public:
97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        typedef ARMRegisters::RegisterID RegisterID;
98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        typedef ARMRegisters::FPRegisterID FPRegisterID;
990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        typedef AssemblerBufferWithConstantPool<2048, 4, 4, ARMAssembler> ARMBuffer;
100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        typedef SegmentedVector<int, 64> Jumps;
1010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ARMAssembler() { }
1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // ARM conditional constants
1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        typedef enum {
1060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            EQ = 0x00000000, // Zero
1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            NE = 0x10000000, // Non-zero
1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            CS = 0x20000000,
1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            CC = 0x30000000,
1100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            MI = 0x40000000,
1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            PL = 0x50000000,
1120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            VS = 0x60000000,
1130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            VC = 0x70000000,
1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            HI = 0x80000000,
1150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            LS = 0x90000000,
1160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            GE = 0xa0000000,
1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            LT = 0xb0000000,
1180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            GT = 0xc0000000,
1190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            LE = 0xd0000000,
1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            AL = 0xe0000000
1210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        } Condition;
1220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // ARM instruction constants
1240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        enum {
1250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            AND = (0x0 << 21),
1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            EOR = (0x1 << 21),
1270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            SUB = (0x2 << 21),
1280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            RSB = (0x3 << 21),
1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ADD = (0x4 << 21),
1300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ADC = (0x5 << 21),
1310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            SBC = (0x6 << 21),
1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            RSC = (0x7 << 21),
1330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            TST = (0x8 << 21),
1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            TEQ = (0x9 << 21),
1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            CMP = (0xa << 21),
1360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            CMN = (0xb << 21),
1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ORR = (0xc << 21),
1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            MOV = (0xd << 21),
1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            BIC = (0xe << 21),
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            MVN = (0xf << 21),
1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            MUL = 0x00000090,
1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            MULL = 0x00c00090,
143f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            VADD_F64 = 0x0e300b00,
144f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            VDIV_F64 = 0x0e800b00,
145f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            VSUB_F64 = 0x0e300b40,
146f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            VMUL_F64 = 0x0e200b00,
147f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            VCMP_F64 = 0x0eb40b40,
148f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            VSQRT_F64 = 0x0eb10bc0,
1490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            DTR = 0x05000000,
1500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            LDRH = 0x00100090,
1510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            STRH = 0x00000090,
1520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            STMDB = 0x09200000,
1530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            LDMIA = 0x08b00000,
1540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            FDTR = 0x0d000b00,
1550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            B = 0x0a000000,
1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            BL = 0x0b000000,
15721939df44de1705786c545cd1bf519d47250322dBen Murdoch#if WTF_ARM_ARCH_AT_LEAST(5) || defined(__ARM_ARCH_4T__)
15821939df44de1705786c545cd1bf519d47250322dBen Murdoch            BX = 0x012fff10,
15921939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif
160f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            VMOV_VFP = 0x0e000a10,
161f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            VMOV_ARM = 0x0e100a10,
162f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            VCVT_F64_S32 = 0x0eb80bc0,
163f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            VCVT_S32_F64 = 0x0ebd0b40,
164e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            VCVTR_S32_F64 = 0x0ebd0bc0,
165f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            VMRS_APSR = 0x0ef1fa10,
166d0825bca7fe65beaee391d30da42e937db621564Steve Block#if WTF_ARM_ARCH_AT_LEAST(5)
1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            CLZ = 0x016f0f10,
168e14391e94c850b8bd03680c23b38978db68687a8John Reck            BKPT = 0xe1200070,
16921939df44de1705786c545cd1bf519d47250322dBen Murdoch            BLX = 0x012fff30,
1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
171d0825bca7fe65beaee391d30da42e937db621564Steve Block#if WTF_ARM_ARCH_AT_LEAST(7)
172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            MOVW = 0x03000000,
173643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            MOVT = 0x03400000,
174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#endif
1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        };
1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        enum {
1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            OP2_IMM = (1 << 25),
1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            OP2_IMMh = (1 << 22),
1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            OP2_INV_IMM = (1 << 26),
1810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            SET_CC = (1 << 20),
1820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            OP2_OFSREG = (1 << 25),
1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            DT_UP = (1 << 23),
184dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            DT_BYTE = (1 << 22),
1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            DT_WB = (1 << 21),
1860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            // This flag is inlcuded in LDR and STR
1870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            DT_PRE = (1 << 24),
1880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            HDT_UH = (1 << 5),
1890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            DT_LOAD = (1 << 20),
1900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        };
1910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Masks of ARM instructions
1930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        enum {
1940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            BRANCH_MASK = 0x00ffffff,
1950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            NONARM = 0xf0000000,
1960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            SDT_MASK = 0x0c000000,
1970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            SDT_OFFSET_MASK = 0xfff,
1980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        };
1990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        enum {
2010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            BOFFSET_MIN = -0x00800000,
2020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            BOFFSET_MAX = 0x007fffff,
2030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            SDT = 0x04000000,
2040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        };
2050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        enum {
2070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            padForAlign8  = 0x00,
2080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            padForAlign16 = 0x0000,
209e14391e94c850b8bd03680c23b38978db68687a8John Reck            padForAlign32 = 0xe12fff7f // 'bkpt 0xffff' instruction.
2100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        };
2110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
212643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        static const ARMWord INVALID_IMM = 0xf0000000;
21321939df44de1705786c545cd1bf519d47250322dBen Murdoch        static const ARMWord InvalidBranchTarget = 0xffffffff;
214d0825bca7fe65beaee391d30da42e937db621564Steve Block        static const int DefaultPrefetching = 2;
215643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
2160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        class JmpSrc {
2170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            friend class ARMAssembler;
2180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        public:
2190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            JmpSrc()
2200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                : m_offset(-1)
2210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
2220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        private:
2250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            JmpSrc(int offset)
2260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                : m_offset(offset)
2270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
2280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
2290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
230231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            int m_offset;
2310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        };
2320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        class JmpDst {
2340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            friend class ARMAssembler;
2350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        public:
2360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            JmpDst()
2370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                : m_offset(-1)
2380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                , m_used(false)
2390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
2400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
2410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            bool isUsed() const { return m_used; }
243f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch            bool isSet() const { return (m_offset != -1); }
2440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            void used() { m_used = true; }
2450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        private:
2460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            JmpDst(int offset)
2470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                : m_offset(offset)
2480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                , m_used(false)
2490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            {
2500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch                ASSERT(m_offset == offset);
2510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            }
2520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
25381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch            signed int m_offset : 31;
2540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            int m_used : 1;
2550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        };
2560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Instruction formating
2580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void emitInst(ARMWord op, int rd, int rn, ARMWord op2)
2600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
261f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            ASSERT(((op2 & ~OP2_IMM) <= 0xfff) || (((op2 & ~OP2_IMMh) <= 0xfff)));
2620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            m_buffer.putInt(op | RN(rn) | RD(rd) | op2);
2630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
2640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
265f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void emitDoublePrecisionInst(ARMWord op, int dd, int dn, int dm)
266f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        {
267f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            ASSERT((dd >= 0 && dd <= 31) && (dn >= 0 && dn <= 31) && (dm >= 0 && dm <= 31));
268f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            m_buffer.putInt(op | ((dd & 0xf) << 12) | ((dd & 0x10) << (22 - 4))
269f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                               | ((dn & 0xf) << 16) | ((dn & 0x10) << (7 - 4))
270f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                               | (dm & 0xf) | ((dm & 0x10) << (5 - 4)));
271f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        }
272f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
273f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void emitSinglePrecisionInst(ARMWord op, int sd, int sn, int sm)
274f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        {
275f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            ASSERT((sd >= 0 && sd <= 31) && (sn >= 0 && sn <= 31) && (sm >= 0 && sm <= 31));
276f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            m_buffer.putInt(op | ((sd >> 1) << 12) | ((sd & 0x1) << 22)
277f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                               | ((sn >> 1) << 16) | ((sn & 0x1) << 7)
278f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick                               | (sm >> 1) | ((sm & 0x1) << 5));
279f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        }
280f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick
2810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void and_r(int rd, int rn, ARMWord op2, Condition cc = AL)
2820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
2830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | AND, rd, rn, op2);
2840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
2850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void ands_r(int rd, int rn, ARMWord op2, Condition cc = AL)
2870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
2880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | AND | SET_CC, rd, rn, op2);
2890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
2900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void eor_r(int rd, int rn, ARMWord op2, Condition cc = AL)
2920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
2930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | EOR, rd, rn, op2);
2940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
2950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
2960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void eors_r(int rd, int rn, ARMWord op2, Condition cc = AL)
2970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
2980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | EOR | SET_CC, rd, rn, op2);
2990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void sub_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | SUB, rd, rn, op2);
3040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void subs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | SUB | SET_CC, rd, rn, op2);
3090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void rsb_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | RSB, rd, rn, op2);
3140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void rsbs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | RSB | SET_CC, rd, rn, op2);
3190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void add_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | ADD, rd, rn, op2);
3240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void adds_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | ADD | SET_CC, rd, rn, op2);
3290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void adc_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | ADC, rd, rn, op2);
3340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void adcs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | ADC | SET_CC, rd, rn, op2);
3390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void sbc_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | SBC, rd, rn, op2);
3440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void sbcs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | SBC | SET_CC, rd, rn, op2);
3490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void rsc_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | RSC, rd, rn, op2);
3540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void rscs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | RSC | SET_CC, rd, rn, op2);
3590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void tst_r(int rn, ARMWord op2, Condition cc = AL)
3620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | TST | SET_CC, 0, rn, op2);
3640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void teq_r(int rn, ARMWord op2, Condition cc = AL)
3670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | TEQ | SET_CC, 0, rn, op2);
3690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void cmp_r(int rn, ARMWord op2, Condition cc = AL)
3720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | CMP | SET_CC, 0, rn, op2);
3740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
376e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        void cmn_r(int rn, ARMWord op2, Condition cc = AL)
377e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        {
378e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            emitInst(static_cast<ARMWord>(cc) | CMN | SET_CC, 0, rn, op2);
379e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        }
380e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
3810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void orr_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | ORR, rd, rn, op2);
3840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void orrs_r(int rd, int rn, ARMWord op2, Condition cc = AL)
3870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
3880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | ORR | SET_CC, rd, rn, op2);
3890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
3910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void mov_r(int rd, ARMWord op2, Condition cc = AL)
3920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
393231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            emitInst(static_cast<ARMWord>(cc) | MOV, rd, ARMRegisters::r0, op2);
3940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
3950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
396d0825bca7fe65beaee391d30da42e937db621564Steve Block#if WTF_ARM_ARCH_AT_LEAST(7)
397643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        void movw_r(int rd, ARMWord op2, Condition cc = AL)
398643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        {
399643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            ASSERT((op2 | 0xf0fff) == 0xf0fff);
400643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            m_buffer.putInt(static_cast<ARMWord>(cc) | MOVW | RD(rd) | op2);
401643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
402643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
403643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        void movt_r(int rd, ARMWord op2, Condition cc = AL)
404643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        {
405643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            ASSERT((op2 | 0xf0fff) == 0xf0fff);
406643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            m_buffer.putInt(static_cast<ARMWord>(cc) | MOVT | RD(rd) | op2);
407643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
408643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#endif
409643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
4100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void movs_r(int rd, ARMWord op2, Condition cc = AL)
4110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
412231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            emitInst(static_cast<ARMWord>(cc) | MOV | SET_CC, rd, ARMRegisters::r0, op2);
4130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void bic_r(int rd, int rn, ARMWord op2, Condition cc = AL)
4160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
4170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | BIC, rd, rn, op2);
4180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void bics_r(int rd, int rn, ARMWord op2, Condition cc = AL)
4210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
4220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | BIC | SET_CC, rd, rn, op2);
4230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void mvn_r(int rd, ARMWord op2, Condition cc = AL)
4260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
427231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            emitInst(static_cast<ARMWord>(cc) | MVN, rd, ARMRegisters::r0, op2);
4280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void mvns_r(int rd, ARMWord op2, Condition cc = AL)
4310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
432231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            emitInst(static_cast<ARMWord>(cc) | MVN | SET_CC, rd, ARMRegisters::r0, op2);
4330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void mul_r(int rd, int rn, int rm, Condition cc = AL)
4360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
4370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            m_buffer.putInt(static_cast<ARMWord>(cc) | MUL | RN(rd) | RS(rn) | RM(rm));
4380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void muls_r(int rd, int rn, int rm, Condition cc = AL)
4410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
4420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            m_buffer.putInt(static_cast<ARMWord>(cc) | MUL | SET_CC | RN(rd) | RS(rn) | RM(rm));
4430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void mull_r(int rdhi, int rdlo, int rn, int rm, Condition cc = AL)
4460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
4470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            m_buffer.putInt(static_cast<ARMWord>(cc) | MULL | RN(rdhi) | RD(rdlo) | RS(rn) | RM(rm));
4480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
450f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void vadd_f64_r(int dd, int dn, int dm, Condition cc = AL)
4510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
452f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VADD_F64, dd, dn, dm);
4530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
455f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void vdiv_f64_r(int dd, int dn, int dm, Condition cc = AL)
456643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        {
457f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VDIV_F64, dd, dn, dm);
458643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
459643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
460f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void vsub_f64_r(int dd, int dn, int dm, Condition cc = AL)
4610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
462f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VSUB_F64, dd, dn, dm);
4630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
465f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void vmul_f64_r(int dd, int dn, int dm, Condition cc = AL)
4660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
467f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VMUL_F64, dd, dn, dm);
4680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
470f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void vcmp_f64_r(int dd, int dm, Condition cc = AL)
4710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
472f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCMP_F64, dd, 0, dm);
4730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
475f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void vsqrt_f64_r(int dd, int dm, Condition cc = AL)
47621939df44de1705786c545cd1bf519d47250322dBen Murdoch        {
477f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VSQRT_F64, dd, 0, dm);
47821939df44de1705786c545cd1bf519d47250322dBen Murdoch        }
47921939df44de1705786c545cd1bf519d47250322dBen Murdoch
4800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void ldr_imm(int rd, ARMWord imm, Condition cc = AL)
4810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
482231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            m_buffer.putIntWithConstantInt(static_cast<ARMWord>(cc) | DTR | DT_LOAD | DT_UP | RN(ARMRegisters::pc) | RD(rd), imm, true);
4830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void ldr_un_imm(int rd, ARMWord imm, Condition cc = AL)
4860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
487231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            m_buffer.putIntWithConstantInt(static_cast<ARMWord>(cc) | DTR | DT_LOAD | DT_UP | RN(ARMRegisters::pc) | RD(rd), imm);
4880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void dtr_u(bool isLoad, int rd, int rb, ARMWord op2, Condition cc = AL)
4910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
4920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | DTR | (isLoad ? DT_LOAD : 0) | DT_UP, rd, rb, op2);
4930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
4950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void dtr_ur(bool isLoad, int rd, int rb, int rm, Condition cc = AL)
4960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
4970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | DTR | (isLoad ? DT_LOAD : 0) | DT_UP | OP2_OFSREG, rd, rb, rm);
4980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
4990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void dtr_d(bool isLoad, int rd, int rb, ARMWord op2, Condition cc = AL)
5010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
5020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | DTR | (isLoad ? DT_LOAD : 0), rd, rb, op2);
5030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void dtr_dr(bool isLoad, int rd, int rb, int rm, Condition cc = AL)
5060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
5070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | DTR | (isLoad ? DT_LOAD : 0) | OP2_OFSREG, rd, rb, rm);
5080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void ldrh_r(int rd, int rn, int rm, Condition cc = AL)
5110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
5120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | LDRH | HDT_UH | DT_UP | DT_PRE, rd, rn, rm);
5130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void ldrh_d(int rd, int rb, ARMWord op2, Condition cc = AL)
5160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
5170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | LDRH | HDT_UH | DT_PRE, rd, rb, op2);
5180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void ldrh_u(int rd, int rb, ARMWord op2, Condition cc = AL)
5210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
5220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | LDRH | HDT_UH | DT_UP | DT_PRE, rd, rb, op2);
5230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void strh_r(int rn, int rm, int rd, Condition cc = AL)
5260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
5270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | STRH | HDT_UH | DT_UP | DT_PRE, rd, rn, rm);
5280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void fdtr_u(bool isLoad, int rd, int rb, ARMWord op2, Condition cc = AL)
5310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
5320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ASSERT(op2 <= 0xff);
5330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | FDTR | DT_UP | (isLoad ? DT_LOAD : 0), rd, rb, op2);
5340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void fdtr_d(bool isLoad, int rd, int rb, ARMWord op2, Condition cc = AL)
5370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
5380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ASSERT(op2 <= 0xff);
5390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            emitInst(static_cast<ARMWord>(cc) | FDTR | (isLoad ? DT_LOAD : 0), rd, rb, op2);
5400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void push_r(int reg, Condition cc = AL)
5430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
5440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ASSERT(ARMWord(reg) <= 0xf);
545231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            m_buffer.putInt(cc | DTR | DT_WB | RN(ARMRegisters::sp) | RD(reg) | 0x4);
5460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void pop_r(int reg, Condition cc = AL)
5490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
5500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ASSERT(ARMWord(reg) <= 0xf);
551231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            m_buffer.putInt(cc | (DTR ^ DT_PRE) | DT_LOAD | DT_UP | RN(ARMRegisters::sp) | RD(reg) | 0x4);
5520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        inline void poke_r(int reg, Condition cc = AL)
5550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
556231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            dtr_d(false, ARMRegisters::sp, 0, reg, cc);
5570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
5590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        inline void peek_r(int reg, Condition cc = AL)
5600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
561231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            dtr_u(true, reg, ARMRegisters::sp, 0, cc);
5620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
564f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void vmov_vfp_r(int sn, int rt, Condition cc = AL)
5650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
566f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            ASSERT(rt <= 15);
567f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            emitSinglePrecisionInst(static_cast<ARMWord>(cc) | VMOV_VFP, rt << 1, sn, 0);
5680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
570f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void vmov_arm_r(int rt, int sn, Condition cc = AL)
571643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        {
572f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            ASSERT(rt <= 15);
573f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            emitSinglePrecisionInst(static_cast<ARMWord>(cc) | VMOV_ARM, rt << 1, sn, 0);
574643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
575643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
576f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void vcvt_f64_s32_r(int dd, int sm, Condition cc = AL)
5770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
578f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            ASSERT(!(sm & 0x1)); // sm must be divisible by 2
579f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVT_F64_S32, dd, 0, (sm >> 1));
5800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
582f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void vcvt_s32_f64_r(int sd, int dm, Condition cc = AL)
583643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        {
584f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            ASSERT(!(sd & 0x1)); // sd must be divisible by 2
585f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVT_S32_F64, (sd >> 1), 0, dm);
586643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
587643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
588e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        void vcvtr_s32_f64_r(int sd, int dm, Condition cc = AL)
589e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        {
590e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            ASSERT(!(sd & 0x1)); // sd must be divisible by 2
591e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block            emitDoublePrecisionInst(static_cast<ARMWord>(cc) | VCVTR_S32_F64, (sd >> 1), 0, dm);
592e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block        }
593e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block
594f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick        void vmrs_apsr(Condition cc = AL)
5950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
596f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick            m_buffer.putInt(static_cast<ARMWord>(cc) | VMRS_APSR);
5970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
5980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
599d0825bca7fe65beaee391d30da42e937db621564Steve Block#if WTF_ARM_ARCH_AT_LEAST(5)
6000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void clz_r(int rd, int rm, Condition cc = AL)
6010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
6020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            m_buffer.putInt(static_cast<ARMWord>(cc) | CLZ | RD(rd) | RM(rm));
6030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
6040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
6050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void bkpt(ARMWord value)
6070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
608d0825bca7fe65beaee391d30da42e937db621564Steve Block#if WTF_ARM_ARCH_AT_LEAST(5)
6090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            m_buffer.putInt(BKPT | ((value & 0xff0) << 4) | (value & 0xf));
6100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else
6110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            // Cannot access to Zero memory address
612231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            dtr_dr(true, ARMRegisters::S0, ARMRegisters::S0, ARMRegisters::S0);
6130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif
6140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
6150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
61621939df44de1705786c545cd1bf519d47250322dBen Murdoch        void bx(int rm, Condition cc = AL)
61721939df44de1705786c545cd1bf519d47250322dBen Murdoch        {
61821939df44de1705786c545cd1bf519d47250322dBen Murdoch#if WTF_ARM_ARCH_AT_LEAST(5) || defined(__ARM_ARCH_4T__)
61921939df44de1705786c545cd1bf519d47250322dBen Murdoch            emitInst(static_cast<ARMWord>(cc) | BX, 0, 0, RM(rm));
62021939df44de1705786c545cd1bf519d47250322dBen Murdoch#else
62121939df44de1705786c545cd1bf519d47250322dBen Murdoch            mov_r(ARMRegisters::pc, RM(rm), cc);
62221939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif
62321939df44de1705786c545cd1bf519d47250322dBen Murdoch        }
62421939df44de1705786c545cd1bf519d47250322dBen Murdoch
62521939df44de1705786c545cd1bf519d47250322dBen Murdoch        JmpSrc blx(int rm, Condition cc = AL)
62621939df44de1705786c545cd1bf519d47250322dBen Murdoch        {
62721939df44de1705786c545cd1bf519d47250322dBen Murdoch#if WTF_ARM_ARCH_AT_LEAST(5)
62821939df44de1705786c545cd1bf519d47250322dBen Murdoch            emitInst(static_cast<ARMWord>(cc) | BLX, 0, 0, RM(rm));
62921939df44de1705786c545cd1bf519d47250322dBen Murdoch#else
63021939df44de1705786c545cd1bf519d47250322dBen Murdoch            ASSERT(rm != 14);
63121939df44de1705786c545cd1bf519d47250322dBen Murdoch            ensureSpace(2 * sizeof(ARMWord), 0);
63221939df44de1705786c545cd1bf519d47250322dBen Murdoch            mov_r(ARMRegisters::lr, ARMRegisters::pc, cc);
63321939df44de1705786c545cd1bf519d47250322dBen Murdoch            bx(rm, cc);
63421939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif
6354576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            return JmpSrc(m_buffer.uncheckedSize());
63621939df44de1705786c545cd1bf519d47250322dBen Murdoch        }
63721939df44de1705786c545cd1bf519d47250322dBen Murdoch
6380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static ARMWord lsl(int reg, ARMWord value)
6390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
640231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(reg <= ARMRegisters::pc);
6410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ASSERT(value <= 0x1f);
6420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return reg | (value << 7) | 0x00;
6430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
6440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static ARMWord lsr(int reg, ARMWord value)
6460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
647231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(reg <= ARMRegisters::pc);
6480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ASSERT(value <= 0x1f);
6490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return reg | (value << 7) | 0x20;
6500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
6510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static ARMWord asr(int reg, ARMWord value)
6530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
654231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(reg <= ARMRegisters::pc);
6550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ASSERT(value <= 0x1f);
6560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return reg | (value << 7) | 0x40;
6570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
6580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static ARMWord lsl_r(int reg, int shiftReg)
6600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
661231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(reg <= ARMRegisters::pc);
662231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(shiftReg <= ARMRegisters::pc);
6630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return reg | (shiftReg << 8) | 0x10;
6640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
6650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static ARMWord lsr_r(int reg, int shiftReg)
6670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
668231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(reg <= ARMRegisters::pc);
669231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(shiftReg <= ARMRegisters::pc);
6700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return reg | (shiftReg << 8) | 0x30;
6710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
6720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static ARMWord asr_r(int reg, int shiftReg)
6740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
675231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(reg <= ARMRegisters::pc);
676231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(shiftReg <= ARMRegisters::pc);
6770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return reg | (shiftReg << 8) | 0x50;
6780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
6790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // General helpers
6810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        int size()
6830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
6840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return m_buffer.size();
6850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
6860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
6870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void ensureSpace(int insnSpace, int constSpace)
6880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
6890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            m_buffer.ensureSpace(insnSpace, constSpace);
6900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
6910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
692231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        int sizeOfConstantPool()
693231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        {
694231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            return m_buffer.sizeOfConstantPool();
695231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
696231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
6970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        JmpDst label()
6980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
6990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return JmpDst(m_buffer.size());
7000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
7010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        JmpDst align(int alignment)
7030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
7040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            while (!m_buffer.isAligned(alignment))
705231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                mov_r(ARMRegisters::r0, ARMRegisters::r0);
7060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return label();
7080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
7090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
71021939df44de1705786c545cd1bf519d47250322dBen Murdoch        JmpSrc loadBranchTarget(int rd, Condition cc = AL, int useConstantPool = 0)
7110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
712231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ensureSpace(sizeof(ARMWord), sizeof(ARMWord));
7134576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            m_jumps.append(m_buffer.uncheckedSize() | (useConstantPool & 0x1));
71421939df44de1705786c545cd1bf519d47250322dBen Murdoch            ldr_un_imm(rd, InvalidBranchTarget, cc);
7154576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            return JmpSrc(m_buffer.uncheckedSize());
7160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
7170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
71821939df44de1705786c545cd1bf519d47250322dBen Murdoch        JmpSrc jmp(Condition cc = AL, int useConstantPool = 0)
71921939df44de1705786c545cd1bf519d47250322dBen Murdoch        {
72021939df44de1705786c545cd1bf519d47250322dBen Murdoch            return loadBranchTarget(ARMRegisters::pc, cc, useConstantPool);
72121939df44de1705786c545cd1bf519d47250322dBen Murdoch        }
72221939df44de1705786c545cd1bf519d47250322dBen Murdoch
7230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void* executableCopy(ExecutablePool* allocator);
7240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#ifndef NDEBUG
7262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        unsigned debugOffset() { return m_formatter.debugOffset(); }
7272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif
7282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
7290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Patching helpers
7300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
731d0825bca7fe65beaee391d30da42e937db621564Steve Block        static ARMWord* getLdrImmAddress(ARMWord* insn)
732d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
73321939df44de1705786c545cd1bf519d47250322dBen Murdoch#if WTF_ARM_ARCH_AT_LEAST(5)
73421939df44de1705786c545cd1bf519d47250322dBen Murdoch            // Check for call
73521939df44de1705786c545cd1bf519d47250322dBen Murdoch            if ((*insn & 0x0f7f0000) != 0x051f0000) {
73621939df44de1705786c545cd1bf519d47250322dBen Murdoch                // Must be BLX
73721939df44de1705786c545cd1bf519d47250322dBen Murdoch                ASSERT((*insn & 0x012fff30) == 0x012fff30);
73821939df44de1705786c545cd1bf519d47250322dBen Murdoch                insn--;
73921939df44de1705786c545cd1bf519d47250322dBen Murdoch            }
74021939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif
741d0825bca7fe65beaee391d30da42e937db621564Steve Block            // Must be an ldr ..., [pc +/- imm]
742d0825bca7fe65beaee391d30da42e937db621564Steve Block            ASSERT((*insn & 0x0f7f0000) == 0x051f0000);
743d0825bca7fe65beaee391d30da42e937db621564Steve Block
744d0825bca7fe65beaee391d30da42e937db621564Steve Block            ARMWord addr = reinterpret_cast<ARMWord>(insn) + DefaultPrefetching * sizeof(ARMWord);
745d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (*insn & DT_UP)
746d0825bca7fe65beaee391d30da42e937db621564Steve Block                return reinterpret_cast<ARMWord*>(addr + (*insn & SDT_OFFSET_MASK));
747d0825bca7fe65beaee391d30da42e937db621564Steve Block            return reinterpret_cast<ARMWord*>(addr - (*insn & SDT_OFFSET_MASK));
748d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
749d0825bca7fe65beaee391d30da42e937db621564Steve Block
750d0825bca7fe65beaee391d30da42e937db621564Steve Block        static ARMWord* getLdrImmAddressOnPool(ARMWord* insn, uint32_t* constPool)
751d0825bca7fe65beaee391d30da42e937db621564Steve Block        {
752d0825bca7fe65beaee391d30da42e937db621564Steve Block            // Must be an ldr ..., [pc +/- imm]
753d0825bca7fe65beaee391d30da42e937db621564Steve Block            ASSERT((*insn & 0x0f7f0000) == 0x051f0000);
754d0825bca7fe65beaee391d30da42e937db621564Steve Block
755d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (*insn & 0x1)
756d0825bca7fe65beaee391d30da42e937db621564Steve Block                return reinterpret_cast<ARMWord*>(constPool + ((*insn & SDT_OFFSET_MASK) >> 1));
757d0825bca7fe65beaee391d30da42e937db621564Steve Block            return getLdrImmAddress(insn);
758d0825bca7fe65beaee391d30da42e937db621564Steve Block        }
7590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void patchPointerInternal(intptr_t from, void* to)
7610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
7620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ARMWord* insn = reinterpret_cast<ARMWord*>(from);
7630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ARMWord* addr = getLdrImmAddress(insn);
7640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            *addr = reinterpret_cast<ARMWord>(to);
7650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
7660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static ARMWord patchConstantPoolLoad(ARMWord load, ARMWord value)
7680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
7690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            value = (value << 1) + 1;
7700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ASSERT(!(value & ~0xfff));
7710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return (load & ~0xfff) | value;
7720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
7730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void patchConstantPoolLoad(void* loadAddr, void* constPoolAddr);
7750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Patch pointers
7770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void linkPointer(void* code, JmpDst from, void* to)
7790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
7800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            patchPointerInternal(reinterpret_cast<intptr_t>(code) + from.m_offset, to);
7810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
7820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void repatchInt32(void* from, int32_t to)
7840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
7850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            patchPointerInternal(reinterpret_cast<intptr_t>(from), reinterpret_cast<void*>(to));
7860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
7870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7880bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void repatchPointer(void* from, void* to)
7890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
7900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            patchPointerInternal(reinterpret_cast<intptr_t>(from), to);
7910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
7920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Linkers
7944576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        static intptr_t getAbsoluteJumpAddress(void* base, int offset = 0)
7954576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        {
7964576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            return reinterpret_cast<intptr_t>(base) + offset - sizeof(ARMWord);
7974576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        }
7980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
7990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void linkJump(JmpSrc from, JmpDst to)
8000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8014576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            ARMWord* insn = reinterpret_cast<ARMWord*>(getAbsoluteJumpAddress(m_buffer.data(), from.m_offset));
802d0825bca7fe65beaee391d30da42e937db621564Steve Block            ARMWord* addr = getLdrImmAddressOnPool(insn, m_buffer.poolAddress());
803d0825bca7fe65beaee391d30da42e937db621564Steve Block            *addr = static_cast<ARMWord>(to.m_offset);
8040bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
8050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void linkJump(void* code, JmpSrc from, void* to)
8070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8084576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            patchPointerInternal(getAbsoluteJumpAddress(code, from.m_offset), to);
8090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
8100bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void relinkJump(void* from, void* to)
8120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8134576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            patchPointerInternal(getAbsoluteJumpAddress(from), to);
8140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
8150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void linkCall(void* code, JmpSrc from, void* to)
8170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8184576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            patchPointerInternal(getAbsoluteJumpAddress(code, from.m_offset), to);
8190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
8200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void relinkCall(void* from, void* to)
8220bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8234576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            patchPointerInternal(getAbsoluteJumpAddress(from), to);
8240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
8250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Address operations
8270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void* getRelocatedAddress(void* code, JmpSrc jump)
8290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8304576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            return reinterpret_cast<void*>(reinterpret_cast<char*>(code) + jump.m_offset);
8310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
8320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static void* getRelocatedAddress(void* code, JmpDst label)
8340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8354576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            return reinterpret_cast<void*>(reinterpret_cast<char*>(code) + label.m_offset);
8360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
8370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Address differences
8390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static int getDifferenceBetweenLabels(JmpDst from, JmpSrc to)
8410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8424576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            return to.m_offset - from.m_offset;
8430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
8440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static int getDifferenceBetweenLabels(JmpDst from, JmpDst to)
8460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return to.m_offset - from.m_offset;
8480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
8490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static unsigned getCallReturnOffset(JmpSrc call)
8510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8524576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang            return call.m_offset;
8530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
8540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Handle immediates
8560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static ARMWord getOp2Byte(ARMWord imm)
8580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ASSERT(imm <= 0xff);
8600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return OP2_IMMh | (imm & 0x0f) | ((imm & 0xf0) << 4) ;
8610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
8620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static ARMWord getOp2(ARMWord imm);
864643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
865d0825bca7fe65beaee391d30da42e937db621564Steve Block#if WTF_ARM_ARCH_AT_LEAST(7)
866643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        static ARMWord getImm16Op2(ARMWord imm)
867643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        {
868643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            if (imm <= 0xffff)
869643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                return (imm & 0xf000) << 4 | (imm & 0xfff);
870643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return INVALID_IMM;
871643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
872643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#endif
8730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ARMWord getImm(ARMWord imm, int tmpReg, bool invert = false);
8740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void moveImm(ARMWord imm, int dest);
875643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ARMWord encodeComplexImm(ARMWord imm, int dest);
8760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8776c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        ARMWord getOffsetForHalfwordDataTransfer(ARMWord imm, int tmpReg)
8786c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        {
8796c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            // Encode immediate data in the instruction if it is possible
8806c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            if (imm <= 0xff)
8816c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen                return getOp2Byte(imm);
8826c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            // Otherwise, store the data in a temporary register
8836c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen            return encodeComplexImm(imm, tmpReg);
8846c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen        }
8856c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen
8860bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Memory load/store helpers
8870bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
888dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        void dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset, bool bytes = false);
8890bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset);
8900bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        void doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID base, int32_t offset);
8910bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8920bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        // Constant pool hnadlers
8930bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
8940bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static ARMWord placeConstantPoolBarrier(int offset)
8950bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
8960bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            offset = (offset - sizeof(ARMWord)) >> 2;
8970bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            ASSERT((offset <= BOFFSET_MAX && offset >= BOFFSET_MIN));
8980bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return AL | B | (offset & BRANCH_MASK);
8990bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
9000bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
9010bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    private:
9020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ARMWord RM(int reg)
9030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
904231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(reg <= ARMRegisters::pc);
9050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return reg;
9060bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
9070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
9080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ARMWord RS(int reg)
9090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
910231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(reg <= ARMRegisters::pc);
9110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return reg << 8;
9120bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
9130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
9140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ARMWord RD(int reg)
9150bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
916231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(reg <= ARMRegisters::pc);
9170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return reg << 12;
9180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
9190bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
9200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ARMWord RN(int reg)
9210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
922231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ASSERT(reg <= ARMRegisters::pc);
9230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return reg << 16;
9240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
9250bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
9260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        static ARMWord getConditionalField(ARMWord i)
9270bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        {
9280bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            return i & 0xf0000000;
9290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
9300bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
9310bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        int genInt(int reg, ARMWord imm, bool positive);
9320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
9330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ARMBuffer m_buffer;
9340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        Jumps m_jumps;
9350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    };
9360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
9370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch} // namespace JSC
9380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
939d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif // ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
9400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
9410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif // ARMAssembler_h
942