asmkit/riscv/
assembler.rs

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