1#[cfg(test)]
4mod tests;
5pub mod zvexx_widen_narrow_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 ZveXxWidenNarrowInstruction<Hart>
20where
21 Reg: Register,
22 Hart: VectorHartConfig<Reg = Reg>,
23{
24}
25
26#[instruction_execution]
27const impl<Reg, Hart, Env> ExecutableInstructionCsr<Env> for ZveXxWidenNarrowInstruction<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 ZveXxWidenNarrowInstruction<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::VwadduVv { 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 Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
79 ::core::hint::cold_path();
80 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
81 address: PackedAddress::new(
82 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
83 ),
84 });
85 };
86 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
87 program_counter,
88 config,
89 vd,
90 widening_sew.wide().as_eew(),
91 )?;
92 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
93 program_counter,
94 config,
95 vs2,
96 widening_sew.narrow().as_eew(),
97 )?;
98 let vs1 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
99 program_counter,
100 config,
101 vs1,
102 widening_sew.narrow().as_eew(),
103 )?;
104 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
106 program_counter,
107 vd,
108 vs2,
109 )?;
110 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
111 program_counter,
112 vd,
113 vs1,
114 )?;
115 zvexx_widen_narrow_helpers::execute_widen_op::<true, _, _, _>(
116 env,
117 vd,
118 vs2,
119 zvexx_widen_narrow_helpers::OpSrc::Vreg(vs1),
120 vm,
121 widening_sew,
122 u64::wrapping_add,
123 );
124 }
125 Self::VwadduVx {
127 vd,
128 vs2,
129 rs1: _,
130 vm,
131 } => {
132 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
133 ::core::hint::cold_path();
134 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
135 address: PackedAddress::new(
136 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
137 ),
138 });
139 }
140 let Some(config) = env.vector_config() else {
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 = config.vtype().vsew();
149 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
150 ::core::hint::cold_path();
151 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
152 address: PackedAddress::new(
153 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
154 ),
155 });
156 };
157 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
158 program_counter,
159 config,
160 vd,
161 widening_sew.wide().as_eew(),
162 )?;
163 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
164 program_counter,
165 config,
166 vs2,
167 widening_sew.narrow().as_eew(),
168 )?;
169 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
171 program_counter,
172 vd,
173 vs2,
174 )?;
175 let scalar = rs1_value.as_u64();
177 zvexx_widen_narrow_helpers::execute_widen_op::<true, _, _, _>(
178 env,
179 vd,
180 vs2,
181 zvexx_widen_narrow_helpers::OpSrc::Scalar(scalar),
182 vm,
183 widening_sew,
184 u64::wrapping_add,
185 );
186 }
187 Self::VwaddVv { vd, vs2, vs1, vm } => {
189 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
190 ::core::hint::cold_path();
191 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
192 address: PackedAddress::new(
193 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
194 ),
195 });
196 }
197 let Some(config) = env.vector_config() else {
198 ::core::hint::cold_path();
199 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
200 address: PackedAddress::new(
201 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
202 ),
203 });
204 };
205 let sew = config.vtype().vsew();
206 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
207 ::core::hint::cold_path();
208 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
209 address: PackedAddress::new(
210 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
211 ),
212 });
213 };
214 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
215 program_counter,
216 config,
217 vd,
218 widening_sew.wide().as_eew(),
219 )?;
220 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
221 program_counter,
222 config,
223 vs2,
224 widening_sew.narrow().as_eew(),
225 )?;
226 let vs1 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
227 program_counter,
228 config,
229 vs1,
230 widening_sew.narrow().as_eew(),
231 )?;
232 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
234 program_counter,
235 vd,
236 vs2,
237 )?;
238 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
239 program_counter,
240 vd,
241 vs1,
242 )?;
243 zvexx_widen_narrow_helpers::execute_widen_op::<false, _, _, _>(
244 env,
245 vd,
246 vs2,
247 zvexx_widen_narrow_helpers::OpSrc::Vreg(vs1),
248 vm,
249 widening_sew,
250 u64::wrapping_add,
251 );
252 }
253 Self::VwaddVx {
255 vd,
256 vs2,
257 rs1: _,
258 vm,
259 } => {
260 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
261 ::core::hint::cold_path();
262 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
263 address: PackedAddress::new(
264 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
265 ),
266 });
267 }
268 let Some(config) = env.vector_config() else {
269 ::core::hint::cold_path();
270 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
271 address: PackedAddress::new(
272 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
273 ),
274 });
275 };
276 let sew = config.vtype().vsew();
277 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
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 vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
286 program_counter,
287 config,
288 vd,
289 widening_sew.wide().as_eew(),
290 )?;
291 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
292 program_counter,
293 config,
294 vs2,
295 widening_sew.narrow().as_eew(),
296 )?;
297 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
299 program_counter,
300 vd,
301 vs2,
302 )?;
303 let scalar = zvexx_widen_narrow_helpers::sign_extend_bits(
305 rs1_value.as_u64(),
306 Vsew::from_xlen::<Reg>(),
307 )
308 .cast_unsigned();
309 zvexx_widen_narrow_helpers::execute_widen_op::<false, _, _, _>(
310 env,
311 vd,
312 vs2,
313 zvexx_widen_narrow_helpers::OpSrc::Scalar(scalar),
314 vm,
315 widening_sew,
316 u64::wrapping_add,
317 );
318 }
319 Self::VwsubuVv { vd, vs2, vs1, vm } => {
321 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
322 ::core::hint::cold_path();
323 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
324 address: PackedAddress::new(
325 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
326 ),
327 });
328 }
329 let Some(config) = env.vector_config() else {
330 ::core::hint::cold_path();
331 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
332 address: PackedAddress::new(
333 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
334 ),
335 });
336 };
337 let sew = config.vtype().vsew();
338 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
339 ::core::hint::cold_path();
340 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
341 address: PackedAddress::new(
342 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
343 ),
344 });
345 };
346 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
347 program_counter,
348 config,
349 vd,
350 widening_sew.wide().as_eew(),
351 )?;
352 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
353 program_counter,
354 config,
355 vs2,
356 widening_sew.narrow().as_eew(),
357 )?;
358 let vs1 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
359 program_counter,
360 config,
361 vs1,
362 widening_sew.narrow().as_eew(),
363 )?;
364 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
366 program_counter,
367 vd,
368 vs2,
369 )?;
370 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
371 program_counter,
372 vd,
373 vs1,
374 )?;
375 zvexx_widen_narrow_helpers::execute_widen_op::<true, _, _, _>(
376 env,
377 vd,
378 vs2,
379 zvexx_widen_narrow_helpers::OpSrc::Vreg(vs1),
380 vm,
381 widening_sew,
382 u64::wrapping_sub,
383 );
384 }
385 Self::VwsubuVx {
387 vd,
388 vs2,
389 rs1: _,
390 vm,
391 } => {
392 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
393 ::core::hint::cold_path();
394 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
395 address: PackedAddress::new(
396 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
397 ),
398 });
399 }
400 let Some(config) = env.vector_config() else {
401 ::core::hint::cold_path();
402 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
403 address: PackedAddress::new(
404 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
405 ),
406 });
407 };
408 let sew = config.vtype().vsew();
409 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
410 ::core::hint::cold_path();
411 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
412 address: PackedAddress::new(
413 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
414 ),
415 });
416 };
417 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
418 program_counter,
419 config,
420 vd,
421 widening_sew.wide().as_eew(),
422 )?;
423 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
424 program_counter,
425 config,
426 vs2,
427 widening_sew.narrow().as_eew(),
428 )?;
429 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
431 program_counter,
432 vd,
433 vs2,
434 )?;
435 let scalar = rs1_value.as_u64();
436 zvexx_widen_narrow_helpers::execute_widen_op::<true, _, _, _>(
437 env,
438 vd,
439 vs2,
440 zvexx_widen_narrow_helpers::OpSrc::Scalar(scalar),
441 vm,
442 widening_sew,
443 u64::wrapping_sub,
444 );
445 }
446 Self::VwsubVv { vd, vs2, vs1, vm } => {
448 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
449 ::core::hint::cold_path();
450 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
451 address: PackedAddress::new(
452 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
453 ),
454 });
455 }
456 let Some(config) = env.vector_config() else {
457 ::core::hint::cold_path();
458 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
459 address: PackedAddress::new(
460 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
461 ),
462 });
463 };
464 let sew = config.vtype().vsew();
465 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
466 ::core::hint::cold_path();
467 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
468 address: PackedAddress::new(
469 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
470 ),
471 });
472 };
473 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
474 program_counter,
475 config,
476 vd,
477 widening_sew.wide().as_eew(),
478 )?;
479 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
480 program_counter,
481 config,
482 vs2,
483 widening_sew.narrow().as_eew(),
484 )?;
485 let vs1 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
486 program_counter,
487 config,
488 vs1,
489 widening_sew.narrow().as_eew(),
490 )?;
491 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
493 program_counter,
494 vd,
495 vs2,
496 )?;
497 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
498 program_counter,
499 vd,
500 vs1,
501 )?;
502 zvexx_widen_narrow_helpers::execute_widen_op::<false, _, _, _>(
503 env,
504 vd,
505 vs2,
506 zvexx_widen_narrow_helpers::OpSrc::Vreg(vs1),
507 vm,
508 widening_sew,
509 u64::wrapping_sub,
510 );
511 }
512 Self::VwsubVx {
514 vd,
515 vs2,
516 rs1: _,
517 vm,
518 } => {
519 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
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 Some(config) = env.vector_config() else {
528 ::core::hint::cold_path();
529 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
530 address: PackedAddress::new(
531 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
532 ),
533 });
534 };
535 let sew = config.vtype().vsew();
536 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
537 ::core::hint::cold_path();
538 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
539 address: PackedAddress::new(
540 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
541 ),
542 });
543 };
544 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
545 program_counter,
546 config,
547 vd,
548 widening_sew.wide().as_eew(),
549 )?;
550 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
551 program_counter,
552 config,
553 vs2,
554 widening_sew.narrow().as_eew(),
555 )?;
556 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
558 program_counter,
559 vd,
560 vs2,
561 )?;
562 let scalar = zvexx_widen_narrow_helpers::sign_extend_bits(
563 rs1_value.as_u64(),
564 Vsew::from_xlen::<Reg>(),
565 )
566 .cast_unsigned();
567 zvexx_widen_narrow_helpers::execute_widen_op::<false, _, _, _>(
568 env,
569 vd,
570 vs2,
571 zvexx_widen_narrow_helpers::OpSrc::Scalar(scalar),
572 vm,
573 widening_sew,
574 u64::wrapping_sub,
575 );
576 }
577 Self::VwadduWv { vd, vs2, vs1, vm } => {
579 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
580 ::core::hint::cold_path();
581 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
582 address: PackedAddress::new(
583 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
584 ),
585 });
586 }
587 let Some(config) = env.vector_config() else {
588 ::core::hint::cold_path();
589 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
590 address: PackedAddress::new(
591 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
592 ),
593 });
594 };
595 let sew = config.vtype().vsew();
596 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
597 ::core::hint::cold_path();
598 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
599 address: PackedAddress::new(
600 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
601 ),
602 });
603 };
604 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
605 program_counter,
606 config,
607 vd,
608 widening_sew.wide().as_eew(),
609 )?;
610 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
611 program_counter,
612 config,
613 vs2,
614 widening_sew.wide().as_eew(),
615 )?;
616 let vs1 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
617 program_counter,
618 config,
619 vs1,
620 widening_sew.narrow().as_eew(),
621 )?;
622 zvexx_helpers::check_groups_disjoint::<Reg, Env, _, _>(program_counter, vs2, vs1)?;
624 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
627 program_counter,
628 vd,
629 vs1,
630 )?;
631 zvexx_widen_narrow_helpers::execute_widen_w_op::<true, _, _, _>(
632 env,
633 vd,
634 vs2,
635 zvexx_widen_narrow_helpers::OpSrc::Vreg(vs1),
636 vm,
637 widening_sew,
638 u64::wrapping_add,
639 );
640 }
641 Self::VwadduWx {
643 vd,
644 vs2,
645 rs1: _,
646 vm,
647 } => {
648 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
649 ::core::hint::cold_path();
650 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
651 address: PackedAddress::new(
652 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
653 ),
654 });
655 }
656 let Some(config) = env.vector_config() else {
657 ::core::hint::cold_path();
658 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
659 address: PackedAddress::new(
660 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
661 ),
662 });
663 };
664 let sew = config.vtype().vsew();
665 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
666 ::core::hint::cold_path();
667 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
668 address: PackedAddress::new(
669 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
670 ),
671 });
672 };
673 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
674 program_counter,
675 config,
676 vd,
677 widening_sew.wide().as_eew(),
678 )?;
679 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
680 program_counter,
681 config,
682 vs2,
683 widening_sew.wide().as_eew(),
684 )?;
685 let scalar = rs1_value.as_u64();
686 zvexx_widen_narrow_helpers::execute_widen_w_op::<true, _, _, _>(
687 env,
688 vd,
689 vs2,
690 zvexx_widen_narrow_helpers::OpSrc::Scalar(scalar),
691 vm,
692 widening_sew,
693 u64::wrapping_add,
694 );
695 }
696 Self::VwaddWv { vd, vs2, vs1, vm } => {
698 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
699 ::core::hint::cold_path();
700 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
701 address: PackedAddress::new(
702 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
703 ),
704 });
705 }
706 let Some(config) = env.vector_config() else {
707 ::core::hint::cold_path();
708 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
709 address: PackedAddress::new(
710 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
711 ),
712 });
713 };
714 let sew = config.vtype().vsew();
715 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
716 ::core::hint::cold_path();
717 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
718 address: PackedAddress::new(
719 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
720 ),
721 });
722 };
723 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
724 program_counter,
725 config,
726 vd,
727 widening_sew.wide().as_eew(),
728 )?;
729 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
730 program_counter,
731 config,
732 vs2,
733 widening_sew.wide().as_eew(),
734 )?;
735 let vs1 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
736 program_counter,
737 config,
738 vs1,
739 widening_sew.narrow().as_eew(),
740 )?;
741 zvexx_helpers::check_groups_disjoint::<Reg, Env, _, _>(program_counter, vs2, vs1)?;
743 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
746 program_counter,
747 vd,
748 vs1,
749 )?;
750 zvexx_widen_narrow_helpers::execute_widen_w_op::<false, _, _, _>(
751 env,
752 vd,
753 vs2,
754 zvexx_widen_narrow_helpers::OpSrc::Vreg(vs1),
755 vm,
756 widening_sew,
757 u64::wrapping_add,
758 );
759 }
760 Self::VwaddWx {
762 vd,
763 vs2,
764 rs1: _,
765 vm,
766 } => {
767 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
768 ::core::hint::cold_path();
769 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
770 address: PackedAddress::new(
771 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
772 ),
773 });
774 }
775 let Some(config) = env.vector_config() else {
776 ::core::hint::cold_path();
777 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
778 address: PackedAddress::new(
779 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
780 ),
781 });
782 };
783 let sew = config.vtype().vsew();
784 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
785 ::core::hint::cold_path();
786 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
787 address: PackedAddress::new(
788 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
789 ),
790 });
791 };
792 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
793 program_counter,
794 config,
795 vd,
796 widening_sew.wide().as_eew(),
797 )?;
798 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
799 program_counter,
800 config,
801 vs2,
802 widening_sew.wide().as_eew(),
803 )?;
804 let scalar = zvexx_widen_narrow_helpers::sign_extend_bits(
805 rs1_value.as_u64(),
806 Vsew::from_xlen::<Reg>(),
807 )
808 .cast_unsigned();
809 zvexx_widen_narrow_helpers::execute_widen_w_op::<false, _, _, _>(
810 env,
811 vd,
812 vs2,
813 zvexx_widen_narrow_helpers::OpSrc::Scalar(scalar),
814 vm,
815 widening_sew,
816 u64::wrapping_add,
817 );
818 }
819 Self::VwsubuWv { vd, vs2, vs1, vm } => {
821 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
822 ::core::hint::cold_path();
823 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
824 address: PackedAddress::new(
825 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
826 ),
827 });
828 }
829 let Some(config) = env.vector_config() else {
830 ::core::hint::cold_path();
831 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
832 address: PackedAddress::new(
833 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
834 ),
835 });
836 };
837 let sew = config.vtype().vsew();
838 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
839 ::core::hint::cold_path();
840 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
841 address: PackedAddress::new(
842 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
843 ),
844 });
845 };
846 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
847 program_counter,
848 config,
849 vd,
850 widening_sew.wide().as_eew(),
851 )?;
852 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
853 program_counter,
854 config,
855 vs2,
856 widening_sew.wide().as_eew(),
857 )?;
858 let vs1 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
859 program_counter,
860 config,
861 vs1,
862 widening_sew.narrow().as_eew(),
863 )?;
864 zvexx_helpers::check_groups_disjoint::<Reg, Env, _, _>(program_counter, vs2, vs1)?;
866 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
869 program_counter,
870 vd,
871 vs1,
872 )?;
873 zvexx_widen_narrow_helpers::execute_widen_w_op::<true, _, _, _>(
874 env,
875 vd,
876 vs2,
877 zvexx_widen_narrow_helpers::OpSrc::Vreg(vs1),
878 vm,
879 widening_sew,
880 u64::wrapping_sub,
881 );
882 }
883 Self::VwsubuWx {
885 vd,
886 vs2,
887 rs1: _,
888 vm,
889 } => {
890 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
891 ::core::hint::cold_path();
892 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
893 address: PackedAddress::new(
894 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
895 ),
896 });
897 }
898 let Some(config) = env.vector_config() else {
899 ::core::hint::cold_path();
900 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
901 address: PackedAddress::new(
902 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
903 ),
904 });
905 };
906 let sew = config.vtype().vsew();
907 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
908 ::core::hint::cold_path();
909 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
910 address: PackedAddress::new(
911 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
912 ),
913 });
914 };
915 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
916 program_counter,
917 config,
918 vd,
919 widening_sew.wide().as_eew(),
920 )?;
921 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
922 program_counter,
923 config,
924 vs2,
925 widening_sew.wide().as_eew(),
926 )?;
927 let scalar = rs1_value.as_u64();
928 zvexx_widen_narrow_helpers::execute_widen_w_op::<true, _, _, _>(
929 env,
930 vd,
931 vs2,
932 zvexx_widen_narrow_helpers::OpSrc::Scalar(scalar),
933 vm,
934 widening_sew,
935 u64::wrapping_sub,
936 );
937 }
938 Self::VwsubWv { vd, vs2, vs1, vm } => {
940 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
941 ::core::hint::cold_path();
942 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
943 address: PackedAddress::new(
944 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
945 ),
946 });
947 }
948 let Some(config) = env.vector_config() else {
949 ::core::hint::cold_path();
950 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
951 address: PackedAddress::new(
952 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
953 ),
954 });
955 };
956 let sew = config.vtype().vsew();
957 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
958 ::core::hint::cold_path();
959 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
960 address: PackedAddress::new(
961 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
962 ),
963 });
964 };
965 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
966 program_counter,
967 config,
968 vd,
969 widening_sew.wide().as_eew(),
970 )?;
971 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
972 program_counter,
973 config,
974 vs2,
975 widening_sew.wide().as_eew(),
976 )?;
977 let vs1 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
978 program_counter,
979 config,
980 vs1,
981 widening_sew.narrow().as_eew(),
982 )?;
983 zvexx_helpers::check_groups_disjoint::<Reg, Env, _, _>(program_counter, vs2, vs1)?;
985 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
988 program_counter,
989 vd,
990 vs1,
991 )?;
992 zvexx_widen_narrow_helpers::execute_widen_w_op::<false, _, _, _>(
993 env,
994 vd,
995 vs2,
996 zvexx_widen_narrow_helpers::OpSrc::Vreg(vs1),
997 vm,
998 widening_sew,
999 u64::wrapping_sub,
1000 );
1001 }
1002 Self::VwsubWx {
1004 vd,
1005 vs2,
1006 rs1: _,
1007 vm,
1008 } => {
1009 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
1010 ::core::hint::cold_path();
1011 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1012 address: PackedAddress::new(
1013 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1014 ),
1015 });
1016 }
1017 let Some(config) = env.vector_config() else {
1018 ::core::hint::cold_path();
1019 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1020 address: PackedAddress::new(
1021 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1022 ),
1023 });
1024 };
1025 let sew = config.vtype().vsew();
1026 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
1027 ::core::hint::cold_path();
1028 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1029 address: PackedAddress::new(
1030 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1031 ),
1032 });
1033 };
1034 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1035 program_counter,
1036 config,
1037 vd,
1038 widening_sew.wide().as_eew(),
1039 )?;
1040 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1041 program_counter,
1042 config,
1043 vs2,
1044 widening_sew.wide().as_eew(),
1045 )?;
1046 let scalar = zvexx_widen_narrow_helpers::sign_extend_bits(
1047 rs1_value.as_u64(),
1048 Vsew::from_xlen::<Reg>(),
1049 )
1050 .cast_unsigned();
1051 zvexx_widen_narrow_helpers::execute_widen_w_op::<false, _, _, _>(
1052 env,
1053 vd,
1054 vs2,
1055 zvexx_widen_narrow_helpers::OpSrc::Scalar(scalar),
1056 vm,
1057 widening_sew,
1058 u64::wrapping_sub,
1059 );
1060 }
1061 Self::VnsrlWv { vd, vs2, vs1, vm } => {
1063 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
1064 ::core::hint::cold_path();
1065 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1066 address: PackedAddress::new(
1067 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1068 ),
1069 });
1070 }
1071 let Some(config) = env.vector_config() else {
1072 ::core::hint::cold_path();
1073 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1074 address: PackedAddress::new(
1075 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1076 ),
1077 });
1078 };
1079 let sew = config.vtype().vsew();
1080 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
1081 ::core::hint::cold_path();
1082 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1083 address: PackedAddress::new(
1084 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1085 ),
1086 });
1087 };
1088 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1089 program_counter,
1090 config,
1091 vd,
1092 widening_sew.narrow().as_eew(),
1093 )?;
1094 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1095 program_counter,
1096 config,
1097 vs2,
1098 widening_sew.wide().as_eew(),
1099 )?;
1100 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1101 program_counter,
1102 vd,
1103 vs2,
1104 )?;
1105 let vs1 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1106 program_counter,
1107 config,
1108 vs1,
1109 widening_sew.narrow().as_eew(),
1110 )?;
1111 zvexx_helpers::check_groups_disjoint::<Reg, Env, _, _>(program_counter, vs2, vs1)?;
1113 zvexx_widen_narrow_helpers::execute_narrow_shift::<false, _, _>(
1114 env,
1115 vd,
1116 vs2,
1117 zvexx_widen_narrow_helpers::OpSrc::Vreg(vs1),
1118 vm,
1119 widening_sew,
1120 );
1121 }
1122 Self::VnsrlWx {
1124 vd,
1125 vs2,
1126 rs1: _,
1127 vm,
1128 } => {
1129 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
1130 ::core::hint::cold_path();
1131 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1132 address: PackedAddress::new(
1133 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1134 ),
1135 });
1136 }
1137 let Some(config) = env.vector_config() else {
1138 ::core::hint::cold_path();
1139 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1140 address: PackedAddress::new(
1141 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1142 ),
1143 });
1144 };
1145 let sew = config.vtype().vsew();
1146 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
1147 ::core::hint::cold_path();
1148 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1149 address: PackedAddress::new(
1150 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1151 ),
1152 });
1153 };
1154 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1155 program_counter,
1156 config,
1157 vd,
1158 widening_sew.narrow().as_eew(),
1159 )?;
1160 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1161 program_counter,
1162 config,
1163 vs2,
1164 widening_sew.wide().as_eew(),
1165 )?;
1166 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1167 program_counter,
1168 vd,
1169 vs2,
1170 )?;
1171 let scalar = rs1_value.as_u64();
1172 zvexx_widen_narrow_helpers::execute_narrow_shift::<false, _, _>(
1173 env,
1174 vd,
1175 vs2,
1176 zvexx_widen_narrow_helpers::OpSrc::Scalar(scalar),
1177 vm,
1178 widening_sew,
1179 );
1180 }
1181 Self::VnsrlWi { vd, vs2, uimm, vm } => {
1183 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
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 Some(config) = env.vector_config() else {
1192 ::core::hint::cold_path();
1193 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1194 address: PackedAddress::new(
1195 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1196 ),
1197 });
1198 };
1199 let sew = config.vtype().vsew();
1200 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
1201 ::core::hint::cold_path();
1202 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1203 address: PackedAddress::new(
1204 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1205 ),
1206 });
1207 };
1208 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1209 program_counter,
1210 config,
1211 vd,
1212 widening_sew.narrow().as_eew(),
1213 )?;
1214 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1215 program_counter,
1216 config,
1217 vs2,
1218 widening_sew.wide().as_eew(),
1219 )?;
1220 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1221 program_counter,
1222 vd,
1223 vs2,
1224 )?;
1225 zvexx_widen_narrow_helpers::execute_narrow_shift::<false, _, _>(
1226 env,
1227 vd,
1228 vs2,
1229 zvexx_widen_narrow_helpers::OpSrc::Scalar(u64::from(uimm)),
1230 vm,
1231 widening_sew,
1232 );
1233 }
1234 Self::VnsraWv { vd, vs2, vs1, vm } => {
1236 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
1237 ::core::hint::cold_path();
1238 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1239 address: PackedAddress::new(
1240 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1241 ),
1242 });
1243 }
1244 let Some(config) = env.vector_config() else {
1245 ::core::hint::cold_path();
1246 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1247 address: PackedAddress::new(
1248 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1249 ),
1250 });
1251 };
1252 let sew = config.vtype().vsew();
1253 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
1254 ::core::hint::cold_path();
1255 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1256 address: PackedAddress::new(
1257 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1258 ),
1259 });
1260 };
1261 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1262 program_counter,
1263 config,
1264 vd,
1265 widening_sew.narrow().as_eew(),
1266 )?;
1267 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1268 program_counter,
1269 config,
1270 vs2,
1271 widening_sew.wide().as_eew(),
1272 )?;
1273 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1274 program_counter,
1275 vd,
1276 vs2,
1277 )?;
1278 let vs1 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1279 program_counter,
1280 config,
1281 vs1,
1282 widening_sew.narrow().as_eew(),
1283 )?;
1284 zvexx_helpers::check_groups_disjoint::<Reg, Env, _, _>(program_counter, vs2, vs1)?;
1286 zvexx_widen_narrow_helpers::execute_narrow_shift::<true, _, _>(
1287 env,
1288 vd,
1289 vs2,
1290 zvexx_widen_narrow_helpers::OpSrc::Vreg(vs1),
1291 vm,
1292 widening_sew,
1293 );
1294 }
1295 Self::VnsraWx {
1297 vd,
1298 vs2,
1299 rs1: _,
1300 vm,
1301 } => {
1302 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
1303 ::core::hint::cold_path();
1304 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1305 address: PackedAddress::new(
1306 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1307 ),
1308 });
1309 }
1310 let Some(config) = env.vector_config() else {
1311 ::core::hint::cold_path();
1312 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1313 address: PackedAddress::new(
1314 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1315 ),
1316 });
1317 };
1318 let sew = config.vtype().vsew();
1319 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
1320 ::core::hint::cold_path();
1321 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1322 address: PackedAddress::new(
1323 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1324 ),
1325 });
1326 };
1327 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1328 program_counter,
1329 config,
1330 vd,
1331 widening_sew.narrow().as_eew(),
1332 )?;
1333 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1334 program_counter,
1335 config,
1336 vs2,
1337 widening_sew.wide().as_eew(),
1338 )?;
1339 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1340 program_counter,
1341 vd,
1342 vs2,
1343 )?;
1344 let scalar = rs1_value.as_u64();
1345 zvexx_widen_narrow_helpers::execute_narrow_shift::<true, _, _>(
1346 env,
1347 vd,
1348 vs2,
1349 zvexx_widen_narrow_helpers::OpSrc::Scalar(scalar),
1350 vm,
1351 widening_sew,
1352 );
1353 }
1354 Self::VnsraWi { vd, vs2, uimm, vm } => {
1356 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
1357 ::core::hint::cold_path();
1358 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1359 address: PackedAddress::new(
1360 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1361 ),
1362 });
1363 }
1364 let Some(config) = env.vector_config() else {
1365 ::core::hint::cold_path();
1366 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1367 address: PackedAddress::new(
1368 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1369 ),
1370 });
1371 };
1372 let sew = config.vtype().vsew();
1373 let Some(widening_sew) = zvexx_helpers::WideningSew::<Env::Hart>::new(sew) else {
1374 ::core::hint::cold_path();
1375 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1376 address: PackedAddress::new(
1377 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1378 ),
1379 });
1380 };
1381 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1382 program_counter,
1383 config,
1384 vd,
1385 widening_sew.narrow().as_eew(),
1386 )?;
1387 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1388 program_counter,
1389 config,
1390 vs2,
1391 widening_sew.wide().as_eew(),
1392 )?;
1393 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1394 program_counter,
1395 vd,
1396 vs2,
1397 )?;
1398 zvexx_widen_narrow_helpers::execute_narrow_shift::<true, _, _>(
1399 env,
1400 vd,
1401 vs2,
1402 zvexx_widen_narrow_helpers::OpSrc::Scalar(u64::from(uimm)),
1403 vm,
1404 widening_sew,
1405 );
1406 }
1407 Self::VzextVf2 { vd, vs2, vm } => {
1409 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
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 Some(config) = env.vector_config() else {
1418 ::core::hint::cold_path();
1419 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1420 address: PackedAddress::new(
1421 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1422 ),
1423 });
1424 };
1425 let sew = config.vtype().vsew();
1426 let Some(extension_sew) = zvexx_helpers::ExtensionSew::new(sew, VsewFactor::F2)
1427 else {
1428 ::core::hint::cold_path();
1429 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1430 address: PackedAddress::new(
1431 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1432 ),
1433 });
1434 };
1435 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1436 program_counter,
1437 config,
1438 vd,
1439 extension_sew.dest().as_eew(),
1440 )?;
1441 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1442 program_counter,
1443 config,
1444 vs2,
1445 extension_sew.source().as_eew(),
1446 )?;
1447 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1449 program_counter,
1450 vd,
1451 vs2,
1452 )?;
1453 zvexx_widen_narrow_helpers::execute_extension::<false, _, _>(
1454 env,
1455 vd,
1456 vs2,
1457 vm,
1458 extension_sew,
1459 );
1460 }
1461 Self::VzextVf4 { vd, vs2, vm } => {
1463 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
1464 ::core::hint::cold_path();
1465 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1466 address: PackedAddress::new(
1467 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1468 ),
1469 });
1470 }
1471 let Some(config) = env.vector_config() else {
1472 ::core::hint::cold_path();
1473 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1474 address: PackedAddress::new(
1475 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1476 ),
1477 });
1478 };
1479 let sew = config.vtype().vsew();
1480 let Some(extension_sew) = zvexx_helpers::ExtensionSew::new(sew, VsewFactor::F4)
1481 else {
1482 ::core::hint::cold_path();
1483 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1484 address: PackedAddress::new(
1485 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1486 ),
1487 });
1488 };
1489 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1490 program_counter,
1491 config,
1492 vd,
1493 extension_sew.dest().as_eew(),
1494 )?;
1495 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1496 program_counter,
1497 config,
1498 vs2,
1499 extension_sew.source().as_eew(),
1500 )?;
1501 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1503 program_counter,
1504 vd,
1505 vs2,
1506 )?;
1507 zvexx_widen_narrow_helpers::execute_extension::<false, _, _>(
1508 env,
1509 vd,
1510 vs2,
1511 vm,
1512 extension_sew,
1513 );
1514 }
1515 Self::VzextVf8 { vd, vs2, vm } => {
1517 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
1518 ::core::hint::cold_path();
1519 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1520 address: PackedAddress::new(
1521 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1522 ),
1523 });
1524 }
1525 let Some(config) = env.vector_config() else {
1526 ::core::hint::cold_path();
1527 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1528 address: PackedAddress::new(
1529 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1530 ),
1531 });
1532 };
1533 let sew = config.vtype().vsew();
1534 let Some(extension_sew) = zvexx_helpers::ExtensionSew::new(sew, VsewFactor::F8)
1535 else {
1536 ::core::hint::cold_path();
1537 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1538 address: PackedAddress::new(
1539 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1540 ),
1541 });
1542 };
1543 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1544 program_counter,
1545 config,
1546 vd,
1547 extension_sew.dest().as_eew(),
1548 )?;
1549 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1550 program_counter,
1551 config,
1552 vs2,
1553 extension_sew.source().as_eew(),
1554 )?;
1555 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1557 program_counter,
1558 vd,
1559 vs2,
1560 )?;
1561 zvexx_widen_narrow_helpers::execute_extension::<false, _, _>(
1562 env,
1563 vd,
1564 vs2,
1565 vm,
1566 extension_sew,
1567 );
1568 }
1569 Self::VsextVf2 { vd, vs2, vm } => {
1571 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
1572 ::core::hint::cold_path();
1573 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1574 address: PackedAddress::new(
1575 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1576 ),
1577 });
1578 }
1579 let Some(config) = env.vector_config() else {
1580 ::core::hint::cold_path();
1581 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1582 address: PackedAddress::new(
1583 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1584 ),
1585 });
1586 };
1587 let sew = config.vtype().vsew();
1588 let Some(extension_sew) = zvexx_helpers::ExtensionSew::new(sew, VsewFactor::F2)
1589 else {
1590 ::core::hint::cold_path();
1591 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1592 address: PackedAddress::new(
1593 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1594 ),
1595 });
1596 };
1597 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1598 program_counter,
1599 config,
1600 vd,
1601 extension_sew.dest().as_eew(),
1602 )?;
1603 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1604 program_counter,
1605 config,
1606 vs2,
1607 extension_sew.source().as_eew(),
1608 )?;
1609 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1611 program_counter,
1612 vd,
1613 vs2,
1614 )?;
1615 zvexx_widen_narrow_helpers::execute_extension::<true, _, _>(
1616 env,
1617 vd,
1618 vs2,
1619 vm,
1620 extension_sew,
1621 );
1622 }
1623 Self::VsextVf4 { vd, vs2, vm } => {
1625 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
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 Some(config) = env.vector_config() else {
1634 ::core::hint::cold_path();
1635 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1636 address: PackedAddress::new(
1637 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1638 ),
1639 });
1640 };
1641 let sew = config.vtype().vsew();
1642 let Some(extension_sew) = zvexx_helpers::ExtensionSew::new(sew, VsewFactor::F4)
1643 else {
1644 ::core::hint::cold_path();
1645 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1646 address: PackedAddress::new(
1647 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1648 ),
1649 });
1650 };
1651 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1652 program_counter,
1653 config,
1654 vd,
1655 extension_sew.dest().as_eew(),
1656 )?;
1657 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1658 program_counter,
1659 config,
1660 vs2,
1661 extension_sew.source().as_eew(),
1662 )?;
1663 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1665 program_counter,
1666 vd,
1667 vs2,
1668 )?;
1669 zvexx_widen_narrow_helpers::execute_extension::<true, _, _>(
1670 env,
1671 vd,
1672 vs2,
1673 vm,
1674 extension_sew,
1675 );
1676 }
1677 Self::VsextVf8 { vd, vs2, vm } => {
1679 if !zvexx_helpers::non_memory_instruction_allowed::<Reg, _>(env) {
1680 ::core::hint::cold_path();
1681 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1682 address: PackedAddress::new(
1683 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1684 ),
1685 });
1686 }
1687 let Some(config) = env.vector_config() else {
1688 ::core::hint::cold_path();
1689 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1690 address: PackedAddress::new(
1691 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1692 ),
1693 });
1694 };
1695 let sew = config.vtype().vsew();
1696 let Some(extension_sew) = zvexx_helpers::ExtensionSew::new(sew, VsewFactor::F8)
1697 else {
1698 ::core::hint::cold_path();
1699 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
1700 address: PackedAddress::new(
1701 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
1702 ),
1703 });
1704 };
1705 let vd = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1706 program_counter,
1707 config,
1708 vd,
1709 extension_sew.dest().as_eew(),
1710 )?;
1711 let vs2 = zvexx_helpers::vreg_group::<Reg, Env, _, _>(
1712 program_counter,
1713 config,
1714 vs2,
1715 extension_sew.source().as_eew(),
1716 )?;
1717 zvexx_helpers::check_destination_overlap::<Reg, Env, _, _>(
1719 program_counter,
1720 vd,
1721 vs2,
1722 )?;
1723 zvexx_widen_narrow_helpers::execute_extension::<true, _, _>(
1724 env,
1725 vd,
1726 vs2,
1727 vm,
1728 extension_sew,
1729 );
1730 }
1731 }
1732
1733 ExecutionResult::ContinueNoWrite
1734 }
1735}