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