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