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