assembler_arm.cc revision a04d397b990ee7d3ce120e317c19fb4409d80d57
1a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro// Copyright 2011 Google Inc. All Rights Reserved. 2a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 3578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "assembler.h" 4578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "logging.h" 5578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "offsets.h" 6e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro#include "thread.h" 7578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "utils.h" 8a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 96b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapironamespace art { 10a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 11a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Instruction encoding bits. 12a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroenum { 13a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro H = 1 << 5, // halfword (or byte) 14a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro L = 1 << 20, // load (or store) 15a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro S = 1 << 20, // set condition code (or leave unchanged) 16a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro W = 1 << 21, // writeback base register (or leave unchanged) 17a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro A = 1 << 21, // accumulate in multiply instruction (or not) 18a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B = 1 << 22, // unsigned byte (or word) 19a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro N = 1 << 22, // long (or short) 20a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro U = 1 << 23, // positive (or negative) offset/index 21a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing) 22a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro I = 1 << 25, // immediate shifter operand (or not) 23a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 24a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B0 = 1, 25a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B1 = 1 << 1, 26a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B2 = 1 << 2, 27a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B3 = 1 << 3, 28a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B4 = 1 << 4, 29a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B5 = 1 << 5, 30a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B6 = 1 << 6, 31a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B7 = 1 << 7, 32a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B8 = 1 << 8, 33a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B9 = 1 << 9, 34a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B10 = 1 << 10, 35a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 = 1 << 11, 36a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B12 = 1 << 12, 37a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B16 = 1 << 16, 38a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B17 = 1 << 17, 39a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B18 = 1 << 18, 40a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B19 = 1 << 19, 41a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B20 = 1 << 20, 42a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B21 = 1 << 21, 43a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B22 = 1 << 22, 44a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B23 = 1 << 23, 45a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 = 1 << 24, 46a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 = 1 << 25, 47a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B26 = 1 << 26, 48a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 = 1 << 27, 49a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 50a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Instruction bit masks. 51a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro RdMask = 15 << 12, // in str instruction 52a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CondMask = 15 << 28, 53a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CoprocessorMask = 15 << 8, 54a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro OpCodeMask = 15 << 21, // in data-processing instructions 55a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Imm24Mask = (1 << 24) - 1, 56a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Off12Mask = (1 << 12) - 1, 57a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 58a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // ldrex/strex register field encodings. 59a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kLdExRnShift = 16, 60a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kLdExRtShift = 12, 61a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kStrExRnShift = 16, 62a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kStrExRdShift = 12, 63a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kStrExRtShift = 0, 64a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}; 65a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 66a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 671f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kRegisterNames[] = { 681f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 691f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes "fp", "ip", "sp", "lr", "pc" 701f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}; 711f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Register& rhs) { 721f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= R0 && rhs <= PC) { 731f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes os << kRegisterNames[rhs]; 741f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 75b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "Register[" << static_cast<int>(rhs) << "]"; 761f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 771f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 781f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 791f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 801f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 811f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const SRegister& rhs) { 821f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= S0 && rhs < kNumberOfSRegisters) { 83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "s" << static_cast<int>(rhs); 841f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 85b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "SRegister[" << static_cast<int>(rhs) << "]"; 861f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 871f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 881f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 891f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 901f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 911f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const DRegister& rhs) { 921f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= D0 && rhs < kNumberOfDRegisters) { 93b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "d" << static_cast<int>(rhs); 941f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 95b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "DRegister[" << static_cast<int>(rhs) << "]"; 961f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 971f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 981f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 991f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 1001f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 1011f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kConditionNames[] = { 102b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", 103b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers "LE", "AL", 1041f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}; 1051f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Condition& rhs) { 1061f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= EQ && rhs <= AL) { 1071f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes os << kConditionNames[rhs]; 1081f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "Condition[" << static_cast<int>(rhs) << "]"; 1101f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 1111f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 1121f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 1131f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 1141f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 115a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::Emit(int32_t value) { 116a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro AssemblerBuffer::EnsureCapacity ensured(&buffer_); 117a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro buffer_.Emit<int32_t>(value); 118a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 119a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 120a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 121a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitType01(Condition cond, 122a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int type, 123a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Opcode opcode, 124a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int set_cc, 125a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rn, 126a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, 127a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ShifterOperand so) { 128a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 129a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 130a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 131a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro type << kTypeShift | 132a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(opcode) << kOpcodeShift | 133a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro set_cc << kSShift | 134a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rn) << kRnShift | 135a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | 136a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro so.encoding(); 137a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 138a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 139a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 140a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 141a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitType5(Condition cond, int offset, bool link) { 142a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 143a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 144a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5 << kTypeShift | 145a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (link ? 1 : 0) << kLinkShift; 146a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(Assembler::EncodeBranchOffset(offset, encoding)); 147a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 148a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 149a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 150a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMemOp(Condition cond, 151a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro bool load, 152a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro bool byte, 153a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, 154a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Address ad) { 155a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 156a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 157a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 158a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B26 | 159a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (load ? L : 0) | 160a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (byte ? B : 0) | 161a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 162a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ad.encoding(); 163a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 164a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 165a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 166a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 167a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMemOpAddressMode3(Condition cond, 168a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t mode, 169a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, 170a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Address ad) { 171a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 172a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 173a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 174a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B22 | 175a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro mode | 176a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 177a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ad.encoding3(); 178a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 179a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 180a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 181a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 182a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMultiMemOp(Condition cond, 183a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro BlockAddressMode am, 184a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro bool load, 185a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register base, 186a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro RegList regs) { 187a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(base, kNoRegister); 188a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 189a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 190a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | 191a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro am | 192a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (load ? L : 0) | 193a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(base) << kRnShift) | 194a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro regs; 195a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 196a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 197a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 198a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 199a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitShiftImmediate(Condition cond, 200a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Shift opcode, 201a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, 202a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, 203a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ShifterOperand so) { 204a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 2051f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes CHECK_EQ(so.type(), 1U); 206a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 207a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(MOV) << kOpcodeShift | 208a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | 209a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro so.encoding() << kShiftImmShift | 210a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(opcode) << kShiftShift | 211a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rm); 212a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 213a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 214a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 215a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 216a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitShiftRegister(Condition cond, 217a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Shift opcode, 218a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, 219a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, 220a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ShifterOperand so) { 221a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 2221f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes CHECK_EQ(so.type(), 0U); 223a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 224a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(MOV) << kOpcodeShift | 225a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | 226a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro so.encoding() << kShiftRegisterShift | 227a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(opcode) << kShiftShift | 228a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B4 | 229a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rm); 230a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 231a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 232a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 233a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 234a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitBranch(Condition cond, Label* label, bool link) { 235a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro if (label->IsBound()) { 236a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType5(cond, label->Position() - buffer_.Size(), link); 237a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } else { 238a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int position = buffer_.Size(); 239a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Use the offset field of the branch instruction for linking the sites. 240a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType5(cond, label->position_, link); 241a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro label->LinkTo(position); 242a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 243a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 244a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 245a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::and_(Register rd, Register rn, ShifterOperand so, 246a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 247a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), AND, 0, rn, rd, so); 248a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 249a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 250a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 251a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::eor(Register rd, Register rn, ShifterOperand so, 252a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 253a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), EOR, 0, rn, rd, so); 254a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 255a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 256a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 257a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::sub(Register rd, Register rn, ShifterOperand so, 258a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 259a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), SUB, 0, rn, rd, so); 260a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 261a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 262a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::rsb(Register rd, Register rn, ShifterOperand so, 263a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 264a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), RSB, 0, rn, rd, so); 265a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 266a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 267a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::rsbs(Register rd, Register rn, ShifterOperand so, 268a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 269a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), RSB, 1, rn, rd, so); 270a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 271a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 272a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 273a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::add(Register rd, Register rn, ShifterOperand so, 274a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 275a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ADD, 0, rn, rd, so); 276a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 277a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 278a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 279a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::adds(Register rd, Register rn, ShifterOperand so, 280a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 281a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ADD, 1, rn, rd, so); 282a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 283a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 284a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 285a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::subs(Register rd, Register rn, ShifterOperand so, 286a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 287a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), SUB, 1, rn, rd, so); 288a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 289a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 290a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 291a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::adc(Register rd, Register rn, ShifterOperand so, 292a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 293a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ADC, 0, rn, rd, so); 294a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 295a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 296a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 297a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::sbc(Register rd, Register rn, ShifterOperand so, 298a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 299a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), SBC, 0, rn, rd, so); 300a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 301a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 302a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 303a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::rsc(Register rd, Register rn, ShifterOperand so, 304a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 305a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), RSC, 0, rn, rd, so); 306a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 307a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 308a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 309a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::tst(Register rn, ShifterOperand so, Condition cond) { 310a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, PC); // Reserve tst pc instruction for exception handler marker. 311a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), TST, 1, rn, R0, so); 312a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 313a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 314a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 315a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::teq(Register rn, ShifterOperand so, Condition cond) { 316a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, PC); // Reserve teq pc instruction for exception handler marker. 317a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), TEQ, 1, rn, R0, so); 318a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 319a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 320a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 321a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::cmp(Register rn, ShifterOperand so, Condition cond) { 322a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), CMP, 1, rn, R0, so); 323a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 324a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 325a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 326a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::cmn(Register rn, ShifterOperand so, Condition cond) { 327a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), CMN, 1, rn, R0, so); 328a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 329a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 330a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 331a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::orr(Register rd, Register rn, 332a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ShifterOperand so, Condition cond) { 333a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ORR, 0, rn, rd, so); 334a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 335a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 336a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 337a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::orrs(Register rd, Register rn, 338a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ShifterOperand so, Condition cond) { 339a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ORR, 1, rn, rd, so); 340a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 341a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 342a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 343a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mov(Register rd, ShifterOperand so, Condition cond) { 344a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MOV, 0, R0, rd, so); 345a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 346a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 347a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 348a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::movs(Register rd, ShifterOperand so, Condition cond) { 349a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MOV, 1, R0, rd, so); 350a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 351a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 352a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 353a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::bic(Register rd, Register rn, ShifterOperand so, 354a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 355a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), BIC, 0, rn, rd, so); 356a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 357a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 358a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 359a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mvn(Register rd, ShifterOperand so, Condition cond) { 360a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MVN, 0, R0, rd, so); 361a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 362a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 363a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 364a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mvns(Register rd, ShifterOperand so, Condition cond) { 365a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MVN, 1, R0, rd, so); 366a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 367a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 368a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 369a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::clz(Register rd, Register rm, Condition cond) { 370a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 371a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, kNoRegister); 372a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 373a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, PC); 374a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, PC); 375a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 376a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | B22 | B21 | (0xf << 16) | 377a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 378a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (0xf << 8) | B4 | static_cast<int32_t>(rm); 379a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 380a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 381a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 382a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 383a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::movw(Register rd, uint16_t imm16, Condition cond) { 384a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 385a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 386a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 | B24 | ((imm16 >> 12) << 16) | 387a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 388a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 389a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 390a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 391a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 392a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::movt(Register rd, uint16_t imm16, Condition cond) { 393a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 394a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 395a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 | B24 | B22 | ((imm16 >> 12) << 16) | 396a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 397a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 398a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 399a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 400a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 401a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMulOp(Condition cond, int32_t opcode, 402a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, Register rn, 403a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, Register rs) { 404a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 405a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, kNoRegister); 406a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, kNoRegister); 407a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rs, kNoRegister); 408a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 409a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = opcode | 410a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(cond) << kConditionShift) | 411a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rn) << kRnShift) | 412a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 413a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rs) << kRsShift) | 414a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B7 | B4 | 415a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rm) << kRmShift); 416a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 417a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 418a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 419a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 420a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mul(Register rd, Register rn, 421a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, Condition cond) { 422a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 423a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, 0, R0, rd, rn, rm); 424a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 425a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 426a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 427a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mla(Register rd, Register rn, 428a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, Register ra, Condition cond) { 429a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 430a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, B21, ra, rd, rn, rm); 431a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 432a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 433a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 434a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mls(Register rd, Register rn, 435a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, Register ra, Condition cond) { 436a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 437a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); 438a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 439a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 440a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 441a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::umull(Register rd_lo, Register rd_hi, 442a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rn, Register rm, Condition cond) { 443a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 444a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm); 445a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 446a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 447a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 448a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldr(Register rd, Address ad, Condition cond) { 449a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, true, false, rd, ad); 450a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 451a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 452a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 453a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::str(Register rd, Address ad, Condition cond) { 454a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, false, false, rd, ad); 455a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 456a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 457a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 458a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrb(Register rd, Address ad, Condition cond) { 459a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, true, true, rd, ad); 460a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 461a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 462a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 463a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strb(Register rd, Address ad, Condition cond) { 464a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, false, true, rd, ad); 465a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 466a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 467a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 468a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrh(Register rd, Address ad, Condition cond) { 469a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad); 470a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 471a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 472a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 473a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strh(Register rd, Address ad, Condition cond) { 474a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad); 475a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 476a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 477a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 478a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrsb(Register rd, Address ad, Condition cond) { 479a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad); 480a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 481a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 482a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 483a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrsh(Register rd, Address ad, Condition cond) { 484a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad); 485a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 486a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 487a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 488a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrd(Register rd, Address ad, Condition cond) { 489a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_EQ(rd % 2, 0); 490a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad); 491a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 492a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 493a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 494a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strd(Register rd, Address ad, Condition cond) { 495a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_EQ(rd % 2, 0); 496a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad); 497a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 498a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 499a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 500a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldm(BlockAddressMode am, 501a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register base, 502a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro RegList regs, 503a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 504a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMultiMemOp(cond, am, true, base, regs); 505a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 506a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 507a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 508a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::stm(BlockAddressMode am, 509a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register base, 510a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro RegList regs, 511a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 512a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMultiMemOp(cond, am, false, base, regs); 513a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 514a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 515a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 516a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrex(Register rt, Register rn, Condition cond) { 517a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, kNoRegister); 518a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 519a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 520a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 521a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | 522a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B23 | 523a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro L | 524a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rn) << kLdExRnShift) | 525a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt) << kLdExRtShift) | 526a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0; 527a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 528a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 529a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 530a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 531a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strex(Register rd, 532a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rt, 533a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rn, 534a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 535a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, kNoRegister); 536a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 537a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 538a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 539a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 540a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | 541a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B23 | 542a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rn) << kStrExRnShift) | 543a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kStrExRdShift) | 544a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B10 | B9 | B8 | B7 | B4 | 545a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt) << kStrExRtShift); 546a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 547a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 548a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 549a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 550a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::clrex() { 551a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (kSpecialCondition << kConditionShift) | 552a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf; 553a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 554a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 555a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 556a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 557a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::nop(Condition cond) { 558a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 559a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 560a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 | B24 | B21 | (0xf << 12); 561a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 562a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 563a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 564a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 565a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovsr(SRegister sn, Register rt, Condition cond) { 566a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sn, kNoSRegister); 567a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 568a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 569a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 570a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 571a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 572a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | 573a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) >> 1)*B16) | 574a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 575a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) & 1)*B7) | B4; 576a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 577a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 578a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 579a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 580a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovrs(Register rt, SRegister sn, Condition cond) { 581a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sn, kNoSRegister); 582a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 583a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 584a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 585a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 586a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 587a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B20 | 588a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) >> 1)*B16) | 589a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 590a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) & 1)*B7) | B4; 591a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 592a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 593a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 594a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 595a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovsrr(SRegister sm, Register rt, Register rt2, 596a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 597a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 598a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, S31); 599a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 600a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 601a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 602a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 603a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 604a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 605a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 606a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 607a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | 608a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 609a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 610a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 611a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 612a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 613a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 614a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 615a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 616a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovrrs(Register rt, Register rt2, SRegister sm, 617a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 618a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 619a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, S31); 620a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 621a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 622a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 623a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 624a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 625a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 626a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, rt2); 627a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 628a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 629a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | B20 | 630a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 631a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 632a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 633a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 634a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 635a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 636a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 637a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 638a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovdrr(DRegister dm, Register rt, Register rt2, 639a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 640a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 641a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 642a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 643a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 644a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 645a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 646a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 647a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 648a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 649a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | 650a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 651a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 652a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 653a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 654a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 655a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 656a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 657a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 658a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovrrd(Register rt, Register rt2, DRegister dm, 659a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 660a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 661a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 662a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 663a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 664a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 665a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 666a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 667a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, rt2); 668a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 669a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 670a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | B20 | 671a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 672a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 673a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 674a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 675a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 676a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 677a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 678a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 679a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vldrs(SRegister sd, Address ad, Condition cond) { 680a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 681a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 682a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 683a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | B20 | 684a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 685a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 686a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | ad.vencoding(); 687a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 688a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 689a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 690a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 691a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vstrs(SRegister sd, Address ad, Condition cond) { 692a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC); 693a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 694a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 695a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 696a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | 697a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 698a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 699a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | ad.vencoding(); 700a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 701a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 702a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 703a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 704a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vldrd(DRegister dd, Address ad, Condition cond) { 705a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 706a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 707a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 708a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | B20 | 709a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 710a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 711a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | B8 | ad.vencoding(); 712a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 713a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 714a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 715a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 716a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vstrd(DRegister dd, Address ad, Condition cond) { 717a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC); 718a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 719a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 720a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 721a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | 722a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 723a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 724a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | B8 | ad.vencoding(); 725a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 726a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 727a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 728a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 729a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPsss(Condition cond, int32_t opcode, 730a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro SRegister sd, SRegister sn, SRegister sm) { 731a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 732a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sn, kNoSRegister); 733a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 734a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 735a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 736a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | opcode | 737a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 738a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) >> 1)*B16) | 739a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 740a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) & 1)*B7) | 741a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | 742a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 743a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 744a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 745a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 746a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 747a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPddd(Condition cond, int32_t opcode, 748a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro DRegister dd, DRegister dn, DRegister dm) { 749a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 750a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dn, kNoDRegister); 751a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 752a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 753a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 754a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | B8 | opcode | 755a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 756a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dn) & 0xf)*B16) | 757a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 758a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dn) >> 4)*B7) | 759a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | 760a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 761a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 762a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 763a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 764a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 765a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) { 766a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm); 767a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 768a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 769a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 770a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) { 771a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm); 772a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 773a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 774a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 775a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirobool Assembler::vmovs(SRegister sd, float s_imm, Condition cond) { 776a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint32_t imm32 = bit_cast<uint32_t, float>(s_imm); 777a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro if (((imm32 & ((1 << 19) - 1)) == 0) && 778a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) || 779a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) { 780a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) | 781a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((imm32 >> 19) & ((1 << 6) -1)); 782a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf), 783a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro sd, S0, S0); 784a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return true; 785a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 786a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return false; 787a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 788a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 789a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 790a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirobool Assembler::vmovd(DRegister dd, double d_imm, Condition cond) { 791a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint64_t imm64 = bit_cast<uint64_t, double>(d_imm); 792a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro if (((imm64 & ((1LL << 48) - 1)) == 0) && 793a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) || 794a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) { 795a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) | 796a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((imm64 >> 48) & ((1 << 6) -1)); 797a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf), 798a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro dd, D0, D0); 799a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return true; 800a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 801a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return false; 802a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 803a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 804a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 805a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vadds(SRegister sd, SRegister sn, SRegister sm, 806a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 807a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B21 | B20, sd, sn, sm); 808a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 809a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 810a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 811a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm, 812a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 813a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B21 | B20, dd, dn, dm); 814a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 815a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 816a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 817a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm, 818a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 819a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm); 820a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 821a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 822a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 823a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm, 824a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 825a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm); 826a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 827a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 828a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 829a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm, 830a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 831a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B21, sd, sn, sm); 832a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 833a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 834a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 835a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm, 836a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 837a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B21, dd, dn, dm); 838a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 839a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 840a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 841a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm, 842a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 843a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, 0, sd, sn, sm); 844a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 845a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 846a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 847a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm, 848a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 849a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, 0, dd, dn, dm); 850a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 851a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 852a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 853a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm, 854a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 855a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B6, sd, sn, sm); 856a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 857a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 858a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 859a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm, 860a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 861a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B6, dd, dn, dm); 862a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 863a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 864a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 865a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm, 866a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 867a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23, sd, sn, sm); 868a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 869a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 870a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 871a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm, 872a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 873a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23, dd, dn, dm); 874a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 875a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 876a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 877a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vabss(SRegister sd, SRegister sm, Condition cond) { 878a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm); 879a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 880a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 881a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 882a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) { 883a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm); 884a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 885a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 886a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 887a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) { 888a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm); 889a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 890a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 891a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 892a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) { 893a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm); 894a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 895a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 896a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 897a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) { 898a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm); 899a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 900a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 901a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) { 902a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm); 903a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 904a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 905a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 906a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPsd(Condition cond, int32_t opcode, 907a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro SRegister sd, DRegister dm) { 908a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 909a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 910a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 911a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 912a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | opcode | 913a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 914a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 915a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | 916a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 917a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 918a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 919a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 920a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 921a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPds(Condition cond, int32_t opcode, 922a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro DRegister dd, SRegister sm) { 923a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 924a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 925a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 926a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 927a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | opcode | 928a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 929a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 930a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | 931a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 932a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 933a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 934a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 935a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 936a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) { 937a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm); 938a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 939a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 940a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 941a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) { 942a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm); 943a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 944a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 945a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 946a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) { 947a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm); 948a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 949a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 950a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 951a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) { 952a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm); 953a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 954a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 955a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 956a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) { 957a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm); 958a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 959a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 960a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 961a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) { 962a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm); 963a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 964a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 965a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 966a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) { 967a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm); 968a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 969a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 970a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 971a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) { 972a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm); 973a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 974a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 975a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 976a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) { 977a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm); 978a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 979a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 980a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 981a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) { 982a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm); 983a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 984a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 985a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 986a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) { 987a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm); 988a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 989a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 990a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 991a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) { 992a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm); 993a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 994a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 995a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 996a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmpsz(SRegister sd, Condition cond) { 997a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0); 998a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 999a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1000a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1001a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmpdz(DRegister dd, Condition cond) { 1002a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0); 1003a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1004a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1005a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1006a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmstat(Condition cond) { // VMRS APSR_nzcv, FPSCR 1007a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 1008a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1009a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | 1010a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(PC)*B12) | 1011a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | B4; 1012a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1013a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1014a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1015a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1016a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::svc(uint32_t imm24) { 1017a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK(IsUint(24, imm24)); 1018a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24; 1019a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1020a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1021a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1022a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1023a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::bkpt(uint16_t imm16) { 1024a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (AL << kConditionShift) | B24 | B21 | 1025a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); 1026a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1027a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1028a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1029a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1030a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::b(Label* label, Condition cond) { 1031a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitBranch(cond, label, false); 1032a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1033a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1034a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1035a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::bl(Label* label, Condition cond) { 1036a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitBranch(cond, label, true); 1037a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1038a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1039a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1040a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::blx(Register rm, Condition cond) { 1041a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, kNoRegister); 1042a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 1043a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1044a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | B21 | (0xfff << 8) | B5 | B4 | 1045a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rm) << kRmShift); 1046a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1047a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1048a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1049a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1050a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::MarkExceptionHandler(Label* label) { 1051a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); 1052a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Label l; 1053a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro b(&l); 1054a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitBranch(AL, label, false); 1055a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Bind(&l); 1056a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1057a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1058a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1059a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::Bind(Label* label) { 1060a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK(!label->IsBound()); 1061a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int bound_pc = buffer_.Size(); 1062a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro while (label->IsLinked()) { 1063a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t position = label->Position(); 1064a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t next = buffer_.Load<int32_t>(position); 1065a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoded = Assembler::EncodeBranchOffset(bound_pc - position, next); 1066a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro buffer_.Store<int32_t>(position, encoded); 1067a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro label->position_ = Assembler::DecodeBranchOffset(next); 1068a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 1069a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro label->BindTo(bound_pc); 1070a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1071a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1072a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1073a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EncodeUint32InTstInstructions(uint32_t data) { 1074a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // TODO: Consider using movw ip, <16 bits>. 1075a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro while (!IsUint(8, data)) { 1076a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro tst(R0, ShifterOperand(data & 0xFF), VS); 1077a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro data >>= 8; 1078a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 1079a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro tst(R0, ShifterOperand(data), MI); 1080a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1081a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1082b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1083a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroint32_t Assembler::EncodeBranchOffset(int offset, int32_t inst) { 1084a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // The offset is off by 8 due to the way the ARM CPUs read PC. 1085a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro offset -= 8; 1086a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK(IsAligned(offset, 4)); 1087a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK(IsInt(CountOneBits(kBranchOffsetMask), offset)); 1088a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1089a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Properly preserve only the bits supported in the instruction. 1090a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro offset >>= 2; 1091a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro offset &= kBranchOffsetMask; 1092a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return (inst & ~kBranchOffsetMask) | offset; 1093a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1094a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1095a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1096a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroint Assembler::DecodeBranchOffset(int32_t inst) { 1097a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Sign-extend, left-shift by 2, then add 8. 1098a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8); 1099a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1100a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::AddConstant(Register rd, int32_t value, Condition cond) { 1102b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(rd, rd, value, cond); 1103b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1104b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1105b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1106b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::AddConstant(Register rd, Register rn, int32_t value, 1107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Condition cond) { 1108b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value == 0) { 1109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (rd != rn) { 1110b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mov(rd, ShifterOperand(rn), cond); 1111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1112b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return; 1113b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1114b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // We prefer to select the shorter code sequence rather than selecting add for 1115b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // positive values and sub for negatives ones, which would slightly improve 1116b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // the readability of generated code for some constants. 1117b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ShifterOperand shifter_op; 1118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(value, &shifter_op)) { 1119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(rd, rn, shifter_op, cond); 1120b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(-value, &shifter_op)) { 1121b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers sub(rd, rn, shifter_op, cond); 1122b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1123b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(rn != IP); 1124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(~value, &shifter_op)) { 1125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(rd, rn, ShifterOperand(IP), cond); 1127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { 1128b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1129b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers sub(rd, rn, ShifterOperand(IP), cond); 1130b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1131b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movw(IP, Low16Bits(value), cond); 1132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers uint16_t value_high = High16Bits(value); 1133b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value_high != 0) { 1134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movt(IP, value_high, cond); 1135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(rd, rn, ShifterOperand(IP), cond); 1137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1140b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1142b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value, 1143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Condition cond) { 1144b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ShifterOperand shifter_op; 1145b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(value, &shifter_op)) { 1146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers adds(rd, rn, shifter_op, cond); 1147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(-value, &shifter_op)) { 1148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers subs(rd, rn, shifter_op, cond); 1149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1150b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(rn != IP); 1151b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(~value, &shifter_op)) { 1152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1153b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers adds(rd, rn, ShifterOperand(IP), cond); 1154b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { 1155b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers subs(rd, rn, ShifterOperand(IP), cond); 1157b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1158b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movw(IP, Low16Bits(value), cond); 1159b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers uint16_t value_high = High16Bits(value); 1160b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value_high != 0) { 1161b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movt(IP, value_high, cond); 1162b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1163b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers adds(rd, rn, ShifterOperand(IP), cond); 1164b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1165b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1166b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1167b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { 1170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ShifterOperand shifter_op; 1171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(value, &shifter_op)) { 1172b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mov(rd, shifter_op, cond); 1173b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(~value, &shifter_op)) { 1174b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(rd, shifter_op, cond); 1175b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1176b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movw(rd, Low16Bits(value), cond); 1177b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers uint16_t value_high = High16Bits(value); 1178b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value_high != 0) { 1179b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movt(rd, value_high, cond); 1180b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1181b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1182b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1184b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1185b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldLoadOffset(LoadOperandType type, int offset) { 1186b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1187b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedByte: 1188b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedHalfword: 1189b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedHalfword: 1190b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWordPair: 1191b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(8, offset); // Addressing mode 3. 1192b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedByte: 1193b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWord: 1194b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(12, offset); // Addressing mode 2. 1195b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSWord: 1196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadDWord: 1197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(10, offset); // VFP addressing mode. 1198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1199b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1200b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return false; 1201b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1204b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldStoreOffset(StoreOperandType type, int offset) { 1206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1207b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreHalfword: 1208b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWordPair: 1209b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(8, offset); // Addressing mode 3. 1210b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreByte: 1211b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWord: 1212b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(12, offset); // Addressing mode 2. 1213b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreSWord: 1214b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreDWord: 1215b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(10, offset); // VFP addressing mode. 1216b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1217b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1218b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return false; 1219b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1220b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1222b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when 1224b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldLoadOffset. 1225b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadFromOffset(LoadOperandType type, 1226b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register reg, 1227b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register base, 1228b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int32_t offset, 1229b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Condition cond) { 1230b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!Address::CanHoldLoadOffset(type, offset)) { 1231b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(base != IP); 1232b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(IP, offset, cond); 1233b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(IP, IP, ShifterOperand(base), cond); 1234b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers base = IP; 1235b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers offset = 0; 1236b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1237b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(Address::CanHoldLoadOffset(type, offset)); 1238b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1239b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedByte: 1240b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrsb(reg, Address(base, offset), cond); 1241b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1242b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedByte: 1243b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrb(reg, Address(base, offset), cond); 1244b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1245b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedHalfword: 1246b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrsh(reg, Address(base, offset), cond); 1247b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1248b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedHalfword: 1249b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrh(reg, Address(base, offset), cond); 1250b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1251b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWord: 1252b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldr(reg, Address(base, offset), cond); 1253b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1254b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWordPair: 1255b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrd(reg, Address(base, offset), cond); 1256b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1257b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1258b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1259b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1260b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1261b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1262e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when 1263e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldLoadOffset, as expected by JIT::GuardedLoadFromOffset. 1264e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapirovoid Assembler::LoadSFromOffset(SRegister reg, 1265e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Register base, 1266e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro int32_t offset, 1267e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Condition cond) { 1268e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (!Address::CanHoldLoadOffset(kLoadSWord, offset)) { 1269e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_NE(base, IP); 1270e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadImmediate(IP, offset, cond); 1271e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro add(IP, IP, ShifterOperand(base), cond); 1272e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro base = IP; 1273e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro offset = 0; 1274e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1275e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(Address::CanHoldLoadOffset(kLoadSWord, offset)); 1276e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro vldrs(reg, Address(base, offset), cond); 1277e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1278e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 1279e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when 1280e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldLoadOffset, as expected by JIT::GuardedLoadFromOffset. 1281e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapirovoid Assembler::LoadDFromOffset(DRegister reg, 1282e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Register base, 1283e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro int32_t offset, 1284e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Condition cond) { 1285e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (!Address::CanHoldLoadOffset(kLoadDWord, offset)) { 1286e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_NE(base, IP); 1287e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadImmediate(IP, offset, cond); 1288e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro add(IP, IP, ShifterOperand(base), cond); 1289e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro base = IP; 1290e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro offset = 0; 1291e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1292e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(Address::CanHoldLoadOffset(kLoadDWord, offset)); 1293e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro vldrd(reg, Address(base, offset), cond); 1294e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1295b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1296b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when 1297b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldStoreOffset. 1298b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreToOffset(StoreOperandType type, 1299b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register reg, 1300b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register base, 1301b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int32_t offset, 1302b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Condition cond) { 1303b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!Address::CanHoldStoreOffset(type, offset)) { 1304b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(reg != IP); 1305b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(base != IP); 1306b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(IP, offset, cond); 1307b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(IP, IP, ShifterOperand(base), cond); 1308b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers base = IP; 1309b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers offset = 0; 1310b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1311b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(Address::CanHoldStoreOffset(type, offset)); 1312b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1313b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreByte: 1314b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers strb(reg, Address(base, offset), cond); 1315b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1316b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreHalfword: 1317b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers strh(reg, Address(base, offset), cond); 1318b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1319b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWord: 1320b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers str(reg, Address(base, offset), cond); 1321b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1322b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWordPair: 1323b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers strd(reg, Address(base, offset), cond); 1324b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1325b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1326b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1327b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1328b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1329b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1330e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when 1331e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldStoreOffset, as expected by JIT::GuardedStoreToOffset. 1332e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapirovoid Assembler::StoreSToOffset(SRegister reg, 1333e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Register base, 1334e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro int32_t offset, 1335e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Condition cond) { 1336e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (!Address::CanHoldStoreOffset(kStoreSWord, offset)) { 1337e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_NE(base, IP); 1338e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadImmediate(IP, offset, cond); 1339e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro add(IP, IP, ShifterOperand(base), cond); 1340e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro base = IP; 1341e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro offset = 0; 1342e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1343e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(Address::CanHoldStoreOffset(kStoreSWord, offset)); 1344e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro vstrs(reg, Address(base, offset), cond); 1345e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1346e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 1347e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Implementation note: this method must emit at most one instruction when 1348e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro// Address::CanHoldStoreOffset, as expected by JIT::GuardedStoreSToOffset. 1349e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapirovoid Assembler::StoreDToOffset(DRegister reg, 1350e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Register base, 1351e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro int32_t offset, 1352e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Condition cond) { 1353e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (!Address::CanHoldStoreOffset(kStoreDWord, offset)) { 1354e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_NE(base, IP); 1355e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadImmediate(IP, offset, cond); 1356e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro add(IP, IP, ShifterOperand(base), cond); 1357e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro base = IP; 1358e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro offset = 0; 1359e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1360e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(Address::CanHoldStoreOffset(kStoreDWord, offset)); 1361e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro vstrd(reg, Address(base, offset), cond); 1362e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1363e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 13649b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapirovoid Assembler::Push(Register rd, Condition cond) { 13659b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro str(rd, Address(SP, -kRegisterSize, Address::PreIndex), cond); 13669b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 13679b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 13689b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapirovoid Assembler::Pop(Register rd, Condition cond) { 13699b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro ldr(rd, Address(SP, kRegisterSize, Address::PostIndex), cond); 13709b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 13719b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 13729b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapirovoid Assembler::PushList(RegList regs, Condition cond) { 13739b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro stm(DB_W, SP, regs, cond); 13749b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 13759b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 13769b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapirovoid Assembler::PopList(RegList regs, Condition cond) { 13779b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro ldm(IA_W, SP, regs, cond); 13789b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 13799b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 13809b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapirovoid Assembler::Mov(Register rd, Register rm, Condition cond) { 13819b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro if (rd != rm) { 13829b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm), cond); 13839b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro } 13849b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 13859b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 13869b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapirovoid Assembler::Lsl(Register rd, Register rm, uint32_t shift_imm, 13879b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro Condition cond) { 13889b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro CHECK_NE(shift_imm, 0u); // Do not use Lsl if no shift is wanted. 13899b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm, LSL, shift_imm), cond); 13909b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 13919b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 13929b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapirovoid Assembler::Lsr(Register rd, Register rm, uint32_t shift_imm, 13939b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro Condition cond) { 13949b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro CHECK_NE(shift_imm, 0u); // Do not use Lsr if no shift is wanted. 13959b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. 13969b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm, LSR, shift_imm), cond); 13979b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 13989b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 13999b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapirovoid Assembler::Asr(Register rd, Register rm, uint32_t shift_imm, 14009b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro Condition cond) { 14019b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro CHECK_NE(shift_imm, 0u); // Do not use Asr if no shift is wanted. 14029b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro if (shift_imm == 32) shift_imm = 0; // Comply to UAL syntax. 14039b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm, ASR, shift_imm), cond); 14049b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 14059b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 14069b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapirovoid Assembler::Ror(Register rd, Register rm, uint32_t shift_imm, 14079b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro Condition cond) { 14089b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro CHECK_NE(shift_imm, 0u); // Use Rrx instruction. 14099b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm, ROR, shift_imm), cond); 14109b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 14119b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 14129b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapirovoid Assembler::Rrx(Register rd, Register rm, Condition cond) { 14139b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro mov(rd, ShifterOperand(rm, ROR, 0), cond); 14149b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro} 14159b9ba28b1277b4ddb967c5a968c6d550febce6afCarl Shapiro 14160d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogersvoid Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg, 14170d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers const std::vector<ManagedRegister>& spill_regs) { 14180d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers CHECK(IsAligned(frame_size, kStackAlignment)); 14190d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers CHECK_EQ(R0, method_reg.AsCoreRegister()); 1420b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(SP, -frame_size); 14210d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers RegList spill_list = 1 << R0 | 1 << LR; 14220d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers for(size_t i = 0; i < spill_regs.size(); i++) { 14230d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers Register reg = spill_regs.at(i).AsCoreRegister(); 14240d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers // check assumption LR is the last register that gets spilled 14250d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers CHECK_LT(reg, LR); 14260d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers spill_list |= 1 << reg; 14270d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers } 14280d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers // Store spill list from (low to high number register) starting at SP 14290d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers // incrementing after each store but not updating SP 14300d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers stm(IA, SP, spill_list, AL); 1431b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1432b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 14330d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogersvoid Assembler::RemoveFrame(size_t frame_size, 14340d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers const std::vector<ManagedRegister>& spill_regs) { 14350d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers CHECK(IsAligned(frame_size, kStackAlignment)); 14360d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers // Reload LR. TODO: reload any saved callee saves from spill_regs 14370d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers LoadFromOffset(kLoadWord, LR, SP, (spill_regs.size() + 1) * kPointerSize); 1438b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(SP, frame_size); 1439b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mov(PC, ShifterOperand(LR)); 1440b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1441b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 14420d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogersvoid Assembler::FillFromSpillArea(const std::vector<ManagedRegister>& spill_regs, 14430d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers size_t displacement) { 14440d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers for(size_t i = 0; i < spill_regs.size(); i++) { 14450d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers Register reg = spill_regs.at(i).AsCoreRegister(); 14460d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers LoadFromOffset(kLoadWord, reg, SP, displacement + ((i + 1) * kPointerSize)); 14470d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers } 14480d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers} 14490d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers 1450b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::IncreaseFrameSize(size_t adjust) { 14510d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers CHECK(IsAligned(adjust, kStackAlignment)); 1452b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(SP, -adjust); 1453b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1454b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1455b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::DecreaseFrameSize(size_t adjust) { 14560d666d8769714dcbc2acc4dd5b06f0deffa6e0a1Ian Rogers CHECK(IsAligned(adjust, kStackAlignment)); 1457b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(SP, adjust); 1458b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1459b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1460b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Store(FrameOffset dest, ManagedRegister src, size_t size) { 1461e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (src.IsNoRegister()) { 1462e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_EQ(0u, size); 1463e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (src.IsCoreRegister()) { 1464b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_EQ(4u, size); 1465b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value()); 1466e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (src.IsRegisterPair()) { 1467e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_EQ(8u, size); 1468e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro StoreToOffset(kStoreWord, src.AsRegisterPairLow(), SP, dest.Int32Value()); 1469e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro StoreToOffset(kStoreWord, src.AsRegisterPairHigh(), 1470e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro SP, dest.Int32Value() + 4); 1471e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (src.IsSRegister()) { 1472e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro StoreSToOffset(src.AsSRegister(), SP, dest.Int32Value()); 1473b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1474e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(src.IsDRegister()); 1475e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro StoreDToOffset(src.AsDRegister(), SP, dest.Int32Value()); 1476b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1477b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1478b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1479b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreRef(FrameOffset dest, ManagedRegister src) { 1480b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(src.IsCoreRegister()); 1481b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value()); 1482b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1483b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1484df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogersvoid Assembler::StoreRawPtr(FrameOffset dest, ManagedRegister src) { 1485df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers CHECK(src.IsCoreRegister()); 1486df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value()); 1487df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers} 1488df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers 1489b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CopyRef(FrameOffset dest, FrameOffset src, 1490b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1491b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value()); 1492b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value()); 1493b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1494b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1495b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadRef(ManagedRegister dest, ManagedRegister base, 1496b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers MemberOffset offs) { 1497b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(dest.IsCoreRegister() && dest.IsCoreRegister()); 1498b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), 1499b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers base.AsCoreRegister(), offs.Int32Value()); 1500b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1501b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1502a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogersvoid Assembler::LoadRawPtr(ManagedRegister dest, ManagedRegister base, 1503a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers Offset offs) { 1504a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers CHECK(dest.IsCoreRegister() && dest.IsCoreRegister()); 1505a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), 1506a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers base.AsCoreRegister(), offs.Int32Value()); 1507a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers} 1508a04d397b990ee7d3ce120e317c19fb4409d80d57Ian Rogers 1509b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm, 1510b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1511b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1512b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(scratch.AsCoreRegister(), imm); 1513b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value()); 1514b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1515b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1516b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreImmediateToThread(ThreadOffset dest, uint32_t imm, 1517b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1518b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1519b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(scratch.AsCoreRegister(), imm); 1520b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), TR, dest.Int32Value()); 1521b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1522b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1523b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Load(ManagedRegister dest, FrameOffset src, size_t size) { 1524e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (dest.IsNoRegister()) { 1525e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_EQ(0u, size); 1526e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (dest.IsCoreRegister()) { 1527b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_EQ(4u, size); 1528b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), SP, src.Int32Value()); 1529e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (dest.IsRegisterPair()) { 1530e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK_EQ(8u, size); 1531e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, dest.AsRegisterPairLow(), SP, src.Int32Value()); 1532e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, dest.AsRegisterPairHigh(), 1533e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro SP, src.Int32Value() + 4); 1534e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else if (dest.IsSRegister()) { 1535e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadSFromOffset(dest.AsSRegister(), SP, src.Int32Value()); 1536b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1537e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(dest.IsDRegister()); 1538e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadDFromOffset(dest.AsDRegister(), SP, src.Int32Value()); 1539b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1540b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1541b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1542b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadRawPtrFromThread(ManagedRegister dest, ThreadOffset offs) { 1543b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(dest.IsCoreRegister()); 1544b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), 1545b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, offs.Int32Value()); 1546b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1547b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1548b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CopyRawPtrFromThread(FrameOffset fr_offs, ThreadOffset thr_offs, 1549e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro ManagedRegister scratch) { 1550b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1551b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1552b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, thr_offs.Int32Value()); 1553b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 1554b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SP, fr_offs.Int32Value()); 1555b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1556b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1557b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CopyRawPtrToThread(ThreadOffset thr_offs, FrameOffset fr_offs, 1558e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro ManagedRegister scratch) { 1559b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1560b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1561b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SP, fr_offs.Int32Value()); 1562b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 1563b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, thr_offs.Int32Value()); 1564b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1565b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1566b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreStackOffsetToThread(ThreadOffset thr_offs, 1567b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset fr_offs, 1568b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1569b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1570b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(scratch.AsCoreRegister(), SP, fr_offs.Int32Value(), AL); 1571b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 1572b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, thr_offs.Int32Value()); 1573b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1574b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 157545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogersvoid Assembler::StoreStackPointerToThread(ThreadOffset thr_offs) { 157645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers StoreToOffset(kStoreWord, SP, TR, thr_offs.Int32Value()); 157745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers} 157845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 1579b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Move(ManagedRegister dest, ManagedRegister src) { 1580e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (!dest.Equals(src)) { 1581e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (dest.IsCoreRegister()) { 1582e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(src.IsCoreRegister()); 1583e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro mov(dest.AsCoreRegister(), ShifterOperand(src.AsCoreRegister())); 1584e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } else { 1585e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // TODO: VFP 158653b61314370c49354ed6f8d616d6a9a182410fc1Elliott Hughes UNIMPLEMENTED(FATAL) << ": VFP"; 1587e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1588b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1589b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1590b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1591b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Copy(FrameOffset dest, FrameOffset src, ManagedRegister scratch, 1592b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t size) { 1593b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 15945381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao CHECK(size == 4 || size == 8); 1595b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (size == 4) { 1596b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1597b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SP, src.Int32Value()); 1598b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 1599b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SP, dest.Int32Value()); 16005381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao } else if (size == 8) { 16015381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 16025381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao SP, src.Int32Value()); 16035381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 16045381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao SP, dest.Int32Value()); 16055381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 16065381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao SP, src.Int32Value() + 4); 16075381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 16085381cf941d26030199fcdbe61a614ff01e55a27cShih-wei Liao SP, dest.Int32Value() + 4); 1609b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1610b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1611b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1612b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CreateStackHandle(ManagedRegister out_reg, 1613b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset handle_offset, 1614b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister in_reg, bool null_allowed) { 1615e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(in_reg.IsNoRegister() || in_reg.IsCoreRegister()); 1616b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(out_reg.IsCoreRegister()); 1617b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (null_allowed) { 1618b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Null values get a handle value of 0. Otherwise, the handle value is 1619b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // the address in the stack handle block holding the reference. 1620b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // e.g. out_reg = (handle == 0) ? 0 : (SP+handle_offset) 1621e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro if (in_reg.IsNoRegister()) { 1622e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(), 1623e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro SP, handle_offset.Int32Value()); 1624e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro in_reg = out_reg; 1625e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro } 1626b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers cmp(in_reg.AsCoreRegister(), ShifterOperand(0)); 1627b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!out_reg.Equals(in_reg)) { 1628b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(out_reg.AsCoreRegister(), 0, EQ); 1629b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1630b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(out_reg.AsCoreRegister(), SP, handle_offset.Int32Value(), NE); 1631b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1632b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(out_reg.AsCoreRegister(), SP, handle_offset.Int32Value(), AL); 1633b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1634b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1635b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1636b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CreateStackHandle(FrameOffset out_off, 1637b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset handle_offset, 1638b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch, bool null_allowed) { 1639b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1640b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (null_allowed) { 1641b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, 1642b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers handle_offset.Int32Value()); 1643b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Null values get a handle value of 0. Otherwise, the handle value is 1644b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // the address in the stack handle block holding the reference. 1645b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // e.g. scratch = (handle == 0) ? 0 : (SP+handle_offset) 1646b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers cmp(scratch.AsCoreRegister(), ShifterOperand(0)); 1647b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(scratch.AsCoreRegister(), SP, handle_offset.Int32Value(), NE); 1648b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1649b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(scratch.AsCoreRegister(), SP, handle_offset.Int32Value(), AL); 1650b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1651b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, out_off.Int32Value()); 1652b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1653b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1654b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadReferenceFromStackHandle(ManagedRegister out_reg, 1655df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers ManagedRegister in_reg) { 1656b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(out_reg.IsCoreRegister()); 1657b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(in_reg.IsCoreRegister()); 1658b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Label null_arg; 1659b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!out_reg.Equals(in_reg)) { 1660b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(out_reg.AsCoreRegister(), 0, EQ); 1661b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1662b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers cmp(in_reg.AsCoreRegister(), ShifterOperand(0)); 1663df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(), 1664df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogers in_reg.AsCoreRegister(), 0, NE); 1665b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1666b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1667b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::ValidateRef(ManagedRegister src, bool could_be_null) { 1668b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: not validating references 1669b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1670b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1671b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::ValidateRef(FrameOffset src, bool could_be_null) { 1672b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: not validating references 1673b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1674b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1675df20fe0c097073f75f22d16e72fd3636a31d3ca1Ian Rogersvoid Assembler::Call(ManagedRegister base, Offset offset, 1676b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1677b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(base.IsCoreRegister()); 1678b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1679b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1680b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers base.AsCoreRegister(), offset.Int32Value()); 1681b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers blx(scratch.AsCoreRegister()); 1682b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: place reference map on call 1683b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1684b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1685e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapirovoid Assembler::Call(FrameOffset base, Offset offset, 1686e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro ManagedRegister scratch) { 1687e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro CHECK(scratch.IsCoreRegister()); 1688e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // Call *(*(SP + base) + offset) 1689e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1690e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro SP, base.Int32Value()); 1691e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1692e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro scratch.AsCoreRegister(), offset.Int32Value()); 1693e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro blx(scratch.AsCoreRegister()); 1694e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // TODO: place reference map on call 1695e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1696e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 169745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogersvoid Assembler::SuspendPoll(ManagedRegister scratch, ManagedRegister return_reg, 169845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers FrameOffset return_save_location, 169945a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers size_t return_size) { 1700e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro SuspendCountSlowPath* slow = new SuspendCountSlowPath(return_reg, 1701e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro return_save_location, 1702e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro return_size); 1703e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro buffer_.EnqueueSlowPath(slow); 1704e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1705e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro TR, Thread::SuspendCountOffset().Int32Value()); 1706e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro cmp(scratch.AsCoreRegister(), ShifterOperand(0)); 1707e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro b(slow->Entry(), NE); 1708e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Bind(slow->Continuation()); 1709e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1710e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 1711e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapirovoid SuspendCountSlowPath::Emit(Assembler* sp_asm) { 1712e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->Bind(&entry_); 1713e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // Save return value 1714e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->Store(return_save_location_, return_register_, return_size_); 1715e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // Pass top of stack as argument 1716e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->mov(R0, ShifterOperand(SP)); 1717e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->LoadFromOffset(kLoadWord, R12, TR, 1718e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Thread::SuspendCountEntryPointOffset().Int32Value()); 1719e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // Note: assume that link register will be spilled/filled on method entry/exit 1720e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->blx(R12); 1721e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // Reload return value 1722e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->Load(return_register_, return_save_location_, return_size_); 1723e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->b(&continuation_); 172445a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers} 172545a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 172645a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogersvoid Assembler::ExceptionPoll(ManagedRegister scratch) { 1727e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro ExceptionSlowPath* slow = new ExceptionSlowPath(); 1728e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro buffer_.EnqueueSlowPath(slow); 1729e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1730e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro TR, Thread::ExceptionOffset().Int32Value()); 1731e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro cmp(scratch.AsCoreRegister(), ShifterOperand(0)); 1732e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro b(slow->Entry(), NE); 1733e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Bind(slow->Continuation()); 1734e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro} 1735e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro 1736e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapirovoid ExceptionSlowPath::Emit(Assembler* sp_asm) { 1737e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->Bind(&entry_); 1738e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // Pass top of stack as argument 1739e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->mov(R0, ShifterOperand(SP)); 1740e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->LoadFromOffset(kLoadWord, R12, TR, 1741e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro Thread::ExceptionEntryPointOffset().Int32Value()); 1742e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // Note: assume that link register will be spilled/filled on method entry/exit 1743e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->blx(R12); 1744e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // TODO: this call should never return as it should make a long jump to 1745e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro // the appropriate catch block 1746e2d373e6e09c1df9a47e73a26254048adb31ce82Carl Shapiro sp_asm->b(&continuation_); 174745a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers} 174845a76cb99104a222d6a9bd768a084893dcb7cf30Ian Rogers 17496b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro} // namespace art 1750