1*4bdc9457SAndroid Build Coastguard Worker // Copyright 2022 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 <cstddef> 7*4bdc9457SAndroid Build Coastguard Worker #include <cstdint> 8*4bdc9457SAndroid Build Coastguard Worker 9*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/assembler.h> 10*4bdc9457SAndroid Build Coastguard Worker 11*4bdc9457SAndroid Build Coastguard Worker namespace xnnpack { 12*4bdc9457SAndroid Build Coastguard Worker namespace aarch64 { 13*4bdc9457SAndroid Build Coastguard Worker 14*4bdc9457SAndroid Build Coastguard Worker constexpr size_t kInstructionSizeInBytesLog2 = 2; 15*4bdc9457SAndroid Build Coastguard Worker 16*4bdc9457SAndroid Build Coastguard Worker struct XRegister { 17*4bdc9457SAndroid Build Coastguard Worker uint8_t code; 18*4bdc9457SAndroid Build Coastguard Worker }; 19*4bdc9457SAndroid Build Coastguard Worker 20*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x0{0}; 21*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x1{1}; 22*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x2{2}; 23*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x3{3}; 24*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x4{4}; 25*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x5{5}; 26*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x6{6}; 27*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x7{7}; 28*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x8{8}; 29*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x9{9}; 30*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x10{10}; 31*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x11{11}; 32*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x12{12}; 33*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x13{13}; 34*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x14{14}; 35*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x15{15}; 36*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x16{16}; 37*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x17{17}; 38*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x18{18}; 39*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x19{19}; 40*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x20{20}; 41*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x21{21}; 42*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x22{22}; 43*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x23{23}; 44*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x24{24}; 45*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x25{25}; 46*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x26{26}; 47*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x27{27}; 48*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x28{28}; 49*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x29{29}; 50*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister x30{30}; 51*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister xzr{31}; 52*4bdc9457SAndroid Build Coastguard Worker constexpr XRegister sp{31}; 53*4bdc9457SAndroid Build Coastguard Worker 54*4bdc9457SAndroid Build Coastguard Worker struct VRegisterLane { 55*4bdc9457SAndroid Build Coastguard Worker uint8_t code; 56*4bdc9457SAndroid Build Coastguard Worker uint8_t size; 57*4bdc9457SAndroid Build Coastguard Worker uint8_t lane; is_sVRegisterLane58*4bdc9457SAndroid Build Coastguard Worker const bool is_s() { return size == 2; }; 59*4bdc9457SAndroid Build Coastguard Worker }; 60*4bdc9457SAndroid Build Coastguard Worker 61*4bdc9457SAndroid Build Coastguard Worker struct ScalarVRegister{ 62*4bdc9457SAndroid Build Coastguard Worker uint8_t code; 63*4bdc9457SAndroid Build Coastguard Worker uint8_t size; 64*4bdc9457SAndroid Build Coastguard Worker 65*4bdc9457SAndroid Build Coastguard Worker const VRegisterLane operator[](std::size_t pos) const { 66*4bdc9457SAndroid Build Coastguard Worker return VRegisterLane{code, size, static_cast<uint8_t>(pos)}; 67*4bdc9457SAndroid Build Coastguard Worker } 68*4bdc9457SAndroid Build Coastguard Worker }; 69*4bdc9457SAndroid Build Coastguard Worker 70*4bdc9457SAndroid Build Coastguard Worker struct VRegister { 71*4bdc9457SAndroid Build Coastguard Worker uint8_t code; 72*4bdc9457SAndroid Build Coastguard Worker uint8_t size; 73*4bdc9457SAndroid Build Coastguard Worker uint8_t q; 74*4bdc9457SAndroid Build Coastguard Worker v8bVRegister75*4bdc9457SAndroid Build Coastguard Worker VRegister v8b() const { return {code, 0, 0}; } v16bVRegister76*4bdc9457SAndroid Build Coastguard Worker VRegister v16b() const { return {code, 0, 1}; } v4hVRegister77*4bdc9457SAndroid Build Coastguard Worker VRegister v4h() const { return {code, 1, 0}; } v8hVRegister78*4bdc9457SAndroid Build Coastguard Worker VRegister v8h() const { return {code, 1, 1}; } v2sVRegister79*4bdc9457SAndroid Build Coastguard Worker VRegister v2s() const { return {code, 2, 0}; } v4sVRegister80*4bdc9457SAndroid Build Coastguard Worker VRegister v4s() const { return {code, 2, 1}; } v1dVRegister81*4bdc9457SAndroid Build Coastguard Worker VRegister v1d() const { return {code, 3, 0}; } v2dVRegister82*4bdc9457SAndroid Build Coastguard Worker VRegister v2d() const { return {code, 3, 1}; } 83*4bdc9457SAndroid Build Coastguard Worker sVRegister84*4bdc9457SAndroid Build Coastguard Worker ScalarVRegister s() const { return {code, 2}; } dVRegister85*4bdc9457SAndroid Build Coastguard Worker ScalarVRegister d() const { return {code, 3}; } 86*4bdc9457SAndroid Build Coastguard Worker is_sVRegister87*4bdc9457SAndroid Build Coastguard Worker const bool is_s() { return size == 2; }; 88*4bdc9457SAndroid Build Coastguard Worker }; 89*4bdc9457SAndroid Build Coastguard Worker 90*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v0{0}; 91*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v1{1}; 92*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v2{2}; 93*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v3{3}; 94*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v4{4}; 95*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v5{5}; 96*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v6{6}; 97*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v7{7}; 98*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v8{8}; 99*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v9{9}; 100*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v10{10}; 101*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v11{11}; 102*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v12{12}; 103*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v13{13}; 104*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v14{14}; 105*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v15{15}; 106*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v16{16}; 107*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v17{17}; 108*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v18{18}; 109*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v19{19}; 110*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v20{20}; 111*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v21{21}; 112*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v22{22}; 113*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v23{23}; 114*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v24{24}; 115*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v25{25}; 116*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v26{26}; 117*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v27{27}; 118*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v28{28}; 119*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v29{29}; 120*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v30{30}; 121*4bdc9457SAndroid Build Coastguard Worker constexpr VRegister v31{31}; 122*4bdc9457SAndroid Build Coastguard Worker 123*4bdc9457SAndroid Build Coastguard Worker struct VRegisterList { VRegisterListVRegisterList124*4bdc9457SAndroid Build Coastguard Worker VRegisterList(VRegister vt1) 125*4bdc9457SAndroid Build Coastguard Worker : vt1(vt1), length(1) {} VRegisterListVRegisterList126*4bdc9457SAndroid Build Coastguard Worker VRegisterList(VRegister vt1, VRegister vt2) 127*4bdc9457SAndroid Build Coastguard Worker : vt1(vt1), vt2(vt2), length(2) {} VRegisterListVRegisterList128*4bdc9457SAndroid Build Coastguard Worker VRegisterList(VRegister vt1, VRegister vt2, VRegister vt3) 129*4bdc9457SAndroid Build Coastguard Worker : vt1(vt1), vt2(vt2), vt3(vt3), length(3) {} VRegisterListVRegisterList130*4bdc9457SAndroid Build Coastguard Worker VRegisterList(VRegister vt1, VRegister vt2, VRegister vt3, VRegister vt4) 131*4bdc9457SAndroid Build Coastguard Worker : vt1(vt1), vt2(vt2), vt3(vt3), vt4(vt4), length(4) {} 132*4bdc9457SAndroid Build Coastguard Worker 133*4bdc9457SAndroid Build Coastguard Worker VRegister vt1; 134*4bdc9457SAndroid Build Coastguard Worker VRegister vt2; 135*4bdc9457SAndroid Build Coastguard Worker VRegister vt3; 136*4bdc9457SAndroid Build Coastguard Worker VRegister vt4; 137*4bdc9457SAndroid Build Coastguard Worker uint8_t length; 138*4bdc9457SAndroid Build Coastguard Worker }; 139*4bdc9457SAndroid Build Coastguard Worker 140*4bdc9457SAndroid Build Coastguard Worker struct SRegister { 141*4bdc9457SAndroid Build Coastguard Worker uint8_t code; 142*4bdc9457SAndroid Build Coastguard Worker }; 143*4bdc9457SAndroid Build Coastguard Worker 144*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s0{0}; 145*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s1{1}; 146*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s2{2}; 147*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s3{3}; 148*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s4{4}; 149*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s5{5}; 150*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s6{6}; 151*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s7{7}; 152*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s8{8}; 153*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s9{9}; 154*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s10{10}; 155*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s11{11}; 156*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s12{12}; 157*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s13{13}; 158*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s14{14}; 159*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s15{15}; 160*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s16{16}; 161*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s17{17}; 162*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s18{18}; 163*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s19{19}; 164*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s20{20}; 165*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s21{21}; 166*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s22{22}; 167*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s23{23}; 168*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s24{24}; 169*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s25{25}; 170*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s26{26}; 171*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s27{27}; 172*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s28{28}; 173*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s29{29}; 174*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s30{30}; 175*4bdc9457SAndroid Build Coastguard Worker constexpr SRegister s31{31}; 176*4bdc9457SAndroid Build Coastguard Worker 177*4bdc9457SAndroid Build Coastguard Worker struct DRegister { 178*4bdc9457SAndroid Build Coastguard Worker uint8_t code; 179*4bdc9457SAndroid Build Coastguard Worker }; 180*4bdc9457SAndroid Build Coastguard Worker 181*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d0{0}; 182*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d1{1}; 183*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d2{2}; 184*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d3{3}; 185*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d4{4}; 186*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d5{5}; 187*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d6{6}; 188*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d7{7}; 189*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d8{8}; 190*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d9{9}; 191*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d10{10}; 192*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d11{11}; 193*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d12{12}; 194*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d13{13}; 195*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d14{14}; 196*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d15{15}; 197*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d16{16}; 198*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d17{17}; 199*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d18{18}; 200*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d19{19}; 201*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d20{20}; 202*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d21{21}; 203*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d22{22}; 204*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d23{23}; 205*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d24{24}; 206*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d25{25}; 207*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d26{26}; 208*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d27{27}; 209*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d28{28}; 210*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d29{29}; 211*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d30{30}; 212*4bdc9457SAndroid Build Coastguard Worker constexpr DRegister d31{31}; 213*4bdc9457SAndroid Build Coastguard Worker 214*4bdc9457SAndroid Build Coastguard Worker struct QRegister { 215*4bdc9457SAndroid Build Coastguard Worker uint8_t code; 216*4bdc9457SAndroid Build Coastguard Worker }; 217*4bdc9457SAndroid Build Coastguard Worker 218*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q0{0}; 219*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q1{1}; 220*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q2{2}; 221*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q3{3}; 222*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q4{4}; 223*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q5{5}; 224*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q6{6}; 225*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q7{7}; 226*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q8{8}; 227*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q9{9}; 228*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q10{10}; 229*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q11{11}; 230*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q12{12}; 231*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q13{13}; 232*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q14{14}; 233*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q15{15}; 234*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q16{16}; 235*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q17{17}; 236*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q18{18}; 237*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q19{19}; 238*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q20{20}; 239*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q21{21}; 240*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q22{22}; 241*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q23{23}; 242*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q24{24}; 243*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q25{25}; 244*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q26{26}; 245*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q27{27}; 246*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q28{28}; 247*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q29{29}; 248*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q30{30}; 249*4bdc9457SAndroid Build Coastguard Worker constexpr QRegister q31{31}; 250*4bdc9457SAndroid Build Coastguard Worker 251*4bdc9457SAndroid Build Coastguard Worker // C1.3.3 Load/Store addressing modes 252*4bdc9457SAndroid Build Coastguard Worker enum class AddressingMode { 253*4bdc9457SAndroid Build Coastguard Worker kOffset, // Base plus offset: [base{, #imm}] ; [base, Xm{, LSL #imm}]. 254*4bdc9457SAndroid Build Coastguard Worker kPostIndex, // Post-index: [base], #imm ; [base], Xm. 255*4bdc9457SAndroid Build Coastguard Worker kPreIndex, // Pre-index: [base, #imm]! 256*4bdc9457SAndroid Build Coastguard Worker }; 257*4bdc9457SAndroid Build Coastguard Worker 258*4bdc9457SAndroid Build Coastguard Worker struct MemOperand { MemOperandMemOperand259*4bdc9457SAndroid Build Coastguard Worker MemOperand(XRegister xn): base(xn), mode(AddressingMode::kOffset), offset(0) {} MemOperandMemOperand260*4bdc9457SAndroid Build Coastguard Worker MemOperand(XRegister xn, int32_t offset): base(xn), mode(AddressingMode::kOffset), offset(offset) {} MemOperandMemOperand261*4bdc9457SAndroid Build Coastguard Worker MemOperand(XRegister xn, int32_t offset, AddressingMode mode): base(xn), mode(mode), offset(offset) {} 262*4bdc9457SAndroid Build Coastguard Worker 263*4bdc9457SAndroid Build Coastguard Worker // Overload postfix increment to indicate a pre-index addressing mode for load/stores. 264*4bdc9457SAndroid Build Coastguard Worker MemOperand operator++(int) { 265*4bdc9457SAndroid Build Coastguard Worker mode = AddressingMode::kPreIndex; 266*4bdc9457SAndroid Build Coastguard Worker return *this; 267*4bdc9457SAndroid Build Coastguard Worker } 268*4bdc9457SAndroid Build Coastguard Worker 269*4bdc9457SAndroid Build Coastguard Worker XRegister base; 270*4bdc9457SAndroid Build Coastguard Worker AddressingMode mode; 271*4bdc9457SAndroid Build Coastguard Worker int32_t offset; 272*4bdc9457SAndroid Build Coastguard Worker }; 273*4bdc9457SAndroid Build Coastguard Worker 274*4bdc9457SAndroid Build Coastguard Worker static inline MemOperand operator,(XRegister r, int32_t offset) { 275*4bdc9457SAndroid Build Coastguard Worker return MemOperand(r, offset); 276*4bdc9457SAndroid Build Coastguard Worker } 277*4bdc9457SAndroid Build Coastguard Worker 278*4bdc9457SAndroid Build Coastguard Worker // Helper struct for some syntax sugar to look like native assembly, see mem. 279*4bdc9457SAndroid Build Coastguard Worker struct MemOperandHelper { 280*4bdc9457SAndroid Build Coastguard Worker MemOperand operator[](MemOperand op) const { return op; } 281*4bdc9457SAndroid Build Coastguard Worker MemOperand operator[](XRegister r) const { return MemOperand(r, 0); } 282*4bdc9457SAndroid Build Coastguard Worker }; 283*4bdc9457SAndroid Build Coastguard Worker 284*4bdc9457SAndroid Build Coastguard Worker // Use "mem" (and its overload of array subscript operator) to get some syntax 285*4bdc9457SAndroid Build Coastguard Worker // that looks closer to native assembly when accessing memory. For example: 286*4bdc9457SAndroid Build Coastguard Worker // - ldp(x0, x1, mem[rn, offset]); // offset 287*4bdc9457SAndroid Build Coastguard Worker // - ldp(x0, x1, mem[rn], offset); // post-indexed 288*4bdc9457SAndroid Build Coastguard Worker constexpr MemOperandHelper mem; 289*4bdc9457SAndroid Build Coastguard Worker 290*4bdc9457SAndroid Build Coastguard Worker enum PrefetchOp { 291*4bdc9457SAndroid Build Coastguard Worker kPLDL1KEEP = 0 292*4bdc9457SAndroid Build Coastguard Worker }; 293*4bdc9457SAndroid Build Coastguard Worker 294*4bdc9457SAndroid Build Coastguard Worker enum Condition : uint32_t { 295*4bdc9457SAndroid Build Coastguard Worker kEQ = 0x0, 296*4bdc9457SAndroid Build Coastguard Worker kNE = 0x1, 297*4bdc9457SAndroid Build Coastguard Worker kCS = 0x2, 298*4bdc9457SAndroid Build Coastguard Worker kCC = 0x3, 299*4bdc9457SAndroid Build Coastguard Worker kMI = 0x4, 300*4bdc9457SAndroid Build Coastguard Worker kPL = 0x5, 301*4bdc9457SAndroid Build Coastguard Worker kVS = 0x6, 302*4bdc9457SAndroid Build Coastguard Worker kVC = 0x7, 303*4bdc9457SAndroid Build Coastguard Worker kHI = 0x8, 304*4bdc9457SAndroid Build Coastguard Worker kLS = 0x9, 305*4bdc9457SAndroid Build Coastguard Worker kGE = 0xa, 306*4bdc9457SAndroid Build Coastguard Worker kLT = 0xB, 307*4bdc9457SAndroid Build Coastguard Worker kGT = 0xC, 308*4bdc9457SAndroid Build Coastguard Worker kLE = 0xD, 309*4bdc9457SAndroid Build Coastguard Worker kAL = 0xE, 310*4bdc9457SAndroid Build Coastguard Worker kHS = kCS, 311*4bdc9457SAndroid Build Coastguard Worker kLO = kCC, 312*4bdc9457SAndroid Build Coastguard Worker }; 313*4bdc9457SAndroid Build Coastguard Worker 314*4bdc9457SAndroid Build Coastguard Worker enum class BranchType { 315*4bdc9457SAndroid Build Coastguard Worker kConditional, 316*4bdc9457SAndroid Build Coastguard Worker // For encoding, TBZ and TBNZ are treated similarly, called TBXZ here. 317*4bdc9457SAndroid Build Coastguard Worker kTbxz, 318*4bdc9457SAndroid Build Coastguard Worker kUnconditional, 319*4bdc9457SAndroid Build Coastguard Worker }; 320*4bdc9457SAndroid Build Coastguard Worker 321*4bdc9457SAndroid Build Coastguard Worker // Instruction to use for alignment. 322*4bdc9457SAndroid Build Coastguard Worker // kNop should be used for loops, branch targets. kHlt for end of function. 323*4bdc9457SAndroid Build Coastguard Worker enum class AlignInstruction { 324*4bdc9457SAndroid Build Coastguard Worker kHlt, 325*4bdc9457SAndroid Build Coastguard Worker kNop, 326*4bdc9457SAndroid Build Coastguard Worker }; 327*4bdc9457SAndroid Build Coastguard Worker 328*4bdc9457SAndroid Build Coastguard Worker class Assembler : public AssemblerBase { 329*4bdc9457SAndroid Build Coastguard Worker public: 330*4bdc9457SAndroid Build Coastguard Worker using AssemblerBase::AssemblerBase; 331*4bdc9457SAndroid Build Coastguard Worker 332*4bdc9457SAndroid Build Coastguard Worker // Base instructions. 333*4bdc9457SAndroid Build Coastguard Worker void add(XRegister xd, XRegister xn, uint16_t imm12); 334*4bdc9457SAndroid Build Coastguard Worker void add(XRegister xd, XRegister xn, XRegister xm); 335*4bdc9457SAndroid Build Coastguard Worker void b(Label& l); b_eq(Label & l)336*4bdc9457SAndroid Build Coastguard Worker void b_eq(Label& l) { return b(kEQ, l); } b_hi(Label & l)337*4bdc9457SAndroid Build Coastguard Worker void b_hi(Label& l) { return b(kHI, l); } b_hs(Label & l)338*4bdc9457SAndroid Build Coastguard Worker void b_hs(Label& l) { return b(kHS, l); } b_lo(Label & l)339*4bdc9457SAndroid Build Coastguard Worker void b_lo(Label& l) { return b(kLO, l); } b_ne(Label & l)340*4bdc9457SAndroid Build Coastguard Worker void b_ne(Label& l) { return b(kNE, l); } 341*4bdc9457SAndroid Build Coastguard Worker void cmp(XRegister xn, uint16_t imm12); 342*4bdc9457SAndroid Build Coastguard Worker void cmp(XRegister xn, XRegister xm); 343*4bdc9457SAndroid Build Coastguard Worker void csel(XRegister xd, XRegister xn, XRegister xm, Condition c); 344*4bdc9457SAndroid Build Coastguard Worker void hlt(); 345*4bdc9457SAndroid Build Coastguard Worker void ldp(XRegister xt1, XRegister xt2, MemOperand xn); 346*4bdc9457SAndroid Build Coastguard Worker void ldp(XRegister xt1, XRegister xt2, MemOperand xn, int32_t imm); 347*4bdc9457SAndroid Build Coastguard Worker void ldr(XRegister xt, MemOperand xn); 348*4bdc9457SAndroid Build Coastguard Worker void ldr(XRegister xt, MemOperand xn, int32_t imm); 349*4bdc9457SAndroid Build Coastguard Worker void mov(XRegister xd, XRegister xn); 350*4bdc9457SAndroid Build Coastguard Worker void nop(); 351*4bdc9457SAndroid Build Coastguard Worker void prfm(PrefetchOp prfop, MemOperand xn); 352*4bdc9457SAndroid Build Coastguard Worker void ret(); 353*4bdc9457SAndroid Build Coastguard Worker void stp(XRegister xt1, XRegister xt2, MemOperand xn); 354*4bdc9457SAndroid Build Coastguard Worker void str(XRegister xt1, MemOperand xn); 355*4bdc9457SAndroid Build Coastguard Worker void sub(XRegister xd, XRegister xn, XRegister xm); 356*4bdc9457SAndroid Build Coastguard Worker void subs(XRegister xd, XRegister xn, uint16_t imm12); 357*4bdc9457SAndroid Build Coastguard Worker void tbnz(XRegister xd, uint8_t bit, Label& l); 358*4bdc9457SAndroid Build Coastguard Worker void tbz(XRegister xd, uint8_t bit, Label& l); 359*4bdc9457SAndroid Build Coastguard Worker // Only immediates with lowest N bits set are supported. 360*4bdc9457SAndroid Build Coastguard Worker void tst(XRegister xn, uint8_t imm); 361*4bdc9457SAndroid Build Coastguard Worker 362*4bdc9457SAndroid Build Coastguard Worker // SIMD instructions 363*4bdc9457SAndroid Build Coastguard Worker void dup(DRegister dd, VRegisterLane vn); 364*4bdc9457SAndroid Build Coastguard Worker void fabs(VRegister vd, VRegister vn); 365*4bdc9457SAndroid Build Coastguard Worker void fadd(VRegister vd, VRegister vn, VRegister vm); 366*4bdc9457SAndroid Build Coastguard Worker void fmax(VRegister vd, VRegister vn, VRegister vm); 367*4bdc9457SAndroid Build Coastguard Worker void fmin(VRegister vd, VRegister vn, VRegister vm); 368*4bdc9457SAndroid Build Coastguard Worker void fmla(VRegister vd, VRegister vn, VRegisterLane vm); 369*4bdc9457SAndroid Build Coastguard Worker void fmul(VRegister vd, VRegister vn, VRegister vm); 370*4bdc9457SAndroid Build Coastguard Worker void fneg(VRegister vd, VRegister vn); 371*4bdc9457SAndroid Build Coastguard Worker void ld1(VRegisterList vs, MemOperand xn, int32_t imm); 372*4bdc9457SAndroid Build Coastguard Worker void ld1r(VRegisterList xs, MemOperand xn); 373*4bdc9457SAndroid Build Coastguard Worker void ld2r(VRegisterList xs, MemOperand xn); 374*4bdc9457SAndroid Build Coastguard Worker void ld3r(VRegisterList xs, MemOperand xn); 375*4bdc9457SAndroid Build Coastguard Worker void ldp(DRegister dt1, DRegister dt2, MemOperand xn); 376*4bdc9457SAndroid Build Coastguard Worker void ldp(DRegister dt1, DRegister dt2, MemOperand xn, int32_t imm); 377*4bdc9457SAndroid Build Coastguard Worker void ldp(QRegister qt1, QRegister qt2, MemOperand xn, int32_t imm); 378*4bdc9457SAndroid Build Coastguard Worker void ldr(DRegister dt, MemOperand xn, int32_t imm); 379*4bdc9457SAndroid Build Coastguard Worker void ldr(QRegister qt, MemOperand xn, int32_t imm); 380*4bdc9457SAndroid Build Coastguard Worker void ldr(SRegister st, MemOperand xn, int32_t imm); 381*4bdc9457SAndroid Build Coastguard Worker void mov(VRegister vd, VRegister vn); 382*4bdc9457SAndroid Build Coastguard Worker void movi(VRegister vd, uint8_t imm); 383*4bdc9457SAndroid Build Coastguard Worker void st1(VRegisterList vs, MemOperand xn, XRegister xm); 384*4bdc9457SAndroid Build Coastguard Worker void stp(DRegister dt1, DRegister dt2, MemOperand xn); 385*4bdc9457SAndroid Build Coastguard Worker void stp(QRegister qt1, QRegister qt2, MemOperand xn); 386*4bdc9457SAndroid Build Coastguard Worker void stp(QRegister qt1, QRegister qt2, MemOperand xn, int32_t imm); 387*4bdc9457SAndroid Build Coastguard Worker void str(DRegister dt, MemOperand xn, int32_t imm); 388*4bdc9457SAndroid Build Coastguard Worker void str(QRegister qt, MemOperand xn, int32_t imm); 389*4bdc9457SAndroid Build Coastguard Worker void str(SRegister st, MemOperand xn); 390*4bdc9457SAndroid Build Coastguard Worker void str(SRegister st, MemOperand xn, int32_t imm); 391*4bdc9457SAndroid Build Coastguard Worker 392*4bdc9457SAndroid Build Coastguard Worker // Aligns the buffer to n (must be a power of 2). 393*4bdc9457SAndroid Build Coastguard Worker void align(uint8_t n, AlignInstruction instr); align(uint8_t n)394*4bdc9457SAndroid Build Coastguard Worker void align(uint8_t n) { align(n, AlignInstruction::kNop); } 395*4bdc9457SAndroid Build Coastguard Worker // Binds Label l to the current location in the code buffer. 396*4bdc9457SAndroid Build Coastguard Worker void bind(Label& l); 397*4bdc9457SAndroid Build Coastguard Worker 398*4bdc9457SAndroid Build Coastguard Worker private: 399*4bdc9457SAndroid Build Coastguard Worker void b(Condition c, Label& l); 400*4bdc9457SAndroid Build Coastguard Worker void branch_to_label(uint32_t opcode, BranchType bt, Label& l); 401*4bdc9457SAndroid Build Coastguard Worker void ldr(uint32_t size, uint32_t opc, MemOperand xn, int32_t imm, uint8_t rt_code); 402*4bdc9457SAndroid Build Coastguard Worker void str(uint32_t size, uint32_t opc, MemOperand xn, int32_t imm, uint8_t rt_code); 403*4bdc9457SAndroid Build Coastguard Worker void tb_helper(uint32_t op, XRegister xd, uint8_t bit, Label& l); 404*4bdc9457SAndroid Build Coastguard Worker 405*4bdc9457SAndroid Build Coastguard Worker }; 406*4bdc9457SAndroid Build Coastguard Worker 407*4bdc9457SAndroid Build Coastguard Worker } // namespace aarch64 408*4bdc9457SAndroid Build Coastguard Worker } // namespace xnnpack 409