1#[cfg(test)]
4mod tests;
5pub mod zve64x_arith_helpers;
6
7use crate::v::vector_registers::VectorRegistersExt;
8use crate::v::zve64x::zve64x_helpers;
9use crate::{
10 ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
11 ProgramCounter, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands, VirtualMemory,
12};
13use ab_riscv_macros::instruction_execution;
14use ab_riscv_primitives::prelude::*;
15use core::fmt;
16use core::ops::ControlFlow;
17
18#[instruction_execution]
19impl<Reg> ExecutableInstructionOperands for Zve64xArithInstruction<Reg> where Reg: Register {}
20
21#[instruction_execution]
22impl<Reg, ExtState, CustomError> ExecutableInstructionCsr<ExtState, CustomError>
23 for Zve64xArithInstruction<Reg>
24where
25 Reg: Register,
26{
27}
28
29#[instruction_execution]
30impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
31 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
32 for Zve64xArithInstruction<Reg>
33where
34 Reg: Register,
35 Regs: RegisterFile<Reg>,
36 ExtState: VectorRegistersExt<Reg, CustomError>,
37 [(); ExtState::ELEN as usize]:,
38 [(); ExtState::VLEN as usize]:,
39 [(); ExtState::VLENB as usize]:,
40 Memory: VirtualMemory,
41 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
42 CustomError: fmt::Debug,
43{
44 #[inline(always)]
45 fn execute(
46 self,
47 Rs1Rs2OperandValues {
48 rs1_value,
49 rs2_value: _,
50 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
51 _regs: &mut Regs,
52 ext_state: &mut ExtState,
53 _memory: &mut Memory,
54 program_counter: &mut PC,
55 _system_instruction_handler: &mut InstructionHandler,
56 ) -> Result<
57 ControlFlow<(), (Self::Reg, <Self::Reg as Register>::Type)>,
58 ExecutionError<Reg::Type, CustomError>,
59 > {
60 match self {
61 Self::VaddVv { vd, vs2, vs1, vm } => {
63 if !ext_state.vector_instructions_allowed() {
64 Err(ExecutionError::IllegalInstruction {
65 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
66 })?;
67 }
68 let vtype = ext_state
69 .vtype()
70 .ok_or(ExecutionError::IllegalInstruction {
71 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
72 })?;
73 let group_regs = vtype.vlmul().register_count();
74 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
75 program_counter,
76 vd,
77 group_regs,
78 )?;
79 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
80 program_counter,
81 vs2,
82 group_regs,
83 )?;
84 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
85 program_counter,
86 vs1,
87 group_regs,
88 )?;
89 if !vm && vd.bits() == 0 {
90 Err(ExecutionError::IllegalInstruction {
91 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
92 })?;
93 }
94 let sew = vtype.vsew();
95 let vl = ext_state.vl();
96 let vstart = u32::from(ext_state.vstart());
97 unsafe {
100 zve64x_arith_helpers::execute_arith_op(
101 ext_state,
102 vd,
103 vs2,
104 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
105 vm,
106 vl,
107 vstart,
108 sew,
109 |a, b, _| a.wrapping_add(b),
110 );
111 }
112 }
113 Self::VaddVx {
114 vd,
115 vs2,
116 rs1: _,
117 vm,
118 } => {
119 if !ext_state.vector_instructions_allowed() {
120 Err(ExecutionError::IllegalInstruction {
121 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
122 })?;
123 }
124 let vtype = ext_state
125 .vtype()
126 .ok_or(ExecutionError::IllegalInstruction {
127 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
128 })?;
129 let group_regs = vtype.vlmul().register_count();
130 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
131 program_counter,
132 vd,
133 group_regs,
134 )?;
135 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
136 program_counter,
137 vs2,
138 group_regs,
139 )?;
140 if !vm && vd.bits() == 0 {
141 Err(ExecutionError::IllegalInstruction {
142 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
143 })?;
144 }
145 let sew = vtype.vsew();
146 let vl = ext_state.vl();
147 let vstart = u32::from(ext_state.vstart());
148 let scalar = rs1_value.as_u64();
149 unsafe {
151 zve64x_arith_helpers::execute_arith_op(
152 ext_state,
153 vd,
154 vs2,
155 zve64x_arith_helpers::OpSrc::Scalar(scalar),
156 vm,
157 vl,
158 vstart,
159 sew,
160 |a, b, _| a.wrapping_add(b),
161 );
162 }
163 }
164 Self::VaddVi { vd, vs2, imm, vm } => {
165 if !ext_state.vector_instructions_allowed() {
166 Err(ExecutionError::IllegalInstruction {
167 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
168 })?;
169 }
170 let vtype = ext_state
171 .vtype()
172 .ok_or(ExecutionError::IllegalInstruction {
173 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
174 })?;
175 let group_regs = vtype.vlmul().register_count();
176 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
177 program_counter,
178 vd,
179 group_regs,
180 )?;
181 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
182 program_counter,
183 vs2,
184 group_regs,
185 )?;
186 if !vm && vd.bits() == 0 {
187 Err(ExecutionError::IllegalInstruction {
188 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
189 })?;
190 }
191 let sew = vtype.vsew();
192 let vl = ext_state.vl();
193 let vstart = u32::from(ext_state.vstart());
194 let scalar = i64::from(imm).cast_unsigned();
196 unsafe {
198 zve64x_arith_helpers::execute_arith_op(
199 ext_state,
200 vd,
201 vs2,
202 zve64x_arith_helpers::OpSrc::Scalar(scalar),
203 vm,
204 vl,
205 vstart,
206 sew,
207 |a, b, _| a.wrapping_add(b),
208 );
209 }
210 }
211 Self::VsubVv { vd, vs2, vs1, vm } => {
213 if !ext_state.vector_instructions_allowed() {
214 Err(ExecutionError::IllegalInstruction {
215 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
216 })?;
217 }
218 let vtype = ext_state
219 .vtype()
220 .ok_or(ExecutionError::IllegalInstruction {
221 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
222 })?;
223 let group_regs = vtype.vlmul().register_count();
224 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
225 program_counter,
226 vd,
227 group_regs,
228 )?;
229 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
230 program_counter,
231 vs2,
232 group_regs,
233 )?;
234 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
235 program_counter,
236 vs1,
237 group_regs,
238 )?;
239 if !vm && vd.bits() == 0 {
240 Err(ExecutionError::IllegalInstruction {
241 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
242 })?;
243 }
244 let sew = vtype.vsew();
245 let vl = ext_state.vl();
246 let vstart = u32::from(ext_state.vstart());
247 unsafe {
249 zve64x_arith_helpers::execute_arith_op(
250 ext_state,
251 vd,
252 vs2,
253 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
254 vm,
255 vl,
256 vstart,
257 sew,
258 |a, b, _| a.wrapping_sub(b),
259 );
260 }
261 }
262 Self::VsubVx {
263 vd,
264 vs2,
265 rs1: _,
266 vm,
267 } => {
268 if !ext_state.vector_instructions_allowed() {
269 Err(ExecutionError::IllegalInstruction {
270 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
271 })?;
272 }
273 let vtype = ext_state
274 .vtype()
275 .ok_or(ExecutionError::IllegalInstruction {
276 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
277 })?;
278 let group_regs = vtype.vlmul().register_count();
279 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
280 program_counter,
281 vd,
282 group_regs,
283 )?;
284 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
285 program_counter,
286 vs2,
287 group_regs,
288 )?;
289 if !vm && vd.bits() == 0 {
290 Err(ExecutionError::IllegalInstruction {
291 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
292 })?;
293 }
294 let sew = vtype.vsew();
295 let vl = ext_state.vl();
296 let vstart = u32::from(ext_state.vstart());
297 let scalar = rs1_value.as_u64();
298 unsafe {
300 zve64x_arith_helpers::execute_arith_op(
301 ext_state,
302 vd,
303 vs2,
304 zve64x_arith_helpers::OpSrc::Scalar(scalar),
305 vm,
306 vl,
307 vstart,
308 sew,
309 |a, b, _| a.wrapping_sub(b),
310 );
311 }
312 }
313 Self::VrsubVx {
314 vd,
315 vs2,
316 rs1: _,
317 vm,
318 } => {
319 if !ext_state.vector_instructions_allowed() {
320 Err(ExecutionError::IllegalInstruction {
321 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
322 })?;
323 }
324 let vtype = ext_state
325 .vtype()
326 .ok_or(ExecutionError::IllegalInstruction {
327 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
328 })?;
329 let group_regs = vtype.vlmul().register_count();
330 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
331 program_counter,
332 vd,
333 group_regs,
334 )?;
335 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
336 program_counter,
337 vs2,
338 group_regs,
339 )?;
340 if !vm && vd.bits() == 0 {
341 Err(ExecutionError::IllegalInstruction {
342 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
343 })?;
344 }
345 let sew = vtype.vsew();
346 let vl = ext_state.vl();
347 let vstart = u32::from(ext_state.vstart());
348 let scalar = rs1_value.as_u64();
349 unsafe {
352 zve64x_arith_helpers::execute_arith_op(
353 ext_state,
354 vd,
355 vs2,
356 zve64x_arith_helpers::OpSrc::Scalar(scalar),
357 vm,
358 vl,
359 vstart,
360 sew,
361 |a, b, _| b.wrapping_sub(a),
362 );
363 }
364 }
365 Self::VrsubVi { vd, vs2, imm, vm } => {
366 if !ext_state.vector_instructions_allowed() {
367 Err(ExecutionError::IllegalInstruction {
368 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
369 })?;
370 }
371 let vtype = ext_state
372 .vtype()
373 .ok_or(ExecutionError::IllegalInstruction {
374 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
375 })?;
376 let group_regs = vtype.vlmul().register_count();
377 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
378 program_counter,
379 vd,
380 group_regs,
381 )?;
382 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
383 program_counter,
384 vs2,
385 group_regs,
386 )?;
387 if !vm && vd.bits() == 0 {
388 Err(ExecutionError::IllegalInstruction {
389 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
390 })?;
391 }
392 let sew = vtype.vsew();
393 let vl = ext_state.vl();
394 let vstart = u32::from(ext_state.vstart());
395 let scalar = i64::from(imm).cast_unsigned();
396 unsafe {
398 zve64x_arith_helpers::execute_arith_op(
399 ext_state,
400 vd,
401 vs2,
402 zve64x_arith_helpers::OpSrc::Scalar(scalar),
403 vm,
404 vl,
405 vstart,
406 sew,
407 |a, b, _| b.wrapping_sub(a),
408 );
409 }
410 }
411 Self::VandVv { vd, vs2, vs1, vm } => {
413 if !ext_state.vector_instructions_allowed() {
414 Err(ExecutionError::IllegalInstruction {
415 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
416 })?;
417 }
418 let vtype = ext_state
419 .vtype()
420 .ok_or(ExecutionError::IllegalInstruction {
421 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
422 })?;
423 let group_regs = vtype.vlmul().register_count();
424 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
425 program_counter,
426 vd,
427 group_regs,
428 )?;
429 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
430 program_counter,
431 vs2,
432 group_regs,
433 )?;
434 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
435 program_counter,
436 vs1,
437 group_regs,
438 )?;
439 if !vm && vd.bits() == 0 {
440 Err(ExecutionError::IllegalInstruction {
441 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
442 })?;
443 }
444 let sew = vtype.vsew();
445 let vl = ext_state.vl();
446 let vstart = u32::from(ext_state.vstart());
447 unsafe {
449 zve64x_arith_helpers::execute_arith_op(
450 ext_state,
451 vd,
452 vs2,
453 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
454 vm,
455 vl,
456 vstart,
457 sew,
458 |a, b, _| a & b,
459 );
460 }
461 }
462 Self::VandVx {
463 vd,
464 vs2,
465 rs1: _,
466 vm,
467 } => {
468 if !ext_state.vector_instructions_allowed() {
469 Err(ExecutionError::IllegalInstruction {
470 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
471 })?;
472 }
473 let vtype = ext_state
474 .vtype()
475 .ok_or(ExecutionError::IllegalInstruction {
476 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
477 })?;
478 let group_regs = vtype.vlmul().register_count();
479 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
480 program_counter,
481 vd,
482 group_regs,
483 )?;
484 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
485 program_counter,
486 vs2,
487 group_regs,
488 )?;
489 if !vm && vd.bits() == 0 {
490 Err(ExecutionError::IllegalInstruction {
491 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
492 })?;
493 }
494 let sew = vtype.vsew();
495 let vl = ext_state.vl();
496 let vstart = u32::from(ext_state.vstart());
497 let scalar = rs1_value.as_u64();
498 unsafe {
500 zve64x_arith_helpers::execute_arith_op(
501 ext_state,
502 vd,
503 vs2,
504 zve64x_arith_helpers::OpSrc::Scalar(scalar),
505 vm,
506 vl,
507 vstart,
508 sew,
509 |a, b, _| a & b,
510 );
511 }
512 }
513 Self::VandVi { vd, vs2, imm, vm } => {
514 if !ext_state.vector_instructions_allowed() {
515 Err(ExecutionError::IllegalInstruction {
516 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
517 })?;
518 }
519 let vtype = ext_state
520 .vtype()
521 .ok_or(ExecutionError::IllegalInstruction {
522 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
523 })?;
524 let group_regs = vtype.vlmul().register_count();
525 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
526 program_counter,
527 vd,
528 group_regs,
529 )?;
530 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
531 program_counter,
532 vs2,
533 group_regs,
534 )?;
535 if !vm && vd.bits() == 0 {
536 Err(ExecutionError::IllegalInstruction {
537 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
538 })?;
539 }
540 let sew = vtype.vsew();
541 let vl = ext_state.vl();
542 let vstart = u32::from(ext_state.vstart());
543 let scalar = i64::from(imm).cast_unsigned();
544 unsafe {
546 zve64x_arith_helpers::execute_arith_op(
547 ext_state,
548 vd,
549 vs2,
550 zve64x_arith_helpers::OpSrc::Scalar(scalar),
551 vm,
552 vl,
553 vstart,
554 sew,
555 |a, b, _| a & b,
556 );
557 }
558 }
559 Self::VorVv { vd, vs2, vs1, vm } => {
561 if !ext_state.vector_instructions_allowed() {
562 Err(ExecutionError::IllegalInstruction {
563 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
564 })?;
565 }
566 let vtype = ext_state
567 .vtype()
568 .ok_or(ExecutionError::IllegalInstruction {
569 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
570 })?;
571 let group_regs = vtype.vlmul().register_count();
572 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
573 program_counter,
574 vd,
575 group_regs,
576 )?;
577 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
578 program_counter,
579 vs2,
580 group_regs,
581 )?;
582 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
583 program_counter,
584 vs1,
585 group_regs,
586 )?;
587 if !vm && vd.bits() == 0 {
588 Err(ExecutionError::IllegalInstruction {
589 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
590 })?;
591 }
592 let sew = vtype.vsew();
593 let vl = ext_state.vl();
594 let vstart = u32::from(ext_state.vstart());
595 unsafe {
597 zve64x_arith_helpers::execute_arith_op(
598 ext_state,
599 vd,
600 vs2,
601 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
602 vm,
603 vl,
604 vstart,
605 sew,
606 |a, b, _| a | b,
607 );
608 }
609 }
610 Self::VorVx {
611 vd,
612 vs2,
613 rs1: _,
614 vm,
615 } => {
616 if !ext_state.vector_instructions_allowed() {
617 Err(ExecutionError::IllegalInstruction {
618 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
619 })?;
620 }
621 let vtype = ext_state
622 .vtype()
623 .ok_or(ExecutionError::IllegalInstruction {
624 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
625 })?;
626 let group_regs = vtype.vlmul().register_count();
627 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
628 program_counter,
629 vd,
630 group_regs,
631 )?;
632 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
633 program_counter,
634 vs2,
635 group_regs,
636 )?;
637 if !vm && vd.bits() == 0 {
638 Err(ExecutionError::IllegalInstruction {
639 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
640 })?;
641 }
642 let sew = vtype.vsew();
643 let vl = ext_state.vl();
644 let vstart = u32::from(ext_state.vstart());
645 let scalar = rs1_value.as_u64();
646 unsafe {
648 zve64x_arith_helpers::execute_arith_op(
649 ext_state,
650 vd,
651 vs2,
652 zve64x_arith_helpers::OpSrc::Scalar(scalar),
653 vm,
654 vl,
655 vstart,
656 sew,
657 |a, b, _| a | b,
658 );
659 }
660 }
661 Self::VorVi { vd, vs2, imm, vm } => {
662 if !ext_state.vector_instructions_allowed() {
663 Err(ExecutionError::IllegalInstruction {
664 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
665 })?;
666 }
667 let vtype = ext_state
668 .vtype()
669 .ok_or(ExecutionError::IllegalInstruction {
670 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
671 })?;
672 let group_regs = vtype.vlmul().register_count();
673 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
674 program_counter,
675 vd,
676 group_regs,
677 )?;
678 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
679 program_counter,
680 vs2,
681 group_regs,
682 )?;
683 if !vm && vd.bits() == 0 {
684 Err(ExecutionError::IllegalInstruction {
685 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
686 })?;
687 }
688 let sew = vtype.vsew();
689 let vl = ext_state.vl();
690 let vstart = u32::from(ext_state.vstart());
691 let scalar = i64::from(imm).cast_unsigned();
692 unsafe {
694 zve64x_arith_helpers::execute_arith_op(
695 ext_state,
696 vd,
697 vs2,
698 zve64x_arith_helpers::OpSrc::Scalar(scalar),
699 vm,
700 vl,
701 vstart,
702 sew,
703 |a, b, _| a | b,
704 );
705 }
706 }
707 Self::VxorVv { vd, vs2, vs1, vm } => {
709 if !ext_state.vector_instructions_allowed() {
710 Err(ExecutionError::IllegalInstruction {
711 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
712 })?;
713 }
714 let vtype = ext_state
715 .vtype()
716 .ok_or(ExecutionError::IllegalInstruction {
717 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
718 })?;
719 let group_regs = vtype.vlmul().register_count();
720 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
721 program_counter,
722 vd,
723 group_regs,
724 )?;
725 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
726 program_counter,
727 vs2,
728 group_regs,
729 )?;
730 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
731 program_counter,
732 vs1,
733 group_regs,
734 )?;
735 if !vm && vd.bits() == 0 {
736 Err(ExecutionError::IllegalInstruction {
737 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
738 })?;
739 }
740 let sew = vtype.vsew();
741 let vl = ext_state.vl();
742 let vstart = u32::from(ext_state.vstart());
743 unsafe {
745 zve64x_arith_helpers::execute_arith_op(
746 ext_state,
747 vd,
748 vs2,
749 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
750 vm,
751 vl,
752 vstart,
753 sew,
754 |a, b, _| a ^ b,
755 );
756 }
757 }
758 Self::VxorVx {
759 vd,
760 vs2,
761 rs1: _,
762 vm,
763 } => {
764 if !ext_state.vector_instructions_allowed() {
765 Err(ExecutionError::IllegalInstruction {
766 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
767 })?;
768 }
769 let vtype = ext_state
770 .vtype()
771 .ok_or(ExecutionError::IllegalInstruction {
772 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
773 })?;
774 let group_regs = vtype.vlmul().register_count();
775 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
776 program_counter,
777 vd,
778 group_regs,
779 )?;
780 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
781 program_counter,
782 vs2,
783 group_regs,
784 )?;
785 if !vm && vd.bits() == 0 {
786 Err(ExecutionError::IllegalInstruction {
787 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
788 })?;
789 }
790 let sew = vtype.vsew();
791 let vl = ext_state.vl();
792 let vstart = u32::from(ext_state.vstart());
793 let scalar = rs1_value.as_u64();
794 unsafe {
796 zve64x_arith_helpers::execute_arith_op(
797 ext_state,
798 vd,
799 vs2,
800 zve64x_arith_helpers::OpSrc::Scalar(scalar),
801 vm,
802 vl,
803 vstart,
804 sew,
805 |a, b, _| a ^ b,
806 );
807 }
808 }
809 Self::VxorVi { vd, vs2, imm, vm } => {
810 if !ext_state.vector_instructions_allowed() {
811 Err(ExecutionError::IllegalInstruction {
812 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
813 })?;
814 }
815 let vtype = ext_state
816 .vtype()
817 .ok_or(ExecutionError::IllegalInstruction {
818 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
819 })?;
820 let group_regs = vtype.vlmul().register_count();
821 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
822 program_counter,
823 vd,
824 group_regs,
825 )?;
826 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
827 program_counter,
828 vs2,
829 group_regs,
830 )?;
831 if !vm && vd.bits() == 0 {
832 Err(ExecutionError::IllegalInstruction {
833 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
834 })?;
835 }
836 let sew = vtype.vsew();
837 let vl = ext_state.vl();
838 let vstart = u32::from(ext_state.vstart());
839 let scalar = i64::from(imm).cast_unsigned();
840 unsafe {
842 zve64x_arith_helpers::execute_arith_op(
843 ext_state,
844 vd,
845 vs2,
846 zve64x_arith_helpers::OpSrc::Scalar(scalar),
847 vm,
848 vl,
849 vstart,
850 sew,
851 |a, b, _| a ^ b,
852 );
853 }
854 }
855 Self::VsllVv { vd, vs2, vs1, vm } => {
857 if !ext_state.vector_instructions_allowed() {
858 Err(ExecutionError::IllegalInstruction {
859 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
860 })?;
861 }
862 let vtype = ext_state
863 .vtype()
864 .ok_or(ExecutionError::IllegalInstruction {
865 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
866 })?;
867 let group_regs = vtype.vlmul().register_count();
868 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
869 program_counter,
870 vd,
871 group_regs,
872 )?;
873 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
874 program_counter,
875 vs2,
876 group_regs,
877 )?;
878 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
879 program_counter,
880 vs1,
881 group_regs,
882 )?;
883 if !vm && vd.bits() == 0 {
884 Err(ExecutionError::IllegalInstruction {
885 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
886 })?;
887 }
888 let sew = vtype.vsew();
889 let vl = ext_state.vl();
890 let vstart = u32::from(ext_state.vstart());
891 unsafe {
893 zve64x_arith_helpers::execute_arith_op(
894 ext_state,
895 vd,
896 vs2,
897 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
898 vm,
899 vl,
900 vstart,
901 sew,
902 |a, b, sew| a << (b & u64::from(sew.bits() - 1)),
904 );
905 }
906 }
907 Self::VsllVx {
908 vd,
909 vs2,
910 rs1: _,
911 vm,
912 } => {
913 if !ext_state.vector_instructions_allowed() {
914 Err(ExecutionError::IllegalInstruction {
915 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
916 })?;
917 }
918 let vtype = ext_state
919 .vtype()
920 .ok_or(ExecutionError::IllegalInstruction {
921 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
922 })?;
923 let group_regs = vtype.vlmul().register_count();
924 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
925 program_counter,
926 vd,
927 group_regs,
928 )?;
929 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
930 program_counter,
931 vs2,
932 group_regs,
933 )?;
934 if !vm && vd.bits() == 0 {
935 Err(ExecutionError::IllegalInstruction {
936 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
937 })?;
938 }
939 let sew = vtype.vsew();
940 let vl = ext_state.vl();
941 let vstart = u32::from(ext_state.vstart());
942 let scalar = rs1_value.as_u64();
943 unsafe {
945 zve64x_arith_helpers::execute_arith_op(
946 ext_state,
947 vd,
948 vs2,
949 zve64x_arith_helpers::OpSrc::Scalar(scalar),
950 vm,
951 vl,
952 vstart,
953 sew,
954 |a, b, sew| a << (b & u64::from(sew.bits() - 1)),
955 );
956 }
957 }
958 Self::VsllVi { vd, vs2, uimm, vm } => {
959 if !ext_state.vector_instructions_allowed() {
960 Err(ExecutionError::IllegalInstruction {
961 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
962 })?;
963 }
964 let vtype = ext_state
965 .vtype()
966 .ok_or(ExecutionError::IllegalInstruction {
967 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
968 })?;
969 let group_regs = vtype.vlmul().register_count();
970 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
971 program_counter,
972 vd,
973 group_regs,
974 )?;
975 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
976 program_counter,
977 vs2,
978 group_regs,
979 )?;
980 if !vm && vd.bits() == 0 {
981 Err(ExecutionError::IllegalInstruction {
982 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
983 })?;
984 }
985 let sew = vtype.vsew();
986 let vl = ext_state.vl();
987 let vstart = u32::from(ext_state.vstart());
988 let shamt = u64::from(uimm) & u64::from(sew.bits() - 1);
990 unsafe {
992 zve64x_arith_helpers::execute_arith_op(
993 ext_state,
994 vd,
995 vs2,
996 zve64x_arith_helpers::OpSrc::Scalar(shamt),
997 vm,
998 vl,
999 vstart,
1000 sew,
1001 |a, b, _| a << b,
1002 );
1003 }
1004 }
1005 Self::VsrlVv { vd, vs2, vs1, vm } => {
1007 if !ext_state.vector_instructions_allowed() {
1008 Err(ExecutionError::IllegalInstruction {
1009 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1010 })?;
1011 }
1012 let vtype = ext_state
1013 .vtype()
1014 .ok_or(ExecutionError::IllegalInstruction {
1015 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1016 })?;
1017 let group_regs = vtype.vlmul().register_count();
1018 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1019 program_counter,
1020 vd,
1021 group_regs,
1022 )?;
1023 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1024 program_counter,
1025 vs2,
1026 group_regs,
1027 )?;
1028 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1029 program_counter,
1030 vs1,
1031 group_regs,
1032 )?;
1033 if !vm && vd.bits() == 0 {
1034 Err(ExecutionError::IllegalInstruction {
1035 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1036 })?;
1037 }
1038 let sew = vtype.vsew();
1039 let vl = ext_state.vl();
1040 let vstart = u32::from(ext_state.vstart());
1041 unsafe {
1043 zve64x_arith_helpers::execute_arith_op(
1044 ext_state,
1045 vd,
1046 vs2,
1047 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
1048 vm,
1049 vl,
1050 vstart,
1051 sew,
1052 |a, b, sew| {
1054 let mask = zve64x_arith_helpers::sew_mask(sew);
1055 let shamt = b & u64::from(sew.bits() - 1);
1056 (a & mask) >> shamt
1057 },
1058 );
1059 }
1060 }
1061 Self::VsrlVx {
1062 vd,
1063 vs2,
1064 rs1: _,
1065 vm,
1066 } => {
1067 if !ext_state.vector_instructions_allowed() {
1068 Err(ExecutionError::IllegalInstruction {
1069 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1070 })?;
1071 }
1072 let vtype = ext_state
1073 .vtype()
1074 .ok_or(ExecutionError::IllegalInstruction {
1075 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1076 })?;
1077 let group_regs = vtype.vlmul().register_count();
1078 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1079 program_counter,
1080 vd,
1081 group_regs,
1082 )?;
1083 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1084 program_counter,
1085 vs2,
1086 group_regs,
1087 )?;
1088 if !vm && vd.bits() == 0 {
1089 Err(ExecutionError::IllegalInstruction {
1090 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1091 })?;
1092 }
1093 let sew = vtype.vsew();
1094 let vl = ext_state.vl();
1095 let vstart = u32::from(ext_state.vstart());
1096 let scalar = rs1_value.as_u64();
1097 unsafe {
1099 zve64x_arith_helpers::execute_arith_op(
1100 ext_state,
1101 vd,
1102 vs2,
1103 zve64x_arith_helpers::OpSrc::Scalar(scalar),
1104 vm,
1105 vl,
1106 vstart,
1107 sew,
1108 |a, b, sew| {
1109 let mask = zve64x_arith_helpers::sew_mask(sew);
1110 let shamt = b & u64::from(sew.bits() - 1);
1111 (a & mask) >> shamt
1112 },
1113 );
1114 }
1115 }
1116 Self::VsrlVi { vd, vs2, uimm, vm } => {
1117 if !ext_state.vector_instructions_allowed() {
1118 Err(ExecutionError::IllegalInstruction {
1119 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1120 })?;
1121 }
1122 let vtype = ext_state
1123 .vtype()
1124 .ok_or(ExecutionError::IllegalInstruction {
1125 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1126 })?;
1127 let group_regs = vtype.vlmul().register_count();
1128 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1129 program_counter,
1130 vd,
1131 group_regs,
1132 )?;
1133 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1134 program_counter,
1135 vs2,
1136 group_regs,
1137 )?;
1138 if !vm && vd.bits() == 0 {
1139 Err(ExecutionError::IllegalInstruction {
1140 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1141 })?;
1142 }
1143 let sew = vtype.vsew();
1144 let vl = ext_state.vl();
1145 let vstart = u32::from(ext_state.vstart());
1146 let shamt = u64::from(uimm) & u64::from(sew.bits() - 1);
1147 unsafe {
1149 zve64x_arith_helpers::execute_arith_op(
1150 ext_state,
1151 vd,
1152 vs2,
1153 zve64x_arith_helpers::OpSrc::Scalar(shamt),
1154 vm,
1155 vl,
1156 vstart,
1157 sew,
1158 |a, b, sew| (a & zve64x_arith_helpers::sew_mask(sew)) >> b,
1159 );
1160 }
1161 }
1162 Self::VsraVv { vd, vs2, vs1, vm } => {
1164 if !ext_state.vector_instructions_allowed() {
1165 Err(ExecutionError::IllegalInstruction {
1166 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1167 })?;
1168 }
1169 let vtype = ext_state
1170 .vtype()
1171 .ok_or(ExecutionError::IllegalInstruction {
1172 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1173 })?;
1174 let group_regs = vtype.vlmul().register_count();
1175 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1176 program_counter,
1177 vd,
1178 group_regs,
1179 )?;
1180 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1181 program_counter,
1182 vs2,
1183 group_regs,
1184 )?;
1185 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1186 program_counter,
1187 vs1,
1188 group_regs,
1189 )?;
1190 if !vm && vd.bits() == 0 {
1191 Err(ExecutionError::IllegalInstruction {
1192 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1193 })?;
1194 }
1195 let sew = vtype.vsew();
1196 let vl = ext_state.vl();
1197 let vstart = u32::from(ext_state.vstart());
1198 unsafe {
1200 zve64x_arith_helpers::execute_arith_op(
1201 ext_state,
1202 vd,
1203 vs2,
1204 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
1205 vm,
1206 vl,
1207 vstart,
1208 sew,
1209 |a, b, sew| {
1210 let shamt = b & u64::from(sew.bits() - 1);
1211 let signed = zve64x_arith_helpers::sign_extend(a, sew);
1212 (signed >> shamt).cast_unsigned()
1213 },
1214 );
1215 }
1216 }
1217 Self::VsraVx {
1218 vd,
1219 vs2,
1220 rs1: _,
1221 vm,
1222 } => {
1223 if !ext_state.vector_instructions_allowed() {
1224 Err(ExecutionError::IllegalInstruction {
1225 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1226 })?;
1227 }
1228 let vtype = ext_state
1229 .vtype()
1230 .ok_or(ExecutionError::IllegalInstruction {
1231 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1232 })?;
1233 let group_regs = vtype.vlmul().register_count();
1234 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1235 program_counter,
1236 vd,
1237 group_regs,
1238 )?;
1239 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1240 program_counter,
1241 vs2,
1242 group_regs,
1243 )?;
1244 if !vm && vd.bits() == 0 {
1245 Err(ExecutionError::IllegalInstruction {
1246 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1247 })?;
1248 }
1249 let sew = vtype.vsew();
1250 let vl = ext_state.vl();
1251 let vstart = u32::from(ext_state.vstart());
1252 let scalar = rs1_value.as_u64();
1253 unsafe {
1255 zve64x_arith_helpers::execute_arith_op(
1256 ext_state,
1257 vd,
1258 vs2,
1259 zve64x_arith_helpers::OpSrc::Scalar(scalar),
1260 vm,
1261 vl,
1262 vstart,
1263 sew,
1264 |a, b, sew| {
1265 let shamt = b & u64::from(sew.bits() - 1);
1266 let signed = zve64x_arith_helpers::sign_extend(a, sew);
1267 (signed >> shamt).cast_unsigned()
1268 },
1269 );
1270 }
1271 }
1272 Self::VsraVi { vd, vs2, uimm, vm } => {
1273 if !ext_state.vector_instructions_allowed() {
1274 Err(ExecutionError::IllegalInstruction {
1275 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1276 })?;
1277 }
1278 let vtype = ext_state
1279 .vtype()
1280 .ok_or(ExecutionError::IllegalInstruction {
1281 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1282 })?;
1283 let group_regs = vtype.vlmul().register_count();
1284 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1285 program_counter,
1286 vd,
1287 group_regs,
1288 )?;
1289 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1290 program_counter,
1291 vs2,
1292 group_regs,
1293 )?;
1294 if !vm && vd.bits() == 0 {
1295 Err(ExecutionError::IllegalInstruction {
1296 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1297 })?;
1298 }
1299 let sew = vtype.vsew();
1300 let vl = ext_state.vl();
1301 let vstart = u32::from(ext_state.vstart());
1302 let shamt = u64::from(uimm) & u64::from(sew.bits() - 1);
1303 unsafe {
1305 zve64x_arith_helpers::execute_arith_op(
1306 ext_state,
1307 vd,
1308 vs2,
1309 zve64x_arith_helpers::OpSrc::Scalar(shamt),
1310 vm,
1311 vl,
1312 vstart,
1313 sew,
1314 |a, b, sew| {
1315 let signed = zve64x_arith_helpers::sign_extend(a, sew);
1316 (signed >> b).cast_unsigned()
1317 },
1318 );
1319 }
1320 }
1321 Self::VminuVv { vd, vs2, vs1, vm } => {
1323 if !ext_state.vector_instructions_allowed() {
1324 Err(ExecutionError::IllegalInstruction {
1325 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1326 })?;
1327 }
1328 let vtype = ext_state
1329 .vtype()
1330 .ok_or(ExecutionError::IllegalInstruction {
1331 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1332 })?;
1333 let group_regs = vtype.vlmul().register_count();
1334 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1335 program_counter,
1336 vd,
1337 group_regs,
1338 )?;
1339 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1340 program_counter,
1341 vs2,
1342 group_regs,
1343 )?;
1344 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1345 program_counter,
1346 vs1,
1347 group_regs,
1348 )?;
1349 if !vm && vd.bits() == 0 {
1350 Err(ExecutionError::IllegalInstruction {
1351 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1352 })?;
1353 }
1354 let sew = vtype.vsew();
1355 let vl = ext_state.vl();
1356 let vstart = u32::from(ext_state.vstart());
1357 unsafe {
1359 zve64x_arith_helpers::execute_arith_op(
1360 ext_state,
1361 vd,
1362 vs2,
1363 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
1364 vm,
1365 vl,
1366 vstart,
1367 sew,
1368 |a, b, sew| {
1369 let mask = zve64x_arith_helpers::sew_mask(sew);
1370 if a & mask <= b & mask { a } else { b }
1371 },
1372 );
1373 }
1374 }
1375 Self::VminuVx {
1376 vd,
1377 vs2,
1378 rs1: _,
1379 vm,
1380 } => {
1381 if !ext_state.vector_instructions_allowed() {
1382 Err(ExecutionError::IllegalInstruction {
1383 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1384 })?;
1385 }
1386 let vtype = ext_state
1387 .vtype()
1388 .ok_or(ExecutionError::IllegalInstruction {
1389 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1390 })?;
1391 let group_regs = vtype.vlmul().register_count();
1392 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1393 program_counter,
1394 vd,
1395 group_regs,
1396 )?;
1397 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1398 program_counter,
1399 vs2,
1400 group_regs,
1401 )?;
1402 if !vm && vd.bits() == 0 {
1403 Err(ExecutionError::IllegalInstruction {
1404 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1405 })?;
1406 }
1407 let sew = vtype.vsew();
1408 let vl = ext_state.vl();
1409 let vstart = u32::from(ext_state.vstart());
1410 let scalar = rs1_value.as_u64();
1411 unsafe {
1413 zve64x_arith_helpers::execute_arith_op(
1414 ext_state,
1415 vd,
1416 vs2,
1417 zve64x_arith_helpers::OpSrc::Scalar(scalar),
1418 vm,
1419 vl,
1420 vstart,
1421 sew,
1422 |a, b, sew| {
1423 let mask = zve64x_arith_helpers::sew_mask(sew);
1424 if a & mask <= b & mask { a } else { b }
1425 },
1426 );
1427 }
1428 }
1429 Self::VminVv { vd, vs2, vs1, vm } => {
1430 if !ext_state.vector_instructions_allowed() {
1431 Err(ExecutionError::IllegalInstruction {
1432 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1433 })?;
1434 }
1435 let vtype = ext_state
1436 .vtype()
1437 .ok_or(ExecutionError::IllegalInstruction {
1438 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1439 })?;
1440 let group_regs = vtype.vlmul().register_count();
1441 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1442 program_counter,
1443 vd,
1444 group_regs,
1445 )?;
1446 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1447 program_counter,
1448 vs2,
1449 group_regs,
1450 )?;
1451 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1452 program_counter,
1453 vs1,
1454 group_regs,
1455 )?;
1456 if !vm && vd.bits() == 0 {
1457 Err(ExecutionError::IllegalInstruction {
1458 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1459 })?;
1460 }
1461 let sew = vtype.vsew();
1462 let vl = ext_state.vl();
1463 let vstart = u32::from(ext_state.vstart());
1464 unsafe {
1466 zve64x_arith_helpers::execute_arith_op(
1467 ext_state,
1468 vd,
1469 vs2,
1470 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
1471 vm,
1472 vl,
1473 vstart,
1474 sew,
1475 |a, b, sew| {
1476 if zve64x_arith_helpers::sign_extend(a, sew)
1477 <= zve64x_arith_helpers::sign_extend(b, sew)
1478 {
1479 a
1480 } else {
1481 b
1482 }
1483 },
1484 );
1485 }
1486 }
1487 Self::VminVx {
1488 vd,
1489 vs2,
1490 rs1: _,
1491 vm,
1492 } => {
1493 if !ext_state.vector_instructions_allowed() {
1494 Err(ExecutionError::IllegalInstruction {
1495 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1496 })?;
1497 }
1498 let vtype = ext_state
1499 .vtype()
1500 .ok_or(ExecutionError::IllegalInstruction {
1501 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1502 })?;
1503 let group_regs = vtype.vlmul().register_count();
1504 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1505 program_counter,
1506 vd,
1507 group_regs,
1508 )?;
1509 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1510 program_counter,
1511 vs2,
1512 group_regs,
1513 )?;
1514 if !vm && vd.bits() == 0 {
1515 Err(ExecutionError::IllegalInstruction {
1516 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1517 })?;
1518 }
1519 let sew = vtype.vsew();
1520 let vl = ext_state.vl();
1521 let vstart = u32::from(ext_state.vstart());
1522 let scalar = rs1_value.as_u64();
1523 unsafe {
1525 zve64x_arith_helpers::execute_arith_op(
1526 ext_state,
1527 vd,
1528 vs2,
1529 zve64x_arith_helpers::OpSrc::Scalar(scalar),
1530 vm,
1531 vl,
1532 vstart,
1533 sew,
1534 |a, b, sew| {
1535 if zve64x_arith_helpers::sign_extend(a, sew)
1536 <= zve64x_arith_helpers::sign_extend(b, sew)
1537 {
1538 a
1539 } else {
1540 b
1541 }
1542 },
1543 );
1544 }
1545 }
1546 Self::VmaxuVv { vd, vs2, vs1, vm } => {
1548 if !ext_state.vector_instructions_allowed() {
1549 Err(ExecutionError::IllegalInstruction {
1550 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1551 })?;
1552 }
1553 let vtype = ext_state
1554 .vtype()
1555 .ok_or(ExecutionError::IllegalInstruction {
1556 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1557 })?;
1558 let group_regs = vtype.vlmul().register_count();
1559 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1560 program_counter,
1561 vd,
1562 group_regs,
1563 )?;
1564 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1565 program_counter,
1566 vs2,
1567 group_regs,
1568 )?;
1569 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1570 program_counter,
1571 vs1,
1572 group_regs,
1573 )?;
1574 if !vm && vd.bits() == 0 {
1575 Err(ExecutionError::IllegalInstruction {
1576 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1577 })?;
1578 }
1579 let sew = vtype.vsew();
1580 let vl = ext_state.vl();
1581 let vstart = u32::from(ext_state.vstart());
1582 unsafe {
1584 zve64x_arith_helpers::execute_arith_op(
1585 ext_state,
1586 vd,
1587 vs2,
1588 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
1589 vm,
1590 vl,
1591 vstart,
1592 sew,
1593 |a, b, sew| {
1594 let mask = zve64x_arith_helpers::sew_mask(sew);
1595 if a & mask >= b & mask { a } else { b }
1596 },
1597 );
1598 }
1599 }
1600 Self::VmaxuVx {
1601 vd,
1602 vs2,
1603 rs1: _,
1604 vm,
1605 } => {
1606 if !ext_state.vector_instructions_allowed() {
1607 Err(ExecutionError::IllegalInstruction {
1608 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1609 })?;
1610 }
1611 let vtype = ext_state
1612 .vtype()
1613 .ok_or(ExecutionError::IllegalInstruction {
1614 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1615 })?;
1616 let group_regs = vtype.vlmul().register_count();
1617 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1618 program_counter,
1619 vd,
1620 group_regs,
1621 )?;
1622 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1623 program_counter,
1624 vs2,
1625 group_regs,
1626 )?;
1627 if !vm && vd.bits() == 0 {
1628 Err(ExecutionError::IllegalInstruction {
1629 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1630 })?;
1631 }
1632 let sew = vtype.vsew();
1633 let vl = ext_state.vl();
1634 let vstart = u32::from(ext_state.vstart());
1635 let scalar = rs1_value.as_u64();
1636 unsafe {
1638 zve64x_arith_helpers::execute_arith_op(
1639 ext_state,
1640 vd,
1641 vs2,
1642 zve64x_arith_helpers::OpSrc::Scalar(scalar),
1643 vm,
1644 vl,
1645 vstart,
1646 sew,
1647 |a, b, sew| {
1648 let mask = zve64x_arith_helpers::sew_mask(sew);
1649 if a & mask >= b & mask { a } else { b }
1650 },
1651 );
1652 }
1653 }
1654 Self::VmaxVv { vd, vs2, vs1, vm } => {
1655 if !ext_state.vector_instructions_allowed() {
1656 Err(ExecutionError::IllegalInstruction {
1657 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1658 })?;
1659 }
1660 let vtype = ext_state
1661 .vtype()
1662 .ok_or(ExecutionError::IllegalInstruction {
1663 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1664 })?;
1665 let group_regs = vtype.vlmul().register_count();
1666 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1667 program_counter,
1668 vd,
1669 group_regs,
1670 )?;
1671 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1672 program_counter,
1673 vs2,
1674 group_regs,
1675 )?;
1676 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1677 program_counter,
1678 vs1,
1679 group_regs,
1680 )?;
1681 if !vm && vd.bits() == 0 {
1682 Err(ExecutionError::IllegalInstruction {
1683 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1684 })?;
1685 }
1686 let sew = vtype.vsew();
1687 let vl = ext_state.vl();
1688 let vstart = u32::from(ext_state.vstart());
1689 unsafe {
1691 zve64x_arith_helpers::execute_arith_op(
1692 ext_state,
1693 vd,
1694 vs2,
1695 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
1696 vm,
1697 vl,
1698 vstart,
1699 sew,
1700 |a, b, sew| {
1701 if zve64x_arith_helpers::sign_extend(a, sew)
1702 >= zve64x_arith_helpers::sign_extend(b, sew)
1703 {
1704 a
1705 } else {
1706 b
1707 }
1708 },
1709 );
1710 }
1711 }
1712 Self::VmaxVx {
1713 vd,
1714 vs2,
1715 rs1: _,
1716 vm,
1717 } => {
1718 if !ext_state.vector_instructions_allowed() {
1719 Err(ExecutionError::IllegalInstruction {
1720 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1721 })?;
1722 }
1723 let vtype = ext_state
1724 .vtype()
1725 .ok_or(ExecutionError::IllegalInstruction {
1726 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1727 })?;
1728 let group_regs = vtype.vlmul().register_count();
1729 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1730 program_counter,
1731 vd,
1732 group_regs,
1733 )?;
1734 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1735 program_counter,
1736 vs2,
1737 group_regs,
1738 )?;
1739 if !vm && vd.bits() == 0 {
1740 Err(ExecutionError::IllegalInstruction {
1741 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1742 })?;
1743 }
1744 let sew = vtype.vsew();
1745 let vl = ext_state.vl();
1746 let vstart = u32::from(ext_state.vstart());
1747 let scalar = rs1_value.as_u64();
1748 unsafe {
1750 zve64x_arith_helpers::execute_arith_op(
1751 ext_state,
1752 vd,
1753 vs2,
1754 zve64x_arith_helpers::OpSrc::Scalar(scalar),
1755 vm,
1756 vl,
1757 vstart,
1758 sew,
1759 |a, b, sew| {
1760 if zve64x_arith_helpers::sign_extend(a, sew)
1761 >= zve64x_arith_helpers::sign_extend(b, sew)
1762 {
1763 a
1764 } else {
1765 b
1766 }
1767 },
1768 );
1769 }
1770 }
1771 Self::VmseqVv { vd, vs2, vs1, vm } => {
1773 if !ext_state.vector_instructions_allowed() {
1774 Err(ExecutionError::IllegalInstruction {
1775 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1776 })?;
1777 }
1778 let vtype = ext_state
1779 .vtype()
1780 .ok_or(ExecutionError::IllegalInstruction {
1781 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1782 })?;
1783 let group_regs = vtype.vlmul().register_count();
1784 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1785 program_counter,
1786 vs2,
1787 group_regs,
1788 )?;
1789 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1790 program_counter,
1791 vs1,
1792 group_regs,
1793 )?;
1794 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
1795 program_counter,
1796 vd,
1797 vs2,
1798 group_regs,
1799 )?;
1800 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
1801 program_counter,
1802 vd,
1803 vs1,
1804 group_regs,
1805 )?;
1806 let sew = vtype.vsew();
1807 let vl = ext_state.vl();
1808 let vstart = u32::from(ext_state.vstart());
1809 unsafe {
1813 zve64x_arith_helpers::execute_compare_op(
1814 ext_state,
1815 vd,
1816 vs2,
1817 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
1818 vm,
1819 vl,
1820 vstart,
1821 sew,
1822 |a, b, sew| {
1823 (a & zve64x_arith_helpers::sew_mask(sew))
1824 == (b & zve64x_arith_helpers::sew_mask(sew))
1825 },
1826 );
1827 }
1828 }
1829 Self::VmseqVx {
1830 vd,
1831 vs2,
1832 rs1: _,
1833 vm,
1834 } => {
1835 if !ext_state.vector_instructions_allowed() {
1836 Err(ExecutionError::IllegalInstruction {
1837 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1838 })?;
1839 }
1840 let vtype = ext_state
1841 .vtype()
1842 .ok_or(ExecutionError::IllegalInstruction {
1843 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1844 })?;
1845 let group_regs = vtype.vlmul().register_count();
1846 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1847 program_counter,
1848 vs2,
1849 group_regs,
1850 )?;
1851 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
1852 program_counter,
1853 vd,
1854 vs2,
1855 group_regs,
1856 )?;
1857 let sew = vtype.vsew();
1858 let vl = ext_state.vl();
1859 let vstart = u32::from(ext_state.vstart());
1860 let scalar = rs1_value.as_u64();
1861 unsafe {
1863 zve64x_arith_helpers::execute_compare_op(
1864 ext_state,
1865 vd,
1866 vs2,
1867 zve64x_arith_helpers::OpSrc::Scalar(scalar),
1868 vm,
1869 vl,
1870 vstart,
1871 sew,
1872 |a, b, sew| {
1873 (a & zve64x_arith_helpers::sew_mask(sew))
1874 == (b & zve64x_arith_helpers::sew_mask(sew))
1875 },
1876 );
1877 }
1878 }
1879 Self::VmseqVi { vd, vs2, imm, vm } => {
1880 if !ext_state.vector_instructions_allowed() {
1881 Err(ExecutionError::IllegalInstruction {
1882 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1883 })?;
1884 }
1885 let vtype = ext_state
1886 .vtype()
1887 .ok_or(ExecutionError::IllegalInstruction {
1888 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1889 })?;
1890 let group_regs = vtype.vlmul().register_count();
1891 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1892 program_counter,
1893 vs2,
1894 group_regs,
1895 )?;
1896 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
1897 program_counter,
1898 vd,
1899 vs2,
1900 group_regs,
1901 )?;
1902 let sew = vtype.vsew();
1903 let vl = ext_state.vl();
1904 let vstart = u32::from(ext_state.vstart());
1905 let scalar = i64::from(imm).cast_unsigned();
1906 unsafe {
1908 zve64x_arith_helpers::execute_compare_op(
1909 ext_state,
1910 vd,
1911 vs2,
1912 zve64x_arith_helpers::OpSrc::Scalar(scalar),
1913 vm,
1914 vl,
1915 vstart,
1916 sew,
1917 |a, b, sew| {
1918 (a & zve64x_arith_helpers::sew_mask(sew))
1919 == (b & zve64x_arith_helpers::sew_mask(sew))
1920 },
1921 );
1922 }
1923 }
1924 Self::VmsneVv { vd, vs2, vs1, vm } => {
1926 if !ext_state.vector_instructions_allowed() {
1927 Err(ExecutionError::IllegalInstruction {
1928 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1929 })?;
1930 }
1931 let vtype = ext_state
1932 .vtype()
1933 .ok_or(ExecutionError::IllegalInstruction {
1934 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1935 })?;
1936 let group_regs = vtype.vlmul().register_count();
1937 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1938 program_counter,
1939 vs2,
1940 group_regs,
1941 )?;
1942 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1943 program_counter,
1944 vs1,
1945 group_regs,
1946 )?;
1947 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
1948 program_counter,
1949 vd,
1950 vs2,
1951 group_regs,
1952 )?;
1953 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
1954 program_counter,
1955 vd,
1956 vs1,
1957 group_regs,
1958 )?;
1959 let sew = vtype.vsew();
1960 let vl = ext_state.vl();
1961 let vstart = u32::from(ext_state.vstart());
1962 unsafe {
1964 zve64x_arith_helpers::execute_compare_op(
1965 ext_state,
1966 vd,
1967 vs2,
1968 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
1969 vm,
1970 vl,
1971 vstart,
1972 sew,
1973 |a, b, sew| {
1974 (a & zve64x_arith_helpers::sew_mask(sew))
1975 != (b & zve64x_arith_helpers::sew_mask(sew))
1976 },
1977 );
1978 }
1979 }
1980 Self::VmsneVx {
1981 vd,
1982 vs2,
1983 rs1: _,
1984 vm,
1985 } => {
1986 if !ext_state.vector_instructions_allowed() {
1987 Err(ExecutionError::IllegalInstruction {
1988 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1989 })?;
1990 }
1991 let vtype = ext_state
1992 .vtype()
1993 .ok_or(ExecutionError::IllegalInstruction {
1994 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1995 })?;
1996 let group_regs = vtype.vlmul().register_count();
1997 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
1998 program_counter,
1999 vs2,
2000 group_regs,
2001 )?;
2002 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2003 program_counter,
2004 vd,
2005 vs2,
2006 group_regs,
2007 )?;
2008 let sew = vtype.vsew();
2009 let vl = ext_state.vl();
2010 let vstart = u32::from(ext_state.vstart());
2011 let scalar = rs1_value.as_u64();
2012 unsafe {
2014 zve64x_arith_helpers::execute_compare_op(
2015 ext_state,
2016 vd,
2017 vs2,
2018 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2019 vm,
2020 vl,
2021 vstart,
2022 sew,
2023 |a, b, sew| {
2024 (a & zve64x_arith_helpers::sew_mask(sew))
2025 != (b & zve64x_arith_helpers::sew_mask(sew))
2026 },
2027 );
2028 }
2029 }
2030 Self::VmsneVi { vd, vs2, imm, vm } => {
2031 if !ext_state.vector_instructions_allowed() {
2032 Err(ExecutionError::IllegalInstruction {
2033 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2034 })?;
2035 }
2036 let vtype = ext_state
2037 .vtype()
2038 .ok_or(ExecutionError::IllegalInstruction {
2039 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2040 })?;
2041 let group_regs = vtype.vlmul().register_count();
2042 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2043 program_counter,
2044 vs2,
2045 group_regs,
2046 )?;
2047 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2048 program_counter,
2049 vd,
2050 vs2,
2051 group_regs,
2052 )?;
2053 let sew = vtype.vsew();
2054 let vl = ext_state.vl();
2055 let vstart = u32::from(ext_state.vstart());
2056 let scalar = i64::from(imm).cast_unsigned();
2057 unsafe {
2059 zve64x_arith_helpers::execute_compare_op(
2060 ext_state,
2061 vd,
2062 vs2,
2063 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2064 vm,
2065 vl,
2066 vstart,
2067 sew,
2068 |a, b, sew| {
2069 (a & zve64x_arith_helpers::sew_mask(sew))
2070 != (b & zve64x_arith_helpers::sew_mask(sew))
2071 },
2072 );
2073 }
2074 }
2075 Self::VmsltuVv { vd, vs2, vs1, vm } => {
2077 if !ext_state.vector_instructions_allowed() {
2078 Err(ExecutionError::IllegalInstruction {
2079 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2080 })?;
2081 }
2082 let vtype = ext_state
2083 .vtype()
2084 .ok_or(ExecutionError::IllegalInstruction {
2085 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2086 })?;
2087 let group_regs = vtype.vlmul().register_count();
2088 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2089 program_counter,
2090 vs2,
2091 group_regs,
2092 )?;
2093 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2094 program_counter,
2095 vs1,
2096 group_regs,
2097 )?;
2098 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2099 program_counter,
2100 vd,
2101 vs2,
2102 group_regs,
2103 )?;
2104 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2105 program_counter,
2106 vd,
2107 vs1,
2108 group_regs,
2109 )?;
2110 let sew = vtype.vsew();
2111 let vl = ext_state.vl();
2112 let vstart = u32::from(ext_state.vstart());
2113 unsafe {
2115 zve64x_arith_helpers::execute_compare_op(
2116 ext_state,
2117 vd,
2118 vs2,
2119 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
2120 vm,
2121 vl,
2122 vstart,
2123 sew,
2124 |a, b, sew| {
2125 (a & zve64x_arith_helpers::sew_mask(sew))
2126 < (b & zve64x_arith_helpers::sew_mask(sew))
2127 },
2128 );
2129 }
2130 }
2131 Self::VmsltuVx {
2132 vd,
2133 vs2,
2134 rs1: _,
2135 vm,
2136 } => {
2137 if !ext_state.vector_instructions_allowed() {
2138 Err(ExecutionError::IllegalInstruction {
2139 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2140 })?;
2141 }
2142 let vtype = ext_state
2143 .vtype()
2144 .ok_or(ExecutionError::IllegalInstruction {
2145 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2146 })?;
2147 let group_regs = vtype.vlmul().register_count();
2148 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2149 program_counter,
2150 vs2,
2151 group_regs,
2152 )?;
2153 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2154 program_counter,
2155 vd,
2156 vs2,
2157 group_regs,
2158 )?;
2159 let sew = vtype.vsew();
2160 let vl = ext_state.vl();
2161 let vstart = u32::from(ext_state.vstart());
2162 let scalar = rs1_value.as_u64();
2163 unsafe {
2165 zve64x_arith_helpers::execute_compare_op(
2166 ext_state,
2167 vd,
2168 vs2,
2169 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2170 vm,
2171 vl,
2172 vstart,
2173 sew,
2174 |a, b, sew| {
2175 (a & zve64x_arith_helpers::sew_mask(sew))
2176 < (b & zve64x_arith_helpers::sew_mask(sew))
2177 },
2178 );
2179 }
2180 }
2181 Self::VmsltVv { vd, vs2, vs1, vm } => {
2183 if !ext_state.vector_instructions_allowed() {
2184 Err(ExecutionError::IllegalInstruction {
2185 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2186 })?;
2187 }
2188 let vtype = ext_state
2189 .vtype()
2190 .ok_or(ExecutionError::IllegalInstruction {
2191 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2192 })?;
2193 let group_regs = vtype.vlmul().register_count();
2194 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2195 program_counter,
2196 vs2,
2197 group_regs,
2198 )?;
2199 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2200 program_counter,
2201 vs1,
2202 group_regs,
2203 )?;
2204 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2205 program_counter,
2206 vd,
2207 vs2,
2208 group_regs,
2209 )?;
2210 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2211 program_counter,
2212 vd,
2213 vs1,
2214 group_regs,
2215 )?;
2216 let sew = vtype.vsew();
2217 let vl = ext_state.vl();
2218 let vstart = u32::from(ext_state.vstart());
2219 unsafe {
2221 zve64x_arith_helpers::execute_compare_op(
2222 ext_state,
2223 vd,
2224 vs2,
2225 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
2226 vm,
2227 vl,
2228 vstart,
2229 sew,
2230 |a, b, sew| {
2231 zve64x_arith_helpers::sign_extend(a, sew)
2232 < zve64x_arith_helpers::sign_extend(b, sew)
2233 },
2234 );
2235 }
2236 }
2237 Self::VmsltVx {
2238 vd,
2239 vs2,
2240 rs1: _,
2241 vm,
2242 } => {
2243 if !ext_state.vector_instructions_allowed() {
2244 Err(ExecutionError::IllegalInstruction {
2245 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2246 })?;
2247 }
2248 let vtype = ext_state
2249 .vtype()
2250 .ok_or(ExecutionError::IllegalInstruction {
2251 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2252 })?;
2253 let group_regs = vtype.vlmul().register_count();
2254 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2255 program_counter,
2256 vs2,
2257 group_regs,
2258 )?;
2259 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2260 program_counter,
2261 vd,
2262 vs2,
2263 group_regs,
2264 )?;
2265 let sew = vtype.vsew();
2266 let vl = ext_state.vl();
2267 let vstart = u32::from(ext_state.vstart());
2268 let scalar = rs1_value.as_u64();
2269 unsafe {
2271 zve64x_arith_helpers::execute_compare_op(
2272 ext_state,
2273 vd,
2274 vs2,
2275 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2276 vm,
2277 vl,
2278 vstart,
2279 sew,
2280 |a, b, sew| {
2281 zve64x_arith_helpers::sign_extend(a, sew)
2282 < zve64x_arith_helpers::sign_extend(b, sew)
2283 },
2284 );
2285 }
2286 }
2287 Self::VmsleuVv { vd, vs2, vs1, vm } => {
2289 if !ext_state.vector_instructions_allowed() {
2290 Err(ExecutionError::IllegalInstruction {
2291 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2292 })?;
2293 }
2294 let vtype = ext_state
2295 .vtype()
2296 .ok_or(ExecutionError::IllegalInstruction {
2297 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2298 })?;
2299 let group_regs = vtype.vlmul().register_count();
2300 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2301 program_counter,
2302 vs2,
2303 group_regs,
2304 )?;
2305 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2306 program_counter,
2307 vs1,
2308 group_regs,
2309 )?;
2310 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2311 program_counter,
2312 vd,
2313 vs2,
2314 group_regs,
2315 )?;
2316 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2317 program_counter,
2318 vd,
2319 vs1,
2320 group_regs,
2321 )?;
2322 let sew = vtype.vsew();
2323 let vl = ext_state.vl();
2324 let vstart = u32::from(ext_state.vstart());
2325 unsafe {
2327 zve64x_arith_helpers::execute_compare_op(
2328 ext_state,
2329 vd,
2330 vs2,
2331 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
2332 vm,
2333 vl,
2334 vstart,
2335 sew,
2336 |a, b, sew| {
2337 (a & zve64x_arith_helpers::sew_mask(sew))
2338 <= (b & zve64x_arith_helpers::sew_mask(sew))
2339 },
2340 );
2341 }
2342 }
2343 Self::VmsleuVx {
2344 vd,
2345 vs2,
2346 rs1: _,
2347 vm,
2348 } => {
2349 if !ext_state.vector_instructions_allowed() {
2350 Err(ExecutionError::IllegalInstruction {
2351 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2352 })?;
2353 }
2354 let vtype = ext_state
2355 .vtype()
2356 .ok_or(ExecutionError::IllegalInstruction {
2357 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2358 })?;
2359 let group_regs = vtype.vlmul().register_count();
2360 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2361 program_counter,
2362 vs2,
2363 group_regs,
2364 )?;
2365 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2366 program_counter,
2367 vd,
2368 vs2,
2369 group_regs,
2370 )?;
2371 let sew = vtype.vsew();
2372 let vl = ext_state.vl();
2373 let vstart = u32::from(ext_state.vstart());
2374 let scalar = rs1_value.as_u64();
2375 unsafe {
2377 zve64x_arith_helpers::execute_compare_op(
2378 ext_state,
2379 vd,
2380 vs2,
2381 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2382 vm,
2383 vl,
2384 vstart,
2385 sew,
2386 |a, b, sew| {
2387 (a & zve64x_arith_helpers::sew_mask(sew))
2388 <= (b & zve64x_arith_helpers::sew_mask(sew))
2389 },
2390 );
2391 }
2392 }
2393 Self::VmsleuVi { vd, vs2, imm, vm } => {
2394 if !ext_state.vector_instructions_allowed() {
2395 Err(ExecutionError::IllegalInstruction {
2396 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2397 })?;
2398 }
2399 let vtype = ext_state
2400 .vtype()
2401 .ok_or(ExecutionError::IllegalInstruction {
2402 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2403 })?;
2404 let group_regs = vtype.vlmul().register_count();
2405 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2406 program_counter,
2407 vs2,
2408 group_regs,
2409 )?;
2410 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2411 program_counter,
2412 vd,
2413 vs2,
2414 group_regs,
2415 )?;
2416 let sew = vtype.vsew();
2417 let vl = ext_state.vl();
2418 let vstart = u32::from(ext_state.vstart());
2419 let scalar = i64::from(imm).cast_unsigned();
2427 unsafe {
2429 zve64x_arith_helpers::execute_compare_op(
2430 ext_state,
2431 vd,
2432 vs2,
2433 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2434 vm,
2435 vl,
2436 vstart,
2437 sew,
2438 |a, b, sew| {
2439 (a & zve64x_arith_helpers::sew_mask(sew))
2440 <= (b & zve64x_arith_helpers::sew_mask(sew))
2441 },
2442 );
2443 }
2444 }
2445 Self::VmsleVv { vd, vs2, vs1, vm } => {
2447 if !ext_state.vector_instructions_allowed() {
2448 Err(ExecutionError::IllegalInstruction {
2449 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2450 })?;
2451 }
2452 let vtype = ext_state
2453 .vtype()
2454 .ok_or(ExecutionError::IllegalInstruction {
2455 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2456 })?;
2457 let group_regs = vtype.vlmul().register_count();
2458 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2459 program_counter,
2460 vs2,
2461 group_regs,
2462 )?;
2463 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2464 program_counter,
2465 vs1,
2466 group_regs,
2467 )?;
2468 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2469 program_counter,
2470 vd,
2471 vs2,
2472 group_regs,
2473 )?;
2474 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2475 program_counter,
2476 vd,
2477 vs1,
2478 group_regs,
2479 )?;
2480 let sew = vtype.vsew();
2481 let vl = ext_state.vl();
2482 let vstart = u32::from(ext_state.vstart());
2483 unsafe {
2485 zve64x_arith_helpers::execute_compare_op(
2486 ext_state,
2487 vd,
2488 vs2,
2489 zve64x_arith_helpers::OpSrc::Vreg(vs1.bits()),
2490 vm,
2491 vl,
2492 vstart,
2493 sew,
2494 |a, b, sew| {
2495 zve64x_arith_helpers::sign_extend(a, sew)
2496 <= zve64x_arith_helpers::sign_extend(b, sew)
2497 },
2498 );
2499 }
2500 }
2501 Self::VmsleVx {
2502 vd,
2503 vs2,
2504 rs1: _,
2505 vm,
2506 } => {
2507 if !ext_state.vector_instructions_allowed() {
2508 Err(ExecutionError::IllegalInstruction {
2509 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2510 })?;
2511 }
2512 let vtype = ext_state
2513 .vtype()
2514 .ok_or(ExecutionError::IllegalInstruction {
2515 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2516 })?;
2517 let group_regs = vtype.vlmul().register_count();
2518 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2519 program_counter,
2520 vs2,
2521 group_regs,
2522 )?;
2523 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2524 program_counter,
2525 vd,
2526 vs2,
2527 group_regs,
2528 )?;
2529 let sew = vtype.vsew();
2530 let vl = ext_state.vl();
2531 let vstart = u32::from(ext_state.vstart());
2532 let scalar = rs1_value.as_u64();
2533 unsafe {
2535 zve64x_arith_helpers::execute_compare_op(
2536 ext_state,
2537 vd,
2538 vs2,
2539 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2540 vm,
2541 vl,
2542 vstart,
2543 sew,
2544 |a, b, sew| {
2545 zve64x_arith_helpers::sign_extend(a, sew)
2546 <= zve64x_arith_helpers::sign_extend(b, sew)
2547 },
2548 );
2549 }
2550 }
2551 Self::VmsleVi { vd, vs2, imm, vm } => {
2552 if !ext_state.vector_instructions_allowed() {
2553 Err(ExecutionError::IllegalInstruction {
2554 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2555 })?;
2556 }
2557 let vtype = ext_state
2558 .vtype()
2559 .ok_or(ExecutionError::IllegalInstruction {
2560 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2561 })?;
2562 let group_regs = vtype.vlmul().register_count();
2563 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2564 program_counter,
2565 vs2,
2566 group_regs,
2567 )?;
2568 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2569 program_counter,
2570 vd,
2571 vs2,
2572 group_regs,
2573 )?;
2574 let sew = vtype.vsew();
2575 let vl = ext_state.vl();
2576 let vstart = u32::from(ext_state.vstart());
2577 let scalar = i64::from(imm).cast_unsigned();
2578 unsafe {
2580 zve64x_arith_helpers::execute_compare_op(
2581 ext_state,
2582 vd,
2583 vs2,
2584 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2585 vm,
2586 vl,
2587 vstart,
2588 sew,
2589 |a, b, sew| {
2590 zve64x_arith_helpers::sign_extend(a, sew)
2591 <= zve64x_arith_helpers::sign_extend(b, sew)
2592 },
2593 );
2594 }
2595 }
2596 Self::VmsgtuVx {
2598 vd,
2599 vs2,
2600 rs1: _,
2601 vm,
2602 } => {
2603 if !ext_state.vector_instructions_allowed() {
2604 Err(ExecutionError::IllegalInstruction {
2605 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2606 })?;
2607 }
2608 let vtype = ext_state
2609 .vtype()
2610 .ok_or(ExecutionError::IllegalInstruction {
2611 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2612 })?;
2613 let group_regs = vtype.vlmul().register_count();
2614 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2615 program_counter,
2616 vs2,
2617 group_regs,
2618 )?;
2619 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2620 program_counter,
2621 vd,
2622 vs2,
2623 group_regs,
2624 )?;
2625 let sew = vtype.vsew();
2626 let vl = ext_state.vl();
2627 let vstart = u32::from(ext_state.vstart());
2628 let scalar = rs1_value.as_u64();
2629 unsafe {
2631 zve64x_arith_helpers::execute_compare_op(
2632 ext_state,
2633 vd,
2634 vs2,
2635 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2636 vm,
2637 vl,
2638 vstart,
2639 sew,
2640 |a, b, sew| {
2641 (a & zve64x_arith_helpers::sew_mask(sew))
2642 > (b & zve64x_arith_helpers::sew_mask(sew))
2643 },
2644 );
2645 }
2646 }
2647 Self::VmsgtuVi { vd, vs2, imm, vm } => {
2648 if !ext_state.vector_instructions_allowed() {
2649 Err(ExecutionError::IllegalInstruction {
2650 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2651 })?;
2652 }
2653 let vtype = ext_state
2654 .vtype()
2655 .ok_or(ExecutionError::IllegalInstruction {
2656 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2657 })?;
2658 let group_regs = vtype.vlmul().register_count();
2659 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2660 program_counter,
2661 vs2,
2662 group_regs,
2663 )?;
2664 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2665 program_counter,
2666 vd,
2667 vs2,
2668 group_regs,
2669 )?;
2670 let sew = vtype.vsew();
2671 let vl = ext_state.vl();
2672 let vstart = u32::from(ext_state.vstart());
2673 let scalar = i64::from(imm).cast_unsigned();
2674 unsafe {
2676 zve64x_arith_helpers::execute_compare_op(
2677 ext_state,
2678 vd,
2679 vs2,
2680 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2681 vm,
2682 vl,
2683 vstart,
2684 sew,
2685 |a, b, sew| {
2686 (a & zve64x_arith_helpers::sew_mask(sew))
2687 > (b & zve64x_arith_helpers::sew_mask(sew))
2688 },
2689 );
2690 }
2691 }
2692 Self::VmsgtVx {
2694 vd,
2695 vs2,
2696 rs1: _,
2697 vm,
2698 } => {
2699 if !ext_state.vector_instructions_allowed() {
2700 Err(ExecutionError::IllegalInstruction {
2701 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2702 })?;
2703 }
2704 let vtype = ext_state
2705 .vtype()
2706 .ok_or(ExecutionError::IllegalInstruction {
2707 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2708 })?;
2709 let group_regs = vtype.vlmul().register_count();
2710 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2711 program_counter,
2712 vs2,
2713 group_regs,
2714 )?;
2715 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2716 program_counter,
2717 vd,
2718 vs2,
2719 group_regs,
2720 )?;
2721 let sew = vtype.vsew();
2722 let vl = ext_state.vl();
2723 let vstart = u32::from(ext_state.vstart());
2724 let scalar = rs1_value.as_u64();
2725 unsafe {
2727 zve64x_arith_helpers::execute_compare_op(
2728 ext_state,
2729 vd,
2730 vs2,
2731 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2732 vm,
2733 vl,
2734 vstart,
2735 sew,
2736 |a, b, sew| {
2737 zve64x_arith_helpers::sign_extend(a, sew)
2738 > zve64x_arith_helpers::sign_extend(b, sew)
2739 },
2740 );
2741 }
2742 }
2743 Self::VmsgtVi { vd, vs2, imm, vm } => {
2744 if !ext_state.vector_instructions_allowed() {
2745 Err(ExecutionError::IllegalInstruction {
2746 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2747 })?;
2748 }
2749 let vtype = ext_state
2750 .vtype()
2751 .ok_or(ExecutionError::IllegalInstruction {
2752 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
2753 })?;
2754 let group_regs = vtype.vlmul().register_count();
2755 zve64x_arith_helpers::check_vreg_group_alignment::<Reg, _, _, _>(
2756 program_counter,
2757 vs2,
2758 group_regs,
2759 )?;
2760 zve64x_arith_helpers::check_mask_dest_no_overlap::<Reg, _, _, _>(
2761 program_counter,
2762 vd,
2763 vs2,
2764 group_regs,
2765 )?;
2766 let sew = vtype.vsew();
2767 let vl = ext_state.vl();
2768 let vstart = u32::from(ext_state.vstart());
2769 let scalar = i64::from(imm).cast_unsigned();
2770 unsafe {
2772 zve64x_arith_helpers::execute_compare_op(
2773 ext_state,
2774 vd,
2775 vs2,
2776 zve64x_arith_helpers::OpSrc::Scalar(scalar),
2777 vm,
2778 vl,
2779 vstart,
2780 sew,
2781 |a, b, sew| {
2782 zve64x_arith_helpers::sign_extend(a, sew)
2783 > zve64x_arith_helpers::sign_extend(b, sew)
2784 },
2785 );
2786 }
2787 }
2788 }
2789
2790 Ok(ControlFlow::Continue(Default::default()))
2791 }
2792}