15f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian/*
2a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
3dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block * Copyright (C) 2010 University of Szeged
45f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *
55f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * Redistribution and use in source and binary forms, with or without
65f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * modification, are permitted provided that the following conditions
75f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * are met:
85f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 1. Redistributions of source code must retain the above copyright
95f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *    notice, this list of conditions and the following disclaimer.
105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * 2. Redistributions in binary form must reproduce the above copyright
115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *    notice, this list of conditions and the following disclaimer in the
125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *    documentation and/or other materials provided with the distribution.
135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian *
145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian */
265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#ifndef MacroAssemblerARMv7_h
285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#define MacroAssemblerARMv7_h
295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#if ENABLE(ASSEMBLER)
315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "ARMv7Assembler.h"
335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "AbstractMacroAssembler.h"
345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qiannamespace JSC {
365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianclass MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> {
385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // FIXME: switch dataTempRegister & addressTempRegister, or possibly use r7?
395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //        - dTR is likely used more than aTR, and we'll get better instruction
405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //        encoding if it's in the low 8 registers.
41ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    static const RegisterID dataTempRegister = ARMRegisters::ip;
42231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    static const RegisterID addressTempRegister = ARMRegisters::r3;
435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
44ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    static const ARMRegisters::FPDoubleRegisterID fpTempRegister = ARMRegisters::d7;
45ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    inline ARMRegisters::FPSingleRegisterID fpTempRegisterAsSingle() { return ARMRegisters::asSingle(fpTempRegister); }
46ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
47ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockpublic:
48dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    typedef ARMv7Assembler::LinkRecord LinkRecord;
49a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    typedef ARMv7Assembler::JumpType JumpType;
50dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    typedef ARMv7Assembler::JumpLinkType JumpLinkType;
51dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
52dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    MacroAssemblerARMv7()
53dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        : m_inUninterruptedSequence(false)
54dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
55dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
56dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
57dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    void beginUninterruptedSequence() { m_inUninterruptedSequence = true; }
58dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    void endUninterruptedSequence() { m_inUninterruptedSequence = false; }
59dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    Vector<LinkRecord>& jumpsToLink() { return m_assembler.jumpsToLink(); }
60dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    void* unlinkedCode() { return m_assembler.unlinkedCode(); }
61a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    bool canCompact(JumpType jumpType) { return m_assembler.canCompact(jumpType); }
62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to) { return m_assembler.computeJumpType(jumpType, from, to); }
63dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to) { return m_assembler.computeJumpType(record, from, to); }
64dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset) {return m_assembler.recordLinkOffsets(regionStart, regionEnd, offset); }
65a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return m_assembler.jumpSizeDelta(jumpType, jumpLinkType); }
66dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    void link(LinkRecord& record, uint8_t* from, uint8_t* to) { return m_assembler.link(record, from, to); }
67dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    struct ArmAddress {
695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        enum AddressType {
705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            HasOffset,
715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            HasIndex,
725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } type;
735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        RegisterID base;
745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        union {
755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            int32_t offset;
765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            struct {
775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                RegisterID index;
785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                Scale scale;
795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            };
805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } u;
815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        explicit ArmAddress(RegisterID base, int32_t offset = 0)
835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            : type(HasOffset)
845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            , base(base)
855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        {
865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            u.offset = offset;
875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        explicit ArmAddress(RegisterID base, RegisterID index, Scale scale = TimesOne)
905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            : type(HasIndex)
915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            , base(base)
925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        {
935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            u.index = index;
945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            u.scale = scale;
955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    };
975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianpublic:
99ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    typedef ARMRegisters::FPDoubleRegisterID FPRegisterID;
1005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    static const Scale ScalePtr = TimesFour;
1025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    enum Condition {
1045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        Equal = ARMv7Assembler::ConditionEQ,
1055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        NotEqual = ARMv7Assembler::ConditionNE,
1065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        Above = ARMv7Assembler::ConditionHI,
1075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        AboveOrEqual = ARMv7Assembler::ConditionHS,
1085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        Below = ARMv7Assembler::ConditionLO,
1095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        BelowOrEqual = ARMv7Assembler::ConditionLS,
1105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        GreaterThan = ARMv7Assembler::ConditionGT,
1115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        GreaterThanOrEqual = ARMv7Assembler::ConditionGE,
1125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        LessThan = ARMv7Assembler::ConditionLT,
1135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        LessThanOrEqual = ARMv7Assembler::ConditionLE,
1145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        Overflow = ARMv7Assembler::ConditionVS,
1155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        Signed = ARMv7Assembler::ConditionMI,
1165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        Zero = ARMv7Assembler::ConditionEQ,
1175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        NonZero = ARMv7Assembler::ConditionNE
1185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    };
1195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    enum DoubleCondition {
120643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
1215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        DoubleEqual = ARMv7Assembler::ConditionEQ,
122643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        DoubleNotEqual = ARMv7Assembler::ConditionVC, // Not the right flag! check for this & handle differently.
1235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        DoubleGreaterThan = ARMv7Assembler::ConditionGT,
1245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        DoubleGreaterThanOrEqual = ARMv7Assembler::ConditionGE,
1255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        DoubleLessThan = ARMv7Assembler::ConditionLO,
1265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        DoubleLessThanOrEqual = ARMv7Assembler::ConditionLS,
127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // If either operand is NaN, these conditions always evaluate to true.
128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        DoubleEqualOrUnordered = ARMv7Assembler::ConditionVS, // Not the right flag! check for this & handle differently.
129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        DoubleNotEqualOrUnordered = ARMv7Assembler::ConditionNE,
130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        DoubleGreaterThanOrUnordered = ARMv7Assembler::ConditionHI,
131643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        DoubleGreaterThanOrEqualOrUnordered = ARMv7Assembler::ConditionHS,
132643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        DoubleLessThanOrUnordered = ARMv7Assembler::ConditionLT,
133643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        DoubleLessThanOrEqualOrUnordered = ARMv7Assembler::ConditionLE,
1345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    };
1355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    static const RegisterID stackPointerRegister = ARMRegisters::sp;
137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    static const RegisterID linkRegister = ARMRegisters::lr;
1385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Integer arithmetic operations:
1405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //
1415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Operations are typically two operand - operation(source, srcDst)
1422bde8e466a4451c7319e3a072d118917957d6554Steve Block    // For many operations the source may be an TrustedImm32, the srcDst operand
1435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // may often be a memory location (explictly described using an Address
1445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // object).
1455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void add32(RegisterID src, RegisterID dest)
1475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.add(dest, dest, src);
1495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1512bde8e466a4451c7319e3a072d118917957d6554Steve Block    void add32(TrustedImm32 imm, RegisterID dest)
1525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        add32(imm, dest, dest);
1545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1562bde8e466a4451c7319e3a072d118917957d6554Steve Block    void add32(TrustedImm32 imm, RegisterID src, RegisterID dest)
1575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
1595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (armImm.isValid())
1605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.add(dest, src, armImm);
1615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
1625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(imm, dataTempRegister);
1635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.add(dest, src, dataTempRegister);
1645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
1655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1672bde8e466a4451c7319e3a072d118917957d6554Steve Block    void add32(TrustedImm32 imm, Address address)
1685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(address, dataTempRegister);
1705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
1725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (armImm.isValid())
1735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.add(dataTempRegister, dataTempRegister, armImm);
1745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
1755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // Hrrrm, since dataTempRegister holds the data loaded,
1765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // use addressTempRegister to hold the immediate.
1775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(imm, addressTempRegister);
1785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.add(dataTempRegister, dataTempRegister, addressTempRegister);
1795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
1805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        store32(dataTempRegister, address);
1825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void add32(Address src, RegisterID dest)
1855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(src, dataTempRegister);
1875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        add32(dataTempRegister, dest);
1885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
1895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1902bde8e466a4451c7319e3a072d118917957d6554Steve Block    void add32(TrustedImm32 imm, AbsoluteAddress address)
1915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(address.m_ptr, dataTempRegister);
1935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
1955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (armImm.isValid())
1965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.add(dataTempRegister, dataTempRegister, armImm);
1975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
1985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // Hrrrm, since dataTempRegister holds the data loaded,
1995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // use addressTempRegister to hold the immediate.
2005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(imm, addressTempRegister);
2015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.add(dataTempRegister, dataTempRegister, addressTempRegister);
2025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
2035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        store32(dataTempRegister, address.m_ptr);
2055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void and32(RegisterID src, RegisterID dest)
2085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
2095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.ARM_and(dest, dest, src);
2105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2122bde8e466a4451c7319e3a072d118917957d6554Steve Block    void and32(TrustedImm32 imm, RegisterID dest)
2135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
2145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
2155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (armImm.isValid())
2165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.ARM_and(dest, dest, armImm);
2175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
2185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(imm, dataTempRegister);
2195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.ARM_and(dest, dest, dataTempRegister);
2205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
2215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2234576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    void countLeadingZeros32(RegisterID src, RegisterID dest)
2244576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    {
2254576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        m_assembler.clz(dest, src);
2264576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    }
2274576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
228643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    void lshift32(RegisterID shift_amount, RegisterID dest)
2295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
230643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // Clamp the shift to the range 0..31
231643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(0x1f);
232643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ASSERT(armImm.isValid());
233643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        m_assembler.ARM_and(dataTempRegister, shift_amount, armImm);
234643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
235643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        m_assembler.lsl(dest, dest, dataTempRegister);
2365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2382bde8e466a4451c7319e3a072d118917957d6554Steve Block    void lshift32(TrustedImm32 imm, RegisterID dest)
2395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
240643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        m_assembler.lsl(dest, dest, imm.m_value & 0x1f);
2415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void mul32(RegisterID src, RegisterID dest)
2445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
2455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.smull(dest, dataTempRegister, dest, src);
2465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2482bde8e466a4451c7319e3a072d118917957d6554Steve Block    void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
2495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
2505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        move(imm, dataTempRegister);
2515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.smull(dest, dataTempRegister, src, dataTempRegister);
2525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
254ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void neg32(RegisterID srcDest)
255ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
256ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.neg(srcDest, srcDest);
257ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
258ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
2595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void not32(RegisterID srcDest)
2605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
2615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.mvn(srcDest, srcDest);
2625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void or32(RegisterID src, RegisterID dest)
2655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
2665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.orr(dest, dest, src);
2675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2692bde8e466a4451c7319e3a072d118917957d6554Steve Block    void or32(TrustedImm32 imm, RegisterID dest)
2705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
2715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
2725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (armImm.isValid())
2735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.orr(dest, dest, armImm);
2745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
2755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(imm, dataTempRegister);
2765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.orr(dest, dest, dataTempRegister);
2775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
2785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void rshift32(RegisterID shift_amount, RegisterID dest)
2815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
282643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // Clamp the shift to the range 0..31
283643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(0x1f);
284643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ASSERT(armImm.isValid());
285643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        m_assembler.ARM_and(dataTempRegister, shift_amount, armImm);
286643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
287643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        m_assembler.asr(dest, dest, dataTempRegister);
2885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
2895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
2902bde8e466a4451c7319e3a072d118917957d6554Steve Block    void rshift32(TrustedImm32 imm, RegisterID dest)
2915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
292643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        m_assembler.asr(dest, dest, imm.m_value & 0x1f);
2935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
29421939df44de1705786c545cd1bf519d47250322dBen Murdoch
29521939df44de1705786c545cd1bf519d47250322dBen Murdoch    void urshift32(RegisterID shift_amount, RegisterID dest)
29621939df44de1705786c545cd1bf519d47250322dBen Murdoch    {
29721939df44de1705786c545cd1bf519d47250322dBen Murdoch        // Clamp the shift to the range 0..31
29821939df44de1705786c545cd1bf519d47250322dBen Murdoch        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(0x1f);
29921939df44de1705786c545cd1bf519d47250322dBen Murdoch        ASSERT(armImm.isValid());
30021939df44de1705786c545cd1bf519d47250322dBen Murdoch        m_assembler.ARM_and(dataTempRegister, shift_amount, armImm);
30121939df44de1705786c545cd1bf519d47250322dBen Murdoch
30221939df44de1705786c545cd1bf519d47250322dBen Murdoch        m_assembler.lsr(dest, dest, dataTempRegister);
30321939df44de1705786c545cd1bf519d47250322dBen Murdoch    }
30421939df44de1705786c545cd1bf519d47250322dBen Murdoch
3052bde8e466a4451c7319e3a072d118917957d6554Steve Block    void urshift32(TrustedImm32 imm, RegisterID dest)
30621939df44de1705786c545cd1bf519d47250322dBen Murdoch    {
30721939df44de1705786c545cd1bf519d47250322dBen Murdoch        m_assembler.lsr(dest, dest, imm.m_value & 0x1f);
30821939df44de1705786c545cd1bf519d47250322dBen Murdoch    }
3095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void sub32(RegisterID src, RegisterID dest)
3115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.sub(dest, dest, src);
3135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3152bde8e466a4451c7319e3a072d118917957d6554Steve Block    void sub32(TrustedImm32 imm, RegisterID dest)
3165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
3185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (armImm.isValid())
3195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.sub(dest, dest, armImm);
3205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
3215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(imm, dataTempRegister);
3225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.sub(dest, dest, dataTempRegister);
3235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
3245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3262bde8e466a4451c7319e3a072d118917957d6554Steve Block    void sub32(TrustedImm32 imm, Address address)
3275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(address, dataTempRegister);
3295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
3315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (armImm.isValid())
3325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.sub(dataTempRegister, dataTempRegister, armImm);
3335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
3345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // Hrrrm, since dataTempRegister holds the data loaded,
3355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // use addressTempRegister to hold the immediate.
3365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(imm, addressTempRegister);
3375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.sub(dataTempRegister, dataTempRegister, addressTempRegister);
3385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
3395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        store32(dataTempRegister, address);
3415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void sub32(Address src, RegisterID dest)
3445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(src, dataTempRegister);
3465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        sub32(dataTempRegister, dest);
3475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3492bde8e466a4451c7319e3a072d118917957d6554Steve Block    void sub32(TrustedImm32 imm, AbsoluteAddress address)
3505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(address.m_ptr, dataTempRegister);
3525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12OrEncodedImm(imm.m_value);
3545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (armImm.isValid())
3555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.sub(dataTempRegister, dataTempRegister, armImm);
3565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
3575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // Hrrrm, since dataTempRegister holds the data loaded,
3585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            // use addressTempRegister to hold the immediate.
3595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(imm, addressTempRegister);
3605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.sub(dataTempRegister, dataTempRegister, addressTempRegister);
3615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
3625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        store32(dataTempRegister, address.m_ptr);
3645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void xor32(RegisterID src, RegisterID dest)
3675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.eor(dest, dest, src);
3695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3712bde8e466a4451c7319e3a072d118917957d6554Steve Block    void xor32(TrustedImm32 imm, RegisterID dest)
3725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
3745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (armImm.isValid())
3755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.eor(dest, dest, armImm);
3765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
3775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(imm, dataTempRegister);
3785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.eor(dest, dest, dataTempRegister);
3795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
3805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
3815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Memory access operations:
3845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //
3855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Loads are of the form load(address, destination) and stores of the form
3862bde8e466a4451c7319e3a072d118917957d6554Steve Block    // store(source, address).  The source for a store may be an TrustedImm32.  Address
3875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // operand objects to loads and store will be implicitly constructed if a
3885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // register is passed.
3895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
3905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianprivate:
3915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void load32(ArmAddress address, RegisterID dest)
3925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
3935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (address.type == ArmAddress::HasIndex)
3945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.ldr(dest, address.base, address.u.index, address.u.scale);
3955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else if (address.u.offset >= 0) {
3965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.u.offset);
3975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ASSERT(armImm.isValid());
3985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.ldr(dest, address.base, armImm);
3995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } else {
4005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ASSERT(address.u.offset >= -255);
4015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.ldr(dest, address.base, address.u.offset, true, false);
4025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
4035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
4045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void load16(ArmAddress address, RegisterID dest)
4065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
4075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (address.type == ArmAddress::HasIndex)
4085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.ldrh(dest, address.base, address.u.index, address.u.scale);
4095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else if (address.u.offset >= 0) {
4105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.u.offset);
4115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ASSERT(armImm.isValid());
4125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.ldrh(dest, address.base, armImm);
4135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } else {
4145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ASSERT(address.u.offset >= -255);
4155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.ldrh(dest, address.base, address.u.offset, true, false);
4165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
4175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
4185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
419dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void load8(ArmAddress address, RegisterID dest)
420dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
421dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        if (address.type == ArmAddress::HasIndex)
422dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_assembler.ldrb(dest, address.base, address.u.index, address.u.scale);
423dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        else if (address.u.offset >= 0) {
424dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.u.offset);
425dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            ASSERT(armImm.isValid());
426dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_assembler.ldrb(dest, address.base, armImm);
427dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        } else {
428dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            ASSERT(address.u.offset >= -255);
429dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            m_assembler.ldrb(dest, address.base, address.u.offset, true, false);
430dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        }
431dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
432dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void store32(RegisterID src, ArmAddress address)
4345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
4355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (address.type == ArmAddress::HasIndex)
4365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.str(src, address.base, address.u.index, address.u.scale);
4375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else if (address.u.offset >= 0) {
4385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.u.offset);
4395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ASSERT(armImm.isValid());
4405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.str(src, address.base, armImm);
4415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } else {
4425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ASSERT(address.u.offset >= -255);
4435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.str(src, address.base, address.u.offset, true, false);
4445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
4455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
4465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianpublic:
4485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void load32(ImplicitAddress address, RegisterID dest)
4495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
4505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(setupArmAddress(address), dest);
4515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
4525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void load32(BaseIndex address, RegisterID dest)
4545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
4555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(setupArmAddress(address), dest);
4565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
4575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
458231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
459231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
460231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        load32(setupArmAddress(address), dest);
461231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
462231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
4632bde8e466a4451c7319e3a072d118917957d6554Steve Block    void load32(const void* address, RegisterID dest)
4645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
4652bde8e466a4451c7319e3a072d118917957d6554Steve Block        move(TrustedImmPtr(address), addressTempRegister);
4665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.ldr(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
4675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
4685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
469dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    void load8(ImplicitAddress address, RegisterID dest)
470dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
471dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        load8(setupArmAddress(address), dest);
472dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
473dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
4745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
4755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
4762bde8e466a4451c7319e3a072d118917957d6554Steve Block        DataLabel32 label = moveWithPatch(TrustedImm32(address.offset), dataTempRegister);
4775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(ArmAddress(address.base, dataTempRegister), dest);
4785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return label;
4795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
4805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void load16(BaseIndex address, RegisterID dest)
4825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
4835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.ldrh(dest, makeBaseIndexBase(address), address.index, address.scale);
4845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
48521939df44de1705786c545cd1bf519d47250322dBen Murdoch
48621939df44de1705786c545cd1bf519d47250322dBen Murdoch    void load16(ImplicitAddress address, RegisterID dest)
48721939df44de1705786c545cd1bf519d47250322dBen Murdoch    {
488545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.offset);
489545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        if (armImm.isValid())
490545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            m_assembler.ldrh(dest, address.base, armImm);
491545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        else {
4922bde8e466a4451c7319e3a072d118917957d6554Steve Block            move(TrustedImm32(address.offset), dataTempRegister);
493545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch            m_assembler.ldrh(dest, address.base, dataTempRegister);
494545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch        }
49521939df44de1705786c545cd1bf519d47250322dBen Murdoch    }
4965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
4975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
4985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
4992bde8e466a4451c7319e3a072d118917957d6554Steve Block        DataLabel32 label = moveWithPatch(TrustedImm32(address.offset), dataTempRegister);
5005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        store32(src, ArmAddress(address.base, dataTempRegister));
5015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return label;
5025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
5035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void store32(RegisterID src, ImplicitAddress address)
5055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
5065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        store32(src, setupArmAddress(address));
5075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
5085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void store32(RegisterID src, BaseIndex address)
5105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
5115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        store32(src, setupArmAddress(address));
5125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
5135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5142bde8e466a4451c7319e3a072d118917957d6554Steve Block    void store32(TrustedImm32 imm, ImplicitAddress address)
5155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
5165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        move(imm, dataTempRegister);
5175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        store32(dataTempRegister, setupArmAddress(address));
5185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
5195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5202bde8e466a4451c7319e3a072d118917957d6554Steve Block    void store32(RegisterID src, const void* address)
5215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
5222bde8e466a4451c7319e3a072d118917957d6554Steve Block        move(TrustedImmPtr(address), addressTempRegister);
5235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.str(src, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
5245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
5255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5262bde8e466a4451c7319e3a072d118917957d6554Steve Block    void store32(TrustedImm32 imm, const void* address)
5275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
5285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        move(imm, dataTempRegister);
5295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        store32(dataTempRegister, address);
5305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
5315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Floating-point operations:
5345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool supportsFloatingPoint() const { return true; }
5365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // On x86(_64) the MacroAssembler provides an interface to truncate a double to an integer.
5375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // If a value is not representable as an integer, and possibly for some values that are,
5385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // (on x86 INT_MIN, since this is indistinguishable from results for out-of-range/NaN input)
5395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // a branch will  be taken.  It is not clear whether this interface will be well suited to
5405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // other platforms.  On ARMv7 the hardware truncation operation produces multiple possible
5415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // failure values (saturates to INT_MIN & INT_MAX, NaN reulsts in a value of 0).  This is a
5425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // temporary solution while we work out what this interface should be.  Either we need to
5435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // decide to make this interface work on all platforms, rework the interface to make it more
5445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // generic, or decide that the MacroAssembler cannot practically be used to abstracted these
5455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // operations, and make clients go directly to the m_assembler to plant truncation instructions.
5465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // In short, FIXME:.
5475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool supportsFloatingPointTruncate() const { return false; }
5485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
54921939df44de1705786c545cd1bf519d47250322dBen Murdoch    bool supportsFloatingPointSqrt() const
55021939df44de1705786c545cd1bf519d47250322dBen Murdoch    {
55121939df44de1705786c545cd1bf519d47250322dBen Murdoch        return false;
55221939df44de1705786c545cd1bf519d47250322dBen Murdoch    }
55321939df44de1705786c545cd1bf519d47250322dBen Murdoch
5545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void loadDouble(ImplicitAddress address, FPRegisterID dest)
5555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
5565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        RegisterID base = address.base;
5575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        int32_t offset = address.offset;
5585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2.
5605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if ((offset & 3) || (offset > (255 * 4)) || (offset < -(255 * 4))) {
5612bde8e466a4451c7319e3a072d118917957d6554Steve Block            add32(TrustedImm32(offset), base, addressTempRegister);
5625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            base = addressTempRegister;
5635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            offset = 0;
5645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
5655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.vldr(dest, base, offset);
5675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
5685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
569ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void loadDouble(const void* address, FPRegisterID dest)
570ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
5712bde8e466a4451c7319e3a072d118917957d6554Steve Block        move(TrustedImmPtr(address), addressTempRegister);
572ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vldr(dest, addressTempRegister, 0);
573ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
574ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
5755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void storeDouble(FPRegisterID src, ImplicitAddress address)
5765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
5775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        RegisterID base = address.base;
5785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        int32_t offset = address.offset;
5795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // Arm vfp addresses can be offset by a 9-bit ones-comp immediate, left shifted by 2.
5815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if ((offset & 3) || (offset > (255 * 4)) || (offset < -(255 * 4))) {
5822bde8e466a4451c7319e3a072d118917957d6554Steve Block            add32(TrustedImm32(offset), base, addressTempRegister);
5835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            base = addressTempRegister;
5845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            offset = 0;
5855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
5865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.vstr(src, base, offset);
5885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
5895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void addDouble(FPRegisterID src, FPRegisterID dest)
5915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
5925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.vadd_F64(dest, dest, src);
5935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
5945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
5955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void addDouble(Address src, FPRegisterID dest)
5965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
5975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        loadDouble(src, fpTempRegister);
5985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        addDouble(fpTempRegister, dest);
5995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
6005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
601ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void divDouble(FPRegisterID src, FPRegisterID dest)
602ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
603ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vdiv_F64(dest, dest, src);
604ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
605ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
6065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void subDouble(FPRegisterID src, FPRegisterID dest)
6075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
6085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.vsub_F64(dest, dest, src);
6095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
6105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
6115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void subDouble(Address src, FPRegisterID dest)
6125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
6135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        loadDouble(src, fpTempRegister);
6145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        subDouble(fpTempRegister, dest);
6155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
6165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
6175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void mulDouble(FPRegisterID src, FPRegisterID dest)
6185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
6195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.vmul_F64(dest, dest, src);
6205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
6215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
6225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void mulDouble(Address src, FPRegisterID dest)
6235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
6245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        loadDouble(src, fpTempRegister);
6255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        mulDouble(fpTempRegister, dest);
6265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
6275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
62821939df44de1705786c545cd1bf519d47250322dBen Murdoch    void sqrtDouble(FPRegisterID, FPRegisterID)
62921939df44de1705786c545cd1bf519d47250322dBen Murdoch    {
63021939df44de1705786c545cd1bf519d47250322dBen Murdoch        ASSERT_NOT_REACHED();
63121939df44de1705786c545cd1bf519d47250322dBen Murdoch    }
63221939df44de1705786c545cd1bf519d47250322dBen Murdoch
6335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
6345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
635ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vmov(fpTempRegisterAsSingle(), src);
636ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle());
637ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
638ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
639ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void convertInt32ToDouble(Address address, FPRegisterID dest)
640ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
641ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fixme: load directly into the fpr!
642ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        load32(address, dataTempRegister);
643ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vmov(fpTempRegisterAsSingle(), dataTempRegister);
644ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle());
645ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
646ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
647ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void convertInt32ToDouble(AbsoluteAddress address, FPRegisterID dest)
648ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
649ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Fixme: load directly into the fpr!
650ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        load32(address.m_ptr, dataTempRegister);
651ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vmov(fpTempRegisterAsSingle(), dataTempRegister);
652ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle());
6535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
6545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
6555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
6565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
6575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.vcmp_F64(left, right);
658ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vmrs();
659643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
660643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (cond == DoubleNotEqual) {
661643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            // ConditionNE jumps if NotEqual *or* unordered - force the unordered cases not to jump.
662643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            Jump unordered = makeBranch(ARMv7Assembler::ConditionVS);
663643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            Jump result = makeBranch(ARMv7Assembler::ConditionNE);
664643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            unordered.link(this);
665643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return result;
666643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
667643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (cond == DoubleEqualOrUnordered) {
668643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            Jump unordered = makeBranch(ARMv7Assembler::ConditionVS);
669643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            Jump notEqual = makeBranch(ARMv7Assembler::ConditionNE);
670643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            unordered.link(this);
671cad810f21b803229eb11403f9209855525a25d57Steve Block            // We get here if either unordered or equal.
672643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            Jump result = makeJump();
673643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            notEqual.link(this);
674643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            return result;
675643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
6765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return makeBranch(cond);
6775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
6785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
6795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump branchTruncateDoubleToInt32(FPRegisterID, RegisterID)
6805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
6815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ASSERT_NOT_REACHED();
682231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return jump();
6835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
6845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
685ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // Convert 'src' to an integer, and places the resulting 'dest'.
686ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // If the result is not representable as a 32 bit value, branch.
687ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // May also branch for some values that are representable in 32 bits
688ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    // (specifically, in this case, 0).
689ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID)
690ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
691ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vcvtr_S32_F64(fpTempRegisterAsSingle(), src);
692ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vmov(dest, fpTempRegisterAsSingle());
693ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
694ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
695ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.vcvt_F64_S32(fpTempRegister, fpTempRegisterAsSingle());
696ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, fpTempRegister));
697ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
698ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
699ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        failureCases.append(branchTest32(Zero, dest));
700ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
701ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
702cad810f21b803229eb11403f9209855525a25d57Steve Block    Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID)
703ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
704cad810f21b803229eb11403f9209855525a25d57Steve Block        m_assembler.vcmpz_F64(reg);
705cad810f21b803229eb11403f9209855525a25d57Steve Block        m_assembler.vmrs();
706cad810f21b803229eb11403f9209855525a25d57Steve Block        Jump unordered = makeBranch(ARMv7Assembler::ConditionVS);
707cad810f21b803229eb11403f9209855525a25d57Steve Block        Jump result = makeBranch(ARMv7Assembler::ConditionNE);
708cad810f21b803229eb11403f9209855525a25d57Steve Block        unordered.link(this);
709cad810f21b803229eb11403f9209855525a25d57Steve Block        return result;
710cad810f21b803229eb11403f9209855525a25d57Steve Block    }
711cad810f21b803229eb11403f9209855525a25d57Steve Block
712cad810f21b803229eb11403f9209855525a25d57Steve Block    Jump branchDoubleZeroOrNaN(FPRegisterID reg, FPRegisterID)
713cad810f21b803229eb11403f9209855525a25d57Steve Block    {
714cad810f21b803229eb11403f9209855525a25d57Steve Block        m_assembler.vcmpz_F64(reg);
715cad810f21b803229eb11403f9209855525a25d57Steve Block        m_assembler.vmrs();
716cad810f21b803229eb11403f9209855525a25d57Steve Block        Jump unordered = makeBranch(ARMv7Assembler::ConditionVS);
717cad810f21b803229eb11403f9209855525a25d57Steve Block        Jump notEqual = makeBranch(ARMv7Assembler::ConditionNE);
718cad810f21b803229eb11403f9209855525a25d57Steve Block        unordered.link(this);
719cad810f21b803229eb11403f9209855525a25d57Steve Block        // We get here if either unordered or equal.
720cad810f21b803229eb11403f9209855525a25d57Steve Block        Jump result = makeJump();
721cad810f21b803229eb11403f9209855525a25d57Steve Block        notEqual.link(this);
722cad810f21b803229eb11403f9209855525a25d57Steve Block        return result;
723ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
7245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Stack manipulation operations:
7265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //
7275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // The ABI is assumed to provide a stack abstraction to memory,
7285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // containing machine word sized units of data.  Push and pop
7295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // operations add and remove a single register sized unit of data
7305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // to or from the stack.  Peek and poke operations read or write
7315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // values on the stack, without moving the current stack position.
7325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void pop(RegisterID dest)
7345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
7355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // store postindexed with writeback
736231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_assembler.ldr(dest, ARMRegisters::sp, sizeof(void*), false, true);
7375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
7385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void push(RegisterID src)
7405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
7415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // store preindexed with writeback
742231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        m_assembler.str(src, ARMRegisters::sp, -sizeof(void*), true, true);
7435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
7445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void push(Address address)
7465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
7475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(address, dataTempRegister);
7485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        push(dataTempRegister);
7495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
7505f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7512bde8e466a4451c7319e3a072d118917957d6554Steve Block    void push(TrustedImm32 imm)
7525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
7535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        move(imm, dataTempRegister);
7545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        push(dataTempRegister);
7555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
7565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Register move operations:
7585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //
7595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Move values in registers.
7605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7612bde8e466a4451c7319e3a072d118917957d6554Steve Block    void move(TrustedImm32 imm, RegisterID dest)
7625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
7635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        uint32_t value = imm.m_value;
7645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (imm.m_isPointer)
7665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            moveFixedWidthEncoding(imm, dest);
7675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
7685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(value);
7695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (armImm.isValid())
7715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                m_assembler.mov(dest, armImm);
7725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            else if ((armImm = ARMThumbImmediate::makeEncodedImm(~value)).isValid())
7735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                m_assembler.mvn(dest, armImm);
7745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            else {
7755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(value));
7765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                if (value & 0xffff0000)
7775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                    m_assembler.movt(dest, ARMThumbImmediate::makeUInt16(value >> 16));
7785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
7795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
7805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
7815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void move(RegisterID src, RegisterID dest)
7835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
7845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.mov(dest, src);
7855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
7865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7872bde8e466a4451c7319e3a072d118917957d6554Steve Block    void move(TrustedImmPtr imm, RegisterID dest)
7885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
7892bde8e466a4451c7319e3a072d118917957d6554Steve Block        move(TrustedImm32(imm), dest);
7905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
7915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void swap(RegisterID reg1, RegisterID reg2)
7935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
7945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        move(reg1, dataTempRegister);
7955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        move(reg2, reg1);
7965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        move(dataTempRegister, reg2);
7975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
7985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
7995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void signExtend32ToPtr(RegisterID src, RegisterID dest)
8005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
8015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (src != dest)
8025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(src, dest);
8035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
8045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
8065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
8075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (src != dest)
8085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(src, dest);
8095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
8105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Forwards / external control flow operations:
8135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //
8145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // This set of jump and conditional branch operations return a Jump
8155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // object which may linked at a later point, allow forwards jump,
8165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // or jumps that will require external linkage (after the code has been
8175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // relocated).
8185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //
8195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // For branches, signed <, >, <= and >= are denoted as l, g, le, and ge
8205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // respecitvely, for unsigned comparisons the names b, a, be, and ae are
8215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // used (representing the names 'below' and 'above').
8225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //
8235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Operands to the comparision are provided in the expected order, e.g.
8242bde8e466a4451c7319e3a072d118917957d6554Steve Block    // jle32(reg1, TrustedImm32(5)) will branch if the value held in reg1, when
8255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // treated as a signed 32bit value, is less than or equal to 5.
8265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //
8275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // jz and jnz test whether the first operand is equal to zero, and take
8285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // an optional second operand of a mask under which to perform the test.
8295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianprivate:
8305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Should we be using TEQ for equal/not-equal?
8322bde8e466a4451c7319e3a072d118917957d6554Steve Block    void compare32(RegisterID left, TrustedImm32 right)
8335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
8345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        int32_t imm = right.m_value;
8355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!imm)
8365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.tst(left, left);
8375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
8385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm);
8395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (armImm.isValid())
8405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                m_assembler.cmp(left, armImm);
841cad810f21b803229eb11403f9209855525a25d57Steve Block            else if ((armImm = ARMThumbImmediate::makeEncodedImm(-imm)).isValid())
8425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                m_assembler.cmn(left, armImm);
8435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            else {
8442bde8e466a4451c7319e3a072d118917957d6554Steve Block                move(TrustedImm32(imm), dataTempRegister);
8455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                m_assembler.cmp(left, dataTempRegister);
8465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
8475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
8485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
8495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8502bde8e466a4451c7319e3a072d118917957d6554Steve Block    void test32(RegisterID reg, TrustedImm32 mask)
8515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
8525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        int32_t imm = mask.m_value;
8535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (imm == -1)
8555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.tst(reg, reg);
8565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
8575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm);
8585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (armImm.isValid())
8595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                m_assembler.tst(reg, armImm);
8605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            else {
8615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                move(mask, dataTempRegister);
8625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                m_assembler.tst(reg, dataTempRegister);
8635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
8645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
8655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
8665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianpublic:
8685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump branch32(Condition cond, RegisterID left, RegisterID right)
8695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
8705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.cmp(left, right);
8715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Jump(makeBranch(cond));
8725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
8735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8742bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branch32(Condition cond, RegisterID left, TrustedImm32 right)
8755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
8765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        compare32(left, right);
8775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Jump(makeBranch(cond));
8785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
8795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump branch32(Condition cond, RegisterID left, Address right)
8815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
8825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(right, dataTempRegister);
8835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branch32(cond, left, dataTempRegister);
8845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
8855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump branch32(Condition cond, Address left, RegisterID right)
8875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
8885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(left, dataTempRegister);
8895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branch32(cond, dataTempRegister, right);
8905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
8915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8922bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branch32(Condition cond, Address left, TrustedImm32 right)
8935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
8945f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
8955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(left, addressTempRegister);
8965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branch32(cond, addressTempRegister, right);
8975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
8985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
8992bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branch32(Condition cond, BaseIndex left, TrustedImm32 right)
9005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
9015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
9025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(left, addressTempRegister);
9035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branch32(cond, addressTempRegister, right);
9045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
9055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
9062bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, TrustedImm32 right)
907231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
908231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
909231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        load32WithUnalignedHalfWords(left, addressTempRegister);
910231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return branch32(cond, addressTempRegister, right);
911231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
912231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
9135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right)
9145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
9155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(left.m_ptr, dataTempRegister);
9165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branch32(cond, dataTempRegister, right);
9175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
9185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
9192bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branch32(Condition cond, AbsoluteAddress left, TrustedImm32 right)
9205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
9215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
9225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(left.m_ptr, addressTempRegister);
9235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branch32(cond, addressTempRegister, right);
9245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
9255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
9265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump branch16(Condition cond, BaseIndex left, RegisterID right)
9275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
9285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load16(left, dataTempRegister);
9295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.lsl(addressTempRegister, right, 16);
9305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.lsl(dataTempRegister, dataTempRegister, 16);
9315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branch32(cond, dataTempRegister, addressTempRegister);
9325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
9335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
9342bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branch16(Condition cond, BaseIndex left, TrustedImm32 right)
9355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
9365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // use addressTempRegister incase the branch32 we call uses dataTempRegister. :-/
9375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load16(left, addressTempRegister);
9385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.lsl(addressTempRegister, addressTempRegister, 16);
9392bde8e466a4451c7319e3a072d118917957d6554Steve Block        return branch32(cond, addressTempRegister, TrustedImm32(right.m_value << 16));
9405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
9415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
9422bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branch8(Condition cond, RegisterID left, TrustedImm32 right)
943dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
944dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        compare32(left, right);
945dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return Jump(makeBranch(cond));
946dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
947dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
9482bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branch8(Condition cond, Address left, TrustedImm32 right)
949dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
950dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // use addressTempRegister incase the branch8 we call uses dataTempRegister. :-/
951dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        load8(left, addressTempRegister);
952dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return branch8(cond, addressTempRegister, right);
953dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
954dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
9555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
9565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
9575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ASSERT((cond == Zero) || (cond == NonZero));
9585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.tst(reg, mask);
9595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Jump(makeBranch(cond));
9605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
9615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
9622bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branchTest32(Condition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
9635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
9645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ASSERT((cond == Zero) || (cond == NonZero));
9655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        test32(reg, mask);
9665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Jump(makeBranch(cond));
9675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
9685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
9692bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branchTest32(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
9705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
9715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ASSERT((cond == Zero) || (cond == NonZero));
9725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
9735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(address, addressTempRegister);
9745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branchTest32(cond, addressTempRegister, mask);
9755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
9765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
9772bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branchTest32(Condition cond, BaseIndex address, TrustedImm32 mask = TrustedImm32(-1))
9785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
9795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ASSERT((cond == Zero) || (cond == NonZero));
9805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // use addressTempRegister incase the branchTest32 we call uses dataTempRegister. :-/
9815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(address, addressTempRegister);
9825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branchTest32(cond, addressTempRegister, mask);
9835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
9845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
9852bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branchTest8(Condition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
986dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
987dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT((cond == Zero) || (cond == NonZero));
988dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        test32(reg, mask);
989dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return Jump(makeBranch(cond));
990dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
991dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
9922bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branchTest8(Condition cond, Address address, TrustedImm32 mask = TrustedImm32(-1))
993dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
994dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        ASSERT((cond == Zero) || (cond == NonZero));
995dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        // use addressTempRegister incase the branchTest8 we call uses dataTempRegister. :-/
996dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        load8(address, addressTempRegister);
997dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        return branchTest8(cond, addressTempRegister, mask);
998dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
999dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
10005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump jump()
10015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
10025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Jump(makeJump());
10035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
10045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
10055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void jump(RegisterID target)
10065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1007a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_assembler.bx(target, ARMv7Assembler::JumpFixed);
10085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
10095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
10105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Address is a memory location containing the address to jump to
10115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void jump(Address address)
10125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
10135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(address, dataTempRegister);
1014a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_assembler.bx(dataTempRegister, ARMv7Assembler::JumpFixed);
10155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
10165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
10175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
10185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Arithmetic control flow operations:
10195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //
10205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // This set of conditional branch operations branch based
10215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // on the result of an arithmetic operation.  The operation
10225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // is performed as normal, storing the result.
10235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //
10245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // * jz operations branch if the result is zero.
10255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // * jo operations branch if the (signed) arithmetic
10265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    //   operation caused an overflow to occur.
10275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
10285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump branchAdd32(Condition cond, RegisterID src, RegisterID dest)
10295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
10305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
10315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.add_S(dest, dest, src);
10325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Jump(makeBranch(cond));
10335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
10345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
10352bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branchAdd32(Condition cond, TrustedImm32 imm, RegisterID dest)
10365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
10375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
10385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
10395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (armImm.isValid())
10405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.add_S(dest, dest, armImm);
10415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
10425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(imm, dataTempRegister);
10435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.add_S(dest, dest, dataTempRegister);
10445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
10455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Jump(makeBranch(cond));
10465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
10475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
10485f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump branchMul32(Condition cond, RegisterID src, RegisterID dest)
10495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1050dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        ASSERT_UNUSED(cond, cond == Overflow);
10515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.smull(dest, dataTempRegister, dest, src);
10525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.asr(addressTempRegister, dest, 31);
10535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branch32(NotEqual, addressTempRegister, dataTempRegister);
10545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
10555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
10562bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branchMul32(Condition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
10575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1058dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        ASSERT_UNUSED(cond, cond == Overflow);
10595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        move(imm, dataTempRegister);
10605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.smull(dest, dataTempRegister, src, dataTempRegister);
10615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.asr(addressTempRegister, dest, 31);
10625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branch32(NotEqual, addressTempRegister, dataTempRegister);
10635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
10645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1065ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    Jump branchOr32(Condition cond, RegisterID src, RegisterID dest)
1066ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
1067ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
1068ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        m_assembler.orr_S(dest, dest, src);
1069ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        return Jump(makeBranch(cond));
1070ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
1071ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
10725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Jump branchSub32(Condition cond, RegisterID src, RegisterID dest)
10735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
10745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
10755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.sub_S(dest, dest, src);
10765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Jump(makeBranch(cond));
10775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
10785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
10792bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branchSub32(Condition cond, TrustedImm32 imm, RegisterID dest)
10805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
10815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
10825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
10835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (armImm.isValid())
10845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.sub_S(dest, dest, armImm);
10855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
10865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            move(imm, dataTempRegister);
10875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.sub_S(dest, dest, dataTempRegister);
10885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
10895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return Jump(makeBranch(cond));
10905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
10915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
10924576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    void relativeTableJump(RegisterID index, int scale)
10934576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    {
10944576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        ASSERT(scale >= 0 && scale <= 31);
10954576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
10964576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        // dataTempRegister will point after the jump if index register contains zero
10974576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        move(ARMRegisters::pc, dataTempRegister);
10984576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        m_assembler.add(dataTempRegister, dataTempRegister, ARMThumbImmediate::makeEncodedImm(9));
10994576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang
11004576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        ShiftTypeAndAmount shift(SRType_LSL, scale);
11014576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        m_assembler.add(dataTempRegister, dataTempRegister, index, shift);
11024576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang        jump(dataTempRegister);
11034576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang    }
11045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
11055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Miscellaneous operations:
11065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
11075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void breakpoint()
11085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1109dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        m_assembler.bkpt(0);
11105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
11115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
11125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Call nearCall()
11135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
11142bde8e466a4451c7319e3a072d118917957d6554Steve Block        moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
1115a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::LinkableNear);
11165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
11175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
11185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Call call()
11195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
11202bde8e466a4451c7319e3a072d118917957d6554Steve Block        moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
1121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::Linkable);
11225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
11235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
11245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Call call(RegisterID target)
11255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1126a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return Call(m_assembler.blx(target, ARMv7Assembler::JumpFixed), Call::None);
11275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
11285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
11295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Call call(Address address)
11305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
11315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(address, dataTempRegister);
1132a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::None);
11335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
11345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
11355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void ret()
11365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1137a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        m_assembler.bx(linkRegister, ARMv7Assembler::JumpFixed);
11385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
11395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1140f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    void set32Compare32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
11415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
11425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.cmp(left, right);
11435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.it(armV7Condition(cond), false);
11445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1));
11455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
11465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
11475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1148f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    void set32Compare32(Condition cond, Address left, RegisterID right, RegisterID dest)
1149ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
1150ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block        load32(left, dataTempRegister);
1151f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        set32Compare32(cond, dataTempRegister, right, dest);
1152ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
1153ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
11542bde8e466a4451c7319e3a072d118917957d6554Steve Block    void set32Compare32(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
11555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
11565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        compare32(left, right);
11575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.it(armV7Condition(cond), false);
11585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1));
11595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
11605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
11615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1162f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    void set8Compare32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
1163ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
1164f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        set32Compare32(cond, left, right, dest);
1165ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
1166ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
1167f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    void set8Compare32(Condition cond, Address left, RegisterID right, RegisterID dest)
1168ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
1169f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        set32Compare32(cond, left, right, dest);
1170ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
1171ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
11722bde8e466a4451c7319e3a072d118917957d6554Steve Block    void set8Compare32(Condition cond, RegisterID left, TrustedImm32 right, RegisterID dest)
1173ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    {
1174f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch        set32Compare32(cond, left, right, dest);
1175ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block    }
1176ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block
11775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // FIXME:
11785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // The mask should be optional... paerhaps the argument order should be
11795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // dest-src, operations always have a dest? ... possibly not true, considering
11805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // asm ops like test, or pseudo ops like pop().
11812bde8e466a4451c7319e3a072d118917957d6554Steve Block    void set32Test32(Condition cond, Address address, TrustedImm32 mask, RegisterID dest)
11825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
11835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(address, dataTempRegister);
11845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        test32(dataTempRegister, mask);
11855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.it(armV7Condition(cond), false);
11865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1));
11875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
11885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
11895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
11902bde8e466a4451c7319e3a072d118917957d6554Steve Block    void set32Test8(Condition cond, Address address, TrustedImm32 mask, RegisterID dest)
1191dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    {
1192dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        load8(address, dataTempRegister);
1193dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        test32(dataTempRegister, mask);
1194dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_assembler.it(armV7Condition(cond), false);
1195dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(1));
1196dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
1197dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    }
11985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
11992bde8e466a4451c7319e3a072d118917957d6554Steve Block    DataLabel32 moveWithPatch(TrustedImm32 imm, RegisterID dst)
12005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
12015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        moveFixedWidthEncoding(imm, dst);
12025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return DataLabel32(this);
12035f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
12045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12052bde8e466a4451c7319e3a072d118917957d6554Steve Block    DataLabelPtr moveWithPatch(TrustedImmPtr imm, RegisterID dst)
12065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
12072bde8e466a4451c7319e3a072d118917957d6554Steve Block        moveFixedWidthEncoding(TrustedImm32(imm), dst);
12085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return DataLabelPtr(this);
12095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
12105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12112bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
12125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
12135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        dataLabel = moveWithPatch(initialRightValue, dataTempRegister);
12145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branch32(cond, left, dataTempRegister);
12155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
12165f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12172bde8e466a4451c7319e3a072d118917957d6554Steve Block    Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, TrustedImmPtr initialRightValue = TrustedImmPtr(0))
12185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
12195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        load32(left, addressTempRegister);
12205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        dataLabel = moveWithPatch(initialRightValue, dataTempRegister);
12215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return branch32(cond, addressTempRegister, dataTempRegister);
12225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
12235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12242bde8e466a4451c7319e3a072d118917957d6554Steve Block    DataLabelPtr storePtrWithPatch(TrustedImmPtr initialValue, ImplicitAddress address)
12255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
12265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        DataLabelPtr label = moveWithPatch(initialValue, dataTempRegister);
12275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        store32(dataTempRegister, address);
12285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return label;
12295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
12302bde8e466a4451c7319e3a072d118917957d6554Steve Block    DataLabelPtr storePtrWithPatch(ImplicitAddress address) { return storePtrWithPatch(TrustedImmPtr(0), address); }
12315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Call tailRecursiveCall()
12345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
12355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        // Like a normal call, but don't link.
12362bde8e466a4451c7319e3a072d118917957d6554Steve Block        moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
1237a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return Call(m_assembler.bx(dataTempRegister, ARMv7Assembler::JumpFixed), Call::Linkable);
12385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
12395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    Call makeTailRecursiveCall(Jump oldJump)
12415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
12425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        oldJump.link(this);
12435f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return tailRecursiveCall();
12445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
12455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
1246dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
1247dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    int executableOffsetFor(int location)
1248dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
1249dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        return m_assembler.executableOffsetFor(location);
1250dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
12515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12525f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianprotected:
1253dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool inUninterruptedSequence()
1254dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    {
1255dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch        return m_inUninterruptedSequence;
1256dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    }
1257dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
12585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ARMv7Assembler::JmpSrc makeJump()
12595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
12602bde8e466a4451c7319e3a072d118917957d6554Steve Block        moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
1261a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpNoConditionFixedSize : ARMv7Assembler::JumpNoCondition);
12625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
12635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ARMv7Assembler::JmpSrc makeBranch(ARMv7Assembler::Condition cond)
12655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
1266cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block        m_assembler.it(cond, true, true);
12672bde8e466a4451c7319e3a072d118917957d6554Steve Block        moveFixedWidthEncoding(TrustedImm32(0), dataTempRegister);
1268a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpConditionFixedSize : ARMv7Assembler::JumpCondition, cond);
12695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
12705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ARMv7Assembler::JmpSrc makeBranch(Condition cond) { return makeBranch(armV7Condition(cond)); }
12715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ARMv7Assembler::JmpSrc makeBranch(DoubleCondition cond) { return makeBranch(armV7Condition(cond)); }
12725f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12735f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ArmAddress setupArmAddress(BaseIndex address)
12745f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
12755f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (address.offset) {
12765f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            ARMThumbImmediate imm = ARMThumbImmediate::makeUInt12OrEncodedImm(address.offset);
12775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            if (imm.isValid())
12785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                m_assembler.add(addressTempRegister, address.base, imm);
12795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            else {
12802bde8e466a4451c7319e3a072d118917957d6554Steve Block                move(TrustedImm32(address.offset), addressTempRegister);
12815f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian                m_assembler.add(addressTempRegister, addressTempRegister, address.base);
12825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            }
12835f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12845f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return ArmAddress(addressTempRegister, address.index, address.scale);
12855f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        } else
12865f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return ArmAddress(address.base, address.index, address.scale);
12875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
12885f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12895f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ArmAddress setupArmAddress(Address address)
12905f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
12915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if ((address.offset >= -0xff) && (address.offset <= 0xfff))
12925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return ArmAddress(address.base, address.offset);
12935f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12942bde8e466a4451c7319e3a072d118917957d6554Steve Block        move(TrustedImm32(address.offset), addressTempRegister);
12955f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return ArmAddress(address.base, addressTempRegister);
12965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
12975f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
12985f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ArmAddress setupArmAddress(ImplicitAddress address)
12995f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
13005f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if ((address.offset >= -0xff) && (address.offset <= 0xfff))
13015f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return ArmAddress(address.base, address.offset);
13025f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13032bde8e466a4451c7319e3a072d118917957d6554Steve Block        move(TrustedImm32(address.offset), addressTempRegister);
13045f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return ArmAddress(address.base, addressTempRegister);
13055f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
13065f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    RegisterID makeBaseIndexBase(BaseIndex address)
13085f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
13095f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (!address.offset)
13105f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            return address.base;
13115f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13125f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        ARMThumbImmediate imm = ARMThumbImmediate::makeUInt12OrEncodedImm(address.offset);
13135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        if (imm.isValid())
13145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.add(addressTempRegister, address.base, imm);
13155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        else {
13162bde8e466a4451c7319e3a072d118917957d6554Steve Block            move(TrustedImm32(address.offset), addressTempRegister);
13175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian            m_assembler.add(addressTempRegister, addressTempRegister, address.base);
13185f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        }
13195f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13205f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return addressTempRegister;
13215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
13225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13232bde8e466a4451c7319e3a072d118917957d6554Steve Block    void moveFixedWidthEncoding(TrustedImm32 imm, RegisterID dst)
13245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
13255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        uint32_t value = imm.m_value;
13265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.movT3(dst, ARMThumbImmediate::makeUInt16(value & 0xffff));
13275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        m_assembler.movt(dst, ARMThumbImmediate::makeUInt16(value >> 16));
13285f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
13295f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13305f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ARMv7Assembler::Condition armV7Condition(Condition cond)
13315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
13325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return static_cast<ARMv7Assembler::Condition>(cond);
13335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
13345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    ARMv7Assembler::Condition armV7Condition(DoubleCondition cond)
13365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    {
13375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian        return static_cast<ARMv7Assembler::Condition>(cond);
13385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    }
13390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
13400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochprivate:
13410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    friend class LinkBuffer;
13420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    friend class RepatchBuffer;
13430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
13440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    static void linkCall(void* code, Call call, FunctionPtr function)
13450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
13460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ARMv7Assembler::linkCall(code, call.m_jmp, function.value());
13470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
13480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
13490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
13500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
13510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
13520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
13530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
13540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    static void repatchCall(CodeLocationCall call, FunctionPtr destination)
13550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    {
13560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress());
13570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1358dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
1359dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch    bool m_inUninterruptedSequence;
13605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian};
13615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} // namespace JSC
13635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif // ENABLE(ASSEMBLER)
13655f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
13665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#endif // MacroAssemblerARMv7_h
1367