xref: /aosp_15_r20/external/XNNPACK/src/xnnpack/aarch32-assembler.h (revision 4bdc94577ba0e567308109d787f7fec7b531ce36)
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