1use super::opcodes::Opcode;
2use crate::core::buffer::{CodeBuffer, CodeOffset, ConstantData, LabelUse, Reloc, RelocTarget};
3use crate::core::operand::*;
4use crate::core::operand::{Imm, Sym};
5use crate::core::patch::PatchSiteId;
6use crate::riscv::opcodes::Encoding;
7use crate::riscv::{EmitterExplicit, RA};
8use crate::AsmError;
9use crate::{core::emitter::Emitter, riscv::opcodes::Inst};
10pub struct Assembler<'a> {
11 pub buffer: &'a mut CodeBuffer,
12 last_error: Option<AsmError>,
13}
14
15impl<'a> Assembler<'a> {
16 pub fn new(buffer: &'a mut CodeBuffer) -> Self {
17 Assembler {
18 buffer,
19 last_error: None,
20 }
21 }
22
23 pub fn get_label(&mut self) -> Label {
24 self.buffer.get_label()
25 }
26
27 pub fn bind_label(&mut self, label: Label) {
28 self.buffer.bind_label(label);
29 }
30
31 pub fn add_constant(&mut self, c: impl Into<ConstantData>) -> Label {
32 let c = self.buffer.add_constant(c);
33 self.buffer.get_label_for_constant(c)
34 }
35
36 pub fn label_offset(&self, label: Label) -> CodeOffset {
37 self.buffer.label_offset(label)
38 }
39
40 pub fn patchable_j(&mut self, label: Label) -> PatchSiteId {
41 let offset = self.buffer.cur_offset();
42 self.j(label);
43 self.buffer
44 .record_label_patch_site(offset, label, LabelUse::RVJal20)
45 }
46
47 pub fn patchable_call(&mut self, label: Label) -> PatchSiteId {
48 let offset = self.buffer.cur_offset();
49 self.jal(RA, label);
50 self.buffer
51 .record_label_patch_site(offset, label, LabelUse::RVJal20)
52 }
53
54 pub fn la(&mut self, rd: impl OperandCast, target: impl OperandCast) {
55 let rd = *rd.as_operand();
56 let target = target.as_operand();
57
58 if target.is_label() {
59 let off = self.buffer.cur_offset();
60 self.buffer
61 .use_label_at_offset(off, target.as_::<Label>(), LabelUse::RVPCRelHi20);
62 self.auipc(rd, imm(0));
63 let off = self.buffer.cur_offset();
64 self.buffer
65 .use_label_at_offset(off, target.as_::<Label>(), LabelUse::RVPCRelLo12I);
66 self.addi(rd, rd, imm(0));
67 return;
68 } else if target.is_sym() {
69 if self.buffer.env().pic() {
70 let sym = target.as_::<Sym>();
82
83 let auipc_label = self.get_label();
85 self.bind_label(auipc_label);
86 self.buffer
87 .add_reloc(Reloc::RiscvGotHi20, RelocTarget::Sym(sym), 0);
88
89 self.auipc(rd, imm(0));
91 self.buffer
93 .add_reloc(Reloc::RiscvPCRelLo12I, RelocTarget::Label(auipc_label), 0);
94 self.ld(rd, rd, imm(0));
95 } else {
96 let label_data = self.get_label();
106 let label_end = self.get_label();
107
108 self.ld(rd, rd, label_data);
109 self.j(label_end);
110 self.bind_label(label_data);
111 self.buffer
112 .add_reloc(Reloc::Abs8, RelocTarget::Sym(target.as_::<Sym>()), 0);
113 self.buffer.put8(0);
114 self.bind_label(label_end);
115 }
116 } else {
117 unreachable!("LA expects label or symbol");
118 }
119 }
120
121 pub fn call(&mut self, target: impl OperandCast) {
122 let target = target.as_operand();
123
124 if target.is_label() {
125 let off = self.buffer.cur_offset();
126 self.buffer
127 .use_label_at_offset(off, target.as_::<Label>(), LabelUse::RVPCRelHi20);
128 self.auipc(RA, imm(0));
129 assert!(!self.last_error.is_some());
130 let off = self.buffer.cur_offset();
131 self.buffer
132 .use_label_at_offset(off, target.as_::<Label>(), LabelUse::RVPCRelLo12I);
133 self.jalr(RA, RA, imm(0));
134 assert!(!self.last_error.is_some());
135 return;
136 } else if target.is_sym() {
137 let sym = target.as_::<Sym>();
138
139 let reloc = Reloc::RiscvCallPlt;
140
141 self.buffer.add_reloc(reloc, RelocTarget::Sym(sym), 0);
142 self.auipc(RA, imm(0));
143 self.jalr(RA, RA, imm(0));
144 } else if target.is_imm() {
145 self.jalr(RA, RA, *target);
146 } else if target.is_reg() {
147 self.jalr(RA, *target, imm(0));
148 } else {
149 unreachable!();
150 }
151 }
152}
153macro_rules! enc_ops1 {
154 ($op0:ident) => {
155 OperandType::$op0 as u32
156 };
157}
158
159macro_rules! enc_ops2 {
160 ($op0:ident, $op1:ident) => {
161 (OperandType::$op0 as u32) | ((OperandType::$op1 as u32) << 3)
162 };
163}
164
165macro_rules! enc_ops3 {
166 ($op0:ident, $op1:ident, $op2:ident) => {
167 (OperandType::$op0 as u32)
168 | ((OperandType::$op1 as u32) << 3)
169 | ((OperandType::$op2 as u32) << 6)
170 };
171}
172
173macro_rules! enc_ops4 {
174 ($op0:ident, $op1:ident, $op2:ident, $op3:ident) => {
175 (OperandType::$op0 as u32)
176 | ((OperandType::$op1 as u32) << 3)
177 | ((OperandType::$op2 as u32) << 6)
178 | ((OperandType::$op3 as u32) << 9)
179 };
180}
181
182impl<'a> Emitter for Assembler<'a> {
183 fn emit(
184 &mut self,
185 opcode: i64,
186 op0: &crate::core::operand::Operand,
187 op1: &crate::core::operand::Operand,
188 op2: &crate::core::operand::Operand,
189 op3: &crate::core::operand::Operand,
190 ) {
191 self.emit_n(opcode, &[op0, op1, op2, op3])
192 }
193
194 #[allow(unused_assignments)]
195 fn emit_n(&mut self, opcode: i64, ops: &[&crate::core::operand::Operand]) {
196 assert!(opcode < Opcode::Invalid as i64 && opcode >= 0);
197 let opcode: Opcode = unsafe { core::mem::transmute(opcode as u32) };
198 let encoding = opcode.encoding();
199
200 let mut inst = Inst::new(opcode).encode();
201 let mut label_use = None;
202 let mut reloc = None;
203
204 let isign3 = match ops {
205 [] => 0,
206 [op0] => op0.op_type() as u32,
207 [op0, op1] => op0.op_type() as u32 + ((op1.op_type() as u32) << 3),
208 [op0, op1, op2, ..] => {
209 op0.op_type() as u32 + ((op1.op_type() as u32) << 3) + ((op2.op_type() as u32) << 6)
210 }
211 };
212
213 let isign4 = match ops {
214 [] => 0,
215 [op0] => op0.op_type() as u32,
216 [op0, op1] => op0.op_type() as u32 + ((op1.op_type() as u32) << 3),
217 [op0, op1, op2] => {
218 op0.op_type() as u32 + ((op1.op_type() as u32) << 3) + ((op2.op_type() as u32) << 6)
219 }
220 [op0, op1, op2, op3, ..] => {
221 op0.op_type() as u32
222 + ((op1.op_type() as u32) << 3)
223 + ((op2.op_type() as u32) << 6)
224 + ((op3.op_type() as u32) << 9)
225 }
226 };
227 let mut short = false;
228 match encoding {
229 Encoding::Bimm12HiRs1Bimm12lo => {
230 let rs1 = ops[0].id();
231 let imm = if ops[1].is_imm() {
232 ops[1].as_::<Imm>().value() as i32
233 } else if ops[1].is_label() {
234 label_use = Some((ops[1], LabelUse::RVB12));
235 0
236 } else {
237 self.last_error = Some(AsmError::InvalidOperand);
238 return;
239 };
240
241 inst = inst.set_rs1(rs1).set_bimm12lohi(imm);
242 }
243
244 Encoding::Bimm12HiRs1Rs2Bimm12lo => {
245 let rs1 = ops[0].id();
246 let rs2 = ops[1].id();
247
248 let imm = if ops[2].is_imm() {
249 ops[2].as_::<Imm>().value() as i32
250 } else if ops[2].is_label() {
251 label_use = Some((ops[2], LabelUse::RVB12));
252 0
253 } else {
254 self.last_error = Some(AsmError::InvalidOperand);
255 return;
256 };
257
258 inst = inst.set_rs1(rs1).set_rs2(rs2).set_bimm12lohi(imm);
259 }
260
261 Encoding::Bimm12HiRs2Rs1Bimm12lo => {
262 let rs1 = ops[0].id();
263 let rs2 = ops[1].id();
264 let imm = if ops[2].is_imm() {
265 ops[2].as_::<Imm>().value() as i32
266 } else if ops[2].is_label() {
267 label_use = Some((ops[2], LabelUse::RVB12));
268 0
269 } else {
270 self.last_error = Some(AsmError::InvalidOperand);
271 return;
272 };
273
274 inst = inst.set_rs2(rs2).set_rs1(rs1).set_bimm12lohi(imm);
275 }
276
277 Encoding::Bimm12HiRs2Bimm12lo => {
278 let rs2 = ops[0].id();
279 let imm = if ops[1].is_imm() {
280 ops[1].as_::<Imm>().value() as i32
281 } else if ops[1].is_label() {
282 label_use = Some((ops[1], LabelUse::RVB12));
283 0
284 } else {
285 self.last_error = Some(AsmError::InvalidOperand);
286 return;
287 };
288
289 inst = inst.set_rs2(rs2).set_bimm12lohi(imm);
290 }
291
292 Encoding::CImm12 => {
293 short = true;
294 let imm = if ops[0].is_imm() {
295 ops[0].as_::<Imm>().value() as i32
296 } else if ops[0].is_label() {
297 label_use = Some((ops[0], LabelUse::RVCJump));
298 0
299 } else {
300 self.last_error = Some(AsmError::InvalidOperand);
301 return;
302 };
303
304 inst = inst.set_c_imm12(imm)
305 }
306
307 Encoding::CIndex => {
308 short = true;
309 let imm = if ops[0].is_imm() {
310 ops[0].as_::<Imm>().value() as i32
311 } else {
312 self.last_error = Some(AsmError::InvalidOperand);
313 return;
314 };
315 inst = inst.set_c_index(imm as _);
316 }
317
318 Encoding::CMopT => {
319 short = true;
320 let imm = if ops[0].is_imm() {
321 ops[0].as_::<Imm>().value() as i32
322 } else {
323 self.last_error = Some(AsmError::InvalidOperand);
324 return;
325 };
326
327 inst = inst.set_c_mop_t(imm as _);
328 }
329
330 Encoding::CNzimm10hiCNzimm10lo => {
331 short = true;
332 let imm = if ops[0].is_imm() {
333 ops[0].as_::<Imm>().value() as i32
334 } else {
335 self.last_error = Some(AsmError::InvalidOperand);
336 return;
337 };
338
339 if imm == 0 || imm > 1024 || imm < -1024 {
340 self.last_error = Some(AsmError::InvalidOperand);
341 return;
342 }
343
344 inst = inst.set_c_nzimm10lohi(imm);
345 }
346
347 Encoding::CNzimm6hiCNzimm6lo => {
348 short = true;
349 let imm = if ops[0].is_imm() {
350 ops[0].as_::<Imm>().value() as i32
351 } else {
352 self.last_error = Some(AsmError::InvalidOperand);
353 return;
354 };
355
356 if imm == 0 || imm > 64 {
357 self.last_error = Some(AsmError::InvalidOperand);
358 return;
359 }
360
361 inst = inst.set_c_nzimm6lohi(imm)
362 }
363
364 Encoding::CRlistCSpimm => {
365 short = true;
366 todo!()
367 }
368
369 Encoding::CRs1N0 => {
370 short = true;
371 let rs1 = ops[0].id();
372 inst = inst.set_rs1_n0(rs1);
373 }
374
375 Encoding::CRs2CUimm8spS => {
376 short = true;
377 let rs2 = ops[0].id();
378 let imm = if ops[1].is_imm() {
379 ops[1].as_::<Imm>().value() as i32
380 } else {
381 self.last_error = Some(AsmError::InvalidOperand);
382 return;
383 };
384 if imm < 0 || imm > 256 {
385 self.last_error = Some(AsmError::InvalidOperand);
386 return;
387 }
388 inst = inst.set_c_uimm8lohi(imm as _).set_c_rs2(rs2);
389 }
390
391 Encoding::CRs2CUimm9spS => {
392 short = true;
393 let rs2 = ops[0].id();
394 let imm = if ops[1].is_imm() {
395 ops[1].as_::<Imm>().value() as i32
396 } else {
397 self.last_error = Some(AsmError::InvalidOperand);
398 return;
399 };
400 if imm < 0 || imm > 511 {
401 self.last_error = Some(AsmError::InvalidOperand);
402 return;
403 }
404 inst = inst.set_c_rs2(rs2).set_c_uimm9sp_s(imm as _);
405 }
406
407 Encoding::CSreg1CSreg2 => {
408 short = true;
409 todo!()
410 }
411
412 Encoding::CsrZimm => {
413 let csr_imm = if ops[0].is_imm() {
414 ops[0].as_::<Imm>().value() as i32
415 } else {
416 self.last_error = Some(AsmError::InvalidOperand);
417 return;
418 };
419
420 let zimm = if ops[1].is_imm() {
421 ops[1].as_::<Imm>().value()
422 } else {
423 self.last_error = Some(AsmError::InvalidOperand);
424 return;
425 };
426
427 inst = inst.set_csr(csr_imm as _).set_zimm(zimm as _);
428 }
429
430 Encoding::Empty => {}
431 Encoding::FmPredSuccRs1Rd => {
432 let fm = if ops[0].is_imm() {
433 ops[0].as_::<Imm>().value() as u8
434 } else {
435 self.last_error = Some(AsmError::InvalidOperand);
436 return;
437 };
438
439 let pred = if ops[1].is_imm() {
440 ops[1].as_::<Imm>().value() as u8
441 } else {
442 self.last_error = Some(AsmError::InvalidOperand);
443 return;
444 };
445
446 let succ = if ops[2].is_imm() {
447 ops[2].as_::<Imm>().value() as u8
448 } else {
449 self.last_error = Some(AsmError::InvalidOperand);
450 return;
451 };
452
453 let rs1 = ops[3].id();
454 let rd = ops[4].id();
455
456 inst = inst
457 .set_fm(fm as _)
458 .set_pred(pred as _)
459 .set_succ(succ as _)
460 .set_rs1(rs1)
461 .set_rd(rd);
462 }
463
464 Encoding::Imm12HiRs1Rs2Imm12lo => {
465 if isign3 == enc_ops3!(Reg, Reg, Imm) {
466 let rs1 = ops[0].id();
467 let rs2 = ops[1].id();
468 let imm = ops[2].as_::<Imm>().value() as i32;
469
470 inst = inst.set_rs1(rs1).set_rs2(rs2).set_imm12lohi(imm);
471 } else {
472 self.last_error = Some(AsmError::InvalidOperand);
473 return;
474 };
475 }
476
477 Encoding::Imm12Rs1Rd => {
478 if isign3 == enc_ops3!(Reg, Reg, Imm) {
479 let rs1 = ops[0].id();
480 let rd = ops[1].id();
481 let imm = ops[2].as_::<Imm>().value() as i32;
482
483 inst = inst.set_rs1(rs1).set_rd(rd).set_imm12(imm);
484 } else {
485 self.last_error = Some(AsmError::InvalidOperand);
486 return;
487 }
488 }
489
490 Encoding::Jimm20 => {
491 if isign3 == enc_ops1!(Imm) {
492 let imm = ops[0].as_::<Imm>().value() as i32;
493 inst = inst.set_jimm20(imm);
494 } else if isign3 == enc_ops1!(Label) {
495 label_use = Some((ops[0], LabelUse::RVJal20));
496 inst = inst.set_jimm20(0);
497 } else if isign3 == enc_ops1!(Sym) {
498 let sym = ops[0].as_::<Sym>();
499
500 let _distance = self.buffer.symbol_distance(sym);
501 reloc = Some((sym, Reloc::RiscvGotHi20))
503 } else {
504 self.last_error = Some(AsmError::InvalidOperand);
505 return;
506 }
507 }
508
509 Encoding::MopRT30MopRT2726MopRT2120RdRs1 => {
510 todo!()
511 }
512 Encoding::MopRrT30MopRrT2726RdRs1Rs2 => {
513 todo!()
514 }
515
516 Encoding::NfVmRs1Vd => {
517 if isign3 == enc_ops3!(Reg, Reg, Reg) {
518 let vd = ops[0].id();
519 let rs1 = ops[1].id();
520 let vm = ops[2].id();
521
522 inst = inst.set_vd(vd).set_rs1(rs1).set_vm(vm);
523 } else {
524 self.last_error = Some(AsmError::InvalidOperand);
525 return;
526 }
527 }
528
529 Encoding::NfVmRs1Vs3 => {
530 if isign3 == enc_ops3!(Reg, Reg, Reg) {
531 let vs3 = ops[0].id();
532 let rs1 = ops[1].id();
533 let vm = ops[2].id();
534
535 inst = inst.set_vs3(vs3).set_rs1(rs1).set_vm(vm);
536 } else {
537 self.last_error = Some(AsmError::InvalidOperand);
538 return;
539 }
540 }
541
542 Encoding::NfVmRs2Rs1Vd => {
543 if isign4 == enc_ops4!(Reg, Reg, Reg, Reg) {
544 let vd = ops[0].id();
545 let rs1 = ops[1].id();
546 let vm = ops[3].id();
547 let rs2 = ops[2].id();
548 inst = inst.set_rs1(rs1).set_rs2(rs2).set_vd(vd).set_vm(vm);
549 } else {
550 self.last_error = Some(AsmError::InvalidOperand);
551 return;
552 }
553 }
554
555 Encoding::NfVmRs2Rs1Vs3 => {
556 if isign4 == enc_ops4!(Reg, Reg, Reg, Reg) {
557 let vs3 = ops[0].id();
558 let rs1 = ops[1].id();
559 let vm = ops[3].id();
560 let rs2 = ops[2].id();
561 inst = inst.set_rs1(rs1).set_rs2(rs2).set_vs3(vs3).set_vm(vm);
562 } else {
563 self.last_error = Some(AsmError::InvalidOperand);
564 return;
565 }
566 }
567
568 Encoding::NfVmVs2Rs1Vd => {
569 if isign4 == enc_ops4!(Reg, Reg, Reg, Reg) {
570 let vd = ops[0].id();
571 let rs1 = ops[1].id();
572 let vs2 = ops[2].id();
573 let vm = ops[3].id();
574
575 inst = inst.set_rs1(rs1).set_vd(vd).set_vs2(vs2).set_vm(vm);
576 } else {
577 self.last_error = Some(AsmError::InvalidOperand);
578 return;
579 }
580 }
581
582 Encoding::NfVmVs2Rs1Vs3 => {
583 if isign4 == enc_ops4!(Reg, Reg, Reg, Reg) {
584 let vs3 = ops[0].id();
585 let rs1 = ops[1].id();
586 let vs2 = ops[2].id();
587 let vm = ops[3].id();
588
589 inst = inst.set_vs3(vs3).set_rs1(rs1).set_vs2(vs2).set_vm(vm);
590 } else {
591 self.last_error = Some(AsmError::InvalidOperand);
592 return;
593 }
594 }
595
596 Encoding::Rd => {
597 if isign3 == enc_ops1!(Reg) {
598 let rd = ops[0].id();
599 inst = inst.set_rd(rd);
600 } else {
601 self.last_error = Some(AsmError::InvalidOperand);
602 return;
603 }
604 }
605
606 Encoding::RdCUimm8sphiCUimm8splo => {
607 if isign3 == enc_ops2!(Reg, Imm) {
608 let rd = ops[0].id();
609 let imm = ops[1].as_::<Imm>().value() as u32;
610
611 inst = inst.set_rd(rd).set_c_uimm8splohi(imm);
612 } else {
613 self.last_error = Some(AsmError::InvalidOperand);
614 return;
615 }
616 }
617
618 Encoding::RdCUimm9sphiCUimm9splo => {
619 if isign3 == enc_ops2!(Reg, Imm) {
620 let rd = ops[0].id();
621 let imm = ops[1].as_::<Imm>().value() as u32;
622
623 inst = inst.set_rd(rd).set_c_uimm9splohi(imm);
624 } else {
625 self.last_error = Some(AsmError::InvalidOperand);
626 return;
627 }
628 }
629
630 Encoding::RdCsr => {
631 if isign3 == enc_ops2!(Reg, Imm) {
632 let rd = ops[0].id();
633 let csr = ops[1].as_::<Imm>().value() as u32;
634 inst = inst.set_rd(rd).set_csr(csr);
635 } else {
636 self.last_error = Some(AsmError::InvalidOperand);
637 return;
638 }
639 }
640
641 Encoding::RdCsrZimm => {
642 if isign3 == enc_ops3!(Reg, Imm, Imm) {
643 let rd = ops[0].id();
644 let csr = ops[1].as_::<Imm>().value() as u32;
645 let zimm = ops[2].as_::<Imm>().value() as i32;
646 inst = inst.set_rd(rd).set_csr(csr).set_zimm(zimm);
647 } else {
648 self.last_error = Some(AsmError::InvalidOperand);
649 return;
650 }
651 }
652 Encoding::RdImm20 => {
653 if isign3 == enc_ops2!(Reg, Imm) {
654 let rd = ops[0].id();
655 let imm = ops[1].as_::<Imm>().value() as i32;
656 inst = inst.set_rd(rd).set_imm20(imm);
657 } else if isign3 == enc_ops2!(Reg, Label) {
658 let rd = ops[0].id();
659 label_use = Some((ops[0], LabelUse::RVPCRelHi20));
660 inst = inst.set_rd(rd).set_imm20(0);
661 } else if isign3 == enc_ops2!(Reg, Sym) {
662 todo!()
668 } else {
669 self.last_error = Some(AsmError::InvalidOperand);
670 return;
671 };
672 }
673
674 Encoding::RdJimm20 => {
675 if isign3 == enc_ops2!(Reg, Imm) {
676 let rd = ops[0].id();
677 let imm = ops[1].as_::<Imm>().value() as i32;
678 inst = inst.set_rd(rd).set_jimm20(imm);
679 } else if isign3 == enc_ops2!(Reg, Label) {
680 let rd = ops[0].id();
681 label_use = Some((ops[0], LabelUse::RVJal20));
682 inst = inst.set_rd(rd).set_jimm20(0);
683 } else if isign3 == enc_ops2!(Reg, Sym) {
684 let rd = ops[0].id();
685 let sym = ops[1].as_::<Sym>();
686
687 reloc = Some((sym, Reloc::RiscvGotHi20));
688 inst = inst.set_rd(rd).set_jimm20(0);
689 todo!()
690 } else {
691 self.last_error = Some(AsmError::InvalidOperand);
692 return;
693 };
694 }
695
696 Encoding::RdN0CImm6loCImm6hi => {
697 short = true;
698 if isign3 == enc_ops2!(Reg, Imm) {
699 let rd = ops[0].id();
700 let imm = ops[1].as_::<Imm>().value() as i32;
701 inst = inst.set_rd_n0(rd).set_c_imm6lohi(imm);
702 } else {
703 self.last_error = Some(AsmError::InvalidOperand);
704 return;
705 }
706 }
707
708 Encoding::RdN0CRs2N0 => {
709 short = true;
710 if isign3 == enc_ops2!(Reg, Reg) {
711 let rd = ops[0].id();
712 let rs1 = ops[1].id();
713 inst = inst.set_rd_n0(rd).set_c_rs2(rs1);
714 } else {
715 self.last_error = Some(AsmError::InvalidOperand);
716 return;
717 }
718 }
719
720 Encoding::RdN0CUimm8sphiCUimm8splo => {
721 short = true;
722 if isign3 == enc_ops2!(Reg, Imm) {
723 let rd = ops[0].id();
724 let imm = ops[1].as_::<Imm>().value() as i32;
725 inst = inst.set_rd_n0(rd).set_c_uimm8splohi(imm as _);
726 } else {
727 self.last_error = Some(AsmError::InvalidOperand);
728 return;
729 }
730 }
731
732 Encoding::RdN0CUimm9sphiCUimm9splo => {
733 short = true;
734 if isign3 == enc_ops2!(Reg, Imm) {
735 let rd = ops[0].id();
736 let imm = ops[1].as_::<Imm>().value() as i32;
737 inst = inst.set_rd_n0(rd).set_c_uimm9splohi(imm as _);
738 } else {
739 self.last_error = Some(AsmError::InvalidOperand);
740 return;
741 }
742 }
743
744 Encoding::RdN2CNzimm18hiCNzimm18lo => {
745 short = true;
746 if isign3 == enc_ops2!(Reg, Imm) {
747 let rd = ops[0].id();
748 let imm = ops[1].as_::<Imm>().value() as i32;
749 if imm == 0 {
750 self.last_error = Some(AsmError::InvalidOperand);
751 return;
752 } else {
753 inst = inst.set_rd_n2(rd).set_c_nzimm18lohi(imm);
754 }
755 } else {
756 self.last_error = Some(AsmError::InvalidOperand);
757 return;
758 }
759 }
760
761 Encoding::RdPCNzuimm10 => {
762 if isign3 == enc_ops2!(Reg, Imm) {
763 let rd = ops[0].id();
764 let imm = ops[1].as_::<Imm>().value() as i32;
765 inst = inst.set_rd_p(rd).set_c_nzimm10lohi(imm);
766 } else {
767 self.last_error = Some(AsmError::InvalidOperand);
768 return;
769 }
770 }
771
772 Encoding::RdPRs1PCUimm1 => {
773 if isign3 == enc_ops2!(Reg, Reg) {
774 let rd = ops[0].id();
775 let rs1 = ops[1].id();
776 let imm = ops[2].as_::<Imm>().value() as i32;
777
778 inst = inst.set_rd_p(rd).set_rs1_p(rs1).set_c_uimm1(imm as _);
779 } else {
780 self.last_error = Some(AsmError::InvalidOperand);
781 return;
782 }
783 }
784
785 Encoding::RdPRs1PCUimm2 => {
786 if isign3 == enc_ops2!(Reg, Reg) {
787 let rd = ops[0].id();
788 let rs1 = ops[1].id();
789 let imm = ops[2].as_::<Imm>().value() as i32;
790
791 inst = inst.set_rd_p(rd).set_rs1_p(rs1).set_c_uimm2(imm as _);
792 } else {
793 self.last_error = Some(AsmError::InvalidOperand);
794 return;
795 }
796 }
797
798 Encoding::RdPRs1PCUimm7loCUimm7hi => {
799 if isign3 == enc_ops2!(Reg, Reg) {
800 let rd = ops[0].id();
801 let rs1 = ops[1].id();
802 let imm = ops[2].as_::<Imm>().value() as i32;
803 inst = inst.set_rd(rd).set_rs1(rs1).set_c_uimm7lohi(imm as _);
804 } else {
805 self.last_error = Some(AsmError::InvalidOperand);
806 return;
807 }
808 }
809
810 Encoding::RdPRs1PCUimm8loCUimm8hi => {
811 if isign3 == enc_ops2!(Reg, Reg) {
812 let rd = ops[0].id();
813 let rs1 = ops[1].id();
814 let imm = ops[2].as_::<Imm>().value() as i32;
815 inst = inst.set_rd(rd).set_rs1(rs1).set_c_uimm8lohi(imm as _);
816 } else {
817 self.last_error = Some(AsmError::InvalidOperand);
818 return;
819 }
820 }
821
822 Encoding::RdRs1 => {
823 if isign3 == enc_ops2!(Reg, Reg) {
824 let rd = ops[0].id();
825 let rs1 = ops[1].id();
826 inst = inst.set_rd(rd).set_rs1(rs1);
827 } else {
828 self.last_error = Some(AsmError::InvalidOperand);
829 return;
830 }
831 }
832
833 Encoding::RdRs1AqRl => {
834 if isign3 == enc_ops3!(Reg, Reg, Imm) {
835 let rd = ops[0].id();
836 let rs1 = ops[1].id();
837 let imm = ops[2].as_::<Imm>().value() as i32;
838 inst = inst.set_rd(rd).set_rs1(rs1).set_aqrl(imm as _);
839 } else {
840 self.last_error = Some(AsmError::InvalidOperand);
841 return;
842 }
843 }
844
845 Encoding::RdRs1Csr => {
846 if isign3 == enc_ops3!(Reg, Reg, Imm) {
847 let rd = ops[0].id();
848 let rs1 = ops[1].id();
849 let imm = ops[2].as_::<Imm>().value() as i32;
850 inst = inst.set_rd(rd).set_rs1(rs1).set_csr(imm as _);
851 } else {
852 self.last_error = Some(AsmError::InvalidOperand);
853 return;
854 }
855 }
856
857 Encoding::RdRs1Imm12 => {
858 if isign3 == enc_ops3!(Reg, Reg, Imm) {
859 let rd = ops[0].id();
860 let rs1 = ops[1].id();
861 let imm = ops[2].as_::<Imm>().value() as i32;
862 inst = inst.set_rd(rd).set_rs1(rs1).set_imm12(imm);
863 } else if isign3 == enc_ops3!(Reg, Reg, Label) {
864 let rd = ops[0].id();
865 let rs1 = ops[1].id();
866 let off = self.buffer.cur_offset();
867 self.buffer
868 .use_label_at_offset(off, ops[2].as_(), LabelUse::RVPCRelHi20);
869 self.auipc(*ops[0], imm(0));
870 label_use = Some((ops[2], LabelUse::RVPCRelLo12I));
871 inst = inst.set_rd(rd).set_rs1(rs1).set_imm12(0);
872 } else {
873 self.last_error = Some(AsmError::InvalidOperand);
874 return;
875 }
876 }
877
878 Encoding::RdRs1N0 => {
879 short = true;
880 if isign3 == enc_ops2!(Reg, Reg) {
881 let _rd = ops[0].id();
882 let _rs1 = ops[1].id();
883 todo!()
884 } else {
885 self.last_error = Some(AsmError::InvalidOperand);
886 return;
887 }
888 }
889
890 Encoding::RdRs1Rm => {
891 if isign3 == enc_ops3!(Reg, Reg, Imm) {
892 let rd = ops[0].id();
893 let rs1 = ops[1].id();
894 let rm = ops[2].as_::<Imm>().value() as i32;
895 inst = inst.set_rd(rd).set_rs1(rs1).set_rm(rm as _);
896 } else {
897 self.last_error = Some(AsmError::InvalidOperand);
898 return;
899 }
900 }
901 Encoding::RdRs1Rnum => {
902 if isign3 == enc_ops3!(Reg, Reg, Imm) {
903 let rd = ops[0].id();
904 let rs1 = ops[1].id();
905 let rm = ops[2].as_::<Imm>().value() as i32;
906 inst = inst.set_rd(rd).set_rs1(rs1).set_rnum(rm as _);
907 } else {
908 self.last_error = Some(AsmError::InvalidOperand);
909 return;
910 }
911 }
912
913 Encoding::RdRs1Rs2 => {
914 if isign3 == enc_ops3!(Reg, Reg, Reg) {
915 let rd = ops[0].id();
916 let rs1 = ops[1].id();
917 let rs2 = ops[2].id();
918 inst = inst.set_rd(rd).set_rs1(rs1).set_rs2(rs2);
919 } else {
920 self.last_error = Some(AsmError::InvalidOperand);
921 return;
922 }
923 }
924
925 Encoding::RdRs1Rs2AqRl => {
926 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
927 let rd = ops[0].id();
928 let rs1 = ops[1].id();
929 let rs2 = ops[2].id();
930 let imm = ops[3].as_::<Imm>().value() as i32;
931 inst = inst.set_rd(rd).set_rs1(rs1).set_rs2(rs2).set_aqrl(imm as _);
932 } else {
933 self.last_error = Some(AsmError::InvalidOperand);
934 return;
935 }
936 }
937
938 Encoding::RdRs1Rs2Bs => {
939 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
940 let rd = ops[0].id();
941 let rs1 = ops[1].id();
942 let rs2 = ops[2].id();
943 let imm = ops[3].as_::<Imm>().value() as i32;
944 inst = inst.set_rd(rd).set_rs1(rs1).set_rs2(rs2).set_bs(imm as _);
945 } else {
946 self.last_error = Some(AsmError::InvalidOperand);
947 return;
948 }
949 }
950
951 Encoding::RdRs1Rs2EqRs1 => {
952 if isign3 == enc_ops3!(Reg, Reg, Reg) {
953 let rd = ops[0].id();
954 let rs1 = ops[1].id();
955 let rs2 = ops[2].id();
956 inst = inst.set_rd(rd).set_rs1(rs1).set_rs2_eq_rs1(rs2);
957 } else {
958 self.last_error = Some(AsmError::InvalidOperand);
959 return;
960 }
961 }
962
963 Encoding::RdRs1Rs2Rm => {
964 if isign4 == enc_ops4!(Reg, Reg, Reg, Imm) {
965 let rd = ops[0].id();
966 let rs1 = ops[1].id();
967 let rs2 = ops[2].id();
968 let rm = ops[3].as_::<Imm>().value() as i32;
969 inst = inst.set_rd(rd).set_rs1(rs1).set_rs2(rs2).set_rm(rm as _);
970 } else {
971 self.last_error = Some(AsmError::InvalidOperand);
972 return;
973 }
974 }
975
976 Encoding::RdRs1Rs2Rs3Rm => {
977 if isign4 == enc_ops4!(Reg, Reg, Reg, Reg) && ops[4].op_type() == OperandType::Imm {
978 let rd = ops[0].id();
979 let rs1 = ops[1].id();
980 let rs2 = ops[2].id();
981 let rs3 = ops[3].id();
982 let rm = ops[4].as_::<Imm>().value() as i32;
983
984 inst = inst
985 .set_rd(rd)
986 .set_rs1(rs1)
987 .set_rs2(rs2)
988 .set_rs3(rs3)
989 .set_rm(rm as _);
990 } else {
991 self.last_error = Some(AsmError::InvalidOperand);
992 return;
993 }
994 }
995
996 Encoding::RdRs1Shamtw => {
997 if isign3 == enc_ops3!(Reg, Reg, Imm) {
998 let rd = ops[0].id();
999 let rs1 = ops[1].id();
1000 let shamt = ops[2].as_::<Imm>().value() as i32;
1001 inst = inst.set_rd(rd).set_rs1(rs1).set_shamtw(shamt as _);
1002 } else {
1003 self.last_error = Some(AsmError::InvalidOperand);
1004 return;
1005 }
1006 }
1007 Encoding::RdRs2 => {
1008 if isign3 == enc_ops2!(Reg, Reg) {
1009 let rd = ops[0].id();
1010 let rs1 = ops[1].id();
1011 inst = inst.set_rd(rd).set_rs1(rs1);
1012 } else {
1013 self.last_error = Some(AsmError::InvalidOperand);
1014 return;
1015 }
1016 }
1017
1018 Encoding::RdZimm => {
1019 if isign3 == enc_ops2!(Reg, Imm) {
1020 let rd = ops[0].id();
1021 let imm = ops[1].as_::<Imm>().value() as i32;
1022 inst = inst.set_rd(rd).set_zimm(imm);
1023 } else {
1024 self.last_error = Some(AsmError::InvalidOperand);
1025 return;
1026 }
1027 }
1028
1029 Encoding::Rs1 => {
1030 if isign3 == enc_ops1!(Reg) {
1031 let rs1 = ops[0].id();
1032 inst = inst.set_rs1(rs1);
1033 } else {
1034 self.last_error = Some(AsmError::InvalidOperand);
1035 return;
1036 }
1037 }
1038
1039 Encoding::Rs1Csr => {
1040 if isign3 == enc_ops2!(Reg, Imm) {
1041 let rs1 = ops[0].id();
1042 let csr = ops[1].as_::<Imm>().value() as i32;
1043 inst = inst.set_rs1(rs1).set_csr(csr as _);
1044 } else {
1045 self.last_error = Some(AsmError::InvalidOperand);
1046 return;
1047 }
1048 }
1049
1050 Encoding::Rs1Imm12hi => {
1051 if isign3 == enc_ops2!(Reg, Imm) {
1052 let rs1 = ops[0].id();
1053 let imm = ops[1].as_::<Imm>().value() as i32;
1054 inst = inst.set_rs1(rs1).set_imm12hi_raw(imm as _);
1055 } else {
1056 self.last_error = Some(AsmError::InvalidOperand);
1057 return;
1058 }
1059 }
1060
1061 Encoding::Rs1N0 => {
1062 short = true;
1063 if isign3 == enc_ops1!(Reg) {
1064 let rs1 = ops[0].id();
1065 inst = inst.set_rs1_n0(rs1);
1066 } else {
1067 self.last_error = Some(AsmError::InvalidOperand);
1068 return;
1069 }
1070 }
1071
1072 Encoding::Rs1PCBimm9loCBimm9hi => {
1073 short = true;
1074 if isign3 == enc_ops2!(Reg, Imm) {
1075 let rs1 = ops[0].id();
1076 let imm = ops[1].as_::<Imm>().value();
1077
1078 inst = inst.set_rs1(rs1).set_c_bimm9lohi(imm as _);
1079 } else if isign3 == enc_ops2!(Reg, Label) {
1080 let rs1 = ops[0].id();
1081 label_use = Some((ops[1], LabelUse::RVCB9));
1082 inst = inst.set_rs1(rs1).set_c_bimm9lohi(0);
1083 } else {
1084 self.last_error = Some(AsmError::InvalidOperand);
1085 return;
1086 }
1087 }
1088
1089 Encoding::Rs1PRs2PCUimm7loCUimm7hi => {
1090 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1091 let rs1 = ops[0].id();
1092 let rs2 = ops[1].id();
1093 let imm = ops[2].as_::<Imm>().value() as i32;
1094 inst = inst.set_rs1_p(rs1).set_rs2_p(rs2).set_c_uimm7lohi(imm as _);
1095 } else {
1096 self.last_error = Some(AsmError::InvalidOperand);
1097 return;
1098 }
1099 }
1100
1101 Encoding::Rs1PRs2PCUimm8loCUimm8hi => {
1102 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1103 let rs1 = ops[0].id();
1104 let rs2 = ops[1].id();
1105 let imm = ops[2].as_::<Imm>().value() as i32;
1106 inst = inst.set_rs1_p(rs1).set_rs2_p(rs2).set_c_uimm8lohi(imm as _);
1107 } else {
1108 self.last_error = Some(AsmError::InvalidOperand);
1109 return;
1110 }
1111 }
1112
1113 Encoding::Rs1PRs2PCUimm8hiCUimm8lo => {
1114 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1115 let rs1 = ops[0].id();
1116 let rs2 = ops[1].id();
1117 let imm = ops[2].as_::<Imm>().value() as i32;
1118 inst = inst.set_rs1_p(rs1).set_rs2_p(rs2).set_c_uimm8lohi(imm as _);
1119 } else {
1120 self.last_error = Some(AsmError::InvalidOperand);
1121 return;
1122 }
1123 }
1124
1125 Encoding::Rs1Rd => {
1126 if isign3 == enc_ops2!(Reg, Reg) {
1127 let rd = ops[0].id();
1128 let rs1 = ops[1].id();
1129
1130 inst = inst.set_rd(rd).set_rs1(rs1);
1131 } else {
1132 self.last_error = Some(AsmError::InvalidOperand);
1133 return;
1134 }
1135 }
1136
1137 Encoding::Rs1Rs2 => {
1138 if isign3 == enc_ops2!(Reg, Reg) {
1139 let rs1 = ops[0].id();
1140 let rs2 = ops[1].id();
1141 inst = inst.set_rs1(rs1).set_rs2(rs2);
1142 } else {
1143 self.last_error = Some(AsmError::InvalidOperand);
1144 return;
1145 }
1146 }
1147
1148 Encoding::Rs1Vd => {
1149 if isign3 == enc_ops2!(Reg, Reg) {
1150 let rs1 = ops[1].id();
1151 let vd = ops[0].id();
1152 inst = inst.set_vd(vd).set_rs1(rs1);
1153 } else {
1154 self.last_error = Some(AsmError::InvalidOperand);
1155 return;
1156 }
1157 }
1158 Encoding::Rs1Vs3 => {
1159 if isign3 == enc_ops2!(Reg, Reg) {
1160 let rs1 = ops[1].id();
1161 let vs3 = ops[0].id();
1162 inst = inst.set_rs1(rs1).set_vs3(vs3);
1163 } else {
1164 self.last_error = Some(AsmError::InvalidOperand);
1165 return;
1166 }
1167 }
1168
1169 Encoding::Rs2PRs1PCUimm1 => {
1170 short = true;
1171 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1172 let rs1 = ops[0].id();
1173 let rs2 = ops[1].id();
1174 let imm = ops[2].as_::<Imm>().value() as i32;
1175 inst = inst.set_rs1_p(rs1).set_rs2_p(rs2).set_c_uimm1(imm as _);
1176 } else {
1177 self.last_error = Some(AsmError::InvalidOperand);
1178 return;
1179 }
1180 }
1181
1182 Encoding::Rs2PRs1PCUimm2 => {
1183 short = true;
1184 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1185 let rs1 = ops[0].id();
1186 let rs2 = ops[1].id();
1187 let imm = ops[2].as_::<Imm>().value() as i32;
1188 inst = inst.set_rs1_p(rs1).set_rs2_p(rs2).set_c_uimm2(imm as _);
1189 } else {
1190 self.last_error = Some(AsmError::InvalidOperand);
1191 return;
1192 }
1193 }
1194 Encoding::Rs2Rs1Rd => {
1195 if isign3 == enc_ops3!(Reg, Reg, Reg) {
1196 let rd = ops[0].id();
1197 let rs1 = ops[1].id();
1198 let rs2 = ops[2].id();
1199
1200 inst = inst.set_rd(rd).set_rs1(rs1).set_rs2(rs2);
1201 } else {
1202 self.last_error = Some(AsmError::InvalidOperand);
1203 return;
1204 }
1205 }
1206
1207 Encoding::Simm5Vd => {
1208 if isign3 == enc_ops2!(Reg, Imm) {
1209 let vd = ops[0].id();
1210 let imm = ops[1].as_::<Imm>().value() as i8;
1211 inst = inst.set_vd(vd).set_simm5(imm as _);
1212 } else {
1213 self.last_error = Some(AsmError::InvalidOperand);
1214 return;
1215 }
1216 }
1217
1218 Encoding::VmVs2Rd => {
1219 if isign3 == enc_ops3!(Reg, Reg, Reg) {
1220 let rd = ops[0].id();
1221 let vs2 = ops[1].id();
1222 let vm = ops[2].id();
1223 inst = inst.set_rd(rd).set_vs2(vs2).set_vm(vm);
1224 } else {
1225 self.last_error = Some(AsmError::InvalidOperand);
1226 return;
1227 }
1228 }
1229
1230 Encoding::VmVd => {
1231 if isign3 == enc_ops2!(Reg, Reg) {
1232 let vd = ops[0].id();
1233 let vm = ops[1].id();
1234 inst = inst.set_vd(vd).set_vm(vm);
1235 } else {
1236 self.last_error = Some(AsmError::InvalidOperand);
1237 return;
1238 }
1239 }
1240
1241 Encoding::VmVs2Rs1Vd => {
1242 if isign3 == enc_ops4!(Reg, Reg, Reg, Reg) {
1243 let rs1 = ops[2].id();
1244 let vs2 = ops[1].id();
1245 let vm = ops[3].id();
1246 let vd = ops[0].id();
1247 inst = inst.set_vd(vd).set_vm(vm).set_rs1(rs1).set_vs2(vs2);
1248 } else {
1249 self.last_error = Some(AsmError::InvalidOperand);
1250 return;
1251 }
1252 }
1253
1254 Encoding::VmVs2Simm5Vd => {
1255 if isign3 == enc_ops4!(Reg, Reg, Imm, Reg) {
1256 let simm5 = ops[2].as_::<Imm>().value() as i32;
1257 let vs2 = ops[1].id();
1258 let vm = ops[3].id();
1259 let vd = ops[0].id();
1260 inst = inst.set_vd(vd).set_vm(vm).set_simm5(simm5).set_vs2(vs2);
1261 } else {
1262 self.last_error = Some(AsmError::InvalidOperand);
1263 return;
1264 }
1265 }
1266
1267 Encoding::VmVs2Vd => {
1268 if isign3 == enc_ops3!(Reg, Reg, Reg) {
1269 let vd = ops[0].id();
1270 let vs2 = ops[1].id();
1271 let vm = ops[2].id();
1272
1273 inst = inst.set_vd(vd).set_vs2(vs2).set_vm(vm);
1274 } else {
1275 self.last_error = Some(AsmError::InvalidOperand);
1276 return;
1277 }
1278 }
1279
1280 Encoding::VmVs2Vs1Vd => {
1281 if isign4 == enc_ops4!(Reg, Reg, Reg, Reg) {
1282 let vd = ops[0].id();
1283 let vs1 = ops[1].id();
1284 let vs2 = ops[2].id();
1285 let vm = ops[3].id();
1286 inst = inst.set_vd(vd).set_vs1(vs1).set_vs2(vs2).set_vm(vm);
1287 } else {
1288 self.last_error = Some(AsmError::InvalidOperand);
1289 return;
1290 }
1291 }
1292
1293 Encoding::VmVs2Zimm5Vd => {
1294 if isign4 == enc_ops4!(Reg, Reg, Imm, Reg) {
1295 let vd = ops[0].id();
1296 let vs2 = ops[1].id();
1297 let vm = ops[3].id();
1298 let zimm5 = ops[2].as_::<Imm>().value() as i8;
1299 inst = inst
1300 .set_vd(vd)
1301 .set_vs2(vs2)
1302 .set_vm(vm)
1303 .set_zimm5(zimm5 as _);
1304 } else {
1305 self.last_error = Some(AsmError::InvalidOperand);
1306 return;
1307 }
1308 }
1309
1310 Encoding::Vs1Vd => {
1311 if isign3 == enc_ops2!(Reg, Reg) {
1312 let vd = ops[0].id();
1313 let vs1 = ops[1].id();
1314 inst = inst.set_vd(vd).set_vs1(vs1);
1315 } else {
1316 self.last_error = Some(AsmError::InvalidOperand);
1317 return;
1318 }
1319 }
1320
1321 Encoding::Vs2Rd => {
1322 if isign3 == enc_ops2!(Reg, Reg) {
1323 let rd = ops[0].id();
1324 let vs2 = ops[1].id();
1325 inst = inst.set_rd(rd).set_vs2(vs2);
1326 } else {
1327 self.last_error = Some(AsmError::InvalidOperand);
1328 return;
1329 }
1330 }
1331
1332 Encoding::Vs2Rs1Vd => {
1333 if isign4 == enc_ops3!(Reg, Reg, Reg) {
1334 let rs1 = ops[1].id();
1335 let vs2 = ops[2].id();
1336 let vd = ops[0].id();
1337 inst = inst.set_vd(vd).set_vs2(vs2).set_rs1(rs1);
1338 } else {
1339 self.last_error = Some(AsmError::InvalidOperand);
1340 return;
1341 }
1342 }
1343
1344 Encoding::Vs2Simm5Vd => {
1345 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1346 let vd = ops[0].id();
1347 let vs2 = ops[1].id();
1348 let imm = ops[2].as_::<Imm>().value();
1349
1350 inst = inst.set_vd(vd).set_vs2(vs2).set_simm5(imm as _);
1351 } else {
1352 self.last_error = Some(AsmError::InvalidOperand);
1353 return;
1354 }
1355 }
1356
1357 Encoding::Vs2Vd => {
1358 if isign3 == enc_ops2!(Reg, Reg) {
1359 let vd = ops[0].id();
1360 let vs2 = ops[1].id();
1361 inst = inst.set_vd(vd).set_vs2(vs2);
1362 } else {
1363 self.last_error = Some(AsmError::InvalidOperand);
1364 return;
1365 }
1366 }
1367
1368 Encoding::Vs2Vs1Vd => {
1369 if isign4 == enc_ops3!(Reg, Reg, Reg) {
1370 let vd = ops[0].id();
1371 let vs1 = ops[1].id();
1372 let vs2 = ops[2].id();
1373
1374 inst = inst.set_vd(vd).set_vs1(vs1).set_vs2(vs2);
1375 } else {
1376 self.last_error = Some(AsmError::InvalidOperand);
1377 return;
1378 }
1379 }
1380
1381 Encoding::Vs2Zimm5Vd => {
1382 if isign3 == enc_ops3!(Reg, Imm, Reg) {
1383 let vd = ops[0].id();
1384 let vs2 = ops[1].id();
1385 let zimm5 = ops[2].as_::<Imm>().value() as i8;
1386 inst = inst.set_vd(vd).set_vs2(vs2).set_zimm5(zimm5 as _);
1387 } else {
1388 self.last_error = Some(AsmError::InvalidOperand);
1389 return;
1390 }
1391 }
1392
1393 Encoding::Zimm10ZimmRd => {
1394 if isign3 == enc_ops3!(Reg, Imm, Imm) {
1395 let rd = ops[0].id();
1396 let uimm = ops[1].as_::<Imm>().value() as i8;
1397 let vtypei = ops[2].as_::<Imm>().value() as i8;
1398 inst = inst.set_rd(rd).set_zimm10(vtypei as _).set_zimm(uimm as _);
1399 } else {
1400 self.last_error = Some(AsmError::InvalidOperand);
1401 return;
1402 }
1403 }
1404
1405 Encoding::Zimm11Rs1Rd => {
1406 if isign3 == enc_ops3!(Reg, Reg, Imm) {
1407 let rd = ops[0].id();
1408 let rs1 = ops[1].id();
1409 let imm = ops[2].as_::<Imm>().value() as i32;
1410 inst = inst.set_rd(rd).set_rs1(rs1).set_zimm11(imm);
1411 } else {
1412 self.last_error = Some(AsmError::InvalidOperand);
1413 return;
1414 }
1415 }
1416
1417 Encoding::Zimm6HiVmVs2Zimm6loVd => {
1418 if isign4 == enc_ops4!(Reg, Reg, Imm, Reg) {
1419 let vd = ops[0].id();
1420 let vs2 = ops[1].id();
1421 let imm = ops[2].as_::<Imm>().value();
1422 let vm = ops[3].id();
1423
1424 inst = inst
1425 .set_vd(vd)
1426 .set_vs2(vs2)
1427 .set_zimm6lohi(imm as _)
1428 .set_vm(vm);
1429 } else {
1430 self.last_error = Some(AsmError::InvalidOperand);
1431 return;
1432 }
1433 }
1434 Encoding::RdRs1N0CNzimm6loCNzimm6hi => {
1435 short = true;
1436 if isign3 == enc_ops2!(Reg, Imm) {
1437 let rd = ops[0].id();
1438 let imm = ops[1].as_::<Imm>().value() as i32;
1439 if imm == 0 {
1440 self.last_error = Some(AsmError::InvalidOperand);
1441 return;
1442 } else {
1443 inst = inst.set_rd_n0(rd).set_c_nzimm6lohi(imm);
1444 }
1445 } else {
1446 self.last_error = Some(AsmError::InvalidOperand);
1447 return;
1448 }
1449 }
1450 _ => todo!("unimplemented encoding: {encoding:?}"),
1451 }
1452 let offset = self.buffer.cur_offset();
1453 if let Some((label, kind)) = label_use {
1454 self.buffer
1455 .use_label_at_offset(offset, label.as_::<Label>(), kind);
1456 }
1457
1458 if let Some((sym, kind)) = reloc {
1459 let target = RelocTarget::Sym(sym);
1460 self.buffer.add_reloc_at_offset(offset, kind, target, 0);
1461 }
1462
1463 if short {
1464 self.buffer.put2(inst.value as u16);
1465 } else {
1466 self.buffer.put4(inst.value);
1467 }
1468 }
1469}
1470
1471impl super::emitter::EmitterExplicit for Assembler<'_> {}