1use crate::aarch64::opcodes::{Encoding, Opcode, INST_INFO};
2use crate::core::buffer::{LabelUse, Reloc, RelocTarget};
3use crate::core::operand::*;
4use crate::core::{buffer::CodeBuffer, emitter::Emitter, patch::PatchSiteId};
5use crate::AsmError;
6
7use super::emitter::A64EmitterExplicit;
8pub struct Assembler<'a> {
9 pub buffer: &'a mut CodeBuffer,
10 last_error: Option<AsmError>,
11}
12
13impl<'a> Assembler<'a> {
14 pub fn patchable_b(&mut self, label: Label) -> PatchSiteId {
15 let offset = self.buffer.cur_offset();
16 self.b(label);
17 self.buffer
18 .record_label_patch_site(offset, label, LabelUse::A64Branch26)
19 }
20
21 pub fn patchable_call(&mut self, label: Label) -> PatchSiteId {
22 let offset = self.buffer.cur_offset();
23 self.bl(label);
24 self.buffer
25 .record_label_patch_site(offset, label, LabelUse::A64Branch26)
26 }
27}
28
29fn imm_add(value: i64) -> u32 {
30 let mut inst = 0;
31 let mut uval = value as u64;
32 if value < 0 {
33 inst = 0x40000000;
34 uval = !uval;
35 }
36
37 if (uval & 0xfff) == uval {
38 return inst | (uval << 10) as u32;
39 }
40
41 if (uval & 0xfff000) == uval {
42 return inst | 1 << 22 | (uval >> 2) as u32;
43 }
44
45 u32::MAX
46}
47
48fn imm_logical(mut value: u64, is64: bool) -> u32 {
49 if !is64 {
50 value = value | (value << 32);
51 }
52
53 if value == 0 || !value == 0 {
54 return u32::MAX;
55 }
56
57 let clz = value.leading_zeros();
58 let iclz = (!value).leading_zeros();
59 let ctz = value.trailing_zeros();
60 let ictz = (!value).trailing_zeros();
61 let mut popcount = value.count_ones();
62 let mut elog = 0;
63 let mut shift = 64;
64 let mut imms = (0x1780) | (popcount - 1);
65 while elog < 6 {
66 if (clz + ctz) == (shift - popcount) {
67 return (((if ctz != 0 { shift - ctz } else { 0 }) << 6) | (imms & 0x103f)) << 10;
68 } else if (iclz + ictz) == popcount {
69 return ((iclz << 6) | (imms & 0x103f)) << 10;
70 }
71 elog += 1;
72 popcount >>= 1;
73 shift >>= 1;
74 imms >>= 1;
75 let mask = (1u64 << shift) - 1;
76 if (value & mask) != (value >> shift & mask) {
77 break;
78 }
79 }
80
81 unreachable!()
82}
83
84fn imm_fmov32(value: f32) -> u32 {
85 let vi = value.to_bits();
86 if (vi & 0x7ffff) == 0 && ((vi >> 25 & 0x3f) - 0x1f) <= 1 {
87 return (vi >> 19 & 0x7f) | (vi >> 24 & 0x80);
88 }
89 return 0xffffffff;
90}
91
92fn imm_fmov64(value: f64) -> u64 {
93 let vi = value.to_bits();
94 if (vi & 0xffffffffffff) != 0 && ((vi >> 54 & 0x1ff) - 0xff) <= 1 {
95 return (vi >> 48 & 0x7f) | (vi >> 56 & 0x80);
96 }
97 return 0xffffffff;
98}
99
100const fn movi_encode(imm8: u32, op: u32, cmode: u32) -> u32 {
101 let x = if op != 0 { 0x20000000 } else { 0 };
102 x | ((cmode) << 12) | (((imm8) << 11) & 0x70000) | (((imm8) << 5) & 0x3e0)
103}
104
105fn imm_simdmovi(value: u64) -> u32 {
106 let imm8 = || {
107 return movi_encode((value & 0xff) as u32, 0, 0xe);
108 };
109 let mask64 = || {
110 let mut imm8 = 0u32;
111 for i in 0..8 {
112 let byte = value >> 8 * i & 0xff;
113 if byte == 0xff {
114 imm8 |= 1 << i;
115 } else if byte != 0 {
116 return u32::MAX;
117 }
118 }
119
120 return movi_encode(imm8, 1, 0xe);
121 };
122
123 if value == 0 || !value == 0 {
124 return imm8();
125 }
126 if (value & u32::MAX as u64) != value >> 32 {
127 return mask64();
128 }
129
130 if (value & 0xffff) != (value >> 16 & 0xffff) {
131 let value32 = value as u32;
132 let clz = value32.leading_zeros() >> 3;
133 let iclz = (!value32).leading_zeros() >> 3;
134 let ctz = value32.trailing_zeros() >> 3;
135 let ictz = (!value32).trailing_zeros() >> 3;
136
137 if clz + ctz >= 3 {
138 return movi_encode((value >> ctz * 8) as u32, 0, ctz * 2);
139 }
140 if iclz + ictz >= 3 {
141 return movi_encode((!value >> ictz * 8) as u32, 1, ictz * 2);
142 }
143 if clz + ictz >= 3 {
144 return movi_encode((value >> ictz * 8) as u32, 0, 0xc + ictz - 1);
145 }
146
147 if iclz + ctz >= 3 {
148 return movi_encode((!value >> ctz * 8) as u32, 1, 0xc + ctz - 1);
149 }
150
151 return mask64();
152 }
153
154 if (value & 0xff) != (value >> 8 & 0xff) {
155 let low8 = value & 0xff;
156 let high8 = value >> 8 & 0xff;
157
158 if high8 == 0 {
159 return movi_encode(low8 as _, 0, 0x8);
160 }
161
162 if high8 == 0xff {
163 return movi_encode((!low8) as u32, 1, 0x8);
164 }
165
166 if low8 == 0 {
167 return movi_encode(high8 as _, 0, 0xa);
168 }
169
170 if low8 == 0xff {
171 return movi_encode((!high8) as u32, 1, 0xa);
172 }
173 }
174
175 imm8()
176}
177
178impl<'a> Assembler<'a> {
179 pub fn last_error(&self) -> Option<&AsmError> {
180 self.last_error.as_ref()
181 }
182
183 pub fn new(buffer: &'a mut CodeBuffer) -> Self {
184 Assembler {
185 buffer,
186 last_error: None,
187 }
188 }
189
190 fn use_label(&mut self, label: &Operand, kind: LabelUse) {
191 let off = self.buffer.cur_offset();
192 self.buffer
193 .use_label_at_offset(off, label.as_::<Label>(), kind);
194 }
195}
196
197macro_rules! enc_ops1 {
198 ($op0:ident) => {
199 OperandType::$op0 as u32
200 };
201}
202
203macro_rules! enc_ops2 {
204 ($op0:ident, $op1:ident) => {
205 (OperandType::$op0 as u32) | ((OperandType::$op1 as u32) << 3)
206 };
207}
208
209macro_rules! enc_ops3 {
210 ($op0:ident, $op1:ident, $op2:ident) => {
211 (OperandType::$op0 as u32)
212 | ((OperandType::$op1 as u32) << 3)
213 | ((OperandType::$op2 as u32) << 6)
214 };
215}
216
217macro_rules! enc_ops4 {
218 ($op0:ident, $op1:ident, $op2:ident, $op3:ident) => {
219 (OperandType::$op0 as u32)
220 | ((OperandType::$op1 as u32) << 3)
221 | ((OperandType::$op2 as u32) << 6)
222 | ((OperandType::$op3 as u32) << 9)
223 };
224}
225
226impl<'a> Emitter for Assembler<'a> {
227 fn emit_n(&mut self, opcode: i64, ops: &[&Operand]) {
228 assert!(opcode < Opcode::LAST as i64);
229
230 let opcode: Opcode = unsafe { core::mem::transmute(opcode as u16) };
231
232 let info = &INST_INFO[opcode as usize];
233
234 let isign3 = match ops {
235 [] => 0,
236 [op0] => op0.op_type() as u32,
237 [op0, op1] => op0.op_type() as u32 + ((op1.op_type() as u32) << 3),
238 [op0, op1, op2, ..] => {
239 op0.op_type() as u32 + ((op1.op_type() as u32) << 3) + ((op2.op_type() as u32) << 6)
240 }
241 };
242
243 let isign4 = match ops {
244 [] => 0,
245 [op0] => op0.op_type() as u32,
246 [op0, op1] => op0.op_type() as u32 + ((op1.op_type() as u32) << 3),
247 [op0, op1, op2] => {
248 op0.op_type() as u32 + ((op1.op_type() as u32) << 3) + ((op2.op_type() as u32) << 6)
249 }
250 [op0, op1, op2, op3, ..] => {
251 op0.op_type() as u32
252 + ((op1.op_type() as u32) << 3)
253 + ((op2.op_type() as u32) << 6)
254 + ((op3.op_type() as u32) << 9)
255 }
256 };
257
258 let mut err = None;
259
260 match info.encoding {
261 Encoding::Empty => {
262 self.buffer.put4(info.val);
263 return;
264 }
265
266 Encoding::CondRelAddr19 => {
267 if isign3 == enc_ops2!(Imm, Label) {
268 let cond = ops[0].as_::<Imm>().value() as u32;
269
270 self.use_label(ops[1], LabelUse::A64Branch19);
271 self.buffer
272 .put4(info.val | (0 & 0x7ffff) << 5 | ((cond & 0xf) << 0));
273 return;
274 } else if isign3 == enc_ops2!(Imm, Imm) {
275 let cond = ops[0].as_::<Imm>().value() as u32;
276 let imm = ops[1].as_::<Imm>().value() as u32;
277 self.buffer
278 .put4(info.val | ((imm & 0x7ffff) << 5) | ((cond & 0xf) << 0));
279 return;
280 } else {
281 }
282 }
283
284 Encoding::RelAddr26 => {
285 if isign3 == enc_ops1!(Label) {
286 self.use_label(ops[0], LabelUse::A64Branch26);
287 self.buffer.put4(info.val);
288 return;
289 } else if isign3 == enc_ops1!(Imm) {
290 let imm26 = ops[0].as_::<Imm>().value() as u32;
291 self.buffer.put4(info.val | (imm26 & 0x03ff_ffff));
292 return;
293 }
294 }
295
296 Encoding::Const0 => {
297 self.buffer.put4(info.val | (0 & 0xf) << 8);
298 return;
299 }
300
301 Encoding::Const15 => {
302 self.buffer.put4(info.val | (15 & 0xf) << 8);
303 return;
304 }
305
306 Encoding::FpConst0 => {
307 if isign3 == enc_ops1!(Reg) {
308 let rn = ops[0].id();
309 self.buffer
310 .put4(info.val | (0 & 0x1f) << 16 | (rn & 0x1f) << 5);
311 return;
312 }
313 }
314
315 Encoding::FpFp => {
316 if isign3 == enc_ops2!(Reg, Reg) {
317 let rm = ops[0].id();
318 let rn = ops[1].id();
319 self.buffer
320 .put4(info.val | (rm & 0x1f) << 16 | (rn & 0x1f) << 5);
321 return;
322 }
323 }
324
325 Encoding::FpFpConst0 => {
326 if isign3 == enc_ops2!(Reg, Reg) {
327 let rd = ops[0].id();
328 let rn = ops[1].id();
329 self.buffer
330 .put4(info.val | (0 & 0x7) << 16 | (rn & 0x1f) << 5 | (rd & 0x1f) << 0);
331 return;
332 }
333 }
334
335 Encoding::FpFpFp => {
336 if isign3 == enc_ops3!(Reg, Reg, Reg) {
337 let rd = ops[0].id();
338 let rn = ops[1].id();
339 let rm = ops[2].id();
340
341 self.buffer.put4(
342 info.val | ((rm & 0x1f) << 16) | (rn & 0x1f) << 5 | ((rd & 0x1f) << 0),
343 );
344 return;
345 }
346 }
347
348 Encoding::FpFpFpCond => {
349 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
350 let rd = ops[0].id();
351 let rn = ops[1].id();
352 let rm = ops[2].id();
353 let cond = ops[3].as_::<Imm>().value();
354
355 self.buffer.put4(
356 info.val
357 | ((rm & 0x1f) << 16)
358 | ((cond as u32 & 0xf) << 12)
359 | (rn & 0x1f) << 5
360 | ((rd & 0x1f) << 0),
361 );
362 return;
363 }
364 }
365
366 Encoding::FpFpFpFp => {
367 if isign4 == enc_ops4!(Reg, Reg, Reg, Reg) {
368 let rd = ops[0].id();
369 let rn = ops[1].id();
370 let rm = ops[2].id();
371 let ra = ops[3].id();
372
373 self.buffer.put4(
374 info.val
375 | ((rm & 0x1f) << 16)
376 | ((ra & 0x1f) << 10)
377 | (rn & 0x1f) << 5
378 | ((rd & 0x1f) << 0),
379 );
380 return;
381 }
382 }
383
384 Encoding::FpFpFpImm => {
385 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
386 let rd = ops[0].id();
387 let rn = ops[1].id();
388 let rm = ops[2].id();
389 let imm4 = ops[3].as_::<Imm>().value() as i32 as u32;
390
391 self.buffer.put4(
392 info.val
393 | ((rm & 0x1f) << 16)
394 | ((imm4 & 0xf) << 11)
395 | ((rn & 0x1f) << 5)
396 | ((rd & 0x1f) << 0),
397 );
398 return;
399 }
400 }
401
402 Encoding::FpFpFpImmRotAdd => {
403 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
404 let rd = ops[0].id();
405 let rn = ops[1].id();
406 let rm = ops[2].id();
407 let rot = ops[3].as_::<Imm>().value() as i32 as u32;
408 if rot == 90 || rot == 270 {
409 self.buffer.put4(
410 info.val
411 | ((rm & 0x1f) << 16)
412 | (((rot / 90 - 1) & 0x3) << 11)
413 | ((rn & 0x1f) << 5)
414 | ((rd & 0x1f) << 0),
415 );
416 return;
417 } else {
418 }
419 } else {
420 }
421 }
422
423 Encoding::FpFpFpImmRotMul => {
424 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
425 let rd = ops[0].id();
426 let rn = ops[1].id();
427 let rm = ops[2].id();
428 let rot = ops[3].as_::<Imm>().value() as i32 as u32;
429 if rot < 360 && rot % 90 == 0 {
430 self.buffer.put4(
431 info.val
432 | ((rm & 0x1f) << 16)
433 | (((rot / 90) & 0x3) << 11)
434 | ((rn & 0x1f) << 5)
435 | ((rd & 0x1f) << 0),
436 );
437 return;
438 } else {
439 }
440 } else {
441 }
442 }
443
444 Encoding::FpFpFpVelElemIdx0_1 => {
445 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
446 let rd = ops[0].id();
447 let rn = ops[1].id();
448 let mrm = ops[2].id();
449 let elemidx = ops[3].as_::<Imm>().value() as u32;
450 if mrm < 16 && elemidx < (1 << (4 - 1)) {
452 let v = info.val ^ mrm << 16
453 | ((((elemidx << 1) >> 2) & 0x1) << 21)
454 | ((((elemidx << 1) >> 1) & 0x1) << 20)
455 | (((((elemidx << 1) & 1) << 3) & 0xf) << 16)
456 | ((((elemidx << 1) >> 3) & 0x1) << 11)
457 | ((rn & 0x1f) << 5)
458 | ((rd & 0x1f) << 0);
459
460 self.buffer.put4(v);
461 return;
462 } else {
463 }
464 } else {
465 }
466 }
467
468 Encoding::FpFpFpVelElemIdx1 => {
469 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
470 let rd = ops[0].id();
471 let rn = ops[1].id();
472 let mrm = ops[2].id();
473
474 let elemidx = ops[3].id() as u32;
475 let val = (info.val ^ mrm << 16)
476 | ((((elemidx << 1) >> 2) & 0x1) << 21)
477 | ((((elemidx << 1) >> 1) & 0x1) << 20)
478 | (((0) & 0xf) << 16)
479 | ((((elemidx << 1) >> 3) & 0x1) << 11)
480 | ((rn & 0x1f) << 5)
481 | ((rd & 0x1f) << 0);
482 self.buffer.put4(val);
483 return;
484 }
485 }
486
487 Encoding::FpFpFpVelElemIdx2 => {
488 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
489 let rd = ops[0].id();
490 let rn = ops[1].id();
491 let mrm = ops[2].id();
492
493 let elemidx = ops[3].id() as u32;
494 let val = (info.val ^ mrm << 16)
495 | ((((elemidx << 1) >> 2) & 0x1) << 21)
496 | ((((elemidx << 1) >> 1) & 0x1) << 20)
497 | (((0) & 0xf) << 16)
498 | ((((elemidx << 1) >> 3) & 0x1) << 11)
499 | ((rn & 0x1f) << 5)
500 | ((rd & 0x1f) << 0);
501 self.buffer.put4(val);
502 return;
503 }
504 }
505
506 Encoding::FpFpFpVelElemIdx3 => {
507 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
508 let rd = ops[0].id();
509 let rn = ops[1].id();
510 let mrm = ops[2].id();
511
512 let elemidx = ops[3].id() as u32;
513 let val = (info.val ^ mrm << 16)
514 | ((((elemidx << 2) >> 2) & 0x1) << 21)
515 | ((((elemidx << 2) >> 1) & 0x1) << 20)
516 | (((0) & 0xf) << 16)
517 | ((((elemidx << 2) >> 3) & 0x1) << 11)
518 | ((rn & 0x1f) << 5)
519 | ((rd & 0x1f) << 0);
520 self.buffer.put4(val);
521 return;
522 }
523 }
524
525 Encoding::FpFpFpVelElemIdxLim2_2ImmRotMul => {
526 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) && ops.len() == 5 && ops[4].is_imm() {
527 let rd = ops[0].id();
528 let rn = ops[1].id();
529 let mrm = ops[2].id();
530
531 let elemidx = ops[3].id() as u32;
532 let rot = ops[4].id() as u32;
533 let val = (info.val ^ mrm << 16)
534 | ((((elemidx << 2) >> 2) & 0x1) << 21)
535 | ((((elemidx << 2) >> 1) & 0x1) << 20)
536 | (((0) & 0xf) << 16)
537 | (((rot / 90) & 0x3) << 13)
538 | ((((elemidx << 2) >> 3) & 0x1) << 11)
539 | ((rn & 0x1f) << 5)
540 | ((rd & 0x1f) << 0);
541
542 self.buffer.put4(val);
543 return;
544 }
545 }
546
547 Encoding::FpFpFpVelElemIdxLim2_4ImmRotMul => {
548 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) && ops.len() == 5 && ops[4].is_imm() {
549 let rd = ops[0].id();
550 let rn = ops[1].id();
551 let mrm = ops[2].id();
552
553 let elemidx = ops[3].id() as u32;
554 let rot = ops[4].id() as u32;
555 let val = (info.val ^ mrm << 16)
556 | ((((elemidx << 2) >> 2) & 0x1) << 21)
557 | ((((elemidx << 2) >> 1) & 0x1) << 20)
558 | (((0) & 0xf) << 16)
559 | (((rot / 90) & 0x3) << 13)
560 | ((((elemidx << 2) >> 3) & 0x1) << 11)
561 | ((rn & 0x1f) << 5)
562 | ((rd & 0x1f) << 0);
563
564 self.buffer.put4(val);
565 return;
566 }
567 }
568 Encoding::FpFpFpVelElemIdxLim3_4ImmRotMul => {
570 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) && ops.len() == 5 && ops[4].is_imm() {
571 let rd = ops[0].id();
572 let rn = ops[1].id();
573 let mrm = ops[2].id();
574
575 let elemidx = ops[3].id() as u32;
576 let rot = ops[4].id() as u32;
577 let val = (info.val ^ mrm << 16)
578 | ((((elemidx << 3) >> 2) & 0x1) << 21)
579 | ((((elemidx << 3) >> 1) & 0x1) << 20)
580 | (((0) & 0xf) << 16)
581 | (((rot / 90) & 0x3) << 13)
582 | ((((elemidx << 3) >> 3) & 0x1) << 11)
583 | ((rn & 0x1f) << 5)
584 | ((rd & 0x1f) << 0);
585
586 self.buffer.put4(val);
587 return;
588 }
589 }
590 Encoding::FpFpGpSImm7_2 => {
591 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
592 let rt = ops[0].id();
593 let rt2 = ops[1].id();
594 let rn = ops[2].id();
595 let imm7 = ops[3].as_::<Imm>().value() as i32 as u32;
596
597 let val = info.val
598 | (((imm7 / (1 << 2)) & 0x7f) << 15)
599 | ((rt2 & 0x1f) << 10)
600 | ((rn & 0x1f) << 5)
601 | ((rt & 0x1f) << 0);
602 self.buffer.put4(val);
603 return;
604 }
605 }
606
607 Encoding::FpFpGpSImm7_3 => {
608 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
609 let rt = ops[0].id();
610 let rt2 = ops[1].id();
611 let rn = ops[2].id();
612 let imm7 = ops[3].as_::<Imm>().value() as i32 as u32;
613
614 let val = info.val
615 | (((imm7 / (1 << 3)) & 0x7f) << 15)
616 | ((rt2 & 0x1f) << 10)
617 | ((rn & 0x1f) << 5)
618 | ((rt & 0x1f) << 0);
619 self.buffer.put4(val);
620 return;
621 }
622 }
623
624 Encoding::FpFpGpSImm7_4 => {
625 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
626 let rt = ops[0].id();
627 let rt2 = ops[1].id();
628 let rn = ops[2].id();
629 let imm7 = ops[3].as_::<Imm>().value() as i32 as u32;
630
631 let val = info.val
632 | (((imm7 / (1 << 4)) & 0x7f) << 15)
633 | ((rt2 & 0x1f) << 10)
634 | ((rn & 0x1f) << 5)
635 | ((rt & 0x1f) << 0);
636 self.buffer.put4(val);
637 return;
638 }
639 }
640
641 Encoding::FpFpImmCond => {
642 if isign4 == enc_ops4!(Reg, Reg, Imm, Imm) {
643 let rn = ops[0].id();
644 let rm = ops[1].id();
645 let nzcv = ops[2].as_::<Imm>().value() as u32;
646 let cond = ops[3].as_::<Imm>().value() as u32;
647
648 let val = info.val
649 | ((rm & 0x1f) << 16)
650 | ((cond & 0xf) << 12)
651 | ((rn & 0x1f) << 5)
652 | ((nzcv & 0xf) << 0);
653 self.buffer.put4(val);
654 return;
655 }
656 }
657
658 Encoding::FpFpImmShiftl16 => {
659 if isign3 == enc_ops3!(Reg, Reg, Imm) {
660 let rd = ops[0].id();
661 let rn = ops[1].id();
662 let imm = ops[2].as_::<Imm>().value() as u32;
663
664 let val = (info.val ^ imm << 16)
665 | ((0 & 0xf) << 19)
666 | ((0 & 0x7) << 16)
667 | ((rn & 0x1f) << 5)
668 | ((rd & 0x1f) << 0);
669 self.buffer.put4(val);
670 return;
671 }
672 }
673
674 Encoding::FpFpImmShiftl32 => {
675 if isign3 == enc_ops3!(Reg, Reg, Imm) {
676 let rd = ops[0].id();
677 let rn = ops[1].id();
678 let imm = ops[2].as_::<Imm>().value() as u32;
679
680 let val = (info.val ^ imm << 16)
681 | ((0 & 0xf) << 19)
682 | ((0 & 0x7) << 16)
683 | ((rn & 0x1f) << 5)
684 | ((rd & 0x1f) << 0);
685 self.buffer.put4(val);
686 return;
687 }
688 }
689
690 Encoding::FpFpImmShiftl64 => {
691 if isign3 == enc_ops3!(Reg, Reg, Imm) {
692 let rd = ops[0].id();
693 let rn = ops[1].id();
694 let imm = ops[2].as_::<Imm>().value() as u32;
695
696 let val = ((info.val ^ imm) << 16)
697 | ((0 & 0xf) << 19)
698 | ((0 & 0x7) << 16)
699 | ((rn & 0x1f) << 5)
700 | ((rd & 0x1f) << 0);
701 self.buffer.put4(val);
702 return;
703 }
704 }
705
706 Encoding::FpFpImmShiftl8 => {
707 if isign3 == enc_ops3!(Reg, Reg, Imm) {
708 let rd = ops[0].id();
709 let rn = ops[1].id();
710 let imm = ops[2].as_::<Imm>().value() as i32 as u32;
711
712 let val = (info.val ^ imm << 16)
713 | ((0 & 0xf) << 19)
714 | ((0 & 0x7) << 16)
715 | ((rn & 0x1f) << 5)
716 | ((rd & 0x1f) << 0);
717
718 self.buffer.put4(val);
719 return;
720 }
721 }
722
723 Encoding::FpFpImmShiftr8 => {
724 if isign3 == enc_ops3!(Reg, Reg, Imm) {
725 let rd = ops[0].id();
726 let rn = ops[1].id();
727 let imm = ops[2].as_::<Imm>().value() as u32;
728
729 let val = (info.val ^ 8u32.wrapping_sub(imm << 16))
730 | ((0 & 0xf) << 19)
731 | ((0 & 0x7) << 16)
732 | ((rn & 0x1f) << 5)
733 | ((rd & 0) << 0);
734 self.buffer.put4(val);
735 return;
736 }
737 }
738
739 Encoding::FpFpImmShiftr16 => {
740 if isign3 == enc_ops3!(Reg, Reg, Imm) {
741 let rd = ops[0].id();
742 let rn = ops[1].id();
743 let imm = ops[2].as_::<Imm>().value() as u32;
744
745 let val = (info.val ^ 16u32.wrapping_sub(imm << 16))
746 | ((0 & 0xf) << 19)
747 | ((0 & 0x7) << 16)
748 | ((rn & 0x1f) << 5)
749 | ((rd & 0) << 0);
750 self.buffer.put4(val);
751 return;
752 }
753 }
754
755 Encoding::FpFpImmShiftr32 => {
756 if isign3 == enc_ops3!(Reg, Reg, Imm) {
757 let rd = ops[0].id();
758 let rn = ops[1].id();
759 let imm = ops[2].as_::<Imm>().value() as u32;
760
761 let val = (info.val ^ 32u32.wrapping_sub(imm << 16))
762 | ((0 & 0xf) << 19)
763 | ((0 & 0x7) << 16)
764 | ((rn & 0x1f) << 5)
765 | ((rd & 0) << 0);
766 self.buffer.put4(val);
767 return;
768 }
769 }
770
771 Encoding::FpFpImmShiftr64 => {
772 if isign3 == enc_ops3!(Reg, Reg, Imm) {
773 let rd = ops[0].id();
774 let rn = ops[1].id();
775 let imm = ops[2].as_::<Imm>().value() as u32;
776
777 let val = (info.val ^ 64u32.wrapping_sub(imm << 16))
778 | ((0 & 0xf) << 19)
779 | ((0 & 0x7) << 16)
780 | ((rn & 0x1f) << 5)
781 | ((rd & 0) << 0);
782 self.buffer.put4(val);
783 return;
784 }
785 }
786
787 Encoding::FpFpImmVIdx0_1 => {
788 if isign3 == enc_ops3!(Reg, Reg, Imm) {
789 let rd = ops[0].id();
790 let rn = ops[1].id();
791 let imm5 = ops[2].as_::<Imm>().value() as u32;
792
793 let val = info.val
794 | (((imm5 << (0 + 1)) & 0x1f) << 16)
795 | ((rn & 0x1f) << 5)
796 | ((rd & 0x1f) << 0);
797 self.buffer.put4(val);
798 return;
799 }
800 }
801
802 Encoding::FpFpImmVIdx1_1 => {
803 if isign3 == enc_ops3!(Reg, Reg, Imm) {
804 let rd = ops[0].id();
805 let rn = ops[1].id();
806 let imm5 = ops[2].as_::<Imm>().value() as u32;
807
808 let val = info.val
809 | (((imm5 << (1 + 1)) & 0x1f) << 16)
810 | ((rn & 0x1f) << 5)
811 | ((rd & 0x1f) << 0);
812 self.buffer.put4(val);
813 return;
814 }
815 }
816
817 Encoding::FpFpImmVIdx2_1 => {
818 if isign3 == enc_ops3!(Reg, Reg, Imm) {
819 let rd = ops[0].id();
820 let rn = ops[1].id();
821 let imm5 = ops[2].as_::<Imm>().value() as u32;
822
823 let val = info.val
824 | (((imm5 << (2 + 1)) & 0x1f) << 16)
825 | ((rn & 0x1f) << 5)
826 | ((rd & 0x1f) << 0);
827 self.buffer.put4(val);
828 return;
829 }
830 }
831 Encoding::FpFpImmVIdx3_1 => {
832 if isign3 == enc_ops3!(Reg, Reg, Imm) {
833 let rd = ops[0].id();
834 let rn = ops[1].id();
835 let imm5 = ops[2].as_::<Imm>().value() as u32;
836
837 let val = info.val
838 | (((imm5 << (3 + 1)) & 0x1f) << 16)
839 | ((rn & 0x1f) << 5)
840 | ((rd & 0x1f) << 0);
841 self.buffer.put4(val);
842 return;
843 }
844 }
845
846 Encoding::FpGpFcvtFixScale => {
847 if isign3 == enc_ops3!(Reg, Reg, Imm) {
848 let rd = ops[0].id();
849 let rn = ops[1].id();
850 let fbits = ops[2].as_::<Imm>().value() as u32;
851 let val = info.val
852 | (((64 - fbits) & 0x3f) << 10)
853 | ((rn & 0x1f) << 5)
854 | ((rd & 0x1f) << 0);
855 self.buffer.put4(val);
856 return;
857 }
858 }
859
860 Encoding::FpGpGp => {
861 if isign3 == enc_ops3!(Reg, Reg, Reg) {
862 let rt = ops[0].id();
863 let rn = ops[1].id();
864 let rm = ops[2].id();
865
866 let val =
867 info.val | ((rm & 0x1f) << 16) | ((rn & 0x1f) << 5) | ((rt & 0x1f) << 0);
868 self.buffer.put4(val);
869 return;
870 }
871 }
872
873 Encoding::FpGpGpBool => {
874 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
875 let rt = ops[0].id();
876 let rn = ops[1].id();
877 let rm = ops[2].id();
878 let sc = ops[3].as_::<Imm>().value() as u32;
879
880 let val = info.val
881 | ((rm & 0x1f) << 16)
882 | ((sc & 0x1) << 12)
883 | ((rn & 0x1f) << 5)
884 | ((rt & 0x1f) << 0);
885 self.buffer.put4(val);
886 return;
887 }
888 }
889
890 Encoding::FpGpSImm9_0 => {
891 if isign3 == enc_ops3!(Reg, Reg, Imm) {
892 let rt = ops[0].id();
893 let rn = ops[1].id();
894 let imm9 = ops[2].as_::<Imm>().value() as i32 as u32;
895 let val = info.val
896 | (((imm9 / (1 << 0)) & 0x1ff) << 12)
897 | ((rn & 0x1f) << 5)
898 | ((rt & 0x1f) << 0);
899 self.buffer.put4(val);
900 return;
901 }
902 }
903
904 Encoding::FpGpUImm12_0 => {
905 if isign3 == enc_ops3!(Reg, Reg, Imm) {
906 let rt = ops[0].id();
907 let rn = ops[1].id();
908 let imm12 = ops[2].as_::<Imm>().value() as i32 as u32;
909 let val = info.val
910 | (((imm12 >> 0) & 0xfff) << 10)
911 | ((rn & 0x1f) << 5)
912 | ((rt & 0x1f) << 0);
913 self.buffer.put4(val);
914 return;
915 }
916 }
917
918 Encoding::FpGpUImm12_1 => {
919 if isign3 == enc_ops3!(Reg, Reg, Imm) {
920 let rt = ops[0].id();
921 let rn = ops[1].id();
922 let imm12 = ops[2].as_::<Imm>().value() as i32 as u32;
923 let val = info.val
924 | (((imm12 >> 1) & 0xfff) << 10)
925 | ((rn & 0x1f) << 5)
926 | ((rt & 0x1f) << 0);
927 self.buffer.put4(val);
928 return;
929 }
930 }
931
932 Encoding::FpGpUImm12_2 => {
933 if isign3 == enc_ops3!(Reg, Reg, Imm) {
934 let rt = ops[0].id();
935 let rn = ops[1].id();
936 let imm12 = ops[2].as_::<Imm>().value() as i32 as u32;
937 let val = info.val
938 | (((imm12 >> 2) & 0xfff) << 10)
939 | ((rn & 0x1f) << 5)
940 | ((rt & 0x1f) << 0);
941 self.buffer.put4(val);
942 return;
943 }
944 }
945
946 Encoding::FpGpUImm12_3 => {
947 if isign3 == enc_ops3!(Reg, Reg, Imm) {
948 let rt = ops[0].id();
949 let rn = ops[1].id();
950 let imm12 = ops[2].as_::<Imm>().value() as i32 as u32;
951 let val = info.val
952 | (((imm12 >> 3) & 0xfff) << 10)
953 | ((rn & 0x1f) << 5)
954 | ((rt & 0x1f) << 0);
955 self.buffer.put4(val);
956 return;
957 }
958 }
959
960 Encoding::FpGpUImm12_4 => {
961 if isign3 == enc_ops3!(Reg, Reg, Imm) {
962 let rt = ops[0].id();
963 let rn = ops[1].id();
964 let imm12 = ops[2].as_::<Imm>().value() as i32 as u32;
965 let val = info.val
966 | (((imm12 >> 4) & 0xfff) << 10)
967 | ((rn & 0x1f) << 5)
968 | ((rt & 0x1f) << 0);
969 self.buffer.put4(val);
970 return;
971 }
972 }
973
974 Encoding::FpGpZero => {
975 if isign3 == enc_ops2!(Reg, Reg) {
976 let rt = ops[0].id();
977 let rn = ops[1].id();
978
979 let val =
980 info.val | (((31) & 0x1f) << 16) | ((rn & 0x1f) << 5) | ((rt & 0x1f) << 0);
981
982 self.buffer.put4(val);
983 return;
984 }
985 }
986
987 Encoding::FpImmFMov32 => {
988 if isign3 == enc_ops2!(Reg, Imm) {
989 let rd = ops[0].id();
990 let imm = ops[1].as_::<Imm>().value_f32();
991 let val = info.val | ((imm_fmov32(imm) & 0xff) << 13) | ((rd & 0x1f) << 0);
992 self.buffer.put4(val);
993 return;
994 }
995 }
996
997 Encoding::FpImmFMov64 => {
998 if isign3 == enc_ops2!(Reg, Imm) {
999 let rd = ops[0].id();
1000 let imm = ops[1].as_::<Imm>().value_f64();
1001 let val =
1002 info.val | (((imm_fmov64(imm) & 0xff) as u32) << 13) | ((rd & 0x1f) << 0);
1003 self.buffer.put4(val);
1004 return;
1005 }
1006 }
1007
1008 Encoding::FpImmSIMD8Fmov => {
1009 if isign3 == enc_ops2!(Reg, Imm) {
1010 let rd = ops[0].id();
1011 let imm = ops[1].as_::<Imm>().value_f32();
1012 let val = info.val
1013 | (((imm_fmov32(imm) >> 5) & 0x7) << 16)
1014 | (((imm_fmov32(imm) & 0x1f) & 0x1f) << 5)
1015 | ((rd & 0x1f) << 0);
1016 self.buffer.put4(val);
1017 return;
1018 }
1019 }
1020
1021 Encoding::FpImmSIMD8Lsl => {
1022 if isign3 == enc_ops3!(Reg, Imm, Imm) {
1023 let rd = ops[0].id();
1024 let imm = ops[1].as_::<Imm>().value() as u32;
1025 let lsl = ops[2].as_::<Imm>().value() as u32;
1026
1027 let val = info.val
1028 | (((imm >> 5) & 0x7) << 16)
1029 | (((lsl >> 2 | 1) & 0x1f) << 12)
1030 | (((imm & 0x1f) & 0x1f) << 5)
1031 | ((rd & 0x1f) << 0);
1032 self.buffer.put4(val);
1033 return;
1034 }
1035 }
1036
1037 Encoding::FpImmSIMD8Movi => {
1038 if isign3 == enc_ops2!(Reg, Imm) {
1039 let rd = ops[0].id();
1040 let imm64 = ops[1].as_::<Imm>().value() as u64;
1041
1042 let val = (info.val ^ imm_simdmovi(imm64))
1043 | ((0 & 0x1) << 29)
1044 | ((0 & 0x7) << 16)
1045 | ((0 & 0xf) << 12)
1046 | ((0 & 0x1f) << 5)
1047 | ((rd & 0x1f) << 0);
1048
1049 self.buffer.put4(val);
1050 return;
1051 }
1052 }
1053
1054 Encoding::FpImmVIdx0_1FpImmVIdx0_0 => {
1055 if isign4 == enc_ops4!(Reg, Imm, Reg, Imm) {
1056 let rd = ops[0].id();
1057 let imm5 = ops[1].as_::<Imm>().value() as u32;
1058 let rn = ops[2].id();
1059 let imm4 = ops[3].as_::<Imm>().value() as u32;
1060
1061 let val = info.val
1062 | (((imm5 << (0 + 1)) & 0x1f) << 16)
1063 | (((imm4 << (0 + 0)) & 0xf) << 11)
1064 | ((rn & 0x1f) << 5)
1065 | ((rd & 0x1f) << 0);
1066 self.buffer.put4(val);
1067 return;
1068 }
1069 }
1070
1071 Encoding::FpImmVIdx0_1Gp => {
1072 if enc_ops3!(Reg, Imm, Reg) == isign3 {
1073 let rd = ops[0].id();
1074 let imm5 = ops[1].as_::<Imm>().value() as u32;
1075 let rn = ops[2].id();
1076
1077 let val = info.val
1078 | (((imm5 << (0 + 1)) & 0x1f) << 16)
1079 | ((rn & 0x1f) << 5)
1080 | ((rd & 0x1f) << 0);
1081 self.buffer.put4(val);
1082 return;
1083 }
1084 }
1085
1086 Encoding::FpImmVIdx1_1FpImmVIdx1_0 => {
1087 if isign4 == enc_ops4!(Reg, Imm, Reg, Imm) {
1088 let rd = ops[0].id();
1089 let imm5 = ops[1].as_::<Imm>().value() as u32;
1090 let rn = ops[2].id();
1091 let imm4 = ops[3].as_::<Imm>().value() as u32;
1092
1093 let val = info.val
1094 | (((imm5 << (1 + 1)) & 0x1f) << 16)
1095 | (((imm4 << (0 + 0)) & 0xf) << 11)
1096 | ((rn & 0x1f) << 5)
1097 | ((rd & 0x1f) << 0);
1098 self.buffer.put4(val);
1099 return;
1100 }
1101 }
1102
1103 Encoding::FpImmVIdx1_1Gp => {
1104 if enc_ops3!(Reg, Imm, Reg) == isign3 {
1105 let rd = ops[0].id();
1106 let imm5 = ops[1].as_::<Imm>().value() as u32;
1107 let rn = ops[2].id();
1108
1109 let val = info.val
1110 | (((imm5 << (1 + 1)) & 0x1f) << 16)
1111 | ((rn & 0x1f) << 5)
1112 | ((rd & 0x1f) << 0);
1113 self.buffer.put4(val);
1114 return;
1115 }
1116 }
1117
1118 Encoding::FpImmVIdx2_1FpImmVIdx2_0 => {
1119 if isign4 == enc_ops4!(Reg, Imm, Reg, Imm) {
1120 let rd = ops[0].id();
1121 let imm5 = ops[1].as_::<Imm>().value() as u32;
1122 let rn = ops[2].id();
1123 let imm4 = ops[3].as_::<Imm>().value() as u32;
1124
1125 let val = info.val
1126 | (((imm5 << (2 + 1)) & 0x1f) << 16)
1127 | (((imm4 << (2 + 0)) & 0xf) << 11)
1128 | ((rn & 0x1f) << 5)
1129 | ((rd & 0x1f) << 0);
1130 self.buffer.put4(val);
1131 return;
1132 }
1133 }
1134
1135 Encoding::FpImmVIdx2_1Gp => {
1136 if enc_ops3!(Reg, Imm, Reg) == isign3 {
1137 let rd = ops[0].id();
1138 let imm5 = ops[1].as_::<Imm>().value() as u32;
1139 let rn = ops[2].id();
1140
1141 let val = info.val
1142 | (((imm5 << (2 + 1)) & 0x1f) << 16)
1143 | ((rn & 0x1f) << 5)
1144 | ((rd & 0x1f) << 0);
1145 self.buffer.put4(val);
1146 return;
1147 }
1148 }
1149
1150 Encoding::FpImmVIdx3_1FpImmVIdx3_0 => {
1151 if isign4 == enc_ops4!(Reg, Imm, Reg, Imm) {
1152 let rd = ops[0].id();
1153 let imm5 = ops[1].as_::<Imm>().value() as u32;
1154 let rn = ops[2].id();
1155 let imm4 = ops[3].as_::<Imm>().value() as u32;
1156
1157 let val = info.val
1158 | (((imm5 << (3 + 1)) & 0x1f) << 16)
1159 | (((imm4 << (3 + 0)) & 0xf) << 11)
1160 | ((rn & 0x1f) << 5)
1161 | ((rd & 0x1f) << 0);
1162 self.buffer.put4(val);
1163 return;
1164 }
1165 }
1166
1167 Encoding::FpImmVIdx3_1Gp => {
1168 if enc_ops3!(Reg, Imm, Reg) == isign3 {
1169 let rd = ops[0].id();
1170 let imm5 = ops[1].as_::<Imm>().value() as u32;
1171 let rn = ops[2].id();
1172
1173 let val = info.val
1174 | (((imm5 << (3 + 1)) & 0x1f) << 16)
1175 | ((rn & 0x1f) << 5)
1176 | ((rd & 0x1f) << 0);
1177 self.buffer.put4(val);
1178 return;
1179 }
1180 }
1181
1182 Encoding::FpMemSIMDIdx0Gp => {
1183 if isign3 == enc_ops3!(Reg, Imm, Reg) {
1184 let rt = ops[0].id();
1185 let elemidx = ops[1].as_::<Imm>().value() as usize as u32;
1186 let rn = ops[2].id();
1187
1188 let val = info.val
1189 | ((((elemidx << 0) >> 3) & 0x1) << 30)
1190 | ((((elemidx << 0) >> 2) & 0x1) << 12)
1191 | (((elemidx << 0) & 0x3) << 10)
1192 | ((rn & 0x1f) << 5)
1193 | ((rt & 0x1f) << 0);
1194 self.buffer.put4(val);
1195 return;
1196 }
1197 }
1198
1199 Encoding::FpMemSIMDIdx0GpGp => {
1200 if isign4 == enc_ops4!(Reg, Imm, Reg, Reg) {
1201 let rt = ops[0].id();
1202 let elemidx = ops[1].as_::<Imm>().value() as u32;
1203 let rn = ops[2].id();
1204 let rm = ops[3].id();
1205
1206 let val = info.val
1207 | ((((elemidx << 0) >> 3) & 0x1) << 30)
1208 | ((rm & 0x1f) << 16)
1209 | ((((elemidx << 0) >> 2) & 0x1) << 12)
1210 | (((elemidx << 0) & 0x3) << 10)
1211 | ((rn & 0x1f) << 5)
1212 | ((rt & 0x1f) << 0);
1213 self.buffer.put4(val);
1214 return;
1215 }
1216 }
1217
1218 Encoding::FpMemSIMDIdx0GpZero => {
1219 if isign3 == enc_ops3!(Reg, Imm, Reg) {
1220 let rt = ops[0].id();
1221 let elemidx = ops[1].as_::<Imm>().value() as u32;
1222 let rn = ops[2].id();
1223
1224 let val = info.val
1225 | ((((elemidx << 0) >> 3) & 0x1) << 30)
1226 | (((31) & 0x1f) << 16)
1227 | ((((elemidx << 0) >> 2) & 0x1) << 12)
1228 | (((elemidx << 0) & 0x3) << 10)
1229 | ((rn & 0x1f) << 5)
1230 | ((rt & 0x1f) << 0);
1231 self.buffer.put4(val);
1232 return;
1233 }
1234 }
1235
1236 Encoding::FpMemSIMDIdx1GpGp => {
1237 if isign4 == enc_ops4!(Reg, Imm, Reg, Reg) {
1238 let rt = ops[0].id();
1239 let elemidx = ops[1].as_::<Imm>().value() as u32;
1240 let rn = ops[2].id();
1241 let rm = ops[3].id();
1242
1243 let val = info.val
1244 | ((((elemidx << 1) >> 3) & 0x1) << 30)
1245 | ((rm & 0x1f) << 16)
1246 | ((((elemidx << 1) >> 2) & 0x1) << 12)
1247 | (((elemidx << 1) & 0x3) << 10)
1248 | ((rn & 0x1f) << 5)
1249 | ((rt & 0x1f) << 0);
1250 self.buffer.put4(val);
1251 return;
1252 }
1253 }
1254
1255 Encoding::FpMemSIMDIdx1GpZero => {
1256 if isign3 == enc_ops3!(Reg, Imm, Reg) {
1257 let rt = ops[0].id();
1258 let elemidx = ops[1].as_::<Imm>().value() as u32;
1259 let rn = ops[2].id();
1260
1261 let val = info.val
1262 | ((((elemidx << 1) >> 3) & 0x1) << 30)
1263 | (((31) & 0x1f) << 16)
1264 | ((((elemidx << 1) >> 2) & 0x1) << 12)
1265 | (((elemidx << 1) & 0x3) << 10)
1266 | ((rn & 0x1f) << 5)
1267 | ((rt & 0x1f) << 0);
1268 self.buffer.put4(val);
1269 return;
1270 }
1271 }
1272
1273 Encoding::FpMemSIMDIdx2Gp => {
1274 if isign4 == enc_ops4!(Reg, Imm, Reg, Reg) {
1275 let rt = ops[0].id();
1276 let elemidx = ops[1].as_::<Imm>().value() as u32;
1277 let rn = ops[1].id();
1278 let rm = ops[2].id();
1279
1280 let val = info.val
1281 | ((((elemidx << 2) >> 3) & 0x1) << 30)
1282 | ((rm & 0x1f) << 16)
1283 | ((((elemidx << 2) >> 2) & 0x1) << 12)
1284 | (((elemidx << 2) & 0x3) << 10)
1285 | ((rn & 0x1f) << 5)
1286 | ((rt & 0x1f) << 0);
1287 self.buffer.put4(val);
1288 return;
1289 }
1290 }
1291
1292 Encoding::FpMemSIMDIdx2GpGp => {
1293 if isign4 == enc_ops4!(Reg, Imm, Reg, Reg) {
1294 let rt = ops[0].id();
1295 let elemidx = ops[1].as_::<Imm>().value() as u32;
1296 let rn = ops[2].id();
1297 let rm = ops[3].id();
1298
1299 let val = info.val
1300 | ((((elemidx << 2) >> 3) & 0x1) << 30)
1301 | ((rm & 0x1f) << 16)
1302 | ((((elemidx << 2) >> 2) & 0x1) << 12)
1303 | (((elemidx << 2) & 0x3) << 10)
1304 | ((rn & 0x1f) << 5)
1305 | ((rt & 0x1f) << 0);
1306 self.buffer.put4(val);
1307 return;
1308 }
1309 }
1310
1311 Encoding::FpMemSIMDIdx2GpZero => {
1312 if isign3 == enc_ops3!(Reg, Imm, Reg) {
1313 let rt = ops[0].id();
1314 let elemidx = ops[1].as_::<Imm>().value() as u32;
1315 let rn = ops[2].id();
1316
1317 let val = info.val
1318 | ((((elemidx << 2) >> 3) & 0x1) << 30)
1319 | (((31) & 0x1f) << 16)
1320 | ((((elemidx << 2) >> 2) & 0x1) << 12)
1321 | (((elemidx << 2) & 0x3) << 10)
1322 | ((rn & 0x1f) << 5)
1323 | ((rt & 0x1f) << 0);
1324 self.buffer.put4(val);
1325 return;
1326 }
1327 }
1328
1329 Encoding::FpMemSIMDIdx3Gp => {
1330 if isign4 == enc_ops4!(Reg, Imm, Reg, Reg) {
1331 let rt = ops[0].id();
1332 let elemidx = ops[1].as_::<Imm>().value() as u32;
1333 let rn = ops[1].id();
1334 let rm = ops[2].id();
1335
1336 let val = info.val
1337 | ((((elemidx << 3) >> 3) & 0x1) << 30)
1338 | ((rm & 0x1f) << 16)
1339 | ((((elemidx << 3) >> 2) & 0x1) << 12)
1340 | (((elemidx << 3) & 0x3) << 10)
1341 | ((rn & 0x1f) << 5)
1342 | ((rt & 0x1f) << 0);
1343 self.buffer.put4(val);
1344 return;
1345 }
1346 }
1347
1348 Encoding::FpMemSIMDIdx3GpGp => {
1349 if isign4 == enc_ops4!(Reg, Imm, Reg, Reg) {
1350 let rt = ops[0].id();
1351 let elemidx = ops[1].as_::<Imm>().value() as u32;
1352 let rn = ops[2].id();
1353 let rm = ops[3].id();
1354
1355 let val = info.val
1356 | ((((elemidx << 3) >> 3) & 0x1) << 30)
1357 | ((rm & 0x1f) << 16)
1358 | ((((elemidx << 3) >> 2) & 0x1) << 12)
1359 | (((elemidx << 3) & 0x3) << 10)
1360 | ((rn & 0x1f) << 5)
1361 | ((rt & 0x1f) << 0);
1362 self.buffer.put4(val);
1363 return;
1364 }
1365 }
1366
1367 Encoding::FpMemSIMDIdx3GpZero => {
1368 if isign3 == enc_ops3!(Reg, Imm, Reg) {
1369 let rt = ops[0].id();
1370 let elemidx = ops[1].as_::<Imm>().value() as u32;
1371 let rn = ops[2].id();
1372
1373 let val = info.val
1374 | ((((elemidx << 3) >> 3) & 0x1) << 30)
1375 | (((31) & 0x1f) << 16)
1376 | ((((elemidx << 3) >> 2) & 0x1) << 12)
1377 | (((elemidx << 3) & 0x3) << 10)
1378 | ((rn & 0x1f) << 5)
1379 | ((rt & 0x1f) << 0);
1380 self.buffer.put4(val);
1381 return;
1382 }
1383 }
1384
1385 Encoding::FpRelAddr19 => {
1386 if isign3 == enc_ops2!(Reg, Imm) {
1387 let rt = ops[0].id();
1388 let imm19 = ops[1].as_::<Imm>().value() as isize as i32 as u32;
1389
1390 let val = info.val | ((imm19 & 0x7ffff) << 5) | ((rt & 0x1f) << 0);
1391
1392 self.buffer.put4(val);
1393 return;
1394 } else if isign3 == enc_ops2!(Reg, Label) {
1395 let rt = ops[0].id();
1396
1397 self.use_label(ops[1], LabelUse::A64Branch19);
1398
1399 let val = info.val | ((0 & 0x7ffff) << 5) | ((rt & 0x1f) << 0);
1400
1401 self.buffer.put4(val);
1402 return;
1403 }
1404 }
1405
1406 Encoding::GpFp => {
1407 if isign3 == enc_ops2!(Reg, Reg) {
1408 let rd = ops[0].id();
1409 let rn = ops[1].id();
1410
1411 let val = info.val | ((rn & 0x1f) << 5) | ((rd & 0x1f) << 0);
1412 self.buffer.put4(val);
1413 return;
1414 }
1415 }
1416
1417 Encoding::GpFpFcvtFixScale => {
1418 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1419 let rd = ops[0].id();
1420 let rn = ops[1].id();
1421 let fbits = ops[2].as_::<Imm>().value() as u32;
1422
1423 let val = info.val
1424 | (((64 - fbits) & &0x3f) << 10)
1425 | ((rn & 0x1f) << 5)
1426 | ((rd & 0x1f) << 0);
1427 self.buffer.put4(val);
1428 return;
1429 }
1430 }
1431
1432 Encoding::GpFpImmVIdx0_1 => {
1433 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1434 let rd = ops[0].id();
1435 let rn = ops[1].id();
1436 let imm5 = ops[2].as_::<Imm>().value() as u32;
1437 let val = info.val
1438 | (((imm5 << (0 + 1)) & 0x1f) << 16)
1439 | ((rn & 0x1f) << 5)
1440 | ((rd & 0x1f) << 0);
1441 self.buffer.put4(val);
1442 return;
1443 }
1444 }
1445
1446 Encoding::GpFpImmVIdx1_1 => {
1447 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1448 let rd = ops[0].id();
1449 let rn = ops[1].id();
1450 let imm5 = ops[2].as_::<Imm>().value() as u32;
1451 let val = info.val
1452 | (((imm5 << (1 + 1)) & 0x1f) << 16)
1453 | ((rn & 0x1f) << 5)
1454 | ((rd & 0x1f) << 0);
1455 self.buffer.put4(val);
1456 return;
1457 }
1458 }
1459
1460 Encoding::GpFpImmVIdx2_1 => {
1461 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1462 let rd = ops[0].id();
1463 let rn = ops[1].id();
1464 let imm5 = ops[2].as_::<Imm>().value() as u32;
1465 let val = info.val
1466 | (((imm5 << (2 + 1)) & 0x1f) << 16)
1467 | ((rn & 0x1f) << 5)
1468 | ((rd & 0x1f) << 0);
1469 self.buffer.put4(val);
1470 return;
1471 }
1472 }
1473
1474 Encoding::GpFpImmVIdx3_1 => {
1475 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1476 let rd = ops[0].id();
1477 let rn = ops[1].id();
1478 let imm5 = ops[2].as_::<Imm>().value() as u32;
1479 let val = info.val
1480 | (((imm5 << (3 + 1)) & 0x1f) << 16)
1481 | ((rn & 0x1f) << 5)
1482 | ((rd & 0x1f) << 0);
1483 self.buffer.put4(val);
1484 return;
1485 }
1486 }
1487
1488 Encoding::GpGpConst0Const0 => {
1489 if isign3 == enc_ops2!(Reg, Reg) {
1490 let rd = ops[0].id();
1491 let rn = ops[1].id();
1492
1493 let val = info.val
1494 | ((0 & 0x3) << 22)
1495 | ((0 & 0xfff) << 10)
1496 | ((rn & 0x1f) << 5)
1497 | ((rd & 0x1f) << 0);
1498 self.buffer.put4(val);
1499 return;
1500 }
1501 }
1502
1503 Encoding::GpGpConst0Const15 => {
1504 if isign3 == enc_ops2!(Reg, Reg) {
1505 let rd = ops[0].id();
1506 let rn = ops[1].id();
1507
1508 let val = info.val
1509 | ((0 & 0x3) << 16)
1510 | ((15 & 0x3f) << 10)
1511 | ((rn & 0x1f) << 5)
1512 | ((rd & 0x1f) << 0);
1513 self.buffer.put4(val);
1514 return;
1515 }
1516 }
1517
1518 Encoding::GpGpConst0Const31 => {
1519 if isign3 == enc_ops2!(Reg, Reg) {
1520 let rd = ops[0].id();
1521 let rn = ops[1].id();
1522
1523 let val = info.val
1524 | ((0 & 0x3) << 16)
1525 | ((31 & 0x3f) << 10)
1526 | ((rn & 0x1f) << 5)
1527 | ((rd & 0x1f) << 0);
1528 self.buffer.put4(val);
1529 return;
1530 }
1531 }
1532 Encoding::GpGpConst0Const7 => {
1533 if isign3 == enc_ops2!(Reg, Reg) {
1534 let rd = ops[0].id();
1535 let rn = ops[1].id();
1536
1537 let val = info.val
1538 | ((0 & 0x3) << 16)
1539 | ((7 & 0x3f) << 10)
1540 | ((rn & 0x1f) << 5)
1541 | ((rd & 0x1f) << 0);
1542 self.buffer.put4(val);
1543 return;
1544 }
1545 }
1546
1547 Encoding::GpGpGpBool => {
1548 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
1549 let rt = ops[0].id();
1550 let rn = ops[1].id();
1551 let rm = ops[2].id();
1552 let sc = ops[3].as_::<Imm>().value() as u32;
1553
1554 let val = info.val
1555 | ((rm & 0x1f) << 16)
1556 | ((sc & 0x1) << 12)
1557 | ((rn & 0x1f) << 5)
1558 | ((rt & 0x1f) << 0);
1559 self.buffer.put4(val);
1560 return;
1561 }
1562 }
1563
1564 Encoding::GpGpGpCond => {
1565 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
1566 let rt = ops[0].id();
1567 let rn = ops[1].id();
1568 let rm = ops[2].id();
1569 let sc = ops[3].as_::<Imm>().value() as u32;
1570
1571 let val = info.val
1572 | ((rm & 0x1f) << 16)
1573 | ((sc & 0xf) << 12)
1574 | ((rn & 0x1f) << 5)
1575 | ((rt & 0x1f) << 0);
1576 self.buffer.put4(val);
1577 return;
1578 }
1579 }
1580
1581 Encoding::GpGpGpGp => {
1582 if isign4 == enc_ops4!(Reg, Reg, Reg, Reg) {
1583 let rs = ops[0].id();
1584 let rt = ops[1].id();
1585 let rt2 = ops[2].id();
1586 let rn = ops[3].id();
1587
1588 let val = info.val
1589 | ((rs & 0x1f) << 16)
1590 | ((rt2 & 0x1f) << 10)
1591 | ((rn & 0x1f) << 5)
1592 | ((rt & 0x1f) << 0);
1593 self.buffer.put4(val);
1594 return;
1595 }
1596 }
1597
1598 Encoding::GpGpGpImm => {
1599 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
1600 let rd = ops[0].id();
1601 let rn = ops[1].id();
1602 let rm = ops[2].id();
1603 let imm3 = ops[3].as_::<Imm>().value() as i32 as u32;
1604
1605 self.buffer.put4(
1606 info.val
1607 | ((rm & 0x1f) << 16)
1608 | ((imm3 & 0x7) << 10)
1609 | ((rn & 0x1f) << 5)
1610 | ((rd & 0x1f) << 0),
1611 );
1612 return;
1613 }
1614 }
1615
1616 Encoding::GpGpGpSImm7_2 => {
1617 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
1618 let rt = ops[0].id();
1619 let rt2 = ops[1].id();
1620 let rn = ops[2].id();
1621 let imm7 = ops[3].as_::<Imm>().value() as i32 as u32;
1622
1623 let val = info.val
1624 | (((imm7 / (1 << 2)) & 0x7f) << 15)
1625 | ((rt2 & 0x1f) << 10)
1626 | ((rn & 0x1f) << 5)
1627 | ((rt & 0x1f) << 0);
1628 self.buffer.put4(val);
1629 return;
1630 }
1631 }
1632
1633 Encoding::GpGpGpSImm7_3 => {
1634 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
1635 let rt = ops[0].id();
1636 let rt2 = ops[1].id();
1637 let rn = ops[2].id();
1638 let imm7 = ops[3].as_::<Imm>().value() as i32 as u32;
1639
1640 let val = info.val
1641 | (((imm7 / (1 << 3)) & 0x7f) << 15)
1642 | ((rt2 & 0x1f) << 10)
1643 | ((rn & 0x1f) << 5)
1644 | ((rt & 0x1f) << 0);
1645 self.buffer.put4(val);
1646 return;
1647 }
1648 }
1649 Encoding::GpGpGpSImm7_4 => {
1650 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
1651 let rt = ops[0].id();
1652 let rt2 = ops[1].id();
1653 let rn = ops[2].id();
1654 let imm7 = ops[3].as_::<Imm>().value() as i32 as u32;
1655
1656 let val = info.val
1657 | (((imm7 / (1 << 4)) & 0x7f) << 15)
1658 | ((rt2 & 0x1f) << 10)
1659 | ((rn & 0x1f) << 5)
1660 | ((rt & 0x1f) << 0);
1661 self.buffer.put4(val);
1662 return;
1663 }
1664 }
1665
1666 Encoding::GpGpGpZero => {
1667 if isign3 == enc_ops3!(Reg, Reg, Reg) {
1668 let rd = ops[0].id();
1669 let rn = ops[1].id();
1670 let rm = ops[2].id();
1671
1672 let val = info.val
1673 | ((rm & 0x1f) << 16)
1674 | ((31 & 0x1f) << 10)
1675 | ((rn & 0x1f) << 5)
1676 | ((rd & 0x1f) << 0);
1677 self.buffer.put4(val);
1678 return;
1679 }
1680 }
1681
1682 Encoding::GpGpImmAdd32 => {
1683 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1684 let rd = ops[0].id();
1685 let rn = ops[1].id();
1686 let imm = ops[2].as_::<Imm>().value();
1687
1688 let val = (info.val ^ imm_add(imm))
1689 | ((0 & 0x3) << 22)
1690 | ((0 & 0xfff) << 10)
1691 | ((rn & 0x1f) << 5)
1692 | ((rd & 0x1f) << 0);
1693 self.buffer.put4(val);
1694 return;
1695 }
1696 }
1697
1698 Encoding::GpGpImmAdd64 => {
1699 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1700 let rd = ops[0].id();
1701 let rn = ops[1].id();
1702 let imm = ops[2].as_::<Imm>().value();
1703
1704 let val = (info.val ^ imm_add(imm))
1705 | ((0 & 0x3) << 22)
1706 | ((0 & 0xfff) << 10)
1707 | ((rn & 0x1f) << 5)
1708 | ((rd & 0x1f) << 0);
1709 self.buffer.put4(val);
1710 return;
1711 }
1712 }
1713
1714 Encoding::GpGpImmCond => {
1715 if isign4 == enc_ops4!(Reg, Reg, Imm, Imm) {
1716 let rn = ops[0].id();
1717 let rm = ops[1].id();
1718 let nzcv = ops[2].as_::<Imm>().value() as u32;
1719 let cond = ops[3].as_::<Imm>().value() as u32;
1720
1721 let val = info.val
1722 | ((rm & 0x1f) << 16)
1723 | ((cond & 0xf) << 12)
1724 | ((rn & 0x1f) << 5)
1725 | ((nzcv & 0xf) << 0);
1726 self.buffer.put4(val);
1727 return;
1728 }
1729 }
1730
1731 Encoding::GpGpImmConst31 => {
1733 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1734 let rd = ops[0].id();
1735 let rn = ops[1].id();
1736 let immr = ops[2].as_::<Imm>().value() as u32;
1737
1738 let val = info.val
1739 | ((immr & 0x3f) << 16)
1740 | ((31 & 0x3f) << 10)
1741 | ((rn & 0x1f) << 5)
1742 | ((rd & 0x1f) << 0);
1743 self.buffer.put4(val);
1744 return;
1745 }
1746 }
1747
1748 Encoding::GpGpImmConst63 => {
1749 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1750 let rd = ops[0].id();
1751 let rn = ops[1].id();
1752 let immr = ops[2].as_::<Imm>().value() as u32;
1753
1754 let val = info.val
1755 | ((immr & 0x3f) << 16)
1756 | ((63 & 0x3f) << 10)
1757 | ((rn & 0x1f) << 5)
1758 | ((rd & 0x1f) << 0);
1759 self.buffer.put4(val);
1760 return;
1761 }
1762 }
1763
1764 Encoding::GpGpImmImm => {
1766 if isign4 == enc_ops4!(Reg, Reg, Imm, Imm) {
1767 let rd = ops[0].id();
1768 let rn = ops[1].id();
1769 let immr = ops[2].as_::<Imm>().value() as u32;
1770 let imms = ops[3].as_::<Imm>().value() as u32;
1771
1772 let val = info.val
1773 | ((immr & 0x3f) << 16)
1774 | ((imms & 0x3f) << 10)
1775 | ((rn & 0x1f) << 5)
1776 | ((rd & 0x1f) << 0);
1777 self.buffer.put4(val);
1778 return;
1779 }
1780 }
1781
1782 Encoding::GpGpImmLDraut => {
1784 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1785 let rt = ops[0].id();
1786 let rn = ops[1].id();
1787 let simm9 = ops[2].as_::<Imm>().value() as i32 as u32;
1788
1789 let val = info.val
1790 | ((((simm9 >> 12) & 1) & 0x1) << 22)
1791 | ((((simm9 & 0xff8) >> 3) & 0x1ff) << 12)
1792 | ((rn & 0x1f) << 5)
1793 | ((rt & 0x1f) << 0);
1794 self.buffer.put4(val);
1795 return;
1796 }
1797 }
1798
1799 Encoding::GpGpImmLogical32 => {
1801 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1802 let rd = ops[0].id();
1803 let rn = ops[1].id();
1804 let imm = ops[2].as_::<Imm>().value() as u64;
1805
1806 let val = (info.val ^ imm_logical(imm, (32 >> 6) != 0))
1807 | ((0 & 0x3f) << 16)
1808 | ((0 & 0x3f) << 10)
1809 | ((rn & 0x1f) << 5)
1810 | ((rd & 0x1f) << 0);
1811 self.buffer.put4(val);
1812 return;
1813 }
1814 }
1815
1816 Encoding::GpGpImmLogical64 => {
1818 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1819 let rd = ops[0].id();
1820 let rn = ops[1].id();
1821 let imm = ops[2].as_::<Imm>().value() as u64;
1822
1823 let val = (info.val ^ imm_logical(imm, (64 >> 6) != 0))
1824 | ((0 & 0x3f) << 16)
1825 | ((0 & 0x3f) << 10)
1826 | ((rn & 0x1f) << 5)
1827 | ((rd & 0x1f) << 0);
1828 self.buffer.put4(val);
1829 return;
1830 }
1831 }
1832
1833 Encoding::GpGpInvCond => {
1835 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1836 let rd = ops[0].id();
1837 let rn = ops[1].id();
1838 let cond = ops[2].as_::<Imm>().value() as u32;
1839
1840 let val = info.val
1841 | ((rn & 0x1f) << 16)
1842 | (((cond ^ 1) & 0xf) << 12)
1843 | ((rn & 0x1f) << 5)
1844 | ((rd & 0x1f) << 0);
1845 self.buffer.put4(val);
1846 return;
1847 }
1848 }
1849
1850 Encoding::GpGpLs64Gp => {
1852 if isign3 == enc_ops3!(Reg, Reg, Reg) {
1853 let rs = ops[0].id();
1854 let rt = ops[1].id();
1855 let rn = ops[2].id();
1856
1857 let val =
1858 info.val | ((rs & 0x1f) << 16) | ((rt & 0x1f) << 5) | ((rn & 0x1f) << 0);
1859 self.buffer.put4(val);
1860 return;
1861 }
1862 }
1863
1864 Encoding::GpGpSImm8_0 => {
1866 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1867 let rd = ops[0].id();
1868 let rn = ops[1].id();
1869 let imm8 = ops[2].as_::<Imm>().value() as u32;
1870
1871 let val = info.val
1872 | (((imm8 / (1 << 0)) & 0xff) << 10)
1873 | (((rn) & 0x1f) << 5)
1874 | (((rd) & 0x1f) << 0);
1875 self.buffer.put4(val);
1876 return;
1877 }
1878 }
1879
1880 Encoding::GpGpSImm9_0 => {
1881 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1882 let rd = ops[0].id();
1883 let rn = ops[1].id();
1884 let imm9 = ops[2].as_::<Imm>().value() as u32;
1885
1886 let val = info.val
1887 | (((imm9 / (1 << 0)) & 0x1ff) << 12)
1888 | (((rn) & 0x1f) << 5)
1889 | (((rd) & 0x1f) << 0);
1890 self.buffer.put4(val);
1891 return;
1892 }
1893 }
1894
1895 Encoding::GpGpSImm9_4 => {
1896 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1897 let rd = ops[0].id();
1898 let rn = ops[1].id();
1899 let imm9 = ops[2].as_::<Imm>().value() as u32;
1900
1901 let val = info.val
1902 | (((imm9 / (1 << 4)) & 0x1ff) << 12)
1903 | (((rn) & 0x1f) << 5)
1904 | (((rd) & 0x1f) << 0);
1905 self.buffer.put4(val);
1906 return;
1907 }
1908 }
1909
1910 Encoding::GpGpUImm12_0 => {
1911 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1912 let rt = ops[0].id();
1913 let rn = ops[1].id();
1914 let imm12 = ops[2].as_::<Imm>().value() as i32 as u32;
1915
1916 let val = info.val
1917 | (((imm12 >> 0) & 0xfff) << 10)
1918 | ((rn & 0x1f) << 5)
1919 | ((rt & 0x1f) << 0);
1920 self.buffer.put4(val);
1921 return;
1922 }
1923 }
1924
1925 Encoding::GpGpUImm12_1 => {
1926 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1927 let rt = ops[0].id();
1928 let rn = ops[1].id();
1929 let imm12 = ops[2].as_::<Imm>().value() as i32 as u32;
1930
1931 let val = info.val
1932 | (((imm12 >> 1) & 0xfff) << 10)
1933 | ((rn & 0x1f) << 5)
1934 | ((rt & 0x1f) << 0);
1935 self.buffer.put4(val);
1936 return;
1937 }
1938 }
1939
1940 Encoding::GpGpUImm12_2 => {
1941 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1942 let rt = ops[0].id();
1943 let rn = ops[1].id();
1944 let imm12 = ops[2].as_::<Imm>().value() as i32 as u32;
1945
1946 let val = info.val
1947 | (((imm12 >> 2) & 0xfff) << 10)
1948 | ((rn & 0x1f) << 5)
1949 | ((rt & 0x1f) << 0);
1950 self.buffer.put4(val);
1951 return;
1952 }
1953 }
1954
1955 Encoding::GpGpUImm12_3 => {
1956 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1957 let rt = ops[0].id();
1958 let rn = ops[1].id();
1959 let imm12 = ops[2].as_::<Imm>().value() as i32 as u32;
1960
1961 let val = info.val
1962 | (((imm12 >> 3) & 0xfff) << 10)
1963 | ((rn & 0x1f) << 5)
1964 | ((rt & 0x1f) << 0);
1965 self.buffer.put4(val);
1966 return;
1967 }
1968 }
1969
1970 Encoding::GpGpUImm6_4UImm4_0Const0 => {
1972 if isign4 == enc_ops4!(Reg, Reg, Imm, Imm) {
1973 let rd = ops[0].id();
1974 let rn = ops[1].id();
1975 let imm6 = ops[2].as_::<Imm>().value() as u32;
1976 let imm4 = ops[3].as_::<Imm>().value() as u32;
1977
1978 let val = info.val
1979 | ((rn & 0x1f) << 5)
1980 | ((rd & 0x1f) << 0)
1981 | ((0 & 0x3) << 14)
1982 | (((imm4 >> 0) & 0xf) << 10)
1983 | (((imm6 >> 4) & 0x3f) << 16);
1984
1985 self.buffer.put4(val);
1986 return;
1987 }
1988 }
1989
1990 Encoding::GpGpUImm8_0 => {
1992 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1993 let rd = ops[0].id();
1994 let rn = ops[1].id();
1995 let imm8 = ops[2].as_::<Imm>().value() as u32;
1996
1997 let val = info.val
1998 | (((imm8 >> 0) & 0xff) << 12)
1999 | ((rn & 0x1f) << 5)
2000 | ((rd & 0x1f) << 0);
2001 self.buffer.put4(val);
2002 return;
2003 }
2004 }
2005
2006 Encoding::GpGpZeroGp => {
2008 if isign3 == enc_ops3!(Reg, Reg, Reg) {
2009 let rs = ops[0].id();
2010 let rn = ops[1].id();
2011 let rt = ops[2].id();
2012
2013 let val = info.val
2014 | ((31 & 0x1f) << 10)
2015 | ((rn & 0x1f) << 5)
2016 | ((rt & 0x1f) << 0)
2017 | ((rs & 0x1f) << 16);
2018
2019 self.buffer.put4(val);
2020 return;
2021 }
2022 }
2023
2024 Encoding::GpGplsbwidth => {
2026 if isign4 == enc_ops4!(Reg, Reg, Imm, Imm) {
2027 let rd = ops[0].id();
2028 let rn = ops[1].id();
2029 let lsb = ops[2].as_::<Imm>().value() as u32;
2030 let width = ops[3].as_::<Imm>().value() as u32;
2031
2032 let val = info.val
2033 | (((lsb + width - 1) & 0x3f) << 10)
2034 | (((rn) & 0x1f) << 5)
2035 | (((rd) & 0x1f) << 0);
2036 self.buffer.put4(val);
2037 return;
2038 }
2039 }
2040
2041 Encoding::GpGplsl32 => {
2042 if isign3 == enc_ops3!(Reg, Reg, Imm) {
2043 let rd = ops[0].id();
2044 let rn = ops[1].id();
2045 let lsl32 = ops[2].as_::<Imm>().value() as u32;
2046
2047 let val = info.val
2048 | (((32 - 1 - lsl32) & 0x3f) << 10)
2049 | (((rn) & 0x1f) << 5)
2050 | (((rd) & 0x1f) << 0);
2051 self.buffer.put4(val);
2052 return;
2053 }
2054 }
2055
2056 Encoding::GpGplsl64 => {
2057 if isign3 == enc_ops3!(Reg, Reg, Imm) {
2058 let rd = ops[0].id();
2059 let rn = ops[1].id();
2060 let lsl64 = ops[2].as_::<Imm>().value() as u32;
2061
2062 let val = info.val
2063 | (((64 - 1 - lsl64) & 0x3f) << 10)
2064 | (((rn) & 0x1f) << 5)
2065 | (((rd) & 0x1f) << 0);
2066 self.buffer.put4(val);
2067 return;
2068 }
2069 }
2070
2071 Encoding::GpImmAddr => {
2073 if isign3 == enc_ops2!(Reg, Imm) {
2074 let rd = ops[0].id();
2075 let target = ops[1].as_::<Imm>().value() as i32 as u32;
2076
2077 let val = info.val
2078 | (((target & 3) & 0x3) << 29)
2079 | (((target >> 2) & 0x7ffff) << 5)
2080 | ((rd & 0x1f) << 0);
2081
2082 self.buffer.put4(val);
2083 return;
2084 } else if isign3 == enc_ops2!(Reg, Label) {
2085 let rd = ops[0].id();
2086 self.use_label(&ops[1], LabelUse::A64Adr21);
2087 let val = info.val | (rd & 0x1f) << 0;
2088 self.buffer.put4(val);
2089 return;
2090 }
2091 }
2092
2093 Encoding::GpImmAddrP => {
2094 if isign3 == enc_ops2!(Reg, Imm) {
2095 let rd = ops[0].id();
2096 let target = ops[1].as_::<Imm>().value() as u64;
2097
2098 let val = info.val
2099 | ((((target & !0xfffu64) >> 12) as u32 & 3) << 29)
2100 | ((((target & !0xfffu64) >> 14) as u32 & 0x7ffff) << 5)
2101 | ((rd & 0x1f) << 0);
2102
2103 self.buffer.put4(val);
2104 return;
2105 } else if isign3 == enc_ops2!(Reg, Label) {
2106 let rd = ops[0].id();
2107 self.use_label(&ops[1], LabelUse::A64Adr21);
2108 let val = info.val | (rd & 0x1f) << 0;
2109 self.buffer.put4(val);
2110 return;
2111 } else if isign3 == enc_ops2!(Reg, Sym) {
2112 let rd = ops[0].id();
2113 self.buffer.add_reloc(
2114 Reloc::Aarch64AdrGotPage21,
2115 RelocTarget::Sym(ops[1].as_::<Sym>()),
2116 0,
2117 );
2118 let val = info.val | (rd & 0x1f) << 0;
2119 self.buffer.put4(val);
2120 return;
2121 }
2122 }
2123
2124 Encoding::GpImmImmCond => {
2126 if isign4 == enc_ops4!(Reg, Imm, Imm, Imm) {
2127 let rn = ops[0].id();
2128 let imm5 = ops[1].as_::<Imm>().value() as u32;
2129 let nzcv = ops[2].as_::<Imm>().value() as u32;
2130 let cond = ops[3].as_::<Imm>().value() as u32;
2131 let val = info.val
2132 | ((imm5 & 0x1f) << 16)
2133 | ((cond & 0xf) << 12)
2134 | ((rn & 0x1f) << 5)
2135 | ((nzcv & 0xf) << 0);
2136
2137 self.buffer.put4(val);
2138 return;
2139 }
2140 }
2141
2142 Encoding::GpRelAddr19 => {
2144 if isign3 == enc_ops2!(Reg, Imm) {
2145 let rt = ops[0].id();
2146 let imm19 = ops[1].as_::<Imm>().value() as i32 as u32;
2147
2148 let val = info.val | (((imm19 & 0x7ffff) << 5) & 0x7ffff0) | ((rt & 0x1f) << 0);
2149
2150 self.buffer.put4(val);
2151 return;
2152 } else if isign3 == enc_ops2!(Reg, Label) {
2153 let rt = ops[0].id();
2154 self.use_label(&ops[1], LabelUse::A64Ldr19);
2155 let val = info.val | (rt & 0x1f) << 0;
2156 self.buffer.put4(val);
2157 return;
2158 }
2159 }
2160 Encoding::GpTBZRelAddr14 => {
2162 if isign3 == enc_ops3!(Reg, Imm, Label) {
2163 let rt = ops[0].id();
2164 let bit = ops[1].as_::<Imm>().value() as u32;
2165
2166 self.use_label(ops[2], LabelUse::A64Branch14);
2167 let val = info.val
2168 | (((bit >> 5) & 0x1) << 31)
2169 | (((bit & 0x1f) & 0x1f) << 19)
2170 | (((0 >> 2) & 0x3fff) << 5)
2171 | ((rt & 0x1f) << 0);
2172
2173 self.buffer.put4(val);
2174 return;
2175 } else if isign3 == enc_ops3!(Reg, Imm, Imm) {
2176 let rt = ops[0].id();
2177 let bit = ops[1].as_::<Imm>().value() as u32;
2178 let imm14 = ops[2].as_::<Imm>();
2179
2180 let val = info.val
2181 | (((bit >> 5) & 0x1) << 31)
2182 | (((bit & 0x1f) & 0x1f) << 19)
2183 | (((imm14.value() as i32 as u32 >> 2) & 0x3fff) << 5)
2184 | ((rt & 0x1f) << 0);
2185
2186 self.buffer.put4(val);
2187 return;
2188 }
2189 }
2190
2191 Encoding::GpUImm16_0 => {
2193 if isign3 == enc_ops2!(Reg, Imm) {
2194 let rd = ops[0].id();
2195 let imm16 = ops[1].as_::<Imm>().value() as u32;
2196
2197 let val = info.val | (((imm16 >> 0) & 0xffff) << 5) | ((rd & 0x1f) << 0);
2198
2199 self.buffer.put4(val);
2200 return;
2201 }
2202 }
2203
2204 Encoding::GpUImm16_0Imm => {
2206 if isign3 == enc_ops3!(Reg, Imm, Imm) {
2207 let rd = ops[0].id();
2208 let imm16 = ops[1].as_::<Imm>().value() as u32;
2209 let hw = ops[2].as_::<Imm>().value() as u32;
2210
2211 let val = info.val
2212 | (((imm16 >> 0) & 0xffff) << 5)
2213 | (((hw >> 0) & 0x3) << 21)
2214 | ((rd & 0x1f) << 0);
2215
2216 self.buffer.put4(val);
2217 return;
2218 }
2219 }
2220
2221 Encoding::GpZeroGpConst0 => {
2222 todo!()
2223 }
2224
2225 Encoding::GpConst0 => {
2226 if isign3 == enc_ops1!(Reg) {
2227 let rn = ops[0].id();
2228 self.buffer.put4(info.val | ((rn & 0x1f) << 5));
2229 return;
2230 }
2231 }
2232
2233 Encoding::GpGpGp => {
2234 if isign3 == enc_ops3!(Reg, Reg, Reg) {
2235 let rd = ops[0].id();
2236 let rn = ops[1].id();
2237 let rm = ops[2].id();
2238
2239 self.buffer.put4(
2240 info.val
2241 | ((rm & 0x1f) << 16)
2242 | (0 << 10)
2243 | (rn & 0x1f) << 5
2244 | ((rd & 0x1f) << 0),
2245 );
2246 return;
2247 }
2248 }
2249
2250 Encoding::GpGpGpConst0 => {
2251 if isign3 == enc_ops3!(Reg, Reg, Reg) {
2252 let rd = ops[0].id();
2253 let rn = ops[1].id();
2254 let rm = ops[2].id();
2255
2256 self.buffer.put4(
2257 info.val
2258 | ((rm & 0x1f) << 16)
2259 | (0 << 10)
2260 | (rn & 0x1f) << 5
2261 | ((rd & 0x1f) << 0),
2262 );
2263 return;
2264 }
2265 }
2266
2267 _ => panic!("{:?}", info.encoding),
2268 };
2269 if err.is_none() {
2270 err = Some(AsmError::InvalidOperand);
2271 }
2272 self.last_error = err;
2273 }
2274
2275 fn emit(&mut self, opcode: i64, op0: &Operand, op1: &Operand, op2: &Operand, op3: &Operand) {
2276 let _ = opcode;
2277 let _ = op0;
2278 let _ = op1;
2279 let _ = op2;
2280 let _ = op3;
2281 todo!()
2282 }
2283}
2284
2285impl<'a> A64EmitterExplicit for Assembler<'a> {}