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