assembler_arm.cc revision b033c75ebda80ac75f936366fe78d1edf5cec937
1a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro// Copyright 2011 Google Inc. All Rights Reserved. 2a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 3a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro#include "src/assembler.h" 4a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro#include "src/logging.h" 5b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers#include "src/utils.h" 6a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 76b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapironamespace art { 8a5d5cfda6239d8876937e75eba43222f639d2447Carl Shapiro 9a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro// Instruction encoding bits. 10a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroenum { 11a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro H = 1 << 5, // halfword (or byte) 12a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro L = 1 << 20, // load (or store) 13a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro S = 1 << 20, // set condition code (or leave unchanged) 14a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro W = 1 << 21, // writeback base register (or leave unchanged) 15a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro A = 1 << 21, // accumulate in multiply instruction (or not) 16a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B = 1 << 22, // unsigned byte (or word) 17a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro N = 1 << 22, // long (or short) 18a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro U = 1 << 23, // positive (or negative) offset/index 19a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing) 20a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro I = 1 << 25, // immediate shifter operand (or not) 21a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 22a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B0 = 1, 23a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B1 = 1 << 1, 24a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B2 = 1 << 2, 25a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B3 = 1 << 3, 26a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B4 = 1 << 4, 27a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B5 = 1 << 5, 28a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B6 = 1 << 6, 29a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B7 = 1 << 7, 30a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B8 = 1 << 8, 31a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B9 = 1 << 9, 32a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B10 = 1 << 10, 33a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 = 1 << 11, 34a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B12 = 1 << 12, 35a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B16 = 1 << 16, 36a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B17 = 1 << 17, 37a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B18 = 1 << 18, 38a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B19 = 1 << 19, 39a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B20 = 1 << 20, 40a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B21 = 1 << 21, 41a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B22 = 1 << 22, 42a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B23 = 1 << 23, 43a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 = 1 << 24, 44a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 = 1 << 25, 45a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B26 = 1 << 26, 46a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 = 1 << 27, 47a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 48a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Instruction bit masks. 49a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro RdMask = 15 << 12, // in str instruction 50a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CondMask = 15 << 28, 51a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CoprocessorMask = 15 << 8, 52a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro OpCodeMask = 15 << 21, // in data-processing instructions 53a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Imm24Mask = (1 << 24) - 1, 54a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Off12Mask = (1 << 12) - 1, 55a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 56a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // ldrex/strex register field encodings. 57a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kLdExRnShift = 16, 58a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kLdExRtShift = 12, 59a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kStrExRnShift = 16, 60a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kStrExRdShift = 12, 61a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro kStrExRtShift = 0, 62a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro}; 63a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 64a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 651f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kRegisterNames[] = { 661f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", 671f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes "fp", "ip", "sp", "lr", "pc" 681f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}; 691f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Register& rhs) { 701f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= R0 && rhs <= PC) { 711f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes os << kRegisterNames[rhs]; 721f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 73b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "Register[" << static_cast<int>(rhs) << "]"; 741f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 751f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 761f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 771f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 781f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 791f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const SRegister& rhs) { 801f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= S0 && rhs < kNumberOfSRegisters) { 81b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "s" << static_cast<int>(rhs); 821f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 83b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "SRegister[" << static_cast<int>(rhs) << "]"; 841f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 851f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 861f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 871f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 881f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 891f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const DRegister& rhs) { 901f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= D0 && rhs < kNumberOfDRegisters) { 91b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "d" << static_cast<int>(rhs); 921f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 93b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "DRegister[" << static_cast<int>(rhs) << "]"; 941f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 951f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 961f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 971f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 981f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 991f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstatic const char* kConditionNames[] = { 100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers "EQ", "NE", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", 101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers "LE", "AL", 1021f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes}; 1031f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughesstd::ostream& operator<<(std::ostream& os, const Condition& rhs) { 1041f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes if (rhs >= EQ && rhs <= AL) { 1051f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes os << kConditionNames[rhs]; 1061f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } else { 107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers os << "Condition[" << static_cast<int>(rhs) << "]"; 1081f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes } 1091f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes return os; 1101f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes} 1111f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 1121f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes 113a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::Emit(int32_t value) { 114a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro AssemblerBuffer::EnsureCapacity ensured(&buffer_); 115a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro buffer_.Emit<int32_t>(value); 116a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 117a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 118a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 119a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitType01(Condition cond, 120a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int type, 121a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Opcode opcode, 122a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int set_cc, 123a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rn, 124a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, 125a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ShifterOperand so) { 126a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 127a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 128a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 129a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro type << kTypeShift | 130a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(opcode) << kOpcodeShift | 131a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro set_cc << kSShift | 132a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rn) << kRnShift | 133a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | 134a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro so.encoding(); 135a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 136a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 137a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 138a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 139a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitType5(Condition cond, int offset, bool link) { 140a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 141a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 142a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 5 << kTypeShift | 143a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (link ? 1 : 0) << kLinkShift; 144a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(Assembler::EncodeBranchOffset(offset, encoding)); 145a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 146a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 147a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 148a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMemOp(Condition cond, 149a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro bool load, 150a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro bool byte, 151a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, 152a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Address ad) { 153a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 154a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 155a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 156a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B26 | 157a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (load ? L : 0) | 158a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (byte ? B : 0) | 159a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 160a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ad.encoding(); 161a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 162a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 163a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 164a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 165a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMemOpAddressMode3(Condition cond, 166a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t mode, 167a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, 168a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Address ad) { 169a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 170a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 171a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 172a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B22 | 173a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro mode | 174a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 175a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ad.encoding3(); 176a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 177a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 178a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 179a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 180a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMultiMemOp(Condition cond, 181a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro BlockAddressMode am, 182a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro bool load, 183a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register base, 184a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro RegList regs) { 185a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(base, kNoRegister); 186a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 187a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 188a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | 189a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro am | 190a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (load ? L : 0) | 191a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(base) << kRnShift) | 192a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro regs; 193a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 194a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 195a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 196a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 197a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitShiftImmediate(Condition cond, 198a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Shift opcode, 199a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, 200a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, 201a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ShifterOperand so) { 202a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 2031f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes CHECK_EQ(so.type(), 1U); 204a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 205a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(MOV) << kOpcodeShift | 206a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | 207a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro so.encoding() << kShiftImmShift | 208a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(opcode) << kShiftShift | 209a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rm); 210a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 211a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 212a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 213a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 214a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitShiftRegister(Condition cond, 215a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Shift opcode, 216a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, 217a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, 218a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ShifterOperand so) { 219a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 2201f359b08f5ad33ae72e4073b86a9257fe1ed11e5Elliott Hughes CHECK_EQ(so.type(), 0U); 221a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 222a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(MOV) << kOpcodeShift | 223a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | 224a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro so.encoding() << kShiftRegisterShift | 225a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(opcode) << kShiftShift | 226a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B4 | 227a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rm); 228a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 229a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 230a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 231a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 232a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitBranch(Condition cond, Label* label, bool link) { 233a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro if (label->IsBound()) { 234a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType5(cond, label->Position() - buffer_.Size(), link); 235a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } else { 236a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int position = buffer_.Size(); 237a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Use the offset field of the branch instruction for linking the sites. 238a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType5(cond, label->position_, link); 239a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro label->LinkTo(position); 240a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 241a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 242a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 243a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 244a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::and_(Register rd, Register rn, ShifterOperand so, 245a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 246a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), AND, 0, rn, rd, so); 247a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 248a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 249a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 250a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::eor(Register rd, Register rn, ShifterOperand so, 251a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 252a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), EOR, 0, rn, rd, so); 253a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 254a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 255a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 256a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::sub(Register rd, Register rn, ShifterOperand so, 257a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 258a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), SUB, 0, rn, rd, so); 259a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 260a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 261a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::rsb(Register rd, Register rn, ShifterOperand so, 262a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 263a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), RSB, 0, rn, rd, so); 264a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 265a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 266a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::rsbs(Register rd, Register rn, ShifterOperand so, 267a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 268a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), RSB, 1, rn, rd, so); 269a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 270a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 271a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 272a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::add(Register rd, Register rn, ShifterOperand so, 273a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 274a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ADD, 0, rn, rd, so); 275a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 276a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 277a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 278a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::adds(Register rd, Register rn, ShifterOperand so, 279a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 280a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ADD, 1, rn, rd, so); 281a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 282a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 283a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 284a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::subs(Register rd, Register rn, ShifterOperand so, 285a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 286a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), SUB, 1, rn, rd, so); 287a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 288a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 289a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 290a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::adc(Register rd, Register rn, ShifterOperand so, 291a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 292a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ADC, 0, rn, rd, so); 293a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 294a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 295a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 296a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::sbc(Register rd, Register rn, ShifterOperand so, 297a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 298a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), SBC, 0, rn, rd, so); 299a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 300a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 301a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 302a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::rsc(Register rd, Register rn, ShifterOperand so, 303a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 304a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), RSC, 0, rn, rd, so); 305a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 306a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 307a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 308a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::tst(Register rn, ShifterOperand so, Condition cond) { 309a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, PC); // Reserve tst pc instruction for exception handler marker. 310a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), TST, 1, rn, R0, so); 311a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 312a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 313a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 314a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::teq(Register rn, ShifterOperand so, Condition cond) { 315a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, PC); // Reserve teq pc instruction for exception handler marker. 316a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), TEQ, 1, rn, R0, so); 317a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 318a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 319a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 320a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::cmp(Register rn, ShifterOperand so, Condition cond) { 321a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), CMP, 1, rn, R0, so); 322a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 323a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 324a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 325a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::cmn(Register rn, ShifterOperand so, Condition cond) { 326a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), CMN, 1, rn, R0, so); 327a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 328a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 329a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 330a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::orr(Register rd, Register rn, 331a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ShifterOperand so, Condition cond) { 332a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ORR, 0, rn, rd, so); 333a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 334a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 335a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 336a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::orrs(Register rd, Register rn, 337a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ShifterOperand so, Condition cond) { 338a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), ORR, 1, rn, rd, so); 339a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 340a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 341a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 342a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mov(Register rd, ShifterOperand so, Condition cond) { 343a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MOV, 0, R0, rd, so); 344a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 345a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 346a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 347a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::movs(Register rd, ShifterOperand so, Condition cond) { 348a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MOV, 1, R0, rd, so); 349a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 350a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 351a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 352a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::bic(Register rd, Register rn, ShifterOperand so, 353a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 354a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), BIC, 0, rn, rd, so); 355a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 356a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 357a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 358a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mvn(Register rd, ShifterOperand so, Condition cond) { 359a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MVN, 0, R0, rd, so); 360a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 361a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 362a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 363a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mvns(Register rd, ShifterOperand so, Condition cond) { 364a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(cond, so.type(), MVN, 1, R0, rd, so); 365a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 366a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 367a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 368a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::clz(Register rd, Register rm, Condition cond) { 369a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 370a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, kNoRegister); 371a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 372a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, PC); 373a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, PC); 374a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 375a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | B22 | B21 | (0xf << 16) | 376a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 377a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (0xf << 8) | B4 | static_cast<int32_t>(rm); 378a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 379a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 380a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 381a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 382a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::movw(Register rd, uint16_t imm16, Condition cond) { 383a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 384a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 385a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 | B24 | ((imm16 >> 12) << 16) | 386a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 387a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 388a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 389a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 390a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 391a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::movt(Register rd, uint16_t imm16, Condition cond) { 392a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 393a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = static_cast<int32_t>(cond) << kConditionShift | 394a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 | B24 | B22 | ((imm16 >> 12) << 16) | 395a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro static_cast<int32_t>(rd) << kRdShift | (imm16 & 0xfff); 396a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 397a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 398a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 399a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 400a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitMulOp(Condition cond, int32_t opcode, 401a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rd, Register rn, 402a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, Register rs) { 403a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 404a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, kNoRegister); 405a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, kNoRegister); 406a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rs, kNoRegister); 407a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 408a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = opcode | 409a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(cond) << kConditionShift) | 410a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rn) << kRnShift) | 411a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kRdShift) | 412a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rs) << kRsShift) | 413a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B7 | B4 | 414a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rm) << kRmShift); 415a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 416a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 417a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 418a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 419a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mul(Register rd, Register rn, 420a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, Condition cond) { 421a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd, rn, rm are encoded as rn, rm, rs. 422a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, 0, R0, rd, rn, rm); 423a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 424a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 425a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 426a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mla(Register rd, Register rn, 427a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, Register ra, Condition cond) { 428a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 429a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, B21, ra, rd, rn, rm); 430a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 431a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 432a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 433a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::mls(Register rd, Register rn, 434a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rm, Register ra, Condition cond) { 435a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd, rn, rm, ra are encoded as rn, rm, rs, rd. 436a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, B22 | B21, ra, rd, rn, rm); 437a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 438a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 439a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 440a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::umull(Register rd_lo, Register rd_hi, 441a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rn, Register rm, Condition cond) { 442a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Assembler registers rd_lo, rd_hi, rn, rm are encoded as rd, rn, rm, rs. 443a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMulOp(cond, B23, rd_lo, rd_hi, rn, rm); 444a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 445a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 446a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 447a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldr(Register rd, Address ad, Condition cond) { 448a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, true, false, rd, ad); 449a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 450a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 451a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 452a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::str(Register rd, Address ad, Condition cond) { 453a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, false, false, rd, ad); 454a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 455a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 456a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 457a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrb(Register rd, Address ad, Condition cond) { 458a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, true, true, rd, ad); 459a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 460a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 461a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 462a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strb(Register rd, Address ad, Condition cond) { 463a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOp(cond, false, true, rd, ad); 464a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 465a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 466a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 467a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrh(Register rd, Address ad, Condition cond) { 468a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, L | B7 | H | B4, rd, ad); 469a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 470a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 471a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 472a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strh(Register rd, Address ad, Condition cond) { 473a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, B7 | H | B4, rd, ad); 474a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 475a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 476a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 477a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrsb(Register rd, Address ad, Condition cond) { 478a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, L | B7 | B6 | B4, rd, ad); 479a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 480a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 481a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 482a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrsh(Register rd, Address ad, Condition cond) { 483a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, L | B7 | B6 | H | B4, rd, ad); 484a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 485a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 486a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 487a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrd(Register rd, Address ad, Condition cond) { 488a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_EQ(rd % 2, 0); 489a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, B7 | B6 | B4, rd, ad); 490a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 491a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 492a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 493a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strd(Register rd, Address ad, Condition cond) { 494a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_EQ(rd % 2, 0); 495a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMemOpAddressMode3(cond, B7 | B6 | B5 | B4, rd, ad); 496a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 497a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 498a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 499a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldm(BlockAddressMode am, 500a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register base, 501a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro RegList regs, 502a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 503a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMultiMemOp(cond, am, true, base, regs); 504a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 505a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 506a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 507a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::stm(BlockAddressMode am, 508a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register base, 509a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro RegList regs, 510a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 511a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitMultiMemOp(cond, am, false, base, regs); 512a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 513a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 514a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 515a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::ldrex(Register rt, Register rn, Condition cond) { 516a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, kNoRegister); 517a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 518a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 519a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 520a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | 521a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B23 | 522a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro L | 523a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rn) << kLdExRnShift) | 524a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt) << kLdExRtShift) | 525a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B10 | B9 | B8 | B7 | B4 | B3 | B2 | B1 | B0; 526a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 527a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 528a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 529a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 530a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::strex(Register rd, 531a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rt, 532a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Register rn, 533a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 534a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rn, kNoRegister); 535a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rd, kNoRegister); 536a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 537a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 538a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 539a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | 540a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B23 | 541a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rn) << kStrExRnShift) | 542a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rd) << kStrExRdShift) | 543a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B10 | B9 | B8 | B7 | B4 | 544a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt) << kStrExRtShift); 545a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 546a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 547a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 548a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 549a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::clrex() { 550a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (kSpecialCondition << kConditionShift) | 551a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B26 | B24 | B22 | B21 | B20 | (0xff << 12) | B4 | 0xf; 552a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 553a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 554a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 555a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 556a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::nop(Condition cond) { 557a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 558a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 559a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B25 | B24 | B21 | (0xf << 12); 560a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 561a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 562a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 563a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 564a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovsr(SRegister sn, Register rt, Condition cond) { 565a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sn, kNoSRegister); 566a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 567a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 568a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 569a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 570a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 571a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | 572a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) >> 1)*B16) | 573a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 574a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) & 1)*B7) | B4; 575a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 576a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 577a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 578a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 579a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovrs(Register rt, SRegister sn, Condition cond) { 580a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sn, kNoSRegister); 581a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 582a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 583a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 584a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 585a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 586a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B20 | 587a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) >> 1)*B16) | 588a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 589a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) & 1)*B7) | B4; 590a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 591a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 592a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 593a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 594a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovsrr(SRegister sm, Register rt, Register rt2, 595a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 596a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 597a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, S31); 598a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 599a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 600a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 601a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 602a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 603a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 604a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 605a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 606a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | 607a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 608a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 609a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 610a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 611a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 612a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 613a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 614a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 615a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovrrs(Register rt, Register rt2, SRegister sm, 616a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 617a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 618a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, S31); 619a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 620a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 621a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 622a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 623a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 624a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 625a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, rt2); 626a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 627a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 628a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | B20 | 629a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 630a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | 631a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | B4 | 632a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 633a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 634a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 635a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 636a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 637a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovdrr(DRegister dm, Register rt, Register rt2, 638a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 639a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 640a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 641a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 642a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 643a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 644a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 645a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 646a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 647a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 648a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | 649a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 650a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 651a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 652a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 653a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 654a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 655a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 656a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 657a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovrrd(Register rt, Register rt2, DRegister dm, 658a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 659a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 660a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, kNoRegister); 661a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, SP); 662a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, PC); 663a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, kNoRegister); 664a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, SP); 665a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt2, PC); 666a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rt, rt2); 667a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 668a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 669a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B22 | B20 | 670a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt2)*B16) | 671a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rt)*B12) | B11 | B9 | B8 | 672a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | B4 | 673a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 674a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 675a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 676a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 677a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 678a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vldrs(SRegister sd, Address ad, Condition cond) { 679a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 680a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 681a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 682a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | B20 | 683a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 684a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 685a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | ad.vencoding(); 686a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 687a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 688a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 689a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 690a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vstrs(SRegister sd, Address ad, Condition cond) { 691a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC); 692a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 693a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 694a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 695a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | 696a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 697a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 698a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | ad.vencoding(); 699a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 700a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 701a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 702a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 703a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vldrd(DRegister dd, Address ad, Condition cond) { 704a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 705a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 706a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 707a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | B20 | 708a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 709a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 710a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | B8 | ad.vencoding(); 711a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 712a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 713a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 714a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 715a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vstrd(DRegister dd, Address ad, Condition cond) { 716a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(static_cast<Register>(ad.encoding_ & (0xf << kRnShift)), PC); 717a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 718a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 719a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 720a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B24 | 721a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 722a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 723a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | B8 | ad.vencoding(); 724a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 725a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 726a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 727a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 728a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPsss(Condition cond, int32_t opcode, 729a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro SRegister sd, SRegister sn, SRegister sm) { 730a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 731a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sn, kNoSRegister); 732a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 733a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 734a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 735a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | opcode | 736a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 737a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) >> 1)*B16) | 738a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 739a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sn) & 1)*B7) | 740a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | 741a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 742a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 743a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 744a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 745a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 746a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPddd(Condition cond, int32_t opcode, 747a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro DRegister dd, DRegister dn, DRegister dm) { 748a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 749a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dn, kNoDRegister); 750a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 751a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 752a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 753a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | B8 | opcode | 754a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 755a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dn) & 0xf)*B16) | 756a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 757a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dn) >> 4)*B7) | 758a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | 759a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 760a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 761a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 762a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 763a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 764a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovs(SRegister sd, SRegister sm, Condition cond) { 765a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B6, sd, S0, sm); 766a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 767a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 768a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 769a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmovd(DRegister dd, DRegister dm, Condition cond) { 770a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B6, dd, D0, dm); 771a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 772a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 773a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 774a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirobool Assembler::vmovs(SRegister sd, float s_imm, Condition cond) { 775a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint32_t imm32 = bit_cast<uint32_t, float>(s_imm); 776a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro if (((imm32 & ((1 << 19) - 1)) == 0) && 777a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((((imm32 >> 25) & ((1 << 6) - 1)) == (1 << 5)) || 778a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (((imm32 >> 25) & ((1 << 6) - 1)) == ((1 << 5) -1)))) { 779a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint8_t imm8 = ((imm32 >> 31) << 7) | (((imm32 >> 29) & 1) << 6) | 780a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((imm32 >> 19) & ((1 << 6) -1)); 781a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | (imm8 & 0xf), 782a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro sd, S0, S0); 783a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return true; 784a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 785a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return false; 786a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 787a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 788a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 789a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirobool Assembler::vmovd(DRegister dd, double d_imm, Condition cond) { 790a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint64_t imm64 = bit_cast<uint64_t, double>(d_imm); 791a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro if (((imm64 & ((1LL << 48) - 1)) == 0) && 792a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((((imm64 >> 54) & ((1 << 9) - 1)) == (1 << 8)) || 793a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (((imm64 >> 54) & ((1 << 9) - 1)) == ((1 << 8) -1)))) { 794a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro uint8_t imm8 = ((imm64 >> 63) << 7) | (((imm64 >> 61) & 1) << 6) | 795a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((imm64 >> 48) & ((1 << 6) -1)); 796a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | ((imm8 >> 4)*B16) | B8 | (imm8 & 0xf), 797a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro dd, D0, D0); 798a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return true; 799a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 800a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return false; 801a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 802a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 803a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 804a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vadds(SRegister sd, SRegister sn, SRegister sm, 805a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 806a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B21 | B20, sd, sn, sm); 807a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 808a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 809a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 810a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vaddd(DRegister dd, DRegister dn, DRegister dm, 811a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 812a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B21 | B20, dd, dn, dm); 813a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 814a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 815a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 816a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsubs(SRegister sd, SRegister sn, SRegister sm, 817a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 818a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B21 | B20 | B6, sd, sn, sm); 819a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 820a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 821a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 822a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsubd(DRegister dd, DRegister dn, DRegister dm, 823a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 824a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B21 | B20 | B6, dd, dn, dm); 825a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 826a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 827a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 828a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmuls(SRegister sd, SRegister sn, SRegister sm, 829a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 830a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B21, sd, sn, sm); 831a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 832a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 833a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 834a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmuld(DRegister dd, DRegister dn, DRegister dm, 835a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 836a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B21, dd, dn, dm); 837a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 838a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 839a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 840a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlas(SRegister sd, SRegister sn, SRegister sm, 841a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 842a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, 0, sd, sn, sm); 843a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 844a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 845a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 846a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlad(DRegister dd, DRegister dn, DRegister dm, 847a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 848a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, 0, dd, dn, dm); 849a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 850a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 851a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 852a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlss(SRegister sd, SRegister sn, SRegister sm, 853a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 854a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B6, sd, sn, sm); 855a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 856a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 857a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 858a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmlsd(DRegister dd, DRegister dn, DRegister dm, 859a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 860a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B6, dd, dn, dm); 861a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 862a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 863a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 864a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vdivs(SRegister sd, SRegister sn, SRegister sm, 865a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 866a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23, sd, sn, sm); 867a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 868a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 869a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 870a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vdivd(DRegister dd, DRegister dn, DRegister dm, 871a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Condition cond) { 872a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23, dd, dn, dm); 873a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 874a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 875a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 876a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vabss(SRegister sd, SRegister sm, Condition cond) { 877a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B7 | B6, sd, S0, sm); 878a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 879a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 880a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 881a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vabsd(DRegister dd, DRegister dm, Condition cond) { 882a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B7 | B6, dd, D0, dm); 883a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 884a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 885a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 886a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vnegs(SRegister sd, SRegister sm, Condition cond) { 887a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B16 | B6, sd, S0, sm); 888a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 889a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 890a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 891a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vnegd(DRegister dd, DRegister dm, Condition cond) { 892a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B16 | B6, dd, D0, dm); 893a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 894a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 895a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 896a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsqrts(SRegister sd, SRegister sm, Condition cond) { 897a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B16 | B7 | B6, sd, S0, sm); 898a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 899a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 900a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vsqrtd(DRegister dd, DRegister dm, Condition cond) { 901a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B16 | B7 | B6, dd, D0, dm); 902a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 903a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 904a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 905a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPsd(Condition cond, int32_t opcode, 906a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro SRegister sd, DRegister dm) { 907a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sd, kNoSRegister); 908a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dm, kNoDRegister); 909a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 910a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 911a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | opcode | 912a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) & 1)*B22) | 913a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sd) >> 1)*B12) | 914a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dm) >> 4)*B5) | 915a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(dm) & 0xf); 916a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 917a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 918a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 919a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 920a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EmitVFPds(Condition cond, int32_t opcode, 921a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro DRegister dd, SRegister sm) { 922a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(dd, kNoDRegister); 923a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(sm, kNoSRegister); 924a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 925a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 926a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B11 | B9 | opcode | 927a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) >> 4)*B22) | 928a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(dd) & 0xf)*B12) | 929a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((static_cast<int32_t>(sm) & 1)*B5) | 930a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(sm) >> 1); 931a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 932a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 933a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 934a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 935a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtsd(SRegister sd, DRegister dm, Condition cond) { 936a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsd(cond, B23 | B21 | B20 | B18 | B17 | B16 | B8 | B7 | B6, sd, dm); 937a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 938a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 939a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 940a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtds(DRegister dd, SRegister sm, Condition cond) { 941a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPds(cond, B23 | B21 | B20 | B18 | B17 | B16 | B7 | B6, dd, sm); 942a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 943a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 944a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 945a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtis(SRegister sd, SRegister sm, Condition cond) { 946a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B16 | B7 | B6, sd, S0, sm); 947a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 948a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 949a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 950a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtid(SRegister sd, DRegister dm, Condition cond) { 951a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B16 | B8 | B7 | B6, sd, dm); 952a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 953a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 954a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 955a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtsi(SRegister sd, SRegister sm, Condition cond) { 956a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B7 | B6, sd, S0, sm); 957a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 958a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 959a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 960a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtdi(DRegister dd, SRegister sm, Condition cond) { 961a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B7 | B6, dd, sm); 962a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 963a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 964a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 965a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtus(SRegister sd, SRegister sm, Condition cond) { 966a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B18 | B7 | B6, sd, S0, sm); 967a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 968a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 969a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 970a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtud(SRegister sd, DRegister dm, Condition cond) { 971a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsd(cond, B23 | B21 | B20 | B19 | B18 | B8 | B7 | B6, sd, dm); 972a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 973a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 974a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 975a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtsu(SRegister sd, SRegister sm, Condition cond) { 976a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B19 | B6, sd, S0, sm); 977a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 978a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 979a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 980a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcvtdu(DRegister dd, SRegister sm, Condition cond) { 981a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPds(cond, B23 | B21 | B20 | B19 | B8 | B6, dd, sm); 982a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 983a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 984a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 985a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmps(SRegister sd, SRegister sm, Condition cond) { 986a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B18 | B6, sd, S0, sm); 987a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 988a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 989a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 990a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmpd(DRegister dd, DRegister dm, Condition cond) { 991a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B18 | B6, dd, D0, dm); 992a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 993a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 994a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 995a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmpsz(SRegister sd, Condition cond) { 996a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPsss(cond, B23 | B21 | B20 | B18 | B16 | B6, sd, S0, S0); 997a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 998a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 999a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1000a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vcmpdz(DRegister dd, Condition cond) { 1001a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitVFPddd(cond, B23 | B21 | B20 | B18 | B16 | B6, dd, D0, D0); 1002a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1003a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1004a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1005a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::vmstat(Condition cond) { // VMRS APSR_nzcv, FPSCR 1006a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 1007a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1008a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B27 | B26 | B25 | B23 | B22 | B21 | B20 | B16 | 1009a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(PC)*B12) | 1010a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B11 | B9 | B4; 1011a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1012a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1013a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1014a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1015a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::svc(uint32_t imm24) { 1016a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK(IsUint(24, imm24)); 1017a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (AL << kConditionShift) | B27 | B26 | B25 | B24 | imm24; 1018a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1019a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1020a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1021a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1022a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::bkpt(uint16_t imm16) { 1023a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (AL << kConditionShift) | B24 | B21 | 1024a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf); 1025a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1026a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1027a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1028a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1029a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::b(Label* label, Condition cond) { 1030a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitBranch(cond, label, false); 1031a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1032a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1033a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1034a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::bl(Label* label, Condition cond) { 1035a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitBranch(cond, label, true); 1036a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1037a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1038a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1039a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::blx(Register rm, Condition cond) { 1040a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(rm, kNoRegister); 1041a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK_NE(cond, kNoCondition); 1042a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoding = (static_cast<int32_t>(cond) << kConditionShift) | 1043a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro B24 | B21 | (0xfff << 8) | B5 | B4 | 1044a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro (static_cast<int32_t>(rm) << kRmShift); 1045a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Emit(encoding); 1046a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1047a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1048a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1049a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::MarkExceptionHandler(Label* label) { 1050a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitType01(AL, 1, TST, 1, PC, R0, ShifterOperand(0)); 1051a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Label l; 1052a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro b(&l); 1053a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro EmitBranch(AL, label, false); 1054a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro Bind(&l); 1055a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1056a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1057a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1058a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::Bind(Label* label) { 1059a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK(!label->IsBound()); 1060a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int bound_pc = buffer_.Size(); 1061a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro while (label->IsLinked()) { 1062a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t position = label->Position(); 1063a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t next = buffer_.Load<int32_t>(position); 1064a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro int32_t encoded = Assembler::EncodeBranchOffset(bound_pc - position, next); 1065a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro buffer_.Store<int32_t>(position, encoded); 1066a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro label->position_ = Assembler::DecodeBranchOffset(next); 1067a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 1068a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro label->BindTo(bound_pc); 1069a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1070a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1071a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1072a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapirovoid Assembler::EncodeUint32InTstInstructions(uint32_t data) { 1073a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // TODO: Consider using movw ip, <16 bits>. 1074a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro while (!IsUint(8, data)) { 1075a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro tst(R0, ShifterOperand(data & 0xFF), VS); 1076a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro data >>= 8; 1077a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro } 1078a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro tst(R0, ShifterOperand(data), MI); 1079a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1080a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1081b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1082a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroint32_t Assembler::EncodeBranchOffset(int offset, int32_t inst) { 1083a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // The offset is off by 8 due to the way the ARM CPUs read PC. 1084a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro offset -= 8; 1085a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK(IsAligned(offset, 4)); 1086a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro CHECK(IsInt(CountOneBits(kBranchOffsetMask), offset)); 1087a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1088a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Properly preserve only the bits supported in the instruction. 1089a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro offset >>= 2; 1090a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro offset &= kBranchOffsetMask; 1091a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return (inst & ~kBranchOffsetMask) | offset; 1092a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1093a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1094a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1095a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiroint Assembler::DecodeBranchOffset(int32_t inst) { 1096a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro // Sign-extend, left-shift by 2, then add 8. 1097a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro return ((((inst & kBranchOffsetMask) << 8) >> 6) + 8); 1098a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro} 1099a2e18e1e77fc25c8260aad5daa267ababfcb65f6Carl Shapiro 1100b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::AddConstant(Register rd, int32_t value, Condition cond) { 1101b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(rd, rd, value, cond); 1102b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1103b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1104b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1105b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::AddConstant(Register rd, Register rn, int32_t value, 1106b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Condition cond) { 1107b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value == 0) { 1108b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (rd != rn) { 1109b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mov(rd, ShifterOperand(rn), cond); 1110b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1111b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return; 1112b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1113b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // We prefer to select the shorter code sequence rather than selecting add for 1114b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // positive values and sub for negatives ones, which would slightly improve 1115b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // the readability of generated code for some constants. 1116b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ShifterOperand shifter_op; 1117b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(value, &shifter_op)) { 1118b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(rd, rn, shifter_op, cond); 1119b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(-value, &shifter_op)) { 1120b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers sub(rd, rn, shifter_op, cond); 1121b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1122b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(rn != IP); 1123b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(~value, &shifter_op)) { 1124b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1125b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(rd, rn, ShifterOperand(IP), cond); 1126b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { 1127b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1128b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers sub(rd, rn, ShifterOperand(IP), cond); 1129b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1130b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movw(IP, Low16Bits(value), cond); 1131b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers uint16_t value_high = High16Bits(value); 1132b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value_high != 0) { 1133b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movt(IP, value_high, cond); 1134b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1135b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(rd, rn, ShifterOperand(IP), cond); 1136b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1137b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1138b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1139b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1140b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1141b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::AddConstantSetFlags(Register rd, Register rn, int32_t value, 1142b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Condition cond) { 1143b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ShifterOperand shifter_op; 1144b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(value, &shifter_op)) { 1145b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers adds(rd, rn, shifter_op, cond); 1146b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(-value, &shifter_op)) { 1147b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers subs(rd, rn, shifter_op, cond); 1148b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1149b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(rn != IP); 1150b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(~value, &shifter_op)) { 1151b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1152b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers adds(rd, rn, ShifterOperand(IP), cond); 1153b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(~(-value), &shifter_op)) { 1154b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(IP, shifter_op, cond); 1155b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers subs(rd, rn, ShifterOperand(IP), cond); 1156b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1157b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movw(IP, Low16Bits(value), cond); 1158b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers uint16_t value_high = High16Bits(value); 1159b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value_high != 0) { 1160b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movt(IP, value_high, cond); 1161b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1162b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers adds(rd, rn, ShifterOperand(IP), cond); 1163b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1164b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1165b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1166b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1167b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1168b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadImmediate(Register rd, int32_t value, Condition cond) { 1169b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ShifterOperand shifter_op; 1170b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (ShifterOperand::CanHold(value, &shifter_op)) { 1171b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mov(rd, shifter_op, cond); 1172b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else if (ShifterOperand::CanHold(~value, &shifter_op)) { 1173b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mvn(rd, shifter_op, cond); 1174b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1175b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movw(rd, Low16Bits(value), cond); 1176b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers uint16_t value_high = High16Bits(value); 1177b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (value_high != 0) { 1178b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers movt(rd, value_high, cond); 1179b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1180b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1181b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1182b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1183b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1184b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldLoadOffset(LoadOperandType type, int offset) { 1185b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1186b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedByte: 1187b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedHalfword: 1188b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedHalfword: 1189b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWordPair: 1190b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(8, offset); // Addressing mode 3. 1191b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedByte: 1192b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWord: 1193b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(12, offset); // Addressing mode 2. 1194b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSWord: 1195b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadDWord: 1196b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(10, offset); // VFP addressing mode. 1197b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1198b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1199b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return false; 1200b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1201b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1202b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1203b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1204b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersbool Address::CanHoldStoreOffset(StoreOperandType type, int offset) { 1205b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1206b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreHalfword: 1207b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWordPair: 1208b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(8, offset); // Addressing mode 3. 1209b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreByte: 1210b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWord: 1211b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(12, offset); // Addressing mode 2. 1212b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreSWord: 1213b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreDWord: 1214b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return IsAbsoluteUint(10, offset); // VFP addressing mode. 1215b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1216b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1217b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers return false; 1218b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1219b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1220b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1221b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1222b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when 1223b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldLoadOffset. 1224b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadFromOffset(LoadOperandType type, 1225b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register reg, 1226b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register base, 1227b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int32_t offset, 1228b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Condition cond) { 1229b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!Address::CanHoldLoadOffset(type, offset)) { 1230b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(base != IP); 1231b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(IP, offset, cond); 1232b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(IP, IP, ShifterOperand(base), cond); 1233b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers base = IP; 1234b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers offset = 0; 1235b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1236b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(Address::CanHoldLoadOffset(type, offset)); 1237b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1238b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedByte: 1239b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrsb(reg, Address(base, offset), cond); 1240b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1241b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedByte: 1242b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrb(reg, Address(base, offset), cond); 1243b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1244b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadSignedHalfword: 1245b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrsh(reg, Address(base, offset), cond); 1246b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1247b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadUnsignedHalfword: 1248b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrh(reg, Address(base, offset), cond); 1249b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1250b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWord: 1251b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldr(reg, Address(base, offset), cond); 1252b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1253b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kLoadWordPair: 1254b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ldrd(reg, Address(base, offset), cond); 1255b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1256b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1257b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1258b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1259b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1260b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1261b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1262b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Implementation note: this method must emit at most one instruction when 1263b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Address::CanHoldStoreOffset. 1264b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreToOffset(StoreOperandType type, 1265b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register reg, 1266b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Register base, 1267b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers int32_t offset, 1268b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Condition cond) { 1269b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!Address::CanHoldStoreOffset(type, offset)) { 1270b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(reg != IP); 1271b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(base != IP); 1272b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(IP, offset, cond); 1273b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers add(IP, IP, ShifterOperand(base), cond); 1274b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers base = IP; 1275b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers offset = 0; 1276b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1277b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(Address::CanHoldStoreOffset(type, offset)); 1278b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers switch (type) { 1279b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreByte: 1280b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers strb(reg, Address(base, offset), cond); 1281b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1282b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreHalfword: 1283b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers strh(reg, Address(base, offset), cond); 1284b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1285b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWord: 1286b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers str(reg, Address(base, offset), cond); 1287b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1288b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers case kStoreWordPair: 1289b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers strd(reg, Address(base, offset), cond); 1290b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers break; 1291b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers default: 1292b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "UNREACHABLE"; 1293b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1294b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1295b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1296b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Emit code that will create an activation on the stack 1297b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg) { 1298b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsAligned(frame_size, 16)); 1299b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: use stm/ldm 1300b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, LR, SP, 0); 1301b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, method_reg.AsCoreRegister(), SP, -4); 1302b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(SP, -frame_size); 1303b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1304b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1305b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Emit code that will remove an activation from the stack 1306b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::RemoveFrame(size_t frame_size) { 1307b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsAligned(frame_size, 16)); 1308b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, LR, SP, 0); 1309b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(SP, frame_size); 1310b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mov(PC, ShifterOperand(LR)); 1311b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1312b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1313b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::IncreaseFrameSize(size_t adjust) { 1314b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsAligned(adjust, 16)); 1315b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(SP, -adjust); 1316b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1317b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1318b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::DecreaseFrameSize(size_t adjust) { 1319b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(IsAligned(adjust, 16)); 1320b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(SP, adjust); 1321b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1322b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1323b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Store bytes from the given register onto the stack 1324b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Store(FrameOffset dest, ManagedRegister src, size_t size) { 1325b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (src.IsCoreRegister()) { 1326b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_EQ(4u, size); 1327b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value()); 1328b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1329b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // VFP 1330b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "TODO"; 1331b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1332b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1333b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1334b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreRef(FrameOffset dest, ManagedRegister src) { 1335b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(src.IsCoreRegister()); 1336b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, src.AsCoreRegister(), SP, dest.Int32Value()); 1337b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1338b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1339b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CopyRef(FrameOffset dest, FrameOffset src, 1340b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1341b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, src.Int32Value()); 1342b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value()); 1343b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1344b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1345b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadRef(ManagedRegister dest, ManagedRegister base, 1346b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers MemberOffset offs) { 1347b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(dest.IsCoreRegister() && dest.IsCoreRegister()); 1348b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), 1349b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers base.AsCoreRegister(), offs.Int32Value()); 1350b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1351b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1352b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm, 1353b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1354b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1355b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(scratch.AsCoreRegister(), imm); 1356b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, dest.Int32Value()); 1357b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1358b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1359b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreImmediateToThread(ThreadOffset dest, uint32_t imm, 1360b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1361b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1362b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(scratch.AsCoreRegister(), imm); 1363b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), TR, dest.Int32Value()); 1364b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1365b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1366b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Load(ManagedRegister dest, FrameOffset src, size_t size) { 1367b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (dest.IsCoreRegister()) { 1368b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK_EQ(4u, size); 1369b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), SP, src.Int32Value()); 1370b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1371b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: VFP 1372b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "Unimplemented"; 1373b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1374b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1375b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1376b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadRawPtrFromThread(ManagedRegister dest, ThreadOffset offs) { 1377b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(dest.IsCoreRegister()); 1378b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, dest.AsCoreRegister(), 1379b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, offs.Int32Value()); 1380b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1381b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1382b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CopyRawPtrFromThread(FrameOffset fr_offs, ThreadOffset thr_offs, 1383b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1384b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1385b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1386b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, thr_offs.Int32Value()); 1387b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 1388b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SP, fr_offs.Int32Value()); 1389b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1390b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1391b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CopyRawPtrToThread(ThreadOffset thr_offs, FrameOffset fr_offs, 1392b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1393b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1394b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1395b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SP, fr_offs.Int32Value()); 1396b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 1397b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, thr_offs.Int32Value()); 1398b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1399b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1400b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::StoreStackOffsetToThread(ThreadOffset thr_offs, 1401b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset fr_offs, 1402b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1403b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1404b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(scratch.AsCoreRegister(), SP, fr_offs.Int32Value(), AL); 1405b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 1406b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers TR, thr_offs.Int32Value()); 1407b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1408b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1409b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Move(ManagedRegister dest, ManagedRegister src) { 1410b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (dest.IsCoreRegister()) { 1411b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(src.IsCoreRegister()); 1412b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers mov(dest.AsCoreRegister(), ShifterOperand(src.AsCoreRegister())); 1413b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1414b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: VFP 1415b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "Unimplemented"; 1416b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1417b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1418b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1419b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Copy(FrameOffset dest, FrameOffset src, ManagedRegister scratch, 1420b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers size_t size) { 1421b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1422b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (size == 4) { 1423b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1424b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SP, src.Int32Value()); 1425b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), 1426b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers SP, dest.Int32Value()); 1427b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1428b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: size != 4 1429b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "Unimplemented"; 1430b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1431b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1432b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1433b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CreateStackHandle(ManagedRegister out_reg, 1434b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset handle_offset, 1435b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister in_reg, bool null_allowed) { 1436b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(in_reg.IsCoreRegister()); 1437b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(out_reg.IsCoreRegister()); 1438b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (null_allowed) { 1439b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Null values get a handle value of 0. Otherwise, the handle value is 1440b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // the address in the stack handle block holding the reference. 1441b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // e.g. out_reg = (handle == 0) ? 0 : (SP+handle_offset) 1442b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers cmp(in_reg.AsCoreRegister(), ShifterOperand(0)); 1443b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!out_reg.Equals(in_reg)) { 1444b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(out_reg.AsCoreRegister(), 0, EQ); 1445b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1446b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(out_reg.AsCoreRegister(), SP, handle_offset.Int32Value(), NE); 1447b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1448b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(out_reg.AsCoreRegister(), SP, handle_offset.Int32Value(), AL); 1449b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1450b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1451b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1452b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::CreateStackHandle(FrameOffset out_off, 1453b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset handle_offset, 1454b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch, bool null_allowed) { 1455b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1456b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (null_allowed) { 1457b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), SP, 1458b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers handle_offset.Int32Value()); 1459b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // Null values get a handle value of 0. Otherwise, the handle value is 1460b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // the address in the stack handle block holding the reference. 1461b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // e.g. scratch = (handle == 0) ? 0 : (SP+handle_offset) 1462b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers cmp(scratch.AsCoreRegister(), ShifterOperand(0)); 1463b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(scratch.AsCoreRegister(), SP, handle_offset.Int32Value(), NE); 1464b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } else { 1465b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers AddConstant(scratch.AsCoreRegister(), SP, handle_offset.Int32Value(), AL); 1466b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1467b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers StoreToOffset(kStoreWord, scratch.AsCoreRegister(), SP, out_off.Int32Value()); 1468b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1469b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1470b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LoadReferenceFromStackHandle(ManagedRegister out_reg, 1471b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister in_reg, 1472b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers FrameOffset shb_offset) { 1473b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(out_reg.IsCoreRegister()); 1474b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(in_reg.IsCoreRegister()); 1475b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers Label null_arg; 1476b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers if (!out_reg.Equals(in_reg)) { 1477b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadImmediate(out_reg.AsCoreRegister(), 0, EQ); 1478b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers } 1479b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers cmp(in_reg.AsCoreRegister(), ShifterOperand(0)); 1480b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, out_reg.AsCoreRegister(), in_reg.AsCoreRegister(), 1481b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers shb_offset.Int32Value(), NE); 1482b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1483b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1484b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::ValidateRef(ManagedRegister src, bool could_be_null) { 1485b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: not validating references 1486b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1487b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1488b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::ValidateRef(FrameOffset src, bool could_be_null) { 1489b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: not validating references 1490b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1491b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1492b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::Call(ManagedRegister base, MemberOffset offset, 1493b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers ManagedRegister scratch) { 1494b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(base.IsCoreRegister()); 1495b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers CHECK(scratch.IsCoreRegister()); 1496b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LoadFromOffset(kLoadWord, scratch.AsCoreRegister(), 1497b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers base.AsCoreRegister(), offset.Int32Value()); 1498b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers blx(scratch.AsCoreRegister()); 1499b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers // TODO: place reference map on call 1500b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1501b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 1502b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Emit code that will lock the reference in the given register 1503b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::LockReferenceOnStack(FrameOffset fr_offs) { 1504b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "TODO"; 1505b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1506b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers// Emit code that will unlock the reference in the given register 1507b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogersvoid Assembler::UnLockReferenceOnStack(FrameOffset fr_offs) { 1508b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers LOG(FATAL) << "TODO"; 1509b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers} 1510b033c75ebda80ac75f936366fe78d1edf5cec937Ian Rogers 15116b6b5f0e67ce03f38223a525612955663bc1799bCarl Shapiro} // namespace art 1512