assembler_arm.cc revision b5d09b2f87202bc132ac3991d4b6d71f4f6d9264
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#include "assembler_arm.h" 182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 19578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "logging.h" 20578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "offsets.h" 21e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro#include "thread.h" 22578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "utils.h" 23a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 246b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapironamespace art { 252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersnamespace arm { 26a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 27a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Instruction encoding bits. 28a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroenum { 29a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro H = 1 << 5, // halfword (or byte) 30a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro L = 1 << 20, // load (or store) 31a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro S = 1 << 20, // set condition code (or leave unchanged) 32a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro W = 1 << 21, // writeback base register (or leave unchanged) 33a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro A = 1 << 21, // accumulate in multiply instruction (or not) 34a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B = 1 << 22, // unsigned byte (or word) 35a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro N = 1 << 22, // long (or short) 36a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro U = 1 << 23, // positive (or negative) offset/index 37a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing) 38a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro I = 1 << 25, // immediate shifter operand (or not) 39a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 40a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B0 = 1, 41a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B1 = 1 << 1, 42a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B2 = 1 << 2, 43a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B3 = 1 << 3, 44a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B4 = 1 << 4, 45a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B5 = 1 << 5, 46a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B6 = 1 << 6, 47a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B7 = 1 << 7, 48a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B8 = 1 << 8, 49a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B9 = 1 << 9, 50a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B10 = 1 << 10, 51a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 = 1 << 11, 52a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B12 = 1 << 12, 53a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B16 = 1 << 16, 54a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B17 = 1 << 17, 55a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B18 = 1 << 18, 56a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B19 = 1 << 19, 57a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B20 = 1 << 20, 58a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B21 = 1 << 21, 59a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B22 = 1 << 22, 60a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B23 = 1 << 23, 61a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 = 1 << 24, 62a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 = 1 << 25, 63a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B26 = 1 << 26, 64a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 = 1 << 27, 65a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 66a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Instruction bit masks. 67a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro RdMask = 15 << 12, // in str instruction 68a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CondMask = 15 << 28, 69a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CoprocessorMask = 15 << 8, 70a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro OpCodeMask = 15 << 21, // in data-processing instructions 71a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Imm24Mask = (1 << 24) - 1, 72a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Off12Mask = (1 << 12) - 1, 73a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 74a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // ldrex/strex register field encodings. 75a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kLdExRnShift = 16, 76a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kLdExRtShift = 12, 77a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kStrExRnShift = 16, 78a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kStrExRdShift = 12, 79a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kStrExRtShift = 0, 80a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}; 81a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 82a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 831f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kRegisterNames[] = { 841f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 851f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes "fp", "ip", "sp", "lr", "pc" 861f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}; 871f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Register& rhs) { 881f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= R0 && rhs <= PC) { 891f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes os << kRegisterNames[rhs]; 901f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "Register[" << static_cast<int>(rhs) << "]"; 921f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 931f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 941f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 951f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 961f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 971f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const SRegister& rhs) { 981f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= S0 && rhs < kNumberOfSRegisters) { 99b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "s" << static_cast<int>(rhs); 1001f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "SRegister[" << static_cast<int>(rhs) << "]"; 1021f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 1031f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 1041f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 1051f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 1061f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 1071f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const DRegister& rhs) { 1081f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= D0 && rhs < kNumberOfDRegisters) { 109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "d" << static_cast<int>(rhs); 1101f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "DRegister[" << static_cast<int>(rhs) << "]"; 1121f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 1131f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 1141f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 1151f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 1161f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 1171f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kConditionNames[] = { 118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", 119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers "LE", "AL", 1201f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}; 1211f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Condition& rhs) { 1221f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= EQ && rhs <= AL) { 1231f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes os << kConditionNames[rhs]; 1241f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "Condition[" << static_cast<int>(rhs) << "]"; 1261f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 1271f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 1281f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 1291f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 1302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Emit(int32_t value) { 131a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro AssemblerBuffer::EnsureCapacity ensured(&buffer_); 132a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro buffer_.Emit<int32_t>(value); 133a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 134a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 135a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitType01(Condition cond, 1372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers int type, 1382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Opcode opcode, 1392c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers int set_cc, 1402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rn, 1412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rd, 1422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ShifterOperand so) { 143a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 144a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 145a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 146a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro type << kTypeShift | 147a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(opcode) << kOpcodeShift | 148a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro set_cc << kSShift | 149a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rn) << kRnShift | 150a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | 151a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro so.encoding(); 152a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 153a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 154a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 155a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitType5(Condition cond, int offset, bool link) { 157a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 158a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 159a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5 << kTypeShift | 160a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (link ? 1 : 0) << kLinkShift; 1612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Emit(ArmAssembler::EncodeBranchOffset(offset, encoding)); 162a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 163a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 164a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMemOp(Condition cond, 1662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers bool load, 1672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers bool byte, 1682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rd, 1692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Address ad) { 170a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 171a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 172a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 173a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B26 | 174a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (load ? L : 0) | 175a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (byte ? B : 0) | 176a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 177a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ad.encoding(); 178a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 179a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 180a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 181a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMemOpAddressMode3(Condition cond, 1832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers int32_t mode, 1842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rd, 1852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Address ad) { 186a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 187a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 188a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 189a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B22 | 190a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro mode | 191a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 192a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ad.encoding3(); 193a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 194a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 195a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 196a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1972c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMultiMemOp(Condition cond, 1982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers BlockAddressMode am, 1992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers bool load, 2002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register base, 2012c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers RegList regs) { 202a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(base, kNoRegister); 203a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 204a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 205a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | 206a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro am | 207a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (load ? L : 0) | 208a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(base) << kRnShift) | 209a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro regs; 210a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 211a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 212a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 213a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 2142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitShiftImmediate(Condition cond, 2152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Shift opcode, 2162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rd, 2172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rm, 2182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ShifterOperand so) { 219a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 2201f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes CHECK_EQ(so.type(), 1U); 221a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 222a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(MOV) << kOpcodeShift | 223a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | 224a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro so.encoding() << kShiftImmShift | 225a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(opcode) << kShiftShift | 226a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rm); 227a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 228a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 229a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 230a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 2312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitShiftRegister(Condition cond, 2322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Shift opcode, 2332c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rd, 2342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rm, 2352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ShifterOperand so) { 236a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 2371f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes CHECK_EQ(so.type(), 0U); 238a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 239a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(MOV) << kOpcodeShift | 240a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | 241a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro so.encoding() << kShiftRegisterShift | 242a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(opcode) << kShiftShift | 243a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B4 | 244a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rm); 245a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 246a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 247a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 248a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 2492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitBranch(Condition cond, Label* label, bool link) { 250a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro if (label->IsBound()) { 251a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType5(cond, label->Position() - buffer_.Size(), link); 252a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } else { 253a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int position = buffer_.Size(); 254a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Use the offset field of the branch instruction for linking the sites. 255a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType5(cond, label->position_, link); 256a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro label->LinkTo(position); 257a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 258a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 259a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 2602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::and_(Register rd, Register rn, ShifterOperand so, 2612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 262a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), AND, 0, rn, rd, so); 263a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 264a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 265a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 2662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::eor(Register rd, Register rn, ShifterOperand so, 2672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 268a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), EOR, 0, rn, rd, so); 269a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 270a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 271a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 2722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::sub(Register rd, Register rn, ShifterOperand so, 2732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 274a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), SUB, 0, rn, rd, so); 275a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 276a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 2772c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::rsb(Register rd, Register rn, ShifterOperand so, 2782c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 279a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), RSB, 0, rn, rd, so); 280a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 281a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 2822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::rsbs(Register rd, Register rn, ShifterOperand so, 2832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 284a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), RSB, 1, rn, rd, so); 285a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 286a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 287a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 2882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::add(Register rd, Register rn, ShifterOperand so, 2892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 290a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ADD, 0, rn, rd, so); 291a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 292a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 293a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 2942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::adds(Register rd, Register rn, ShifterOperand so, 2952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 296a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ADD, 1, rn, rd, so); 297a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 298a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 299a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::subs(Register rd, Register rn, ShifterOperand so, 3012c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 302a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), SUB, 1, rn, rd, so); 303a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 304a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 305a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::adc(Register rd, Register rn, ShifterOperand so, 3072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 308a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ADC, 0, rn, rd, so); 309a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 310a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 311a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3122c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::sbc(Register rd, Register rn, ShifterOperand so, 3132c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 314a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), SBC, 0, rn, rd, so); 315a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 316a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 317a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::rsc(Register rd, Register rn, ShifterOperand so, 3192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 320a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), RSC, 0, rn, rd, so); 321a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 322a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 323a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::tst(Register rn, ShifterOperand so, Condition cond) { 325a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, PC); // Reserve tst pc instruction for exception handler marker. 326a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), TST, 1, rn, R0, so); 327a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 328a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 329a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::teq(Register rn, ShifterOperand so, Condition cond) { 331a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, PC); // Reserve teq pc instruction for exception handler marker. 332a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), TEQ, 1, rn, R0, so); 333a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 334a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 335a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::cmp(Register rn, ShifterOperand so, Condition cond) { 337a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), CMP, 1, rn, R0, so); 338a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 339a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 340a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::cmn(Register rn, ShifterOperand so, Condition cond) { 342a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), CMN, 1, rn, R0, so); 343a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 344a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 345a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3462c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::orr(Register rd, Register rn, 347a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ShifterOperand so, Condition cond) { 348a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ORR, 0, rn, rd, so); 349a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 350a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 351a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3522c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::orrs(Register rd, Register rn, 3532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ShifterOperand so, Condition cond) { 354a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ORR, 1, rn, rd, so); 355a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 356a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 357a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3582c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mov(Register rd, ShifterOperand so, Condition cond) { 359a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MOV, 0, R0, rd, so); 360a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 361a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 362a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::movs(Register rd, ShifterOperand so, Condition cond) { 364a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MOV, 1, R0, rd, so); 365a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 366a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 367a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::bic(Register rd, Register rn, ShifterOperand so, 3692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 370a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), BIC, 0, rn, rd, so); 371a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 372a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 373a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mvn(Register rd, ShifterOperand so, Condition cond) { 375a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MVN, 0, R0, rd, so); 376a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 377a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 378a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mvns(Register rd, ShifterOperand so, Condition cond) { 380a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MVN, 1, R0, rd, so); 381a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 382a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 383a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::clz(Register rd, Register rm, Condition cond) { 385a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 386a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, kNoRegister); 387a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 388a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, PC); 389a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, PC); 390a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 391a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | B22 | B21 | (0xf << 16) | 392a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 393a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (0xf << 8) | B4 | static_cast<int32_t>(rm); 394a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 395a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 396a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 397a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 3982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::movw(Register rd, uint16_t imm16, Condition cond) { 399a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 400a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 401a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 | B24 | ((imm16 >> 12) << 16) | 402a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 403a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 404a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 405a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 406a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::movt(Register rd, uint16_t imm16, Condition cond) { 408a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 409a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 410a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 | B24 | B22 | ((imm16 >> 12) << 16) | 411a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 412a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 413a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 414a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 415a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitMulOp(Condition cond, int32_t opcode, 4172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rd, Register rn, 4182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rm, Register rs) { 419a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 420a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, kNoRegister); 421a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, kNoRegister); 422a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rs, kNoRegister); 423a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 424a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = opcode | 425a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(cond) << kConditionShift) | 426a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rn) << kRnShift) | 427a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 428a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rs) << kRsShift) | 429a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B7 | B4 | 430a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rm) << kRmShift); 431a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 432a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 433a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 434a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mul(Register rd, Register rn, Register rm, Condition cond) { 436a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 437a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, 0, R0, rd, rn, rm); 438a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 439a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 440a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mla(Register rd, Register rn, Register rm, Register ra, 4422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 443a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 444a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, B21, ra, rd, rn, rm); 445a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 446a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 447a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::mls(Register rd, Register rn, Register rm, Register ra, 4492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 450a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 451a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); 452a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 453a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 454a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::umull(Register rd_lo, Register rd_hi, Register rn, 4562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rm, Condition cond) { 457a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 458a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm); 459a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 460a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 461a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldr(Register rd, Address ad, Condition cond) { 463a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, true, false, rd, ad); 464a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 465a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 466a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::str(Register rd, Address ad, Condition cond) { 468a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, false, false, rd, ad); 469a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 470a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 471a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrb(Register rd, Address ad, Condition cond) { 473a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, true, true, rd, ad); 474a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 475a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 476a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4772c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strb(Register rd, Address ad, Condition cond) { 478a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, false, true, rd, ad); 479a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 480a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 481a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrh(Register rd, Address ad, Condition cond) { 483a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad); 484a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 485a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 486a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strh(Register rd, Address ad, Condition cond) { 488a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad); 489a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 490a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 491a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4922c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrsb(Register rd, Address ad, Condition cond) { 493a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad); 494a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 495a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 496a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 4972c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrsh(Register rd, Address ad, Condition cond) { 498a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad); 499a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 500a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 501a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5022c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrd(Register rd, Address ad, Condition cond) { 503a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_EQ(rd % 2, 0); 504a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad); 505a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 506a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 507a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5082c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strd(Register rd, Address ad, Condition cond) { 509a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_EQ(rd % 2, 0); 510a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad); 511a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 512a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 513a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldm(BlockAddressMode am, 5152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register base, 5162c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers RegList regs, 5172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 518a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMultiMemOp(cond, am, true, base, regs); 519a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 520a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 521a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::stm(BlockAddressMode am, 5232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register base, 5242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers RegList regs, 5252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 526a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMultiMemOp(cond, am, false, base, regs); 527a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 528a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 529a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ldrex(Register rt, Register rn, Condition cond) { 531a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, kNoRegister); 532a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 533a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 534a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 535a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | 536a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B23 | 537a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro L | 538a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rn) << kLdExRnShift) | 539a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt) << kLdExRtShift) | 540a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0; 541a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 542a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 543a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 544a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5452c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::strex(Register rd, 5462c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rt, 5472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register rn, 5482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 549a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, kNoRegister); 550a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 551a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 552a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 553a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 554a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | 555a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B23 | 556a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rn) << kStrExRnShift) | 557a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kStrExRdShift) | 558a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B10 | B9 | B8 | B7 | B4 | 559a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt) << kStrExRtShift); 560a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 561a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 562a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 563a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::clrex() { 565a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (kSpecialCondition << kConditionShift) | 566a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf; 567a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 568a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 569a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 570a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::nop(Condition cond) { 572a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 573a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 574a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 | B24 | B21 | (0xf << 12); 575a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 576a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 577a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 578a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovsr(SRegister sn, Register rt, Condition cond) { 580a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sn, kNoSRegister); 581a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 582a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 583a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 584a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 585a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 586a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | 587a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) >> 1)*B16) | 588a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 589a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) & 1)*B7) | B4; 590a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 591a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 592a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 593a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovrs(Register rt, SRegister sn, Condition cond) { 595a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sn, kNoSRegister); 596a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 597a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 598a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 599a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 600a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 601a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B20 | 602a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) >> 1)*B16) | 603a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 604a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) & 1)*B7) | B4; 605a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 606a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 607a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 608a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 6092c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovsrr(SRegister sm, Register rt, Register rt2, 6102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 611a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 612a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, S31); 613a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 614a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 615a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 616a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 617a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 618a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 619a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 620a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 621a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | 622a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 623a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 624a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 625a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 626a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 627a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 628a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 629a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 6302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovrrs(Register rt, Register rt2, SRegister sm, 6312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 632a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 633a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, S31); 634a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 635a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 636a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 637a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 638a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 639a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 640a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, rt2); 641a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 642a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 643a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | B20 | 644a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 645a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 646a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 647a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 648a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 649a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 650a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 651a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 6522c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovdrr(DRegister dm, Register rt, Register rt2, 6532c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 654a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 655a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 656a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 657a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 658a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 659a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 660a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 661a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 662a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 663a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | 664a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 665a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 666a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 667a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 668a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 669a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 670a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 671a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 6722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovrrd(Register rt, Register rt2, DRegister dm, 6732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 674a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 675a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 676a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 677a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 678a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 679a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 680a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 681a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, rt2); 682a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 683a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 684a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | B20 | 685a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 686a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 687a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 688a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 689a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 690a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 691a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 692a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 6932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vldrs(SRegister sd, Address ad, Condition cond) { 694a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 695a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 696a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 697a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | B20 | 698a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 699a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 700a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | ad.vencoding(); 701a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 702a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 703a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 704a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 7052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vstrs(SRegister sd, Address ad, Condition cond) { 706a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC); 707a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 708a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 709a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 710a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | 711a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 712a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 713a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | ad.vencoding(); 714a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 715a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 716a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 717a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 7182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vldrd(DRegister dd, Address ad, Condition cond) { 719a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 720a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 721a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 722a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | B20 | 723a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 724a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 725a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | B8 | ad.vencoding(); 726a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 727a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 728a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 729a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 7302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vstrd(DRegister dd, Address ad, Condition cond) { 731a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC); 732a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 733a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 734a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 735a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | 736a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 737a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 738a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | B8 | ad.vencoding(); 739a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 740a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 741a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 742a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 7432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPsss(Condition cond, int32_t opcode, 7442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers SRegister sd, SRegister sn, SRegister sm) { 745a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 746a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sn, kNoSRegister); 747a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 748a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 749a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 750a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | opcode | 751a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 752a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) >> 1)*B16) | 753a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 754a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) & 1)*B7) | 755a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | 756a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 757a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 758a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 759a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 760a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 7612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPddd(Condition cond, int32_t opcode, 7622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers DRegister dd, DRegister dn, DRegister dm) { 763a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 764a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dn, kNoDRegister); 765a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 766a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 767a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 768a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | B8 | opcode | 769a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 770a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dn) & 0xf)*B16) | 771a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 772a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dn) >> 4)*B7) | 773a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | 774a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 775a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 776a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 777a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 778a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 7792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovs(SRegister sd, SRegister sm, Condition cond) { 780a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm); 781a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 782a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 783a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 7842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmovd(DRegister dd, DRegister dm, Condition cond) { 785a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm); 786a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 787a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 788a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 7892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool ArmAssembler::vmovs(SRegister sd, float s_imm, Condition cond) { 790a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint32_t imm32 = bit_cast<uint32_t, float>(s_imm); 791a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro if (((imm32 & ((1 << 19) - 1)) == 0) && 792a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) || 793a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) { 794a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) | 795a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((imm32 >> 19) & ((1 << 6) -1)); 796a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf), 797a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro sd, S0, S0); 798a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return true; 799a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 800a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return false; 801a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 802a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 803a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8042c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersbool ArmAssembler::vmovd(DRegister dd, double d_imm, Condition cond) { 805a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint64_t imm64 = bit_cast<uint64_t, double>(d_imm); 806a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro if (((imm64 & ((1LL << 48) - 1)) == 0) && 807a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) || 808a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) { 809a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) | 810a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((imm64 >> 48) & ((1 << 6) -1)); 811a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf), 812a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro dd, D0, D0); 813a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return true; 814a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 815a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return false; 816a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 817a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 818a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vadds(SRegister sd, SRegister sn, SRegister sm, 8202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 821a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B21 | B20, sd, sn, sm); 822a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 823a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 824a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vaddd(DRegister dd, DRegister dn, DRegister dm, 8262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 827a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B21 | B20, dd, dn, dm); 828a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 829a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 830a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8312c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsubs(SRegister sd, SRegister sn, SRegister sm, 8322c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 833a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm); 834a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 835a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 836a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsubd(DRegister dd, DRegister dn, DRegister dm, 8382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 839a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm); 840a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 841a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 842a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmuls(SRegister sd, SRegister sn, SRegister sm, 8442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 845a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B21, sd, sn, sm); 846a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 847a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 848a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmuld(DRegister dd, DRegister dn, DRegister dm, 8502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 851a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B21, dd, dn, dm); 852a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 853a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 854a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlas(SRegister sd, SRegister sn, SRegister sm, 8562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 857a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, 0, sd, sn, sm); 858a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 859a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 860a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlad(DRegister dd, DRegister dn, DRegister dm, 8622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 863a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, 0, dd, dn, dm); 864a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 865a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 866a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlss(SRegister sd, SRegister sn, SRegister sm, 8682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 869a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B6, sd, sn, sm); 870a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 871a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 872a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmlsd(DRegister dd, DRegister dn, DRegister dm, 8742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 875a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B6, dd, dn, dm); 876a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 877a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 878a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vdivs(SRegister sd, SRegister sn, SRegister sm, 8802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 881a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23, sd, sn, sm); 882a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 883a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 884a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vdivd(DRegister dd, DRegister dn, DRegister dm, 8862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 887a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23, dd, dn, dm); 888a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 889a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 890a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vabss(SRegister sd, SRegister sm, Condition cond) { 892a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm); 893a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 894a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 895a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 8962c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vabsd(DRegister dd, DRegister dm, Condition cond) { 897a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm); 898a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 899a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 900a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9012c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vnegs(SRegister sd, SRegister sm, Condition cond) { 902a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm); 903a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 904a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 905a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vnegd(DRegister dd, DRegister dm, Condition cond) { 907a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm); 908a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 909a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 910a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9112c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsqrts(SRegister sd, SRegister sm, Condition cond) { 912a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm); 913a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 914a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) { 916a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm); 917a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 918a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 919a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPsd(Condition cond, int32_t opcode, 9212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers SRegister sd, DRegister dm) { 922a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 923a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 924a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 925a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 926a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | opcode | 927a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 928a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 929a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | 930a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 931a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 932a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 933a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 934a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EmitVFPds(Condition cond, int32_t opcode, 9362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers DRegister dd, SRegister sm) { 937a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 938a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 939a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 940a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 941a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | opcode | 942a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 943a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 944a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | 945a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 946a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 947a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 948a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 949a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) { 951a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm); 952a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 953a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 954a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtds(DRegister dd, SRegister sm, Condition cond) { 956a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm); 957a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 958a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 959a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtis(SRegister sd, SRegister sm, Condition cond) { 961a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm); 962a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 963a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 964a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtid(SRegister sd, DRegister dm, Condition cond) { 966a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm); 967a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 968a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 969a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) { 971a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm); 972a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 973a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 974a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9752c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) { 976a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm); 977a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 978a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 979a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtus(SRegister sd, SRegister sm, Condition cond) { 981a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm); 982a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 983a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 984a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtud(SRegister sd, DRegister dm, Condition cond) { 986a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm); 987a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 988a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 989a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) { 991a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm); 992a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 993a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 994a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 9952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) { 996a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm); 997a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 998a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 999a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10002c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmps(SRegister sd, SRegister sm, Condition cond) { 1001a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm); 1002a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1003a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1004a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmpd(DRegister dd, DRegister dm, Condition cond) { 1006a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm); 1007a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1008a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1009a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmpsz(SRegister sd, Condition cond) { 1011a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0); 1012a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1013a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1014a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vcmpdz(DRegister dd, Condition cond) { 1016a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0); 1017a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1018a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1019a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::vmstat(Condition cond) { // VMRS APSR_nzcv, FPSCR 1021a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 1022a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1023a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | 1024a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(PC)*B12) | 1025a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | B4; 1026a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1027a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1028a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1029a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::svc(uint32_t imm24) { 1031a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK(IsUint(24, imm24)); 1032a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24; 1033a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1034a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1035a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1036a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::bkpt(uint16_t imm16) { 1038a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (AL << kConditionShift) | B24 | B21 | 1039a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); 1040a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1041a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1042a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1043a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10442c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::b(Label* label, Condition cond) { 1045a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitBranch(cond, label, false); 1046a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1047a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1048a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::bl(Label* label, Condition cond) { 1050a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitBranch(cond, label, true); 1051a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1052a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1053a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10542c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::blx(Register rm, Condition cond) { 1055a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, kNoRegister); 1056a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 1057a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1058a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | B21 | (0xfff << 8) | B5 | B4 | 1059a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rm) << kRmShift); 1060a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1061a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1062a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1063ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogersvoid ArmAssembler::bx(Register rm, Condition cond) { 1064ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers CHECK_NE(rm, kNoRegister); 1065ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers CHECK_NE(cond, kNoCondition); 1066ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1067ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers B24 | B21 | (0xfff << 8) | B4 | 1068ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers (static_cast<int32_t>(rm) << kRmShift); 1069ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers Emit(encoding); 1070ae67599981e17cdfd51418c35e56e2a7c5ef4c72Ian Rogers} 1071a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::MarkExceptionHandler(Label* label) { 1073a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); 1074a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Label l; 1075a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro b(&l); 1076a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitBranch(AL, label, false); 1077a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Bind(&l); 1078a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1079a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1080a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10812c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Bind(Label* label) { 1082a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK(!label->IsBound()); 1083a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int bound_pc = buffer_.Size(); 1084a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro while (label->IsLinked()) { 1085a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t position = label->Position(); 1086a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t next = buffer_.Load<int32_t>(position); 10872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers int32_t encoded = ArmAssembler::EncodeBranchOffset(bound_pc - position, next); 1088a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro buffer_.Store<int32_t>(position, encoded); 10892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers label->position_ = ArmAssembler::DecodeBranchOffset(next); 1090a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 1091a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro label->BindTo(bound_pc); 1092a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1093a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1094a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 10952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::EncodeUint32InTstInstructions(uint32_t data) { 1096a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // TODO: Consider using movw ip, <16 bits>. 1097a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro while (!IsUint(8, data)) { 1098a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro tst(R0, ShifterOperand(data & 0xFF), VS); 1099a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro data >>= 8; 1100a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 1101a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro tst(R0, ShifterOperand(data), MI); 1102a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1103a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1104b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 11052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersint32_t ArmAssembler::EncodeBranchOffset(int offset, int32_t inst) { 1106a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // The offset is off by 8 due to the way the ARM CPUs read PC. 1107a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro offset -= 8; 110806b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes CHECK_ALIGNED(offset, 4); 1109a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK(IsInt(CountOneBits(kBranchOffsetMask), offset)); 1110a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1111a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Properly preserve only the bits supported in the instruction. 1112a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro offset >>= 2; 1113a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro offset &= kBranchOffsetMask; 1114a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return (inst & ~kBranchOffsetMask) | offset; 1115a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1116a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1117a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 11182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersint ArmAssembler::DecodeBranchOffset(int32_t inst) { 1119a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Sign-extend, left-shift by 2, then add 8. 1120a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8); 1121a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1122a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 11232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::AddConstant(Register rd, int32_t value, Condition cond) { 1124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(rd, rd, value, cond); 1125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 11282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::AddConstant(Register rd, Register rn, int32_t value, 11292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 1130b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value == 0) { 1131b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (rd != rn) { 1132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mov(rd, ShifterOperand(rn), cond); 1133b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return; 1135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // We prefer to select the shorter code sequence rather than selecting add for 1137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // positive values and sub for negatives ones, which would slightly improve 1138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // the readability of generated code for some constants. 1139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ShifterOperand shifter_op; 1140b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(value, &shifter_op)) { 1141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(rd, rn, shifter_op, cond); 1142b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(-value, &shifter_op)) { 1143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers sub(rd, rn, shifter_op, cond); 1144b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1145b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(rn != IP); 1146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(~value, &shifter_op)) { 1147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(rd, rn, ShifterOperand(IP), cond); 1149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { 1150b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1151b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers sub(rd, rn, ShifterOperand(IP), cond); 1152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1153b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movw(IP, Low16Bits(value), cond); 1154b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers uint16_t value_high = High16Bits(value); 1155b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value_high != 0) { 1156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movt(IP, value_high, cond); 1157b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1158b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(rd, rn, ShifterOperand(IP), cond); 1159b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1160b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1161b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1162b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1163b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 11642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::AddConstantSetFlags(Register rd, Register rn, int32_t value, 11652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 1166b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ShifterOperand shifter_op; 1167b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(value, &shifter_op)) { 1168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers adds(rd, rn, shifter_op, cond); 1169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(-value, &shifter_op)) { 1170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers subs(rd, rn, shifter_op, cond); 1171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1172b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(rn != IP); 1173b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(~value, &shifter_op)) { 1174b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1175b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers adds(rd, rn, ShifterOperand(IP), cond); 1176b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { 1177b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1178b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers subs(rd, rn, ShifterOperand(IP), cond); 1179b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1180b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movw(IP, Low16Bits(value), cond); 1181b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers uint16_t value_high = High16Bits(value); 1182b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value_high != 0) { 1183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movt(IP, value_high, cond); 1184b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1185b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers adds(rd, rn, ShifterOperand(IP), cond); 1186b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1187b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1188b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1189b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1190b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 11912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadImmediate(Register rd, int32_t value, Condition cond) { 1192b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ShifterOperand shifter_op; 1193b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(value, &shifter_op)) { 1194b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mov(rd, shifter_op, cond); 1195b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(~value, &shifter_op)) { 1196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(rd, shifter_op, cond); 1197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movw(rd, Low16Bits(value), cond); 1199b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers uint16_t value_high = High16Bits(value); 1200b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value_high != 0) { 1201b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movt(rd, value_high, cond); 1202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1204b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1207b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldLoadOffset(LoadOperandType type, int offset) { 1208b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1209b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedByte: 1210b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedHalfword: 1211b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedHalfword: 1212b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWordPair: 1213b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(8, offset); // Addressing mode 3. 1214b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedByte: 1215b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWord: 1216b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(12, offset); // Addressing mode 2. 1217b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSWord: 1218b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadDWord: 1219b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(10, offset); // VFP addressing mode. 1220b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1222b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return false; 1223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1224b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1225b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1226b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1227b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldStoreOffset(StoreOperandType type, int offset) { 1228b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1229b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreHalfword: 1230b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWordPair: 1231b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(8, offset); // Addressing mode 3. 1232b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreByte: 1233b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWord: 1234b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(12, offset); // Addressing mode 2. 1235b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreSWord: 1236b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreDWord: 1237b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(10, offset); // VFP addressing mode. 1238b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1239b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1240b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return false; 1241b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1242b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1243b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1244b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1245b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when 1246b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldLoadOffset. 12472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadFromOffset(LoadOperandType type, 1248b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register reg, 1249b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register base, 1250b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int32_t offset, 1251b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Condition cond) { 1252b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!Address::CanHoldLoadOffset(type, offset)) { 1253b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(base != IP); 1254b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(IP, offset, cond); 1255b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(IP, IP, ShifterOperand(base), cond); 1256b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers base = IP; 1257b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers offset = 0; 1258b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1259b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(Address::CanHoldLoadOffset(type, offset)); 1260b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1261b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedByte: 1262b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrsb(reg, Address(base, offset), cond); 1263b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1264b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedByte: 1265b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrb(reg, Address(base, offset), cond); 1266b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1267b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedHalfword: 1268b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrsh(reg, Address(base, offset), cond); 1269b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1270b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedHalfword: 1271b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrh(reg, Address(base, offset), cond); 1272b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1273b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWord: 1274b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldr(reg, Address(base, offset), cond); 1275b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1276b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWordPair: 1277b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrd(reg, Address(base, offset), cond); 1278b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1279b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1280b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1281b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1282b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1283b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1284e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when 1285e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldLoadOffset, as expected by JIT::GuardedLoadFromOffset. 12862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadSFromOffset(SRegister reg, 12872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register base, 12882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers int32_t offset, 12892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 1290e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (!Address::CanHoldLoadOffset(kLoadSWord, offset)) { 1291e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_NE(base, IP); 1292e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadImmediate(IP, offset, cond); 1293e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro add(IP, IP, ShifterOperand(base), cond); 1294e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro base = IP; 1295e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro offset = 0; 1296e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1297e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(Address::CanHoldLoadOffset(kLoadSWord, offset)); 1298e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro vldrs(reg, Address(base, offset), cond); 1299e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1300e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 1301e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when 1302e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldLoadOffset, as expected by JIT::GuardedLoadFromOffset. 13032c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadDFromOffset(DRegister reg, 13042c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register base, 13052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers int32_t offset, 13062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 1307e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (!Address::CanHoldLoadOffset(kLoadDWord, offset)) { 1308e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_NE(base, IP); 1309e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadImmediate(IP, offset, cond); 1310e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro add(IP, IP, ShifterOperand(base), cond); 1311e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro base = IP; 1312e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro offset = 0; 1313e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1314e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(Address::CanHoldLoadOffset(kLoadDWord, offset)); 1315e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro vldrd(reg, Address(base, offset), cond); 1316e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1317b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1318b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when 1319b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldStoreOffset. 13202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreToOffset(StoreOperandType type, 13212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register reg, 13222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register base, 13232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers int32_t offset, 13242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 1325b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!Address::CanHoldStoreOffset(type, offset)) { 1326b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(reg != IP); 1327b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(base != IP); 1328b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(IP, offset, cond); 1329b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(IP, IP, ShifterOperand(base), cond); 1330b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers base = IP; 1331b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers offset = 0; 1332b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1333b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(Address::CanHoldStoreOffset(type, offset)); 1334b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1335b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreByte: 1336b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers strb(reg, Address(base, offset), cond); 1337b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1338b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreHalfword: 1339b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers strh(reg, Address(base, offset), cond); 1340b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1341b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWord: 1342b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers str(reg, Address(base, offset), cond); 1343b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1344b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWordPair: 1345b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers strd(reg, Address(base, offset), cond); 1346b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1347b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1348b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1349b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1350b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1351b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1352e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when 1353e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldStoreOffset, as expected by JIT::GuardedStoreToOffset. 13542c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreSToOffset(SRegister reg, 13552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register base, 13562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers int32_t offset, 13572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 1358e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (!Address::CanHoldStoreOffset(kStoreSWord, offset)) { 1359e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_NE(base, IP); 1360e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadImmediate(IP, offset, cond); 1361e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro add(IP, IP, ShifterOperand(base), cond); 1362e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro base = IP; 1363e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro offset = 0; 1364e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1365e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(Address::CanHoldStoreOffset(kStoreSWord, offset)); 1366e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro vstrs(reg, Address(base, offset), cond); 1367e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1368e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 1369e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when 1370e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldStoreOffset, as expected by JIT::GuardedStoreSToOffset. 13712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreDToOffset(DRegister reg, 13722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Register base, 13732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers int32_t offset, 13742c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 1375e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (!Address::CanHoldStoreOffset(kStoreDWord, offset)) { 1376e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_NE(base, IP); 1377e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadImmediate(IP, offset, cond); 1378e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro add(IP, IP, ShifterOperand(base), cond); 1379e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro base = IP; 1380e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro offset = 0; 1381e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1382e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(Address::CanHoldStoreOffset(kStoreDWord, offset)); 1383e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro vstrd(reg, Address(base, offset), cond); 1384e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1385e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 13862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Push(Register rd, Condition cond) { 13879b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond); 13889b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 13899b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 13902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Pop(Register rd, Condition cond) { 13919b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond); 13929b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 13939b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 13942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::PushList(RegList regs, Condition cond) { 13959b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro stm(DB_W, SP, regs, cond); 13969b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 13979b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 13982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::PopList(RegList regs, Condition cond) { 13999b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro ldm(IA_W, SP, regs, cond); 14009b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 14019b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 14022c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Mov(Register rd, Register rm, Condition cond) { 14039b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro if (rd != rm) { 14049b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm), cond); 14059b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro } 14069b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 14079b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 14082c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Lsl(Register rd, Register rm, uint32_t shift_imm, 14092c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 14109b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro CHECK_NE(shift_imm, 0u); // Do not use Lsl if no shift is wanted. 14119b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm, LSL, shift_imm), cond); 14129b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 14139b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 14142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Lsr(Register rd, Register rm, uint32_t shift_imm, 14152c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 14169b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro CHECK_NE(shift_imm, 0u); // Do not use Lsr if no shift is wanted. 14179b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. 14189b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm, LSR, shift_imm), cond); 14199b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 14209b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 14212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Asr(Register rd, Register rm, uint32_t shift_imm, 14222c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 14239b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro CHECK_NE(shift_imm, 0u); // Do not use Asr if no shift is wanted. 14249b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. 14259b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm, ASR, shift_imm), cond); 14269b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 14279b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 14282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Ror(Register rd, Register rm, uint32_t shift_imm, 14292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers Condition cond) { 14309b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro CHECK_NE(shift_imm, 0u); // Use Rrx instruction. 14319b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm, ROR, shift_imm), cond); 14329b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 14339b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 14342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Rrx(Register rd, Register rm, Condition cond) { 14359b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm, ROR, 0), cond); 14369b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 14379b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 14382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, 1439b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers const std::vector<ManagedRegister>& callee_save_regs, 1440b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers const std::vector<ManagedRegister>& entry_spills) { 144106b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes CHECK_ALIGNED(frame_size, kStackAlignment); 1442b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogers DCHECK_EQ(entry_spills.size(), 0u); 14432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers CHECK_EQ(R0, method_reg.AsArm().AsCoreRegister()); 1444bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 1445bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Push callee saves and link register 1446bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers RegList push_list = 1 << LR; 1447bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers size_t pushed_values = 1; 1448bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers for (size_t i = 0; i < callee_save_regs.size(); i++) { 1449bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers Register reg = callee_save_regs.at(i).AsArm().AsCoreRegister(); 1450bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers push_list |= 1 << reg; 1451bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers pushed_values++; 14520d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers } 1453bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers PushList(push_list); 1454bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 1455bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Increase frame to required size 1456bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers CHECK_GT(frame_size, pushed_values * kPointerSize); // Must be at least space to push Method* 1457bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers size_t adjust = frame_size - (pushed_values * kPointerSize); 1458bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers IncreaseFrameSize(adjust); 1459bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 1460bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Write out Method* 1461bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers StoreToOffset(kStoreWord, R0, SP, 0); 1462b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1463b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 14642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::RemoveFrame(size_t frame_size, 1465bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers const std::vector<ManagedRegister>& callee_save_regs) { 146606b37d91bb3d543002b1aee9829691f5e8bebc7eElliott Hughes CHECK_ALIGNED(frame_size, kStackAlignment); 1467bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Compute callee saves to pop and PC 1468bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers RegList pop_list = 1 << PC; 1469bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers size_t pop_values = 1; 1470bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers for (size_t i = 0; i < callee_save_regs.size(); i++) { 1471bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers Register reg = callee_save_regs.at(i).AsArm().AsCoreRegister(); 1472bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers pop_list |= 1 << reg; 1473bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers pop_values++; 14740d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers } 1475bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 1476bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Decrease frame to start of callee saves 1477bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers CHECK_GT(frame_size, pop_values * kPointerSize); 1478bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers size_t adjust = frame_size - (pop_values * kPointerSize); 1479bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers DecreaseFrameSize(adjust); 1480bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 1481bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers // Pop callee saves and PC 1482bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers PopList(pop_list); 14830d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers} 14840d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers 14852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::IncreaseFrameSize(size_t adjust) { 1486b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(SP, -adjust); 1487b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1488b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 14892c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::DecreaseFrameSize(size_t adjust) { 1490b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(SP, adjust); 1491b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1492b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 14932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Store(FrameOffset dest, ManagedRegister msrc, size_t size) { 14942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister src = msrc.AsArm(); 1495e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (src.IsNoRegister()) { 1496e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_EQ(0u, size); 1497e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (src.IsCoreRegister()) { 1498b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_EQ(4u, size); 1499b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value()); 1500e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (src.IsRegisterPair()) { 1501e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_EQ(8u, size); 1502e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro StoreToOffset(kStoreWord, src.AsRegisterPairLow(), SP, dest.Int32Value()); 1503e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro StoreToOffset(kStoreWord, src.AsRegisterPairHigh(), 1504e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro SP, dest.Int32Value() + 4); 1505e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (src.IsSRegister()) { 1506e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro StoreSToOffset(src.AsSRegister(), SP, dest.Int32Value()); 1507b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1508e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(src.IsDRegister()); 1509e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro StoreDToOffset(src.AsDRegister(), SP, dest.Int32Value()); 1510b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1511b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1512b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 15132c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreRef(FrameOffset dest, ManagedRegister msrc) { 15142c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister src = msrc.AsArm(); 1515b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(src.IsCoreRegister()); 1516b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value()); 1517b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1518b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 15192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) { 15202c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister src = msrc.AsArm(); 1521df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers CHECK(src.IsCoreRegister()); 1522df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value()); 1523df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers} 1524df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers 15252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreSpanning(FrameOffset dest, ManagedRegister msrc, 15262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers FrameOffset in_off, ManagedRegister mscratch) { 15272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister src = msrc.AsArm(); 15282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 15297a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value()); 15307a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, in_off.Int32Value()); 15317a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value() + 4); 15327a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers} 15337a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers 15342c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CopyRef(FrameOffset dest, FrameOffset src, 15352c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister mscratch) { 15362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 1537b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value()); 1538b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value()); 1539b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1540b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 15412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadRef(ManagedRegister mdest, ManagedRegister base, 15422c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers MemberOffset offs) { 15432c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister dest = mdest.AsArm(); 1544b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(dest.IsCoreRegister() && dest.IsCoreRegister()); 1545b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), 15462c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers base.AsArm().AsCoreRegister(), offs.Int32Value()); 1547b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1548b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 15492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadRef(ManagedRegister mdest, FrameOffset src) { 15502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister dest = mdest.AsArm(); 1551362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes CHECK(dest.IsCoreRegister()); 1552362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes LoadFromOffset(kLoadWord, dest.AsCoreRegister(), SP, src.Int32Value()); 1553362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes} 15542c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers 15552c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base, 1556a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers Offset offs) { 15572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister dest = mdest.AsArm(); 1558a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers CHECK(dest.IsCoreRegister() && dest.IsCoreRegister()); 1559a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), 15602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers base.AsArm().AsCoreRegister(), offs.Int32Value()); 1561a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers} 1562a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers 15632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm, 15642c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister mscratch) { 15652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 1566b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1567b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(scratch.AsCoreRegister(), imm); 1568b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value()); 1569b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1570b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 15712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreImmediateToThread(ThreadOffset dest, uint32_t imm, 15722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister mscratch) { 15732c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 1574b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1575b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(scratch.AsCoreRegister(), imm); 1576b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), TR, dest.Int32Value()); 1577b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1578b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 15792c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Load(ManagedRegister mdest, FrameOffset src, size_t size) { 15802c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister dest = mdest.AsArm(); 1581e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (dest.IsNoRegister()) { 1582e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_EQ(0u, size); 1583e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (dest.IsCoreRegister()) { 1584b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_EQ(4u, size); 1585b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), SP, src.Int32Value()); 1586e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (dest.IsRegisterPair()) { 1587e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_EQ(8u, size); 1588e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, dest.AsRegisterPairLow(), SP, src.Int32Value()); 15895a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers LoadFromOffset(kLoadWord, dest.AsRegisterPairHigh(), SP, src.Int32Value() + 4); 1590e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (dest.IsSRegister()) { 1591e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadSFromOffset(dest.AsSRegister(), SP, src.Int32Value()); 1592b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1593e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(dest.IsDRegister()); 1594e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadDFromOffset(dest.AsDRegister(), SP, src.Int32Value()); 1595b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1596b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1597b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 15985a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogersvoid ArmAssembler::Load(ManagedRegister mdest, ThreadOffset src, size_t size) { 15995a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers ArmManagedRegister dest = mdest.AsArm(); 16005a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers if (dest.IsNoRegister()) { 16015a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers CHECK_EQ(0u, size); 16025a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers } else if (dest.IsCoreRegister()) { 16035a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers CHECK_EQ(4u, size); 16045a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), TR, src.Int32Value()); 16055a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers } else if (dest.IsRegisterPair()) { 16065a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers CHECK_EQ(8u, size); 16075a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers LoadFromOffset(kLoadWord, dest.AsRegisterPairLow(), TR, src.Int32Value()); 16085a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers LoadFromOffset(kLoadWord, dest.AsRegisterPairHigh(), TR, src.Int32Value() + 4); 16095a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers } else if (dest.IsSRegister()) { 16105a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers LoadSFromOffset(dest.AsSRegister(), TR, src.Int32Value()); 16115a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers } else { 16125a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers CHECK(dest.IsDRegister()); 16135a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers LoadDFromOffset(dest.AsDRegister(), TR, src.Int32Value()); 16145a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers } 16155a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers} 16165a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers 16172c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadRawPtrFromThread(ManagedRegister mdest, 16182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ThreadOffset offs) { 16192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister dest = mdest.AsArm(); 1620b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(dest.IsCoreRegister()); 1621b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), 1622b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, offs.Int32Value()); 1623b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1624b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 16252c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CopyRawPtrFromThread(FrameOffset fr_offs, 16262c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ThreadOffset thr_offs, 16272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister mscratch) { 16282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 1629b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1630b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1631b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, thr_offs.Int32Value()); 1632b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 1633b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SP, fr_offs.Int32Value()); 1634b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1635b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 16362c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CopyRawPtrToThread(ThreadOffset thr_offs, 16372c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers FrameOffset fr_offs, 16382c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister mscratch) { 16392c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 1640b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1641b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1642b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SP, fr_offs.Int32Value()); 1643b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 1644b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, thr_offs.Int32Value()); 1645b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1646b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 16472c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreStackOffsetToThread(ThreadOffset thr_offs, 16482c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers FrameOffset fr_offs, 16492c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister mscratch) { 16502c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 1651b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1652b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(scratch.AsCoreRegister(), SP, fr_offs.Int32Value(), AL); 1653b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 1654b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, thr_offs.Int32Value()); 1655b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1656b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 16572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::StoreStackPointerToThread(ThreadOffset thr_offs) { 165845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers StoreToOffset(kStoreWord, SP, TR, thr_offs.Int32Value()); 165945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers} 166045a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 1661b5d09b2f87202bc132ac3991d4b6d71f4f6d9264Ian Rogersvoid ArmAssembler::Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) { 16622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister dest = mdest.AsArm(); 16632c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister src = msrc.AsArm(); 1664e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (!dest.Equals(src)) { 1665e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (dest.IsCoreRegister()) { 1666e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(src.IsCoreRegister()); 1667e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro mov(dest.AsCoreRegister(), ShifterOperand(src.AsCoreRegister())); 16687a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } else if (dest.IsDRegister()) { 16697a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers CHECK(src.IsDRegister()); 16707a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers vmovd(dest.AsDRegister(), src.AsDRegister()); 16717a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } else if (dest.IsSRegister()) { 16727a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers CHECK(src.IsSRegister()); 16737a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers vmovs(dest.AsSRegister(), src.AsSRegister()); 1674e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else { 16757a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers CHECK(dest.IsRegisterPair()); 16767a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers CHECK(src.IsRegisterPair()); 16777a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers // Ensure that the first move doesn't clobber the input of the second 16787a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers if (src.AsRegisterPairHigh() != dest.AsRegisterPairLow()) { 16797a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers mov(dest.AsRegisterPairLow(), ShifterOperand(src.AsRegisterPairLow())); 16807a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers mov(dest.AsRegisterPairHigh(), ShifterOperand(src.AsRegisterPairHigh())); 16817a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } else { 16827a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers mov(dest.AsRegisterPairHigh(), ShifterOperand(src.AsRegisterPairHigh())); 16837a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers mov(dest.AsRegisterPairLow(), ShifterOperand(src.AsRegisterPairLow())); 16847a99c11d220ec68c208b507570e3a78c2c18a7a1Ian Rogers } 1685e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1686b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1687b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1688b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1689dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogersvoid ArmAssembler::Copy(FrameOffset dest, FrameOffset src, ManagedRegister mscratch, size_t size) { 16902c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 1691b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 16925381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao CHECK(size == 4 || size == 8); 1693b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (size == 4) { 1694dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value()); 1695dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value()); 16965381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao } else if (size == 8) { 1697dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value()); 1698dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value()); 1699dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value() + 4); 1700dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value() + 4); 1701b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1702b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1703b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1704dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogersvoid ArmAssembler::Copy(FrameOffset dest, ManagedRegister src_base, Offset src_offset, 1705dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers ManagedRegister mscratch, size_t size) { 1706dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers Register scratch = mscratch.AsArm().AsCoreRegister(); 1707dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers CHECK_EQ(size, 4u); 1708dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers LoadFromOffset(kLoadWord, scratch, src_base.AsArm().AsCoreRegister(), src_offset.Int32Value()); 1709dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers StoreToOffset(kStoreWord, scratch, SP, dest.Int32Value()); 1710dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers} 1711dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers 17125a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogersvoid ArmAssembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src, 17135a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers ManagedRegister mscratch, size_t size) { 17145a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers Register scratch = mscratch.AsArm().AsCoreRegister(); 17155a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers CHECK_EQ(size, 4u); 17165a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers LoadFromOffset(kLoadWord, scratch, SP, src.Int32Value()); 17175a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers StoreToOffset(kStoreWord, scratch, dest_base.AsArm().AsCoreRegister(), dest_offset.Int32Value()); 17185a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers} 17195a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers 1720dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogersvoid ArmAssembler::Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset, 1721dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers ManagedRegister mscratch, size_t size) { 1722dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers UNIMPLEMENTED(FATAL); 1723dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers} 1724dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers 17255a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogersvoid ArmAssembler::Copy(ManagedRegister dest, Offset dest_offset, 17265a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers ManagedRegister src, Offset src_offset, 17275a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers ManagedRegister mscratch, size_t size) { 1728dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers CHECK_EQ(size, 4u); 17295a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers Register scratch = mscratch.AsArm().AsCoreRegister(); 17305a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers LoadFromOffset(kLoadWord, scratch, src.AsArm().AsCoreRegister(), src_offset.Int32Value()); 17315a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers StoreToOffset(kStoreWord, scratch, dest.AsArm().AsCoreRegister(), dest_offset.Int32Value()); 17325a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers} 17335a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers 17345a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogersvoid ArmAssembler::Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset, 17355a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers ManagedRegister scratch, size_t size) { 17365a7a74a042e73a355f5cedffa0d2faf5340028faIan Rogers UNIMPLEMENTED(FATAL); 1737dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers} 1738dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers 1739dc51b79e65abcdad094ccd5e5a2caf5153433d49Ian Rogers 1740e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogersvoid ArmAssembler::MemoryBarrier(ManagedRegister mscratch) { 1741e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#if ANDROID_SMP != 0 1742e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#if defined(__ARM_HAVE_DMB) 1743e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers int32_t encoding = 0xf57ff05f; // dmb 1744e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers Emit(encoding); 1745e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#elif defined(__ARM_HAVE_LDREX_STREX) 1746e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers CHECK(mscratch.AsArm().AsCoreRegister() == R12); 1747e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers LoadImmediate(R12, 0); 1748e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers int32_t encoding = 0xee07cfba; // mcr p15, 0, r12, c7, c10, 5 1749e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers Emit(encoding); 1750e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#else 1751e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers CHECK(mscratch.AsArm().AsCoreRegister() == R12); 1752e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers LoadImmediate(R12, 0xffff0fa0); // kuser_memory_barrier 1753e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers blx(R12); 1754e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#endif 1755e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers#endif 1756e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers} 1757e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers 17582c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CreateSirtEntry(ManagedRegister mout_reg, 17592c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers FrameOffset sirt_offset, 17602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister min_reg, bool null_allowed) { 17612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister out_reg = mout_reg.AsArm(); 17622c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister in_reg = min_reg.AsArm(); 1763e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(in_reg.IsNoRegister() || in_reg.IsCoreRegister()); 1764b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(out_reg.IsCoreRegister()); 1765b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (null_allowed) { 1766408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Null values get a SIRT entry value of 0. Otherwise, the SIRT entry is 1767408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // the address in the SIRT holding the reference. 1768b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // e.g. out_reg = (handle == 0) ? 0 : (SP+handle_offset) 1769e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (in_reg.IsNoRegister()) { 1770e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(), 1771408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers SP, sirt_offset.Int32Value()); 1772e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro in_reg = out_reg; 1773e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1774b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers cmp(in_reg.AsCoreRegister(), ShifterOperand(0)); 1775b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!out_reg.Equals(in_reg)) { 1776b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(out_reg.AsCoreRegister(), 0, EQ); 1777b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1778408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers AddConstant(out_reg.AsCoreRegister(), SP, sirt_offset.Int32Value(), NE); 1779b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1780408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers AddConstant(out_reg.AsCoreRegister(), SP, sirt_offset.Int32Value(), AL); 1781b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1782b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1783b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 17842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::CreateSirtEntry(FrameOffset out_off, 17852c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers FrameOffset sirt_offset, 17862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister mscratch, 17872c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers bool null_allowed) { 17882c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 1789b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1790b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (null_allowed) { 1791b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, 1792408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers sirt_offset.Int32Value()); 1793408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // Null values get a SIRT entry value of 0. Otherwise, the sirt entry is 1794408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // the address in the SIRT holding the reference. 1795408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers // e.g. scratch = (scratch == 0) ? 0 : (SP+sirt_offset) 1796b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers cmp(scratch.AsCoreRegister(), ShifterOperand(0)); 1797408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers AddConstant(scratch.AsCoreRegister(), SP, sirt_offset.Int32Value(), NE); 1798b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1799408f79aeb676251ba35667a64e86c20638d7cb0bIan Rogers AddConstant(scratch.AsCoreRegister(), SP, sirt_offset.Int32Value(), AL); 1800b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1801b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, out_off.Int32Value()); 1802b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1803b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 18042c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::LoadReferenceFromSirt(ManagedRegister mout_reg, 18052c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister min_reg) { 18062c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister out_reg = mout_reg.AsArm(); 18072c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister in_reg = min_reg.AsArm(); 1808b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(out_reg.IsCoreRegister()); 1809b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(in_reg.IsCoreRegister()); 1810b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Label null_arg; 1811b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!out_reg.Equals(in_reg)) { 1812b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(out_reg.AsCoreRegister(), 0, EQ); 1813b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1814b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers cmp(in_reg.AsCoreRegister(), ShifterOperand(0)); 1815df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(), 1816df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers in_reg.AsCoreRegister(), 0, NE); 1817b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1818b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 18192c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::VerifyObject(ManagedRegister src, bool could_be_null) { 1820b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: not validating references 1821b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1822b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 18232c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::VerifyObject(FrameOffset src, bool could_be_null) { 1824b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: not validating references 1825b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1826b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 18272c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Call(ManagedRegister mbase, Offset offset, 18282c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister mscratch) { 18292c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister base = mbase.AsArm(); 18302c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 1831b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(base.IsCoreRegister()); 1832b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1833b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1834b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers base.AsCoreRegister(), offset.Int32Value()); 1835b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers blx(scratch.AsCoreRegister()); 1836b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: place reference map on call 1837b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1838b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 18392c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::Call(FrameOffset base, Offset offset, 18402c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister mscratch) { 18412c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 1842e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(scratch.IsCoreRegister()); 1843e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // Call *(*(SP + base) + offset) 1844e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1845e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro SP, base.Int32Value()); 1846e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1847e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro scratch.AsCoreRegister(), offset.Int32Value()); 1848e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro blx(scratch.AsCoreRegister()); 1849e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // TODO: place reference map on call 1850e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1851e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 1852bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogersvoid ArmAssembler::Call(ThreadOffset offset, ManagedRegister scratch) { 1853bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers UNIMPLEMENTED(FATAL); 1854bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers} 1855bdb0391258abc54bf77c676e36847d28a783bfe5Ian Rogers 18562c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::GetCurrentThread(ManagedRegister tr) { 18572c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers mov(tr.AsArm().AsCoreRegister(), ShifterOperand(TR)); 1858668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao} 1859668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao 18602c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::GetCurrentThread(FrameOffset offset, 18612c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister scratch) { 1862668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao StoreToOffset(kStoreWord, TR, SP, offset.Int32Value(), AL); 1863668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao} 1864668512afd0d9b3772a0abc589208b729ee16bc61Shih-wei Liao 18652c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::SuspendPoll(ManagedRegister mscratch, 18662c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ManagedRegister return_reg, 18672c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers FrameOffset return_save_location, 18682c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers size_t return_size) { 18692c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 18702c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmSuspendCountSlowPath* slow = 18712c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers new ArmSuspendCountSlowPath(return_reg.AsArm(), return_save_location, 18722c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers return_size); 1873e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro buffer_.EnqueueSlowPath(slow); 1874e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1875e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro TR, Thread::SuspendCountOffset().Int32Value()); 1876e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro cmp(scratch.AsCoreRegister(), ShifterOperand(0)); 1877e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro b(slow->Entry(), NE); 1878e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Bind(slow->Continuation()); 1879e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1880e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 18812c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmSuspendCountSlowPath::Emit(Assembler* sasm) { 18822c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmAssembler* sp_asm = down_cast<ArmAssembler*>(sasm); 18832c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#define __ sp_asm-> 18842c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers __ Bind(&entry_); 1885e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // Save return value 18862c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers __ Store(return_save_location_, return_register_, return_size_); 1887e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers // Pass thread as argument 1888e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers __ mov(R0, ShifterOperand(TR)); 1889e5de95b3f9609e02fefd7cda7b21f30c9412eb4cIan Rogers __ LoadFromOffset(kLoadWord, R12, TR, OFFSETOF_MEMBER(Thread, pCheckSuspendFromCode)); 1890e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // Note: assume that link register will be spilled/filled on method entry/exit 18912c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers __ blx(R12); 1892e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // Reload return value 18932c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers __ Load(return_register_, return_save_location_, return_size_); 18942c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers __ b(&continuation_); 18952c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#undef __ 189645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers} 189745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 18982c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmAssembler::ExceptionPoll(ManagedRegister mscratch) { 18992c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmManagedRegister scratch = mscratch.AsArm(); 190067375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers ArmExceptionSlowPath* slow = new ArmExceptionSlowPath(scratch); 1901e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro buffer_.EnqueueSlowPath(slow); 1902e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1903e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro TR, Thread::ExceptionOffset().Int32Value()); 1904e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro cmp(scratch.AsCoreRegister(), ShifterOperand(0)); 1905e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro b(slow->Entry(), NE); 1906e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1907e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 19082c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogersvoid ArmExceptionSlowPath::Emit(Assembler* sasm) { 19092c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers ArmAssembler* sp_asm = down_cast<ArmAssembler*>(sasm); 19102c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#define __ sp_asm-> 19112c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers __ Bind(&entry_); 191267375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers 191367375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers // Pass exception object as argument 191467375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers // Don't care about preserving R0 as this call won't return 191567375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers __ mov(R0, ShifterOperand(scratch_.AsCoreRegister())); 191667375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers // Set up call to Thread::Current()->pDeliverException 191767375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers __ LoadFromOffset(kLoadWord, R12, TR, OFFSETOF_MEMBER(Thread, pDeliverException)); 19182c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers __ blx(R12); 191967375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers // Call never returns 192067375acd9fec74cc2054554fe1ed0a7d213e1e47Ian Rogers __ bkpt(0); 19212c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers#undef __ 192245a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers} 192345a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 19242c8f653c98d658419f464b6147c10e11a664d2e6Ian Rogers} // namespace arm 19256b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro} // namespace art 1926