1*4bdc9457SAndroid Build Coastguard Worker // Copyright 2021 Google LLC 2*4bdc9457SAndroid Build Coastguard Worker // 3*4bdc9457SAndroid Build Coastguard Worker // This source code is licensed under the BSD-style license found in the 4*4bdc9457SAndroid Build Coastguard Worker // LICENSE file in the root directory of this source tree. 5*4bdc9457SAndroid Build Coastguard Worker 6*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/allocator.h> 7*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/assembler.h> 8*4bdc9457SAndroid Build Coastguard Worker 9*4bdc9457SAndroid Build Coastguard Worker #include <cstddef> 10*4bdc9457SAndroid Build Coastguard Worker #include <cstdint> 11*4bdc9457SAndroid Build Coastguard Worker #include <initializer_list> 12*4bdc9457SAndroid Build Coastguard Worker 13*4bdc9457SAndroid Build Coastguard Worker namespace xnnpack { 14*4bdc9457SAndroid Build Coastguard Worker namespace aarch32 { 15*4bdc9457SAndroid Build Coastguard Worker 16*4bdc9457SAndroid Build Coastguard Worker enum class SpecialFPRegister { 17*4bdc9457SAndroid Build Coastguard Worker kFPSCR = 1, 18*4bdc9457SAndroid Build Coastguard Worker }; 19*4bdc9457SAndroid Build Coastguard Worker 20*4bdc9457SAndroid Build Coastguard Worker constexpr SpecialFPRegister FPSCR = SpecialFPRegister::kFPSCR; 21*4bdc9457SAndroid Build Coastguard Worker 22*4bdc9457SAndroid Build Coastguard Worker struct CoreRegister { 23*4bdc9457SAndroid Build Coastguard Worker uint8_t code; 24*4bdc9457SAndroid Build Coastguard Worker }; 25*4bdc9457SAndroid Build Coastguard Worker 26*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r0{0}; 27*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r1{1}; 28*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r2{2}; 29*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r3{3}; 30*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r4{4}; 31*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r5{5}; 32*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r6{6}; 33*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r7{7}; 34*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r8{8}; 35*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r9{9}; 36*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r10{10}; 37*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r11{11}; 38*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r12{12}; 39*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r13{13}; 40*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r14{14}; 41*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister r15{15}; 42*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister sp = r13; 43*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister lr = r14; 44*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister pc = r15; 45*4bdc9457SAndroid Build Coastguard Worker constexpr CoreRegister APSR_nzcv = r15; 46*4bdc9457SAndroid Build Coastguard Worker 47*4bdc9457SAndroid Build Coastguard Worker static inline bool operator==(const CoreRegister lhs, const CoreRegister rhs) { 48*4bdc9457SAndroid Build Coastguard Worker return lhs.code == rhs.code; 49*4bdc9457SAndroid Build Coastguard Worker } 50*4bdc9457SAndroid Build Coastguard Worker 51*4bdc9457SAndroid Build Coastguard Worker struct CoreRegisterList { CoreRegisterListCoreRegisterList52*4bdc9457SAndroid Build Coastguard Worker CoreRegisterList(std::initializer_list<CoreRegister> rs) { 53*4bdc9457SAndroid Build Coastguard Worker for (auto r : rs) { 54*4bdc9457SAndroid Build Coastguard Worker list |= 1 << r.code; 55*4bdc9457SAndroid Build Coastguard Worker } 56*4bdc9457SAndroid Build Coastguard Worker } 57*4bdc9457SAndroid Build Coastguard Worker has_more_than_one_registerCoreRegisterList58*4bdc9457SAndroid Build Coastguard Worker bool has_more_than_one_register() { return (list & (list - 1)) != 0; } 59*4bdc9457SAndroid Build Coastguard Worker 60*4bdc9457SAndroid Build Coastguard Worker // Bit i is set if CoreRegister is in the list. 61*4bdc9457SAndroid Build Coastguard Worker uint16_t list = 0; 62*4bdc9457SAndroid Build Coastguard Worker }; 63*4bdc9457SAndroid Build Coastguard Worker 64*4bdc9457SAndroid Build Coastguard Worker static inline bool operator==(int i, CoreRegisterList registers) { 65*4bdc9457SAndroid Build Coastguard Worker return i == registers.list; 66*4bdc9457SAndroid Build Coastguard Worker } 67*4bdc9457SAndroid Build Coastguard Worker 68*4bdc9457SAndroid Build Coastguard Worker struct SRegister { 69*4bdc9457SAndroid Build Coastguard Worker uint8_t code; dSRegister70*4bdc9457SAndroid Build Coastguard Worker uint8_t d() const { return code & 0x1; } vdSRegister71*4bdc9457SAndroid Build Coastguard Worker uint8_t vd() const { return (code & 0x1e) >> 1; } 72*4bdc9457SAndroid Build Coastguard Worker }; 73*4bdc9457SAndroid Build Coastguard Worker 74*4bdc9457SAndroid Build Coastguard Worker static inline bool operator==(const SRegister lhs, const SRegister rhs) { 75*4bdc9457SAndroid Build Coastguard Worker return lhs.code == rhs.code; 76*4bdc9457SAndroid Build Coastguard Worker } 77*4bdc9457SAndroid Build Coastguard Worker 78*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s0{0}; 79*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s1{1}; 80*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s2{2}; 81*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s3{3}; 82*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s4{4}; 83*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s5{5}; 84*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s6{6}; 85*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s7{7}; 86*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s8{8}; 87*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s9{9}; 88*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s10{10}; 89*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s11{11}; 90*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s12{12}; 91*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s13{13}; 92*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s14{14}; 93*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s15{15}; 94*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s16{16}; 95*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s17{17}; 96*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s18{18}; 97*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s19{19}; 98*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s20{20}; 99*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s21{21}; 100*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s22{22}; 101*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s23{23}; 102*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s24{24}; 103*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s25{25}; 104*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s26{26}; 105*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s27{27}; 106*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s28{28}; 107*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s29{29}; 108*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s30{30}; 109*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s31{31}; 110*4bdc9457SAndroid Build Coastguard Worker 111*4bdc9457SAndroid Build Coastguard Worker // Define DRegisterLane before DRegister so that we can have the operator[] overloading for nice syntax. 112*4bdc9457SAndroid Build Coastguard Worker struct DRegisterLane { 113*4bdc9457SAndroid Build Coastguard Worker uint8_t code; 114*4bdc9457SAndroid Build Coastguard Worker uint8_t lane; 115*4bdc9457SAndroid Build Coastguard Worker dDRegisterLane116*4bdc9457SAndroid Build Coastguard Worker uint8_t d() const { return (code & 0x10) >> 4; } vdDRegisterLane117*4bdc9457SAndroid Build Coastguard Worker uint8_t vd() const { return code & 0xf; } 118*4bdc9457SAndroid Build Coastguard Worker }; 119*4bdc9457SAndroid Build Coastguard Worker 120*4bdc9457SAndroid Build Coastguard Worker static inline bool operator==(const DRegisterLane lhs, const DRegisterLane rhs) { 121*4bdc9457SAndroid Build Coastguard Worker return lhs.code == rhs.code && lhs.lane == rhs.lane; 122*4bdc9457SAndroid Build Coastguard Worker } 123*4bdc9457SAndroid Build Coastguard Worker 124*4bdc9457SAndroid Build Coastguard Worker struct DRegister { 125*4bdc9457SAndroid Build Coastguard Worker uint8_t code; 126*4bdc9457SAndroid Build Coastguard Worker dDRegister127*4bdc9457SAndroid Build Coastguard Worker uint8_t d() const { return (code & 0x10) >> 4; } vdDRegister128*4bdc9457SAndroid Build Coastguard Worker uint8_t vd() const { return code & 0xf; } 129*4bdc9457SAndroid Build Coastguard Worker 130*4bdc9457SAndroid Build Coastguard Worker const DRegisterLane operator[](std::size_t pos) const { 131*4bdc9457SAndroid Build Coastguard Worker return DRegisterLane{code, static_cast<uint8_t>(pos)}; 132*4bdc9457SAndroid Build Coastguard Worker } 133*4bdc9457SAndroid Build Coastguard Worker }; 134*4bdc9457SAndroid Build Coastguard Worker 135*4bdc9457SAndroid Build Coastguard Worker static inline bool operator==(const DRegister lhs, const DRegister rhs) { 136*4bdc9457SAndroid Build Coastguard Worker return lhs.code == rhs.code; 137*4bdc9457SAndroid Build Coastguard Worker } 138*4bdc9457SAndroid Build Coastguard Worker 139*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d0{0}; 140*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d1{1}; 141*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d2{2}; 142*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d3{3}; 143*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d4{4}; 144*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d5{5}; 145*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d6{6}; 146*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d7{7}; 147*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d8{8}; 148*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d9{9}; 149*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d10{10}; 150*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d11{11}; 151*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d12{12}; 152*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d13{13}; 153*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d14{14}; 154*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d15{15}; 155*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d16{16}; 156*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d17{17}; 157*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d18{18}; 158*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d19{19}; 159*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d20{20}; 160*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d21{21}; 161*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d22{22}; 162*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d23{23}; 163*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d24{24}; 164*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d25{25}; 165*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d26{26}; 166*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d27{27}; 167*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d28{28}; 168*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d29{29}; 169*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d30{30}; 170*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d31{31}; 171*4bdc9457SAndroid Build Coastguard Worker 172*4bdc9457SAndroid Build Coastguard Worker struct QRegister { 173*4bdc9457SAndroid Build Coastguard Worker uint8_t code; 174*4bdc9457SAndroid Build Coastguard Worker // Encode code * 2. dQRegister175*4bdc9457SAndroid Build Coastguard Worker uint8_t d() const { return (code & 0x8) >> 3; } vdQRegister176*4bdc9457SAndroid Build Coastguard Worker uint8_t vd() const { return (code & 0x7) << 1; } lowQRegister177*4bdc9457SAndroid Build Coastguard Worker DRegister low() const { return DRegister{uint8_t(code * 2)}; } highQRegister178*4bdc9457SAndroid Build Coastguard Worker DRegister high() const { return DRegister{uint8_t(code * 2 + 1)}; } 179*4bdc9457SAndroid Build Coastguard Worker }; 180*4bdc9457SAndroid Build Coastguard Worker 181*4bdc9457SAndroid Build Coastguard Worker static inline bool operator==(const QRegister lhs, const QRegister rhs) { 182*4bdc9457SAndroid Build Coastguard Worker return lhs.code == rhs.code; 183*4bdc9457SAndroid Build Coastguard Worker } 184*4bdc9457SAndroid Build Coastguard Worker 185*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q0{0}; 186*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q1{1}; 187*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q2{2}; 188*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q3{3}; 189*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q4{4}; 190*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q5{5}; 191*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q6{6}; 192*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q7{7}; 193*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q8{8}; 194*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q9{9}; 195*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q10{10}; 196*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q11{11}; 197*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q12{12}; 198*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q13{13}; 199*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q14{14}; 200*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q15{15}; 201*4bdc9457SAndroid Build Coastguard Worker 202*4bdc9457SAndroid Build Coastguard Worker // SIMD register lists are used in a more restrictive way, compared to core 203*4bdc9457SAndroid Build Coastguard Worker // registers, only consecutive registers are used as an operand to instruction. 204*4bdc9457SAndroid Build Coastguard Worker template <typename RegType> 205*4bdc9457SAndroid Build Coastguard Worker struct ConsecutiveRegisterList { 206*4bdc9457SAndroid Build Coastguard Worker // End must be >= start. ConsecutiveRegisterListConsecutiveRegisterList207*4bdc9457SAndroid Build Coastguard Worker ConsecutiveRegisterList(RegType s, RegType end) 208*4bdc9457SAndroid Build Coastguard Worker : start(s), 209*4bdc9457SAndroid Build Coastguard Worker length(end.code - s.code + 1) {} ConsecutiveRegisterListConsecutiveRegisterList210*4bdc9457SAndroid Build Coastguard Worker explicit ConsecutiveRegisterList(RegType s, int len) 211*4bdc9457SAndroid Build Coastguard Worker : start(s), 212*4bdc9457SAndroid Build Coastguard Worker length(len) {} ConsecutiveRegisterListConsecutiveRegisterList213*4bdc9457SAndroid Build Coastguard Worker ConsecutiveRegisterList(RegType start) 214*4bdc9457SAndroid Build Coastguard Worker : ConsecutiveRegisterList(start, start) {} 215*4bdc9457SAndroid Build Coastguard Worker 216*4bdc9457SAndroid Build Coastguard Worker RegType start; 217*4bdc9457SAndroid Build Coastguard Worker uint8_t length; 218*4bdc9457SAndroid Build Coastguard Worker }; 219*4bdc9457SAndroid Build Coastguard Worker 220*4bdc9457SAndroid Build Coastguard Worker // Specific struct for VLD2 and VLD3 register list operand. 221*4bdc9457SAndroid Build Coastguard Worker struct VLoadStoreRegList { VLoadStoreRegListVLoadStoreRegList222*4bdc9457SAndroid Build Coastguard Worker VLoadStoreRegList(DRegister reg1, DRegister reg2) 223*4bdc9457SAndroid Build Coastguard Worker : reg1(reg1), reg2(reg2) { 224*4bdc9457SAndroid Build Coastguard Worker if (reg1.code == reg2.code - 2) { 225*4bdc9457SAndroid Build Coastguard Worker double_spaced = true; 226*4bdc9457SAndroid Build Coastguard Worker } else { 227*4bdc9457SAndroid Build Coastguard Worker double_spaced = false; 228*4bdc9457SAndroid Build Coastguard Worker } 229*4bdc9457SAndroid Build Coastguard Worker } VLoadStoreRegListVLoadStoreRegList230*4bdc9457SAndroid Build Coastguard Worker VLoadStoreRegList(DRegister reg1, DRegister reg2, DRegister reg3) 231*4bdc9457SAndroid Build Coastguard Worker : reg1(reg1), reg2(reg2), reg3(reg3) { 232*4bdc9457SAndroid Build Coastguard Worker if (reg1.code == reg2.code - 2) { 233*4bdc9457SAndroid Build Coastguard Worker double_spaced = true; 234*4bdc9457SAndroid Build Coastguard Worker } else { 235*4bdc9457SAndroid Build Coastguard Worker double_spaced = false; 236*4bdc9457SAndroid Build Coastguard Worker } 237*4bdc9457SAndroid Build Coastguard Worker } 238*4bdc9457SAndroid Build Coastguard Worker 239*4bdc9457SAndroid Build Coastguard Worker DRegister reg1; 240*4bdc9457SAndroid Build Coastguard Worker DRegister reg2; 241*4bdc9457SAndroid Build Coastguard Worker DRegister reg3; 242*4bdc9457SAndroid Build Coastguard Worker bool double_spaced; 243*4bdc9457SAndroid Build Coastguard Worker }; 244*4bdc9457SAndroid Build Coastguard Worker 245*4bdc9457SAndroid Build Coastguard Worker using SRegisterList = ConsecutiveRegisterList<SRegister>; 246*4bdc9457SAndroid Build Coastguard Worker using DRegisterList = ConsecutiveRegisterList<DRegister>; 247*4bdc9457SAndroid Build Coastguard Worker 248*4bdc9457SAndroid Build Coastguard Worker static inline SRegisterList operator-(const SRegister lhs, const SRegister rhs) { 249*4bdc9457SAndroid Build Coastguard Worker return SRegisterList(lhs, rhs); 250*4bdc9457SAndroid Build Coastguard Worker } 251*4bdc9457SAndroid Build Coastguard Worker 252*4bdc9457SAndroid Build Coastguard Worker static inline DRegisterList operator-(const DRegister lhs, const DRegister rhs) { 253*4bdc9457SAndroid Build Coastguard Worker return DRegisterList(lhs, rhs); 254*4bdc9457SAndroid Build Coastguard Worker } 255*4bdc9457SAndroid Build Coastguard Worker 256*4bdc9457SAndroid Build Coastguard Worker struct QRegisterList { QRegisterListQRegisterList257*4bdc9457SAndroid Build Coastguard Worker QRegisterList(QRegister s) : start(s), length(1) {} QRegisterListQRegisterList258*4bdc9457SAndroid Build Coastguard Worker QRegisterList(QRegister s, QRegister end) : start(s), length(end.code - s.code + 1) {} 259*4bdc9457SAndroid Build Coastguard Worker // Explicit conversion to DRegisterList. DRegisterListQRegisterList260*4bdc9457SAndroid Build Coastguard Worker explicit operator DRegisterList() const { 261*4bdc9457SAndroid Build Coastguard Worker return DRegisterList({static_cast<uint8_t>(start.code * 2)}, length * 2); 262*4bdc9457SAndroid Build Coastguard Worker } 263*4bdc9457SAndroid Build Coastguard Worker 264*4bdc9457SAndroid Build Coastguard Worker QRegister start; 265*4bdc9457SAndroid Build Coastguard Worker uint8_t length; 266*4bdc9457SAndroid Build Coastguard Worker }; 267*4bdc9457SAndroid Build Coastguard Worker 268*4bdc9457SAndroid Build Coastguard Worker static inline QRegisterList operator-(const QRegister lhs, const QRegister rhs) { 269*4bdc9457SAndroid Build Coastguard Worker return QRegisterList(lhs, rhs); 270*4bdc9457SAndroid Build Coastguard Worker } 271*4bdc9457SAndroid Build Coastguard Worker 272*4bdc9457SAndroid Build Coastguard Worker // A8.5 Addressing modes for memory access. 273*4bdc9457SAndroid Build Coastguard Worker enum class AddressingMode { 274*4bdc9457SAndroid Build Coastguard Worker // [<Rn>, <offset>], offset applied to address in Rn. 275*4bdc9457SAndroid Build Coastguard Worker kOffset, 276*4bdc9457SAndroid Build Coastguard Worker // Pre-indexed not used, so not implemented. 277*4bdc9457SAndroid Build Coastguard Worker // [<Rn>], <offset>, address from Rn, offset applied, written back to Rn. 278*4bdc9457SAndroid Build Coastguard Worker kPostIndexed, 279*4bdc9457SAndroid Build Coastguard Worker }; 280*4bdc9457SAndroid Build Coastguard Worker 281*4bdc9457SAndroid Build Coastguard Worker // Memory operands, operands for memory access instructions. See 282*4bdc9457SAndroid Build Coastguard Worker // "MemOperandHelper mem" for a nicer syntax that is closer to assembly. 283*4bdc9457SAndroid Build Coastguard Worker class MemOperand { 284*4bdc9457SAndroid Build Coastguard Worker public: MemOperand(CoreRegister rn,int32_t offset)285*4bdc9457SAndroid Build Coastguard Worker MemOperand(CoreRegister rn, int32_t offset) 286*4bdc9457SAndroid Build Coastguard Worker : mode_(AddressingMode::kOffset), 287*4bdc9457SAndroid Build Coastguard Worker rn_(rn), 288*4bdc9457SAndroid Build Coastguard Worker offset_(offset) {} 289*4bdc9457SAndroid Build Coastguard Worker MemOperand(CoreRegister rn,int32_t offset,AddressingMode mode)290*4bdc9457SAndroid Build Coastguard Worker MemOperand(CoreRegister rn, int32_t offset, AddressingMode mode) 291*4bdc9457SAndroid Build Coastguard Worker : mode_(mode), 292*4bdc9457SAndroid Build Coastguard Worker rn_(rn), 293*4bdc9457SAndroid Build Coastguard Worker offset_(offset) {} 294*4bdc9457SAndroid Build Coastguard Worker base()295*4bdc9457SAndroid Build Coastguard Worker CoreRegister base() const { return rn_; } offset()296*4bdc9457SAndroid Build Coastguard Worker int32_t offset() const { return offset_; } mode()297*4bdc9457SAndroid Build Coastguard Worker AddressingMode mode() const { return mode_; } 298*4bdc9457SAndroid Build Coastguard Worker 299*4bdc9457SAndroid Build Coastguard Worker // These are bits used for encoding, named based on the encoding description. u()300*4bdc9457SAndroid Build Coastguard Worker int32_t u() { return offset_ >= 0; } p()301*4bdc9457SAndroid Build Coastguard Worker int32_t p() { return mode_ != AddressingMode::kPostIndexed; } 302*4bdc9457SAndroid Build Coastguard Worker // Note, kPostIndexed will write back, but doesn't need to set bit w. w()303*4bdc9457SAndroid Build Coastguard Worker int32_t w() { return 0; } 304*4bdc9457SAndroid Build Coastguard Worker 305*4bdc9457SAndroid Build Coastguard Worker // Overload postfix increment to indicate a post-indexed addressing mode for load/stores. 306*4bdc9457SAndroid Build Coastguard Worker MemOperand operator++(int) { 307*4bdc9457SAndroid Build Coastguard Worker mode_ = AddressingMode::kPostIndexed; 308*4bdc9457SAndroid Build Coastguard Worker return *this; 309*4bdc9457SAndroid Build Coastguard Worker } 310*4bdc9457SAndroid Build Coastguard Worker 311*4bdc9457SAndroid Build Coastguard Worker private: 312*4bdc9457SAndroid Build Coastguard Worker AddressingMode mode_; 313*4bdc9457SAndroid Build Coastguard Worker CoreRegister rn_; 314*4bdc9457SAndroid Build Coastguard Worker int32_t offset_; 315*4bdc9457SAndroid Build Coastguard Worker }; 316*4bdc9457SAndroid Build Coastguard Worker 317*4bdc9457SAndroid Build Coastguard Worker static inline bool operator==(const MemOperand lhs, const MemOperand rhs) { 318*4bdc9457SAndroid Build Coastguard Worker return lhs.mode() == rhs.mode() && lhs.base() == rhs.base() && lhs.offset() == rhs.offset(); 319*4bdc9457SAndroid Build Coastguard Worker } 320*4bdc9457SAndroid Build Coastguard Worker 321*4bdc9457SAndroid Build Coastguard Worker static inline MemOperand operator,(CoreRegister r, int32_t offset) { 322*4bdc9457SAndroid Build Coastguard Worker return MemOperand(r, offset); 323*4bdc9457SAndroid Build Coastguard Worker } 324*4bdc9457SAndroid Build Coastguard Worker 325*4bdc9457SAndroid Build Coastguard Worker // Helper struct for some syntax sugar to look like native assembly, see mem. 326*4bdc9457SAndroid Build Coastguard Worker struct MemOperandHelper { 327*4bdc9457SAndroid Build Coastguard Worker const MemOperand operator[](MemOperand op) const { return op; } 328*4bdc9457SAndroid Build Coastguard Worker MemOperand operator[](CoreRegister r) const { return MemOperand(r, 0); } 329*4bdc9457SAndroid Build Coastguard Worker }; 330*4bdc9457SAndroid Build Coastguard Worker 331*4bdc9457SAndroid Build Coastguard Worker // Use "mem" (and its overload of array subscript operator) to get some syntax 332*4bdc9457SAndroid Build Coastguard Worker // that looks closer to native assembly when accessing memory. For example: 333*4bdc9457SAndroid Build Coastguard Worker // - ldr(r0, mem[rn, offset]); // offset 334*4bdc9457SAndroid Build Coastguard Worker // - ldr(r0, mem[rn], offset); // post-indexed 335*4bdc9457SAndroid Build Coastguard Worker constexpr MemOperandHelper mem; 336*4bdc9457SAndroid Build Coastguard Worker 337*4bdc9457SAndroid Build Coastguard Worker // Conditional execution, only support AL (always) for now. 338*4bdc9457SAndroid Build Coastguard Worker enum Condition : uint32_t { 339*4bdc9457SAndroid Build Coastguard Worker kEQ = 0x00000000, 340*4bdc9457SAndroid Build Coastguard Worker kNE = 0x10000000, 341*4bdc9457SAndroid Build Coastguard Worker kCS = 0x20000000, 342*4bdc9457SAndroid Build Coastguard Worker kCC = 0x30000000, 343*4bdc9457SAndroid Build Coastguard Worker kMI = 0x40000000, 344*4bdc9457SAndroid Build Coastguard Worker kPL = 0x50000000, 345*4bdc9457SAndroid Build Coastguard Worker kVS = 0x60000000, 346*4bdc9457SAndroid Build Coastguard Worker kVC = 0x70000000, 347*4bdc9457SAndroid Build Coastguard Worker kHI = 0x80000000, 348*4bdc9457SAndroid Build Coastguard Worker kLS = 0x90000000, 349*4bdc9457SAndroid Build Coastguard Worker kGE = 0xa0000000, 350*4bdc9457SAndroid Build Coastguard Worker kLT = 0xB0000000, 351*4bdc9457SAndroid Build Coastguard Worker kGT = 0xC0000000, 352*4bdc9457SAndroid Build Coastguard Worker kLE = 0xD0000000, 353*4bdc9457SAndroid Build Coastguard Worker kAL = 0xE0000000, 354*4bdc9457SAndroid Build Coastguard Worker kHS = kCS, 355*4bdc9457SAndroid Build Coastguard Worker kLO = kCC, 356*4bdc9457SAndroid Build Coastguard Worker }; 357*4bdc9457SAndroid Build Coastguard Worker 358*4bdc9457SAndroid Build Coastguard Worker enum DataSize { 359*4bdc9457SAndroid Build Coastguard Worker k8 = 0, 360*4bdc9457SAndroid Build Coastguard Worker k16 = 1, 361*4bdc9457SAndroid Build Coastguard Worker k32 = 2, 362*4bdc9457SAndroid Build Coastguard Worker }; 363*4bdc9457SAndroid Build Coastguard Worker 364*4bdc9457SAndroid Build Coastguard Worker // A simple AAarch32 assembler. 365*4bdc9457SAndroid Build Coastguard Worker class Assembler : public AssemblerBase { 366*4bdc9457SAndroid Build Coastguard Worker public: 367*4bdc9457SAndroid Build Coastguard Worker using AssemblerBase::AssemblerBase; 368*4bdc9457SAndroid Build Coastguard Worker add(CoreRegister rn,CoreRegister rm)369*4bdc9457SAndroid Build Coastguard Worker void add(CoreRegister rn, CoreRegister rm) { add(rn, rn, rm); } 370*4bdc9457SAndroid Build Coastguard Worker void add(CoreRegister rd, CoreRegister rn, CoreRegister rm); 371*4bdc9457SAndroid Build Coastguard Worker // Only support uint8_t immediates for now, it simplifies encoding. 372*4bdc9457SAndroid Build Coastguard Worker void add(CoreRegister rd, CoreRegister rn, uint8_t imm); 373*4bdc9457SAndroid Build Coastguard Worker void adds(CoreRegister rd, CoreRegister rn, uint8_t imm); 374*4bdc9457SAndroid Build Coastguard Worker void and_(CoreRegister rd, CoreRegister rn, uint8_t imm); b(Label & l)375*4bdc9457SAndroid Build Coastguard Worker void b(Label& l) { b(kAL, l); } beq(Label & l)376*4bdc9457SAndroid Build Coastguard Worker void beq(Label& l) { b(kEQ, l); } bne(Label & l)377*4bdc9457SAndroid Build Coastguard Worker void bne(Label& l) { b(kNE, l); } bhi(Label & l)378*4bdc9457SAndroid Build Coastguard Worker void bhi(Label& l) { b(kHI, l); } bhs(Label & l)379*4bdc9457SAndroid Build Coastguard Worker void bhs(Label& l) { b(kHS, l); } blo(Label & l)380*4bdc9457SAndroid Build Coastguard Worker void blo(Label& l) { b(kLO, l); } 381*4bdc9457SAndroid Build Coastguard Worker void bic(CoreRegister rd, CoreRegister rn, uint8_t imm); 382*4bdc9457SAndroid Build Coastguard Worker void bx(CoreRegister rm); 383*4bdc9457SAndroid Build Coastguard Worker // Cmp supports a subset of uint32_t offsets, see "A5.2.4 Modified immediate 384*4bdc9457SAndroid Build Coastguard Worker // constants in ARM instructions", for simplicity we start with uint8_t, which 385*4bdc9457SAndroid Build Coastguard Worker // is fully representation using a "rotation" of 0. 386*4bdc9457SAndroid Build Coastguard Worker void cmp(CoreRegister rn, uint8_t imm); 387*4bdc9457SAndroid Build Coastguard Worker void cmp(CoreRegister rn, CoreRegister rm); 388*4bdc9457SAndroid Build Coastguard Worker void ldr(CoreRegister rt, MemOperand operand, int32_t offset); 389*4bdc9457SAndroid Build Coastguard Worker void ldr(CoreRegister rt, MemOperand operand); 390*4bdc9457SAndroid Build Coastguard Worker // LDRD <Rt>, <Rt2>, [<Rn>{, #+/-<imm>}]. 391*4bdc9457SAndroid Build Coastguard Worker void ldrd(CoreRegister rt, CoreRegister rt2, MemOperand op); 392*4bdc9457SAndroid Build Coastguard Worker void mov(CoreRegister rd, CoreRegister rm); moveq(CoreRegister rd,CoreRegister rm)393*4bdc9457SAndroid Build Coastguard Worker void moveq(CoreRegister rd, CoreRegister rm) { mov(kEQ, rd, rm); } movlo(CoreRegister rd,CoreRegister rm)394*4bdc9457SAndroid Build Coastguard Worker void movlo(CoreRegister rd, CoreRegister rm) { mov(kLO, rd, rm); } movls(CoreRegister rd,CoreRegister rm)395*4bdc9457SAndroid Build Coastguard Worker void movls(CoreRegister rd, CoreRegister rm) { mov(kLS, rd, rm); } 396*4bdc9457SAndroid Build Coastguard Worker void nop(); 397*4bdc9457SAndroid Build Coastguard Worker void pld(MemOperand operand); 398*4bdc9457SAndroid Build Coastguard Worker void pop(CoreRegisterList regs); 399*4bdc9457SAndroid Build Coastguard Worker void push(CoreRegisterList regs); 400*4bdc9457SAndroid Build Coastguard Worker void str(CoreRegister rt, MemOperand op); 401*4bdc9457SAndroid Build Coastguard Worker void sub(CoreRegister rd, CoreRegister rn, uint8_t imm); 402*4bdc9457SAndroid Build Coastguard Worker void sub(CoreRegister rd, CoreRegister rn, CoreRegister rm); 403*4bdc9457SAndroid Build Coastguard Worker // Only support uint8_t immediates for now, it simplifies encoding. 404*4bdc9457SAndroid Build Coastguard Worker void subs(CoreRegister rd, CoreRegister rn, uint8_t imm); 405*4bdc9457SAndroid Build Coastguard Worker void tst(CoreRegister rn, uint8_t imm); 406*4bdc9457SAndroid Build Coastguard Worker 407*4bdc9457SAndroid Build Coastguard Worker // SIMD instructions. 408*4bdc9457SAndroid Build Coastguard Worker void vabs_f32(QRegister qd, QRegister qm); 409*4bdc9457SAndroid Build Coastguard Worker void vadd_f32(QRegister qd, QRegister qn, QRegister qm); 410*4bdc9457SAndroid Build Coastguard Worker void vcmpe_f32(SRegister sd, SRegister sm); 411*4bdc9457SAndroid Build Coastguard Worker void vcvt_f32_s32(QRegister qd, QRegister qm); 412*4bdc9457SAndroid Build Coastguard Worker void vcvt_s32_f32(QRegister qd, QRegister qm); 413*4bdc9457SAndroid Build Coastguard Worker void vcvtn_s32_f32(QRegister qd, QRegister qm); vdup_8(QRegister qd,DRegisterLane dm)414*4bdc9457SAndroid Build Coastguard Worker void vdup_8(QRegister qd, DRegisterLane dm) { vdup(k8, qd, dm); } vdup_16(QRegister qd,DRegisterLane dm)415*4bdc9457SAndroid Build Coastguard Worker void vdup_16(QRegister qd, DRegisterLane dm) { vdup(k16, qd, dm); } vdup_32(QRegister qd,DRegisterLane dm)416*4bdc9457SAndroid Build Coastguard Worker void vdup_32(QRegister qd, DRegisterLane dm) { vdup(k32, qd, dm); } 417*4bdc9457SAndroid Build Coastguard Worker void vext_8(QRegister qd, QRegister qn, QRegister qm, uint8_t imm4); 418*4bdc9457SAndroid Build Coastguard Worker // VLD1.8 <list>, [<Rn>]{!} (multiple single elements). vld1_8(DRegisterList regs,MemOperand op)419*4bdc9457SAndroid Build Coastguard Worker void vld1_8(DRegisterList regs, MemOperand op) { vld1(k8, regs, op); } vld1_8(DRegisterList regs,MemOperand op,CoreRegister rm)420*4bdc9457SAndroid Build Coastguard Worker void vld1_8(DRegisterList regs, MemOperand op, CoreRegister rm) { vld1(k8, regs, op, rm); } vld1_8(QRegisterList regs,MemOperand op)421*4bdc9457SAndroid Build Coastguard Worker void vld1_8(QRegisterList regs, MemOperand op) { vld1(k8, static_cast<DRegisterList>(regs), op); } 422*4bdc9457SAndroid Build Coastguard Worker // VLD1.32 <list>, [<Rn>]{!} (multiple single elements). vld1_32(DRegisterList regs,MemOperand op)423*4bdc9457SAndroid Build Coastguard Worker void vld1_32(DRegisterList regs, MemOperand op) { vld1(k32, regs, op); } vld1_32(QRegisterList regs,MemOperand op)424*4bdc9457SAndroid Build Coastguard Worker void vld1_32(QRegisterList regs, MemOperand op) { vld1(k32, static_cast<DRegisterList>(regs), op); } 425*4bdc9457SAndroid Build Coastguard Worker // VLD1.32 <list>, [<Rn>]{!} (single element to one lane). 426*4bdc9457SAndroid Build Coastguard Worker void vld1_32(DRegisterLane dd, MemOperand op); 427*4bdc9457SAndroid Build Coastguard Worker // VLD1.32 <list>, [<Rn>]{!} (single element to all lanes). 428*4bdc9457SAndroid Build Coastguard Worker // We cannot differentiate the register list in C++ syntax, so use an instruction name similar to AArch64 LD1R. 429*4bdc9457SAndroid Build Coastguard Worker void vld1r_32(DRegisterList regs, MemOperand op); 430*4bdc9457SAndroid Build Coastguard Worker void vld2r_32(VLoadStoreRegList regs, MemOperand op); 431*4bdc9457SAndroid Build Coastguard Worker void vld3r_32(VLoadStoreRegList regs, MemOperand op); 432*4bdc9457SAndroid Build Coastguard Worker // VLDM <Rn>{!}, <list> (IA). 433*4bdc9457SAndroid Build Coastguard Worker void vldm(MemOperand rn, SRegisterList regs); 434*4bdc9457SAndroid Build Coastguard Worker void vldm(MemOperand rn, DRegisterList regs); 435*4bdc9457SAndroid Build Coastguard Worker void vldr(SRegister sd, MemOperand op); 436*4bdc9457SAndroid Build Coastguard Worker void vldr(DRegister dd, MemOperand op); 437*4bdc9457SAndroid Build Coastguard Worker void vmax_f32(QRegister qd, QRegister qn, QRegister qm); 438*4bdc9457SAndroid Build Coastguard Worker void vmax_s8(QRegister qd, QRegister qn, QRegister qm); 439*4bdc9457SAndroid Build Coastguard Worker void vmin_f32(QRegister qd, QRegister qn, QRegister qm); 440*4bdc9457SAndroid Build Coastguard Worker void vmin_s8(QRegister qd, QRegister qn, QRegister qm); 441*4bdc9457SAndroid Build Coastguard Worker // VMLA.F32 <Sd>, <Sn>, <Sm> 442*4bdc9457SAndroid Build Coastguard Worker void vmla_f32(SRegister sd, SRegister sn, SRegister sm); 443*4bdc9457SAndroid Build Coastguard Worker // VMLA.F32 <Qd>, <Qn>, <Dm[x]> 444*4bdc9457SAndroid Build Coastguard Worker void vmla_f32(QRegister qd, QRegister qn, DRegisterLane dm); 445*4bdc9457SAndroid Build Coastguard Worker // VMLAL.S16 <Qd>, <Dn>, <Dm[x]> 446*4bdc9457SAndroid Build Coastguard Worker void vmlal_s16(QRegister qd, DRegister dn, DRegisterLane dm); 447*4bdc9457SAndroid Build Coastguard Worker // VMOV.F32 <Qd>, #<imm>; encoding A1 448*4bdc9457SAndroid Build Coastguard Worker void vmov(QRegister qd, uint8_t imm); 449*4bdc9457SAndroid Build Coastguard Worker // VMOV.F32 <Sd>, <Sm>; encoding A2. 450*4bdc9457SAndroid Build Coastguard Worker void vmov(SRegister sd, SRegister sm); 451*4bdc9457SAndroid Build Coastguard Worker // VMOV <Dm>, <Rt>, <Rt2>; encoding A1. 452*4bdc9457SAndroid Build Coastguard Worker void vmov(DRegister dm, CoreRegister rt, CoreRegister rt2); 453*4bdc9457SAndroid Build Coastguard Worker // VMOV <Dd>, <Dm>; encoding A1. 454*4bdc9457SAndroid Build Coastguard Worker void vmov(DRegister dd, DRegister dm); 455*4bdc9457SAndroid Build Coastguard Worker // VMOV <Qd>, <Qm>; encoding A1. 456*4bdc9457SAndroid Build Coastguard Worker void vmov(QRegister qd, QRegister qm); 457*4bdc9457SAndroid Build Coastguard Worker // VMOV_F32 <Sd>, <Sm> vmov_f32(SRegister sd,SRegister sm)458*4bdc9457SAndroid Build Coastguard Worker void vmov_f32(SRegister sd, SRegister sm) { vmov_f32(kAL, sd, sm); } vmovpl_f32(SRegister sd,SRegister sm)459*4bdc9457SAndroid Build Coastguard Worker void vmovpl_f32(SRegister sd, SRegister sm) { vmov_f32(kPL, sd, sm); } vmovmi_f32(SRegister sd,SRegister sm)460*4bdc9457SAndroid Build Coastguard Worker void vmovmi_f32(SRegister sd, SRegister sm) { vmov_f32(kMI, sd, sm); } 461*4bdc9457SAndroid Build Coastguard Worker // VMOV_F64 <Dd>, <Dm> 462*4bdc9457SAndroid Build Coastguard Worker void vmov_f64(DRegister dd, DRegister dm); 463*4bdc9457SAndroid Build Coastguard Worker // VMOVL.S8 <Qd>, <Dm> 464*4bdc9457SAndroid Build Coastguard Worker void vmovl_s8(QRegister qd, DRegister dm); 465*4bdc9457SAndroid Build Coastguard Worker void vmrs(CoreRegister rt, SpecialFPRegister spec_reg); 466*4bdc9457SAndroid Build Coastguard Worker void vmul_f32(QRegister qd, QRegister qn, QRegister qm); 467*4bdc9457SAndroid Build Coastguard Worker void vneg_f32(QRegister qd, QRegister qm); 468*4bdc9457SAndroid Build Coastguard Worker void vpop(DRegisterList regs); 469*4bdc9457SAndroid Build Coastguard Worker void vpush(DRegisterList regs); 470*4bdc9457SAndroid Build Coastguard Worker void vpush(SRegisterList regs); 471*4bdc9457SAndroid Build Coastguard Worker void vqadd_s16(QRegister qd, QRegister qn, QRegister qm); 472*4bdc9457SAndroid Build Coastguard Worker void vqdmulh_s32(QRegister qd, QRegister qn, DRegisterLane dm); 473*4bdc9457SAndroid Build Coastguard Worker void vqmovn_s16(DRegister dd, QRegister qm); 474*4bdc9457SAndroid Build Coastguard Worker void vqmovn_s32(DRegister dd, QRegister qm); 475*4bdc9457SAndroid Build Coastguard Worker void vqshl_s32(QRegister qd, QRegister qm, QRegister qn); 476*4bdc9457SAndroid Build Coastguard Worker void vrshl_s32(QRegister qd, QRegister qm, QRegister qn); 477*4bdc9457SAndroid Build Coastguard Worker void vsdot_s8(QRegister qd, QRegister qn, DRegisterLane dm); 478*4bdc9457SAndroid Build Coastguard Worker // VST1.8 <list>, [<Rn>]{!} (multiple single elements). vst1_8(DRegisterList regs,MemOperand op)479*4bdc9457SAndroid Build Coastguard Worker void vst1_8(DRegisterList regs, MemOperand op) { vst1(k8, regs, op); } 480*4bdc9457SAndroid Build Coastguard Worker // VST1.8 <list>, [<Rn>]{!}, <Rm> (multiple single elements). vst1_8(DRegisterList regs,MemOperand op,CoreRegister rm)481*4bdc9457SAndroid Build Coastguard Worker void vst1_8(DRegisterList regs, MemOperand op, CoreRegister rm) { vst1(k8, regs, op, rm); } 482*4bdc9457SAndroid Build Coastguard Worker // VST1.8 <list>, [<Rn>]{!} (single element form one lane). vst1_8(DRegisterLane dd,MemOperand op)483*4bdc9457SAndroid Build Coastguard Worker void vst1_8(DRegisterLane dd, MemOperand op) { vst1(k8, dd, op); } 484*4bdc9457SAndroid Build Coastguard Worker // VST1.16 <list>, [<Rn>]{!} (multiple single elements). vst1_16(DRegisterList regs,MemOperand op)485*4bdc9457SAndroid Build Coastguard Worker void vst1_16(DRegisterList regs, MemOperand op) { vst1(k16, regs, op); } 486*4bdc9457SAndroid Build Coastguard Worker // VST1.16 <list>, [<Rn>]{!}, <Rm> (multiple single elements). vst1_16(DRegisterList regs,MemOperand op,CoreRegister rm)487*4bdc9457SAndroid Build Coastguard Worker void vst1_16(DRegisterList regs, MemOperand op, CoreRegister rm) { vst1(k16, regs, op, rm); } 488*4bdc9457SAndroid Build Coastguard Worker // VST1.16 <list>, [<Rn>]{!} (single element form one lane). vst1_16(DRegisterLane dd,MemOperand op)489*4bdc9457SAndroid Build Coastguard Worker void vst1_16(DRegisterLane dd, MemOperand op) { vst1(k16, dd, op); } 490*4bdc9457SAndroid Build Coastguard Worker // VST1.32 <list>, [<Rn>]{!} (multiple single elements). vst1_32(DRegisterList regs,MemOperand op)491*4bdc9457SAndroid Build Coastguard Worker void vst1_32(DRegisterList regs, MemOperand op) { vst1(k32, regs, op); } 492*4bdc9457SAndroid Build Coastguard Worker // VST1.32 <list>, [<Rn>]{!}, <Rm> (multiple single elements). vst1_32(DRegisterList regs,MemOperand op,CoreRegister rm)493*4bdc9457SAndroid Build Coastguard Worker void vst1_32(DRegisterList regs, MemOperand op, CoreRegister rm) { vst1(k32, regs, op, rm); } 494*4bdc9457SAndroid Build Coastguard Worker // VST1.32 <list>, [<Rn>]{!} (single element form one lane). vst1_32(DRegisterLane dd,MemOperand op)495*4bdc9457SAndroid Build Coastguard Worker void vst1_32(DRegisterLane dd, MemOperand op) { vst1(k32, dd, op); } 496*4bdc9457SAndroid Build Coastguard Worker // VSTM <Rn>{!}, <list>, consecutive 64-bit registers. 497*4bdc9457SAndroid Build Coastguard Worker void vstm(MemOperand rn, DRegisterList regs); 498*4bdc9457SAndroid Build Coastguard Worker // VSTR <Sd>, [Rn{, #+/-<imm>}], store single extension register to memory. 499*4bdc9457SAndroid Build Coastguard Worker void vstr(SRegister rn, MemOperand op); 500*4bdc9457SAndroid Build Coastguard Worker 501*4bdc9457SAndroid Build Coastguard Worker // Binds Label l to the current location in the code buffer. 502*4bdc9457SAndroid Build Coastguard Worker void bind(Label& l); 503*4bdc9457SAndroid Build Coastguard Worker // Align the cursor to specified number of bytes, `n` must be a power of 2. 504*4bdc9457SAndroid Build Coastguard Worker void align(uint8_t n); 505*4bdc9457SAndroid Build Coastguard Worker 506*4bdc9457SAndroid Build Coastguard Worker private: 507*4bdc9457SAndroid Build Coastguard Worker void mov(Condition c, CoreRegister rd, CoreRegister rm); 508*4bdc9457SAndroid Build Coastguard Worker void b(Condition c, Label& l); 509*4bdc9457SAndroid Build Coastguard Worker void vdup(DataSize size, QRegister qd, DRegisterLane dm); 510*4bdc9457SAndroid Build Coastguard Worker void vmov_f32(Condition c, SRegister sd, SRegister sm); 511*4bdc9457SAndroid Build Coastguard Worker void vld1(DataSize size, DRegisterList regs, MemOperand op); 512*4bdc9457SAndroid Build Coastguard Worker void vld1(DataSize size, DRegisterList regs, MemOperand op, CoreRegister rm); 513*4bdc9457SAndroid Build Coastguard Worker void vst1(DataSize size, DRegisterList regs, MemOperand op); 514*4bdc9457SAndroid Build Coastguard Worker void vst1(DataSize size, DRegisterList regs, MemOperand op, CoreRegister rm); 515*4bdc9457SAndroid Build Coastguard Worker void vst1(DataSize size, DRegisterLane dd, MemOperand op); 516*4bdc9457SAndroid Build Coastguard Worker }; 517*4bdc9457SAndroid Build Coastguard Worker 518*4bdc9457SAndroid Build Coastguard Worker } // namespace aarch32 519*4bdc9457SAndroid Build Coastguard Worker } // namespace xnnpack 520