1 #include <assert.h>
2 #include <stdexcept>
3 #include "AArch64Assembler.h"
4
CAArch64Assembler()5 CAArch64Assembler::CAArch64Assembler()
6 {
7
8 }
9
~CAArch64Assembler()10 CAArch64Assembler::~CAArch64Assembler()
11 {
12
13 }
14
SetStream(Framework::CStream * stream)15 void CAArch64Assembler::SetStream(Framework::CStream* stream)
16 {
17 m_stream = stream;
18 }
19
CreateLabel()20 CAArch64Assembler::LABEL CAArch64Assembler::CreateLabel()
21 {
22 return m_nextLabelId++;
23 }
24
ClearLabels()25 void CAArch64Assembler::ClearLabels()
26 {
27 m_labels.clear();
28 }
29
MarkLabel(LABEL label)30 void CAArch64Assembler::MarkLabel(LABEL label)
31 {
32 m_labels[label] = static_cast<size_t>(m_stream->Tell());
33 }
34
CreateLabelReference(LABEL label,CONDITION condition)35 void CAArch64Assembler::CreateLabelReference(LABEL label, CONDITION condition)
36 {
37 LABELREF reference;
38 reference.offset = static_cast<size_t>(m_stream->Tell());
39 reference.condition = condition;
40 m_labelReferences.insert(std::make_pair(label, reference));
41 }
42
ResolveLabelReferences()43 void CAArch64Assembler::ResolveLabelReferences()
44 {
45 for(const auto& labelReferencePair : m_labelReferences)
46 {
47 auto label(m_labels.find(labelReferencePair.first));
48 if(label == m_labels.end())
49 {
50 throw std::runtime_error("Invalid label.");
51 }
52 const auto& labelReference = labelReferencePair.second;
53 size_t labelPos = label->second;
54 int offset = static_cast<int>(labelPos - labelReference.offset) / 4;
55
56 m_stream->Seek(labelReference.offset, Framework::STREAM_SEEK_SET);
57 if(labelReference.condition == CONDITION_AL)
58 {
59 uint32 opcode = 0x14000000;
60 opcode |= (offset & 0x3FFFFFF);
61 WriteWord(opcode);
62 }
63 else
64 {
65 uint32 opcode = 0x54000000;
66 opcode |= (offset & 0x7FFFF) << 5;
67 opcode |= labelReference.condition;
68 WriteWord(opcode);
69 }
70 }
71 m_stream->Seek(0, Framework::STREAM_SEEK_END);
72 m_labelReferences.clear();
73 }
74
Add(REGISTER32 rd,REGISTER32 rn,REGISTER32 rm)75 void CAArch64Assembler::Add(REGISTER32 rd, REGISTER32 rn, REGISTER32 rm)
76 {
77 uint32 opcode = 0x0B000000;
78 opcode |= (rd << 0);
79 opcode |= (rn << 5);
80 opcode |= (rm << 16);
81 WriteWord(opcode);
82 }
83
Add(REGISTER64 rd,REGISTER64 rn,REGISTER64 rm)84 void CAArch64Assembler::Add(REGISTER64 rd, REGISTER64 rn, REGISTER64 rm)
85 {
86 uint32 opcode = 0x8B000000;
87 opcode |= (rd << 0);
88 opcode |= (rn << 5);
89 opcode |= (rm << 16);
90 WriteWord(opcode);
91 }
92
Add(REGISTER32 rd,REGISTER32 rn,uint16 imm,ADDSUB_IMM_SHIFT_TYPE shift)93 void CAArch64Assembler::Add(REGISTER32 rd, REGISTER32 rn, uint16 imm, ADDSUB_IMM_SHIFT_TYPE shift)
94 {
95 WriteAddSubOpImm(0x11000000, shift, imm, rn, rd);
96 }
97
Add(REGISTER64 rd,REGISTER64 rn,uint16 imm,ADDSUB_IMM_SHIFT_TYPE shift)98 void CAArch64Assembler::Add(REGISTER64 rd, REGISTER64 rn, uint16 imm, ADDSUB_IMM_SHIFT_TYPE shift)
99 {
100 WriteAddSubOpImm(0x91000000, shift, imm, rn, rd);
101 }
102
Add_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)103 void CAArch64Assembler::Add_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
104 {
105 uint32 opcode = 0x4EA08400;
106 opcode |= (rd << 0);
107 opcode |= (rn << 5);
108 opcode |= (rm << 16);
109 WriteWord(opcode);
110 }
111
Add_8h(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)112 void CAArch64Assembler::Add_8h(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
113 {
114 uint32 opcode = 0x4E608400;
115 opcode |= (rd << 0);
116 opcode |= (rn << 5);
117 opcode |= (rm << 16);
118 WriteWord(opcode);
119 }
120
Add_16b(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)121 void CAArch64Assembler::Add_16b(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
122 {
123 uint32 opcode = 0x4E208400;
124 opcode |= (rd << 0);
125 opcode |= (rn << 5);
126 opcode |= (rm << 16);
127 WriteWord(opcode);
128 }
129
And(REGISTER32 rd,REGISTER32 rn,REGISTER32 rm)130 void CAArch64Assembler::And(REGISTER32 rd, REGISTER32 rn, REGISTER32 rm)
131 {
132 uint32 opcode = 0x0A000000;
133 opcode |= (rd << 0);
134 opcode |= (rn << 5);
135 opcode |= (rm << 16);
136 WriteWord(opcode);
137 }
138
And(REGISTER64 rd,REGISTER64 rn,REGISTER64 rm)139 void CAArch64Assembler::And(REGISTER64 rd, REGISTER64 rn, REGISTER64 rm)
140 {
141 uint32 opcode = 0x8A000000;
142 opcode |= (rd << 0);
143 opcode |= (rn << 5);
144 opcode |= (rm << 16);
145 WriteWord(opcode);
146 }
147
And(REGISTER32 rd,REGISTER32 rn,uint8 n,uint8 immr,uint8 imms)148 void CAArch64Assembler::And(REGISTER32 rd, REGISTER32 rn, uint8 n, uint8 immr, uint8 imms)
149 {
150 WriteLogicalOpImm(0x12000000, n, immr, imms, rn, rd);
151 }
152
And_16b(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)153 void CAArch64Assembler::And_16b(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
154 {
155 uint32 opcode = 0x4E201C00;
156 opcode |= (rd << 0);
157 opcode |= (rn << 5);
158 opcode |= (rm << 16);
159 WriteWord(opcode);
160 }
161
Asr(REGISTER32 rd,REGISTER32 rn,uint8 sa)162 void CAArch64Assembler::Asr(REGISTER32 rd, REGISTER32 rn, uint8 sa)
163 {
164 uint32 imms = 0x1F;
165 uint32 immr = sa & 0x1F;
166 WriteLogicalOpImm(0x13000000, 0, immr, imms, rn, rd);
167 }
168
Asr(REGISTER64 rd,REGISTER64 rn,uint8 sa)169 void CAArch64Assembler::Asr(REGISTER64 rd, REGISTER64 rn, uint8 sa)
170 {
171 uint32 imms = 0x3F;
172 uint32 immr = sa & 0x3F;
173 WriteLogicalOpImm(0x93400000, 0, immr, imms, rn, rd);
174 }
175
Asrv(REGISTER32 rd,REGISTER32 rn,REGISTER32 rm)176 void CAArch64Assembler::Asrv(REGISTER32 rd, REGISTER32 rn, REGISTER32 rm)
177 {
178 WriteDataProcOpReg2(0x1AC02800, rm, rn, rd);
179 }
180
Asrv(REGISTER64 rd,REGISTER64 rn,REGISTER64 rm)181 void CAArch64Assembler::Asrv(REGISTER64 rd, REGISTER64 rn, REGISTER64 rm)
182 {
183 WriteDataProcOpReg2(0x9AC02800, rm, rn, rd);
184 }
185
B(LABEL label)186 void CAArch64Assembler::B(LABEL label)
187 {
188 CreateLabelReference(label, CONDITION_AL);
189 WriteWord(0);
190 }
191
Bl(uint32 offset)192 void CAArch64Assembler::Bl(uint32 offset)
193 {
194 assert((offset & 0x3) == 0);
195 offset /= 4;
196 assert(offset < 0x40000000);
197 uint32 opcode = 0x94000000;
198 opcode |= offset;
199 WriteWord(opcode);
200 }
201
BCc(CONDITION condition,LABEL label)202 void CAArch64Assembler::BCc(CONDITION condition, LABEL label)
203 {
204 CreateLabelReference(label, condition);
205 WriteWord(0);
206 }
207
Blr(REGISTER64 rn)208 void CAArch64Assembler::Blr(REGISTER64 rn)
209 {
210 uint32 opcode = 0xD63F0000;
211 opcode |= (rn << 5);
212 WriteWord(opcode);
213 }
214
Clz(REGISTER32 rd,REGISTER32 rn)215 void CAArch64Assembler::Clz(REGISTER32 rd, REGISTER32 rn)
216 {
217 uint32 opcode = 0x5AC01000;
218 opcode |= (rd << 0);
219 opcode |= (rn << 5);
220 WriteWord(opcode);
221 }
222
Cmeq_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)223 void CAArch64Assembler::Cmeq_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
224 {
225 uint32 opcode = 0x6EA08C00;
226 opcode |= (rd << 0);
227 opcode |= (rn << 5);
228 opcode |= (rm << 16);
229 WriteWord(opcode);
230 }
231
Cmgt_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)232 void CAArch64Assembler::Cmgt_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
233 {
234 uint32 opcode = 0x4EA03400;
235 opcode |= (rd << 0);
236 opcode |= (rn << 5);
237 opcode |= (rm << 16);
238 WriteWord(opcode);
239 }
240
Cmn(REGISTER32 rn,uint16 imm,ADDSUB_IMM_SHIFT_TYPE shift)241 void CAArch64Assembler::Cmn(REGISTER32 rn, uint16 imm, ADDSUB_IMM_SHIFT_TYPE shift)
242 {
243 WriteAddSubOpImm(0x31000000, shift, imm, rn, wZR);
244 }
245
Cmn(REGISTER64 rn,uint16 imm,ADDSUB_IMM_SHIFT_TYPE shift)246 void CAArch64Assembler::Cmn(REGISTER64 rn, uint16 imm, ADDSUB_IMM_SHIFT_TYPE shift)
247 {
248 WriteAddSubOpImm(0xB1000000, shift, imm, rn, wZR);
249 }
250
Cmp(REGISTER32 rn,REGISTER32 rm)251 void CAArch64Assembler::Cmp(REGISTER32 rn, REGISTER32 rm)
252 {
253 uint32 opcode = 0x6B000000;
254 opcode |= (wZR << 0);
255 opcode |= (rn << 5);
256 opcode |= (rm << 16);
257 WriteWord(opcode);
258 }
259
Cmp(REGISTER64 rn,REGISTER64 rm)260 void CAArch64Assembler::Cmp(REGISTER64 rn, REGISTER64 rm)
261 {
262 uint32 opcode = 0xEB000000;
263 opcode |= (wZR << 0);
264 opcode |= (rn << 5);
265 opcode |= (rm << 16);
266 WriteWord(opcode);
267 }
268
Cmp(REGISTER32 rn,uint16 imm,ADDSUB_IMM_SHIFT_TYPE shift)269 void CAArch64Assembler::Cmp(REGISTER32 rn, uint16 imm, ADDSUB_IMM_SHIFT_TYPE shift)
270 {
271 WriteAddSubOpImm(0x71000000, shift, imm, rn, wZR);
272 }
273
Cmp(REGISTER64 rn,uint16 imm,ADDSUB_IMM_SHIFT_TYPE shift)274 void CAArch64Assembler::Cmp(REGISTER64 rn, uint16 imm, ADDSUB_IMM_SHIFT_TYPE shift)
275 {
276 WriteAddSubOpImm(0xF1000000, shift, imm, rn, wZR);
277 }
278
Cset(REGISTER32 rd,CONDITION condition)279 void CAArch64Assembler::Cset(REGISTER32 rd, CONDITION condition)
280 {
281 uint32 opcode = 0x1A800400;
282 opcode |= (rd << 0);
283 opcode |= (wZR << 5);
284 opcode |= ((condition ^ 1) << 12); //Inverting lsb inverts condition
285 opcode |= (wZR << 16);
286 WriteWord(opcode);
287 }
288
Dup_4s(REGISTERMD rd,REGISTER32 rn)289 void CAArch64Assembler::Dup_4s(REGISTERMD rd, REGISTER32 rn)
290 {
291 uint32 opcode = 0x4E040C00;
292 opcode |= (rd << 0);
293 opcode |= (rn << 5);
294 WriteWord(opcode);
295 }
296
Eor(REGISTER32 rd,REGISTER32 rn,REGISTER32 rm)297 void CAArch64Assembler::Eor(REGISTER32 rd, REGISTER32 rn, REGISTER32 rm)
298 {
299 uint32 opcode = 0x4A000000;
300 opcode |= (rd << 0);
301 opcode |= (rn << 5);
302 opcode |= (rm << 16);
303 WriteWord(opcode);
304 }
305
Eor(REGISTER32 rd,REGISTER32 rn,uint8 n,uint8 immr,uint8 imms)306 void CAArch64Assembler::Eor(REGISTER32 rd, REGISTER32 rn, uint8 n, uint8 immr, uint8 imms)
307 {
308 WriteLogicalOpImm(0x52000000, n, immr, imms, rn, rd);
309 }
310
Eor_16b(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)311 void CAArch64Assembler::Eor_16b(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
312 {
313 uint32 opcode = 0x6E201C00;
314 opcode |= (rd << 0);
315 opcode |= (rn << 5);
316 opcode |= (rm << 16);
317 WriteWord(opcode);
318 }
319
Fabs_1s(REGISTERMD rd,REGISTERMD rn)320 void CAArch64Assembler::Fabs_1s(REGISTERMD rd, REGISTERMD rn)
321 {
322 uint32 opcode = 0x1E20C000;
323 opcode |= (rd << 0);
324 opcode |= (rn << 5);
325 WriteWord(opcode);
326 }
327
Fabs_4s(REGISTERMD rd,REGISTERMD rn)328 void CAArch64Assembler::Fabs_4s(REGISTERMD rd, REGISTERMD rn)
329 {
330 uint32 opcode = 0x4EA0F800;
331 opcode |= (rd << 0);
332 opcode |= (rn << 5);
333 WriteWord(opcode);
334 }
335
Fadd_1s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)336 void CAArch64Assembler::Fadd_1s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
337 {
338 uint32 opcode = 0x1E202800;
339 opcode |= (rd << 0);
340 opcode |= (rn << 5);
341 opcode |= (rm << 16);
342 WriteWord(opcode);
343 }
344
Fadd_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)345 void CAArch64Assembler::Fadd_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
346 {
347 uint32 opcode = 0x4E20D400;
348 opcode |= (rd << 0);
349 opcode |= (rn << 5);
350 opcode |= (rm << 16);
351 WriteWord(opcode);
352 }
353
Fcmeq_4s(REGISTERMD rd,REGISTERMD rn)354 void CAArch64Assembler::Fcmeq_4s(REGISTERMD rd, REGISTERMD rn)
355 {
356 uint32 opcode = 0x4EA0D800;
357 opcode |= (rd << 0);
358 opcode |= (rn << 5);
359 WriteWord(opcode);
360 }
361
Fcmlt_4s(REGISTERMD rd,REGISTERMD rn)362 void CAArch64Assembler::Fcmlt_4s(REGISTERMD rd, REGISTERMD rn)
363 {
364 uint32 opcode = 0x4EA0E800;
365 opcode |= (rd << 0);
366 opcode |= (rn << 5);
367 WriteWord(opcode);
368 }
369
Fcmp_1s(REGISTERMD rn,REGISTERMD rm)370 void CAArch64Assembler::Fcmp_1s(REGISTERMD rn, REGISTERMD rm)
371 {
372 uint32 opcode = 0x1E202000;
373 opcode |= (rn << 5);
374 opcode |= (rm << 16);
375 WriteWord(opcode);
376 }
377
Fcvtzs_1s(REGISTERMD rd,REGISTERMD rn)378 void CAArch64Assembler::Fcvtzs_1s(REGISTERMD rd, REGISTERMD rn)
379 {
380 uint32 opcode = 0x5EA1B800;
381 opcode |= (rd << 0);
382 opcode |= (rn << 5);
383 WriteWord(opcode);
384 }
385
Fcvtzs_4s(REGISTERMD rd,REGISTERMD rn)386 void CAArch64Assembler::Fcvtzs_4s(REGISTERMD rd, REGISTERMD rn)
387 {
388 uint32 opcode = 0x4EA1B800;
389 opcode |= (rd << 0);
390 opcode |= (rn << 5);
391 WriteWord(opcode);
392 }
393
Fdiv_1s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)394 void CAArch64Assembler::Fdiv_1s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
395 {
396 uint32 opcode = 0x1E201800;
397 opcode |= (rd << 0);
398 opcode |= (rn << 5);
399 opcode |= (rm << 16);
400 WriteWord(opcode);
401 }
402
Fdiv_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)403 void CAArch64Assembler::Fdiv_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
404 {
405 uint32 opcode = 0x6E20FC00;
406 opcode |= (rd << 0);
407 opcode |= (rn << 5);
408 opcode |= (rm << 16);
409 WriteWord(opcode);
410 }
411
Fmov_1s(REGISTERMD rd,uint8 imm)412 void CAArch64Assembler::Fmov_1s(REGISTERMD rd, uint8 imm)
413 {
414 uint32 opcode = 0x1E201000;
415 opcode |= (rd << 0);
416 opcode |= (imm << 13);
417 WriteWord(opcode);
418 }
419
Fmul_1s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)420 void CAArch64Assembler::Fmul_1s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
421 {
422 uint32 opcode = 0x1E200800;
423 opcode |= (rd << 0);
424 opcode |= (rn << 5);
425 opcode |= (rm << 16);
426 WriteWord(opcode);
427 }
428
Fmul_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)429 void CAArch64Assembler::Fmul_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
430 {
431 uint32 opcode = 0x6E20DC00;
432 opcode |= (rd << 0);
433 opcode |= (rn << 5);
434 opcode |= (rm << 16);
435 WriteWord(opcode);
436 }
437
Fmax_1s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)438 void CAArch64Assembler::Fmax_1s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
439 {
440 uint32 opcode = 0x1E204800;
441 opcode |= (rd << 0);
442 opcode |= (rn << 5);
443 opcode |= (rm << 16);
444 WriteWord(opcode);
445 }
446
Fmax_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)447 void CAArch64Assembler::Fmax_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
448 {
449 uint32 opcode = 0x4E20F400;
450 opcode |= (rd << 0);
451 opcode |= (rn << 5);
452 opcode |= (rm << 16);
453 WriteWord(opcode);
454 }
455
Fneg_1s(REGISTERMD rd,REGISTERMD rn)456 void CAArch64Assembler::Fneg_1s(REGISTERMD rd, REGISTERMD rn)
457 {
458 uint32 opcode = 0x1E214000;
459 opcode |= (rd << 0);
460 opcode |= (rn << 5);
461 WriteWord(opcode);
462 }
463
Fmin_1s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)464 void CAArch64Assembler::Fmin_1s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
465 {
466 uint32 opcode = 0x1E205800;
467 opcode |= (rd << 0);
468 opcode |= (rn << 5);
469 opcode |= (rm << 16);
470 WriteWord(opcode);
471 }
472
Fmin_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)473 void CAArch64Assembler::Fmin_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
474 {
475 uint32 opcode = 0x4EA0F400;
476 opcode |= (rd << 0);
477 opcode |= (rn << 5);
478 opcode |= (rm << 16);
479 WriteWord(opcode);
480 }
481
Fsqrt_1s(REGISTERMD rd,REGISTERMD rn)482 void CAArch64Assembler::Fsqrt_1s(REGISTERMD rd, REGISTERMD rn)
483 {
484 uint32 opcode = 0x1E21C000;
485 opcode |= (rd << 0);
486 opcode |= (rn << 5);
487 WriteWord(opcode);
488 }
489
Fsub_1s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)490 void CAArch64Assembler::Fsub_1s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
491 {
492 uint32 opcode = 0x1E203800;
493 opcode |= (rd << 0);
494 opcode |= (rn << 5);
495 opcode |= (rm << 16);
496 WriteWord(opcode);
497 }
498
Fsub_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)499 void CAArch64Assembler::Fsub_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
500 {
501 uint32 opcode = 0x4EA0D400;
502 opcode |= (rd << 0);
503 opcode |= (rn << 5);
504 opcode |= (rm << 16);
505 WriteWord(opcode);
506 }
507
Ins_1s(REGISTERMD rd,uint8 index1,REGISTERMD rn,uint8 index2)508 void CAArch64Assembler::Ins_1s(REGISTERMD rd, uint8 index1, REGISTERMD rn, uint8 index2)
509 {
510 assert(index1 < 4);
511 assert(index2 < 4);
512 index1 &= 0x3;
513 index2 &= 0x3;
514 uint32 opcode = 0x6E040400;
515 opcode |= (rd << 0);
516 opcode |= (rn << 5);
517 opcode |= (index2 << 13);
518 opcode |= (index1 << 19);
519 WriteWord(opcode);
520 }
521
Ins_1d(REGISTERMD rd,uint8 index,REGISTER64 rn)522 void CAArch64Assembler::Ins_1d(REGISTERMD rd, uint8 index, REGISTER64 rn)
523 {
524 assert(index < 2);
525 index &= 0x1;
526 uint8 imm5 = (index << 4) | 0x8;
527 uint32 opcode = 0x4E001C00;
528 opcode |= (rd << 0);
529 opcode |= (rn << 5);
530 opcode |= (imm5 << 16);
531 WriteWord(opcode);
532 }
533
Ld1_4s(REGISTERMD rt,REGISTER64 rn)534 void CAArch64Assembler::Ld1_4s(REGISTERMD rt, REGISTER64 rn)
535 {
536 uint32 opcode = 0x4C407800;
537 opcode |= (rt << 0);
538 opcode |= (rn << 5);
539 WriteWord(opcode);
540 }
541
Ldp_PostIdx(REGISTER64 rt,REGISTER64 rt2,REGISTER64 rn,int32 offset)542 void CAArch64Assembler::Ldp_PostIdx(REGISTER64 rt, REGISTER64 rt2, REGISTER64 rn, int32 offset)
543 {
544 assert((offset & 0x07) == 0);
545 int32 scaledOffset = offset / 8;
546 assert(scaledOffset >= -64 && scaledOffset <= 63);
547 uint32 opcode = 0xA8C00000;
548 opcode |= (rt << 0);
549 opcode |= (rn << 5);
550 opcode |= (rt2 << 10);
551 opcode |= ((scaledOffset & 0x7F) << 15);
552 WriteWord(opcode);
553 }
554
Ldr(REGISTER32 rt,REGISTER64 rn,uint32 offset)555 void CAArch64Assembler::Ldr(REGISTER32 rt, REGISTER64 rn, uint32 offset)
556 {
557 assert((offset & 0x03) == 0);
558 uint32 scaledOffset = offset / 4;
559 assert(scaledOffset < 0x1000);
560 WriteLoadStoreOpImm(0xB9400000, scaledOffset, rn, rt);
561 }
562
Ldr(REGISTER64 rt,REGISTER64 rn,uint32 offset)563 void CAArch64Assembler::Ldr(REGISTER64 rt, REGISTER64 rn, uint32 offset)
564 {
565 assert((offset & 0x07) == 0);
566 uint32 scaledOffset = offset / 8;
567 assert(scaledOffset < 0x1000);
568 WriteLoadStoreOpImm(0xF9400000, scaledOffset, rn, rt);
569 }
570
Ldr_1s(REGISTERMD rt,REGISTER64 rn,uint32 offset)571 void CAArch64Assembler::Ldr_1s(REGISTERMD rt, REGISTER64 rn, uint32 offset)
572 {
573 assert((offset & 0x03) == 0);
574 uint32 scaledOffset = offset / 4;
575 assert(scaledOffset < 0x1000);
576 WriteLoadStoreOpImm(0xBD400000, scaledOffset, rn, rt);
577 }
578
Ldr_1q(REGISTERMD rt,REGISTER64 rn,uint32 offset)579 void CAArch64Assembler::Ldr_1q(REGISTERMD rt, REGISTER64 rn, uint32 offset)
580 {
581 assert((offset & 0x0F) == 0);
582 uint32 scaledOffset = offset / 0x10;
583 assert(scaledOffset < 0x1000);
584 WriteLoadStoreOpImm(0x3DC00000, scaledOffset, rn, rt);
585 }
586
Lsl(REGISTER32 rd,REGISTER32 rn,uint8 sa)587 void CAArch64Assembler::Lsl(REGISTER32 rd, REGISTER32 rn, uint8 sa)
588 {
589 uint32 imms = 0x1F - (sa & 0x1F);
590 uint32 immr = -sa & 0x1F;
591 WriteLogicalOpImm(0x53000000, 0, immr, imms, rn, rd);
592 }
593
Lsl(REGISTER64 rd,REGISTER64 rn,uint8 sa)594 void CAArch64Assembler::Lsl(REGISTER64 rd, REGISTER64 rn, uint8 sa)
595 {
596 uint32 imms = 0x3F - (sa & 0x3F);
597 uint32 immr = -sa & 0x3F;
598 WriteLogicalOpImm(0xD3400000, 0, immr, imms, rn, rd);
599 }
600
Lslv(REGISTER32 rd,REGISTER32 rn,REGISTER32 rm)601 void CAArch64Assembler::Lslv(REGISTER32 rd, REGISTER32 rn, REGISTER32 rm)
602 {
603 WriteDataProcOpReg2(0x1AC02000, rm, rn, rd);
604 }
605
Lslv(REGISTER64 rd,REGISTER64 rn,REGISTER64 rm)606 void CAArch64Assembler::Lslv(REGISTER64 rd, REGISTER64 rn, REGISTER64 rm)
607 {
608 WriteDataProcOpReg2(0x9AC02000, rm, rn, rd);
609 }
610
Lsr(REGISTER32 rd,REGISTER32 rn,uint8 sa)611 void CAArch64Assembler::Lsr(REGISTER32 rd, REGISTER32 rn, uint8 sa)
612 {
613 uint32 imms = 0x1F;
614 uint32 immr = sa & 0x1F;
615 WriteLogicalOpImm(0x53000000, 0, immr, imms, rn, rd);
616 }
617
Lsr(REGISTER64 rd,REGISTER64 rn,uint8 sa)618 void CAArch64Assembler::Lsr(REGISTER64 rd, REGISTER64 rn, uint8 sa)
619 {
620 uint32 imms = 0x3F;
621 uint32 immr = sa & 0x3F;
622 WriteLogicalOpImm(0xD3400000, 0, immr, imms, rn, rd);
623 }
624
Lsrv(REGISTER32 rd,REGISTER32 rn,REGISTER32 rm)625 void CAArch64Assembler::Lsrv(REGISTER32 rd, REGISTER32 rn, REGISTER32 rm)
626 {
627 WriteDataProcOpReg2(0x1AC02400, rm, rn, rd);
628 }
629
Lsrv(REGISTER64 rd,REGISTER64 rn,REGISTER64 rm)630 void CAArch64Assembler::Lsrv(REGISTER64 rd, REGISTER64 rn, REGISTER64 rm)
631 {
632 WriteDataProcOpReg2(0x9AC02400, rm, rn, rd);
633 }
634
Mov(REGISTER32 rd,REGISTER32 rm)635 void CAArch64Assembler::Mov(REGISTER32 rd, REGISTER32 rm)
636 {
637 uint32 opcode = 0x2A0003E0;
638 opcode |= (rd << 0);
639 opcode |= (rm << 16);
640 WriteWord(opcode);
641 }
642
Mov(REGISTER64 rd,REGISTER64 rm)643 void CAArch64Assembler::Mov(REGISTER64 rd, REGISTER64 rm)
644 {
645 uint32 opcode = 0xAA0003E0;
646 opcode |= (rd << 0);
647 opcode |= (rm << 16);
648 WriteWord(opcode);
649 }
650
Mov(REGISTERMD rd,REGISTERMD rn)651 void CAArch64Assembler::Mov(REGISTERMD rd, REGISTERMD rn)
652 {
653 Orr_16b(rd, rn, rn);
654 }
655
Mov_Sp(REGISTER64 rd,REGISTER64 rn)656 void CAArch64Assembler::Mov_Sp(REGISTER64 rd, REGISTER64 rn)
657 {
658 uint32 opcode = 0x91000000;
659 opcode |= (rd << 0);
660 opcode |= (rn << 5);
661 WriteWord(opcode);
662 }
663
Movn(REGISTER32 rd,uint16 imm,uint8 pos)664 void CAArch64Assembler::Movn(REGISTER32 rd, uint16 imm, uint8 pos)
665 {
666 assert(pos < 2);
667 WriteMoveWideOpImm(0x12800000, pos, imm, rd);
668 }
669
Movk(REGISTER32 rd,uint16 imm,uint8 pos)670 void CAArch64Assembler::Movk(REGISTER32 rd, uint16 imm, uint8 pos)
671 {
672 assert(pos < 2);
673 WriteMoveWideOpImm(0x72800000, pos, imm, rd);
674 }
675
Movk(REGISTER64 rd,uint16 imm,uint8 pos)676 void CAArch64Assembler::Movk(REGISTER64 rd, uint16 imm, uint8 pos)
677 {
678 assert(pos < 4);
679 WriteMoveWideOpImm(0xF2800000, pos, imm, rd);
680 }
681
Movz(REGISTER32 rd,uint16 imm,uint8 pos)682 void CAArch64Assembler::Movz(REGISTER32 rd, uint16 imm, uint8 pos)
683 {
684 assert(pos < 2);
685 WriteMoveWideOpImm(0x52800000, pos, imm, rd);
686 }
687
Movz(REGISTER64 rd,uint16 imm,uint8 pos)688 void CAArch64Assembler::Movz(REGISTER64 rd, uint16 imm, uint8 pos)
689 {
690 assert(pos < 4);
691 WriteMoveWideOpImm(0xD2800000, pos, imm, rd);
692 }
693
Msub(REGISTER32 rd,REGISTER32 rn,REGISTER32 rm,REGISTER32 ra)694 void CAArch64Assembler::Msub(REGISTER32 rd, REGISTER32 rn, REGISTER32 rm, REGISTER32 ra)
695 {
696 uint32 opcode = 0x1B008000;
697 opcode |= (rd << 0);
698 opcode |= (rn << 5);
699 opcode |= (ra << 10);
700 opcode |= (rm << 16);
701 WriteWord(opcode);
702 }
703
Mvn(REGISTER32 rd,REGISTER32 rm)704 void CAArch64Assembler::Mvn(REGISTER32 rd, REGISTER32 rm)
705 {
706 uint32 opcode = 0x2A200000;
707 opcode |= (rd << 0);
708 opcode |= (wZR << 5);
709 opcode |= (rm << 16);
710 WriteWord(opcode);
711 }
712
Orn_16b(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)713 void CAArch64Assembler::Orn_16b(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
714 {
715 uint32 opcode = 0x4EE01C00;
716 opcode |= (rd << 0);
717 opcode |= (rn << 5);
718 opcode |= (rm << 16);
719 WriteWord(opcode);
720 }
721
Orr(REGISTER32 rd,REGISTER32 rn,REGISTER32 rm)722 void CAArch64Assembler::Orr(REGISTER32 rd, REGISTER32 rn, REGISTER32 rm)
723 {
724 uint32 opcode = 0x2A000000;
725 opcode |= (rd << 0);
726 opcode |= (rn << 5);
727 opcode |= (rm << 16);
728 WriteWord(opcode);
729 }
730
Orr(REGISTER32 rd,REGISTER32 rn,uint8 n,uint8 immr,uint8 imms)731 void CAArch64Assembler::Orr(REGISTER32 rd, REGISTER32 rn, uint8 n, uint8 immr, uint8 imms)
732 {
733 WriteLogicalOpImm(0x32000000, n, immr, imms, rn, rd);
734 }
735
Orr_16b(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)736 void CAArch64Assembler::Orr_16b(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
737 {
738 uint32 opcode = 0x4EA01C00;
739 opcode |= (rd << 0);
740 opcode |= (rn << 5);
741 opcode |= (rm << 16);
742 WriteWord(opcode);
743 }
744
Ret(REGISTER64 rn)745 void CAArch64Assembler::Ret(REGISTER64 rn)
746 {
747 uint32 opcode = 0xD65F0000;
748 opcode |= (rn << 5);
749 WriteWord(opcode);
750 }
751
Scvtf_1s(REGISTERMD rd,REGISTERMD rn)752 void CAArch64Assembler::Scvtf_1s(REGISTERMD rd, REGISTERMD rn)
753 {
754 uint32 opcode = 0x5E21D800;
755 opcode |= (rd << 0);
756 opcode |= (rn << 5);
757 WriteWord(opcode);
758 }
759
Scvtf_4s(REGISTERMD rd,REGISTERMD rn)760 void CAArch64Assembler::Scvtf_4s(REGISTERMD rd, REGISTERMD rn)
761 {
762 uint32 opcode = 0x4E21D800;
763 opcode |= (rd << 0);
764 opcode |= (rn << 5);
765 WriteWord(opcode);
766 }
767
Sdiv(REGISTER32 rd,REGISTER32 rn,REGISTER32 rm)768 void CAArch64Assembler::Sdiv(REGISTER32 rd, REGISTER32 rn, REGISTER32 rm)
769 {
770 uint32 opcode = 0x1AC00C00;
771 opcode |= (rd << 0);
772 opcode |= (rn << 5);
773 opcode |= (rm << 16);
774 WriteWord(opcode);
775 }
776
Shl_4s(REGISTERMD rd,REGISTERMD rn,uint8 sa)777 void CAArch64Assembler::Shl_4s(REGISTERMD rd, REGISTERMD rn, uint8 sa)
778 {
779 uint8 immhb = (sa & 0x1F) + 32;
780 uint32 opcode = 0x4F005400;
781 opcode |= (rd << 0);
782 opcode |= (rn << 5);
783 opcode |= (immhb << 16);
784 WriteWord(opcode);
785 }
786
Shl_8h(REGISTERMD rd,REGISTERMD rn,uint8 sa)787 void CAArch64Assembler::Shl_8h(REGISTERMD rd, REGISTERMD rn, uint8 sa)
788 {
789 uint8 immhb = (sa & 0xF) + 16;
790 uint32 opcode = 0x4F005400;
791 opcode |= (rd << 0);
792 opcode |= (rn << 5);
793 opcode |= (immhb << 16);
794 WriteWord(opcode);
795 }
796
Smax_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)797 void CAArch64Assembler::Smax_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
798 {
799 uint32 opcode = 0x4EA06400;
800 opcode |= (rd << 0);
801 opcode |= (rn << 5);
802 opcode |= (rm << 16);
803 WriteWord(opcode);
804 }
805
Smax_8h(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)806 void CAArch64Assembler::Smax_8h(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
807 {
808 uint32 opcode = 0x4E606400;
809 opcode |= (rd << 0);
810 opcode |= (rn << 5);
811 opcode |= (rm << 16);
812 WriteWord(opcode);
813 }
814
Smin_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)815 void CAArch64Assembler::Smin_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
816 {
817 uint32 opcode = 0x4EA06C00;
818 opcode |= (rd << 0);
819 opcode |= (rn << 5);
820 opcode |= (rm << 16);
821 WriteWord(opcode);
822 }
823
Smin_8h(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)824 void CAArch64Assembler::Smin_8h(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
825 {
826 uint32 opcode = 0x4E606C00;
827 opcode |= (rd << 0);
828 opcode |= (rn << 5);
829 opcode |= (rm << 16);
830 WriteWord(opcode);
831 }
832
Smull(REGISTER64 rd,REGISTER32 rn,REGISTER32 rm)833 void CAArch64Assembler::Smull(REGISTER64 rd, REGISTER32 rn, REGISTER32 rm)
834 {
835 uint32 opcode = 0x9B200000;
836 opcode |= (rd << 0);
837 opcode |= (rn << 5);
838 opcode |= (wZR << 10);
839 opcode |= (rm << 16);
840 WriteWord(opcode);
841 }
842
Sshr_4s(REGISTERMD rd,REGISTERMD rn,uint8 sa)843 void CAArch64Assembler::Sshr_4s(REGISTERMD rd, REGISTERMD rn, uint8 sa)
844 {
845 uint8 immhb = (32 * 2) - (sa & 0x1F);
846 uint32 opcode = 0x4F000400;
847 opcode |= (rd << 0);
848 opcode |= (rn << 5);
849 opcode |= (immhb << 16);
850 WriteWord(opcode);
851 }
852
Sshr_8h(REGISTERMD rd,REGISTERMD rn,uint8 sa)853 void CAArch64Assembler::Sshr_8h(REGISTERMD rd, REGISTERMD rn, uint8 sa)
854 {
855 uint8 immhb = (16 * 2) - (sa & 0xF);
856 uint32 opcode = 0x4F000400;
857 opcode |= (rd << 0);
858 opcode |= (rn << 5);
859 opcode |= (immhb << 16);
860 WriteWord(opcode);
861 }
862
Sqadd_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)863 void CAArch64Assembler::Sqadd_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
864 {
865 uint32 opcode = 0x4EA00C00;
866 opcode |= (rd << 0);
867 opcode |= (rn << 5);
868 opcode |= (rm << 16);
869 WriteWord(opcode);
870 }
871
Sqadd_8h(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)872 void CAArch64Assembler::Sqadd_8h(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
873 {
874 uint32 opcode = 0x4E600C00;
875 opcode |= (rd << 0);
876 opcode |= (rn << 5);
877 opcode |= (rm << 16);
878 WriteWord(opcode);
879 }
880
Sqsub_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)881 void CAArch64Assembler::Sqsub_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
882 {
883 uint32 opcode = 0x4EA02C00;
884 opcode |= (rd << 0);
885 opcode |= (rn << 5);
886 opcode |= (rm << 16);
887 WriteWord(opcode);
888 }
889
Sqsub_8h(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)890 void CAArch64Assembler::Sqsub_8h(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
891 {
892 uint32 opcode = 0x4E602C00;
893 opcode |= (rd << 0);
894 opcode |= (rn << 5);
895 opcode |= (rm << 16);
896 WriteWord(opcode);
897 }
898
St1_4s(REGISTERMD rt,REGISTER64 rn)899 void CAArch64Assembler::St1_4s(REGISTERMD rt, REGISTER64 rn)
900 {
901 uint32 opcode = 0x4C007800;
902 opcode |= (rt << 0);
903 opcode |= (rn << 5);
904 WriteWord(opcode);
905 }
906
Stp(REGISTER32 rt,REGISTER32 rt2,REGISTER64 rn,int32 offset)907 void CAArch64Assembler::Stp(REGISTER32 rt, REGISTER32 rt2, REGISTER64 rn, int32 offset)
908 {
909 assert((offset & 0x03) == 0);
910 int32 scaledOffset = offset / 4;
911 assert(scaledOffset >= -64 && scaledOffset <= 63);
912 uint32 opcode = 0x29000000;
913 opcode |= (rt << 0);
914 opcode |= (rn << 5);
915 opcode |= (rt2 << 10);
916 opcode |= ((scaledOffset & 0x7F) << 15);
917 WriteWord(opcode);
918 }
919
Stp_PreIdx(REGISTER64 rt,REGISTER64 rt2,REGISTER64 rn,int32 offset)920 void CAArch64Assembler::Stp_PreIdx(REGISTER64 rt, REGISTER64 rt2, REGISTER64 rn, int32 offset)
921 {
922 assert((offset & 0x07) == 0);
923 int32 scaledOffset = offset / 8;
924 assert(scaledOffset >= -64 && scaledOffset <= 63);
925 uint32 opcode = 0xA9800000;
926 opcode |= (rt << 0);
927 opcode |= (rn << 5);
928 opcode |= (rt2 << 10);
929 opcode |= ((scaledOffset & 0x7F) << 15);
930 WriteWord(opcode);
931 }
932
Str(REGISTER32 rt,REGISTER64 rn,uint32 offset)933 void CAArch64Assembler::Str(REGISTER32 rt, REGISTER64 rn, uint32 offset)
934 {
935 assert((offset & 0x03) == 0);
936 uint32 scaledOffset = offset / 4;
937 assert(scaledOffset < 0x1000);
938 WriteLoadStoreOpImm(0xB9000000, scaledOffset, rn, rt);
939 }
940
Str(REGISTER64 rt,REGISTER64 rn,uint32 offset)941 void CAArch64Assembler::Str(REGISTER64 rt, REGISTER64 rn, uint32 offset)
942 {
943 assert((offset & 0x07) == 0);
944 uint32 scaledOffset = offset / 8;
945 assert(scaledOffset < 0x1000);
946 WriteLoadStoreOpImm(0xF9000000, scaledOffset, rn, rt);
947 }
948
Str_1s(REGISTERMD rt,REGISTER64 rn,uint32 offset)949 void CAArch64Assembler::Str_1s(REGISTERMD rt, REGISTER64 rn, uint32 offset)
950 {
951 assert((offset & 0x03) == 0);
952 uint32 scaledOffset = offset / 4;
953 assert(scaledOffset < 0x1000);
954 WriteLoadStoreOpImm(0xBD000000, scaledOffset, rn, rt);
955 }
956
Str_1q(REGISTERMD rt,REGISTER64 rn,uint32 offset)957 void CAArch64Assembler::Str_1q(REGISTERMD rt, REGISTER64 rn, uint32 offset)
958 {
959 assert((offset & 0x0F) == 0);
960 uint32 scaledOffset = offset / 0x10;
961 assert(scaledOffset < 0x1000);
962 WriteLoadStoreOpImm(0x3D800000, scaledOffset, rn, rt);
963 }
964
Sub(REGISTER32 rd,REGISTER32 rn,REGISTER32 rm)965 void CAArch64Assembler::Sub(REGISTER32 rd, REGISTER32 rn, REGISTER32 rm)
966 {
967 uint32 opcode = 0x4B000000;
968 opcode |= (rd << 0);
969 opcode |= (rn << 5);
970 opcode |= (rm << 16);
971 WriteWord(opcode);
972 }
973
Sub(REGISTER64 rd,REGISTER64 rn,REGISTER64 rm)974 void CAArch64Assembler::Sub(REGISTER64 rd, REGISTER64 rn, REGISTER64 rm)
975 {
976 uint32 opcode = 0xCB000000;
977 opcode |= (rd << 0);
978 opcode |= (rn << 5);
979 opcode |= (rm << 16);
980 WriteWord(opcode);
981 }
982
Sub(REGISTER32 rd,REGISTER32 rn,uint16 imm,ADDSUB_IMM_SHIFT_TYPE shift)983 void CAArch64Assembler::Sub(REGISTER32 rd, REGISTER32 rn, uint16 imm, ADDSUB_IMM_SHIFT_TYPE shift)
984 {
985 WriteAddSubOpImm(0x51000000, shift, imm, rn, rd);
986 }
987
Sub(REGISTER64 rd,REGISTER64 rn,uint16 imm,ADDSUB_IMM_SHIFT_TYPE shift)988 void CAArch64Assembler::Sub(REGISTER64 rd, REGISTER64 rn, uint16 imm, ADDSUB_IMM_SHIFT_TYPE shift)
989 {
990 WriteAddSubOpImm(0xD1000000, shift, imm, rn, rd);
991 }
992
Sub_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)993 void CAArch64Assembler::Sub_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
994 {
995 uint32 opcode = 0x6EA08400;
996 opcode |= (rd << 0);
997 opcode |= (rn << 5);
998 opcode |= (rm << 16);
999 WriteWord(opcode);
1000 }
1001
Sub_8h(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1002 void CAArch64Assembler::Sub_8h(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1003 {
1004 uint32 opcode = 0x6E608400;
1005 opcode |= (rd << 0);
1006 opcode |= (rn << 5);
1007 opcode |= (rm << 16);
1008 WriteWord(opcode);
1009 }
1010
Sub_16b(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1011 void CAArch64Assembler::Sub_16b(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1012 {
1013 uint32 opcode = 0x6E208400;
1014 opcode |= (rd << 0);
1015 opcode |= (rn << 5);
1016 opcode |= (rm << 16);
1017 WriteWord(opcode);
1018 }
1019
Tst(REGISTER32 rn,REGISTER32 rm)1020 void CAArch64Assembler::Tst(REGISTER32 rn, REGISTER32 rm)
1021 {
1022 uint32 opcode = 0x6A000000;
1023 opcode |= (wZR << 0);
1024 opcode |= (rn << 5);
1025 opcode |= (rm << 16);
1026 WriteWord(opcode);
1027 }
1028
Udiv(REGISTER32 rd,REGISTER32 rn,REGISTER32 rm)1029 void CAArch64Assembler::Udiv(REGISTER32 rd, REGISTER32 rn, REGISTER32 rm)
1030 {
1031 uint32 opcode = 0x1AC00800;
1032 opcode |= (rd << 0);
1033 opcode |= (rn << 5);
1034 opcode |= (rm << 16);
1035 WriteWord(opcode);
1036 }
1037
Umov_1s(REGISTER32 rd,REGISTERMD rn,uint8 index)1038 void CAArch64Assembler::Umov_1s(REGISTER32 rd, REGISTERMD rn, uint8 index)
1039 {
1040 assert(index < 4);
1041 uint8 imm5 = 0x4 | ((index & 3) << 3);
1042 uint32 opcode = 0x0E003C00;
1043 opcode |= (rd << 0);
1044 opcode |= (rn << 5);
1045 opcode |= (imm5 << 16);
1046 WriteWord(opcode);
1047 }
1048
Umull(REGISTER64 rd,REGISTER32 rn,REGISTER32 rm)1049 void CAArch64Assembler::Umull(REGISTER64 rd, REGISTER32 rn, REGISTER32 rm)
1050 {
1051 uint32 opcode = 0x9BA00000;
1052 opcode |= (rd << 0);
1053 opcode |= (rn << 5);
1054 opcode |= (wZR << 10);
1055 opcode |= (rm << 16);
1056 WriteWord(opcode);
1057 }
1058
Uqadd_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1059 void CAArch64Assembler::Uqadd_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1060 {
1061 uint32 opcode = 0x6EA00C00;
1062 opcode |= (rd << 0);
1063 opcode |= (rn << 5);
1064 opcode |= (rm << 16);
1065 WriteWord(opcode);
1066 }
1067
Uqadd_8h(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1068 void CAArch64Assembler::Uqadd_8h(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1069 {
1070 uint32 opcode = 0x6E600C00;
1071 opcode |= (rd << 0);
1072 opcode |= (rn << 5);
1073 opcode |= (rm << 16);
1074 WriteWord(opcode);
1075 }
1076
Uqadd_16b(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1077 void CAArch64Assembler::Uqadd_16b(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1078 {
1079 uint32 opcode = 0x6E200C00;
1080 opcode |= (rd << 0);
1081 opcode |= (rn << 5);
1082 opcode |= (rm << 16);
1083 WriteWord(opcode);
1084 }
1085
Uqsub_8h(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1086 void CAArch64Assembler::Uqsub_8h(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1087 {
1088 uint32 opcode = 0x6E602C00;
1089 opcode |= (rd << 0);
1090 opcode |= (rn << 5);
1091 opcode |= (rm << 16);
1092 WriteWord(opcode);
1093 }
1094
Uqsub_16b(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1095 void CAArch64Assembler::Uqsub_16b(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1096 {
1097 uint32 opcode = 0x6E202C00;
1098 opcode |= (rd << 0);
1099 opcode |= (rn << 5);
1100 opcode |= (rm << 16);
1101 WriteWord(opcode);
1102 }
1103
Ushr_4s(REGISTERMD rd,REGISTERMD rn,uint8 sa)1104 void CAArch64Assembler::Ushr_4s(REGISTERMD rd, REGISTERMD rn, uint8 sa)
1105 {
1106 uint8 immhb = (32 * 2) - (sa & 0x1F);
1107 uint32 opcode = 0x6F000400;
1108 opcode |= (rd << 0);
1109 opcode |= (rn << 5);
1110 opcode |= (immhb << 16);
1111 WriteWord(opcode);
1112 }
1113
Ushr_8h(REGISTERMD rd,REGISTERMD rn,uint8 sa)1114 void CAArch64Assembler::Ushr_8h(REGISTERMD rd, REGISTERMD rn, uint8 sa)
1115 {
1116 uint8 immhb = (16 * 2) - (sa & 0xF);
1117 uint32 opcode = 0x6F000400;
1118 opcode |= (rd << 0);
1119 opcode |= (rn << 5);
1120 opcode |= (immhb << 16);
1121 WriteWord(opcode);
1122 }
1123
Xtn1_4h(REGISTERMD rd,REGISTERMD rn)1124 void CAArch64Assembler::Xtn1_4h(REGISTERMD rd, REGISTERMD rn)
1125 {
1126 uint32 opcode = 0x0E612800;
1127 opcode |= (rd << 0);
1128 opcode |= (rn << 5);
1129 WriteWord(opcode);
1130 }
1131
Xtn1_8b(REGISTERMD rd,REGISTERMD rn)1132 void CAArch64Assembler::Xtn1_8b(REGISTERMD rd, REGISTERMD rn)
1133 {
1134 uint32 opcode = 0x0E212800;
1135 opcode |= (rd << 0);
1136 opcode |= (rn << 5);
1137 WriteWord(opcode);
1138 }
1139
Xtn2_8h(REGISTERMD rd,REGISTERMD rn)1140 void CAArch64Assembler::Xtn2_8h(REGISTERMD rd, REGISTERMD rn)
1141 {
1142 uint32 opcode = 0x4E612800;
1143 opcode |= (rd << 0);
1144 opcode |= (rn << 5);
1145 WriteWord(opcode);
1146 }
1147
Xtn2_16b(REGISTERMD rd,REGISTERMD rn)1148 void CAArch64Assembler::Xtn2_16b(REGISTERMD rd, REGISTERMD rn)
1149 {
1150 uint32 opcode = 0x4E212800;
1151 opcode |= (rd << 0);
1152 opcode |= (rn << 5);
1153 WriteWord(opcode);
1154 }
1155
Zip1_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1156 void CAArch64Assembler::Zip1_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1157 {
1158 uint32 opcode = 0x4E803800;
1159 opcode |= (rd << 0);
1160 opcode |= (rn << 5);
1161 opcode |= (rm << 16);
1162 WriteWord(opcode);
1163 }
1164
Zip1_8h(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1165 void CAArch64Assembler::Zip1_8h(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1166 {
1167 uint32 opcode = 0x4E403800;
1168 opcode |= (rd << 0);
1169 opcode |= (rn << 5);
1170 opcode |= (rm << 16);
1171 WriteWord(opcode);
1172 }
1173
Zip1_16b(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1174 void CAArch64Assembler::Zip1_16b(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1175 {
1176 uint32 opcode = 0x4E003800;
1177 opcode |= (rd << 0);
1178 opcode |= (rn << 5);
1179 opcode |= (rm << 16);
1180 WriteWord(opcode);
1181 }
1182
Zip2_4s(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1183 void CAArch64Assembler::Zip2_4s(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1184 {
1185 uint32 opcode = 0x4E807800;
1186 opcode |= (rd << 0);
1187 opcode |= (rn << 5);
1188 opcode |= (rm << 16);
1189 WriteWord(opcode);
1190 }
1191
Zip2_8h(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1192 void CAArch64Assembler::Zip2_8h(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1193 {
1194 uint32 opcode = 0x4E407800;
1195 opcode |= (rd << 0);
1196 opcode |= (rn << 5);
1197 opcode |= (rm << 16);
1198 WriteWord(opcode);
1199 }
1200
Zip2_16b(REGISTERMD rd,REGISTERMD rn,REGISTERMD rm)1201 void CAArch64Assembler::Zip2_16b(REGISTERMD rd, REGISTERMD rn, REGISTERMD rm)
1202 {
1203 uint32 opcode = 0x4E007800;
1204 opcode |= (rd << 0);
1205 opcode |= (rn << 5);
1206 opcode |= (rm << 16);
1207 WriteWord(opcode);
1208 }
1209
WriteAddSubOpImm(uint32 opcode,uint32 shift,uint32 imm,uint32 rn,uint32 rd)1210 void CAArch64Assembler::WriteAddSubOpImm(uint32 opcode, uint32 shift, uint32 imm, uint32 rn, uint32 rd)
1211 {
1212 assert(imm < 0x1000);
1213 opcode |= (rd << 0);
1214 opcode |= (rn << 5);
1215 opcode |= ((imm & 0xFFF) << 10);
1216 opcode |= (shift << 22);
1217 WriteWord(opcode);
1218 }
1219
WriteDataProcOpReg2(uint32 opcode,uint32 rm,uint32 rn,uint32 rd)1220 void CAArch64Assembler::WriteDataProcOpReg2(uint32 opcode, uint32 rm, uint32 rn, uint32 rd)
1221 {
1222 opcode |= (rd << 0);
1223 opcode |= (rn << 5);
1224 opcode |= (rm << 16);
1225 WriteWord(opcode);
1226 }
1227
WriteLogicalOpImm(uint32 opcode,uint32 n,uint32 immr,uint32 imms,uint32 rn,uint32 rd)1228 void CAArch64Assembler::WriteLogicalOpImm(uint32 opcode, uint32 n, uint32 immr, uint32 imms, uint32 rn, uint32 rd)
1229 {
1230 opcode |= (rd << 0);
1231 opcode |= (rn << 5);
1232 opcode |= (imms << 10);
1233 opcode |= (immr << 16);
1234 opcode |= (n << 22);
1235 WriteWord(opcode);
1236 }
1237
WriteLoadStoreOpImm(uint32 opcode,uint32 imm,uint32 rn,uint32 rt)1238 void CAArch64Assembler::WriteLoadStoreOpImm(uint32 opcode, uint32 imm, uint32 rn, uint32 rt)
1239 {
1240 opcode |= (rt << 0);
1241 opcode |= (rn << 5);
1242 opcode |= (imm << 10);
1243 WriteWord(opcode);
1244 }
1245
WriteMoveWideOpImm(uint32 opcode,uint32 hw,uint32 imm,uint32 rd)1246 void CAArch64Assembler::WriteMoveWideOpImm(uint32 opcode, uint32 hw, uint32 imm, uint32 rd)
1247 {
1248 opcode |= (rd << 0);
1249 opcode |= (imm << 5);
1250 opcode |= (hw << 21);
1251 WriteWord(opcode);
1252 }
1253
WriteWord(uint32 value)1254 void CAArch64Assembler::WriteWord(uint32 value)
1255 {
1256 m_stream->Write32(value);
1257 }
1258