1#[cfg(test)]
4mod tests;
5pub mod zvexx_carry_helpers;
6
7use crate::v::vector_registers::VectorRegistersExt;
8use crate::v::zvexx::zvexx_helpers;
9use crate::{
10 ExecutableInstruction, ExecutableInstructionCsr, ExecutableInstructionOperands, ExecutionError,
11 ExecutionResult, FetchInstructionResult, InstructionFetcher, OpaqueThreadedExecutionResult,
12 PackedAddress, ProgramCounter, RegisterFile, Rs1Rs2OperandValues, Rs1Rs2Operands,
13 ThreadedExecutableInstruction, ThreadedExecutionResult, VirtualMemory,
14};
15use ab_riscv_macros::instruction_execution;
16use ab_riscv_primitives::prelude::*;
17
18#[instruction_execution]
19const impl<Reg> ExecutableInstructionOperands for ZveXxCarryInstruction<Reg> where Reg: Register {}
20
21#[instruction_execution]
22const impl<Reg, Env> ExecutableInstructionCsr<Env> for ZveXxCarryInstruction<Reg> where Reg: Register
23{}
24
25#[instruction_execution]
26impl<Reg, Regs, Env, Memory, PC> ExecutableInstruction<Regs, Env, Memory, PC>
27 for ZveXxCarryInstruction<Reg>
28where
29 Reg: Register,
30 Regs: RegisterFile<Reg>,
31 Env: VectorRegistersExt<Reg>,
32 [(); SUPPORTED_ELEN_VLEN::<{ Env::ELEN }, { Env::VLEN }>]:,
33 Memory: VirtualMemory,
34 PC: ProgramCounter<Reg::Type, Memory>,
35{
36 #[inline(always)]
37 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
38 fn execute(
39 self,
40 Rs1Rs2OperandValues {
41 rs1_value,
42 rs2_value: _,
43 }: Rs1Rs2OperandValues<<Self::Reg as Register>::Type>,
44 _regs: &mut Regs,
45 env: &mut Env,
46 _memory: &mut Memory,
47 program_counter: &mut PC,
48 ) -> ExecutionResult<Self::Reg> {
49 match self {
50 Self::VadcVvm { vd, vs2, vs1 } => {
52 if !env.vector_instructions_allowed() {
53 ::core::hint::cold_path();
54 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
55 address: PackedAddress::new(
56 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
57 ),
58 });
59 }
60 let Some(vtype) = env.vtype() else {
61 ::core::hint::cold_path();
62 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
63 address: PackedAddress::new(
64 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
65 ),
66 });
67 };
68 let group_regs = vtype.vlmul().register_count();
69 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
70 program_counter,
71 vd,
72 group_regs,
73 )?;
74 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
75 program_counter,
76 vs2,
77 group_regs,
78 )?;
79 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
80 program_counter,
81 vs1,
82 group_regs,
83 )?;
84 if vd == VReg::V0 {
86 ::core::hint::cold_path();
87 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
88 address: PackedAddress::new(
89 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
90 ),
91 });
92 }
93 let sew = vtype.vsew();
94 unsafe {
96 zvexx_carry_helpers::execute_carry_add::<true, Reg, _>(
97 env,
98 vd,
99 vs2,
100 zvexx_carry_helpers::OpSrc::Vreg(vs1),
101 sew,
102 );
103 }
104 }
105
106 Self::VadcVxm { vd, vs2, rs1: _ } => {
107 if !env.vector_instructions_allowed() {
108 ::core::hint::cold_path();
109 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
110 address: PackedAddress::new(
111 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
112 ),
113 });
114 }
115 let Some(vtype) = env.vtype() else {
116 ::core::hint::cold_path();
117 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
118 address: PackedAddress::new(
119 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
120 ),
121 });
122 };
123 let group_regs = vtype.vlmul().register_count();
124 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
125 program_counter,
126 vd,
127 group_regs,
128 )?;
129 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
130 program_counter,
131 vs2,
132 group_regs,
133 )?;
134 if vd == VReg::V0 {
135 ::core::hint::cold_path();
136 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
137 address: PackedAddress::new(
138 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
139 ),
140 });
141 }
142 let sew = vtype.vsew();
143 let scalar = rs1_value.as_i64().cast_unsigned();
144 unsafe {
146 zvexx_carry_helpers::execute_carry_add::<true, Reg, _>(
147 env,
148 vd,
149 vs2,
150 zvexx_carry_helpers::OpSrc::Scalar(scalar),
151 sew,
152 );
153 }
154 }
155
156 Self::VadcVim { vd, vs2, imm } => {
157 if !env.vector_instructions_allowed() {
158 ::core::hint::cold_path();
159 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
160 address: PackedAddress::new(
161 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
162 ),
163 });
164 }
165 let Some(vtype) = env.vtype() else {
166 ::core::hint::cold_path();
167 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
168 address: PackedAddress::new(
169 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
170 ),
171 });
172 };
173 let group_regs = vtype.vlmul().register_count();
174 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
175 program_counter,
176 vd,
177 group_regs,
178 )?;
179 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
180 program_counter,
181 vs2,
182 group_regs,
183 )?;
184 if vd == VReg::V0 {
185 ::core::hint::cold_path();
186 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
187 address: PackedAddress::new(
188 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
189 ),
190 });
191 }
192 let sew = vtype.vsew();
193 let scalar = i64::from(imm).cast_unsigned();
194 unsafe {
196 zvexx_carry_helpers::execute_carry_add::<true, Reg, _>(
197 env,
198 vd,
199 vs2,
200 zvexx_carry_helpers::OpSrc::Scalar(scalar),
201 sew,
202 );
203 }
204 }
205
206 Self::VmadcVvm { vd, vs2, vs1 } => {
208 if !env.vector_instructions_allowed() {
209 ::core::hint::cold_path();
210 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
211 address: PackedAddress::new(
212 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
213 ),
214 });
215 }
216 let Some(vtype) = env.vtype() else {
217 ::core::hint::cold_path();
218 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
219 address: PackedAddress::new(
220 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
221 ),
222 });
223 };
224 let group_regs = vtype.vlmul().register_count();
225 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
226 program_counter,
227 vs2,
228 group_regs,
229 )?;
230 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
231 program_counter,
232 vs1,
233 group_regs,
234 )?;
235 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
236 program_counter,
237 vd,
238 vs2,
239 group_regs,
240 )?;
241 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
242 program_counter,
243 vd,
244 vs1,
245 group_regs,
246 )?;
247 let sew = vtype.vsew();
248 unsafe {
250 zvexx_carry_helpers::execute_carry_add_mask::<true, Reg, _>(
251 env,
252 vd,
253 vs2,
254 zvexx_carry_helpers::OpSrc::Vreg(vs1),
255 sew,
256 );
257 }
258 }
259
260 Self::VmadcVxm { vd, vs2, rs1: _ } => {
261 if !env.vector_instructions_allowed() {
262 ::core::hint::cold_path();
263 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
264 address: PackedAddress::new(
265 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
266 ),
267 });
268 }
269 let Some(vtype) = env.vtype() else {
270 ::core::hint::cold_path();
271 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
272 address: PackedAddress::new(
273 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
274 ),
275 });
276 };
277 let group_regs = vtype.vlmul().register_count();
278 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
279 program_counter,
280 vs2,
281 group_regs,
282 )?;
283 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
284 program_counter,
285 vd,
286 vs2,
287 group_regs,
288 )?;
289 let sew = vtype.vsew();
290 let scalar = rs1_value.as_i64().cast_unsigned();
291 unsafe {
293 zvexx_carry_helpers::execute_carry_add_mask::<true, Reg, _>(
294 env,
295 vd,
296 vs2,
297 zvexx_carry_helpers::OpSrc::Scalar(scalar),
298 sew,
299 );
300 }
301 }
302
303 Self::VmadcVim { vd, vs2, imm } => {
304 if !env.vector_instructions_allowed() {
305 ::core::hint::cold_path();
306 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
307 address: PackedAddress::new(
308 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
309 ),
310 });
311 }
312 let Some(vtype) = env.vtype() else {
313 ::core::hint::cold_path();
314 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
315 address: PackedAddress::new(
316 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
317 ),
318 });
319 };
320 let group_regs = vtype.vlmul().register_count();
321 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
322 program_counter,
323 vs2,
324 group_regs,
325 )?;
326 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
327 program_counter,
328 vd,
329 vs2,
330 group_regs,
331 )?;
332 let sew = vtype.vsew();
333 let scalar = i64::from(imm).cast_unsigned();
334 unsafe {
336 zvexx_carry_helpers::execute_carry_add_mask::<true, Reg, _>(
337 env,
338 vd,
339 vs2,
340 zvexx_carry_helpers::OpSrc::Scalar(scalar),
341 sew,
342 );
343 }
344 }
345
346 Self::VmadcVv { vd, vs2, vs1 } => {
347 if !env.vector_instructions_allowed() {
348 ::core::hint::cold_path();
349 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
350 address: PackedAddress::new(
351 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
352 ),
353 });
354 }
355 let Some(vtype) = env.vtype() else {
356 ::core::hint::cold_path();
357 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
358 address: PackedAddress::new(
359 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
360 ),
361 });
362 };
363 let group_regs = vtype.vlmul().register_count();
364 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
365 program_counter,
366 vs2,
367 group_regs,
368 )?;
369 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
370 program_counter,
371 vs1,
372 group_regs,
373 )?;
374 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
375 program_counter,
376 vd,
377 vs2,
378 group_regs,
379 )?;
380 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
381 program_counter,
382 vd,
383 vs1,
384 group_regs,
385 )?;
386 let sew = vtype.vsew();
387 unsafe {
389 zvexx_carry_helpers::execute_carry_add_mask::<false, Reg, _>(
390 env,
391 vd,
392 vs2,
393 zvexx_carry_helpers::OpSrc::Vreg(vs1),
394 sew,
395 );
396 }
397 }
398
399 Self::VmadcVx { vd, vs2, rs1: _ } => {
400 if !env.vector_instructions_allowed() {
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 Some(vtype) = env.vtype() else {
409 ::core::hint::cold_path();
410 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
411 address: PackedAddress::new(
412 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
413 ),
414 });
415 };
416 let group_regs = vtype.vlmul().register_count();
417 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
418 program_counter,
419 vs2,
420 group_regs,
421 )?;
422 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
423 program_counter,
424 vd,
425 vs2,
426 group_regs,
427 )?;
428 let sew = vtype.vsew();
429 let scalar = rs1_value.as_i64().cast_unsigned();
430 unsafe {
432 zvexx_carry_helpers::execute_carry_add_mask::<false, Reg, _>(
433 env,
434 vd,
435 vs2,
436 zvexx_carry_helpers::OpSrc::Scalar(scalar),
437 sew,
438 );
439 }
440 }
441
442 Self::VmadcVi { vd, vs2, imm } => {
443 if !env.vector_instructions_allowed() {
444 ::core::hint::cold_path();
445 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
446 address: PackedAddress::new(
447 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
448 ),
449 });
450 }
451 let Some(vtype) = env.vtype() else {
452 ::core::hint::cold_path();
453 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
454 address: PackedAddress::new(
455 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
456 ),
457 });
458 };
459 let group_regs = vtype.vlmul().register_count();
460 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
461 program_counter,
462 vs2,
463 group_regs,
464 )?;
465 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
466 program_counter,
467 vd,
468 vs2,
469 group_regs,
470 )?;
471 let sew = vtype.vsew();
472 let scalar = i64::from(imm).cast_unsigned();
473 unsafe {
475 zvexx_carry_helpers::execute_carry_add_mask::<false, Reg, _>(
476 env,
477 vd,
478 vs2,
479 zvexx_carry_helpers::OpSrc::Scalar(scalar),
480 sew,
481 );
482 }
483 }
484
485 Self::VsbcVvm { vd, vs2, vs1 } => {
487 if !env.vector_instructions_allowed() {
488 ::core::hint::cold_path();
489 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
490 address: PackedAddress::new(
491 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
492 ),
493 });
494 }
495 let Some(vtype) = env.vtype() else {
496 ::core::hint::cold_path();
497 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
498 address: PackedAddress::new(
499 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
500 ),
501 });
502 };
503 let group_regs = vtype.vlmul().register_count();
504 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
505 program_counter,
506 vd,
507 group_regs,
508 )?;
509 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
510 program_counter,
511 vs2,
512 group_regs,
513 )?;
514 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
515 program_counter,
516 vs1,
517 group_regs,
518 )?;
519 if vd == VReg::V0 {
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 = vtype.vsew();
528 unsafe {
530 zvexx_carry_helpers::execute_carry_sub::<Reg, _>(
531 env,
532 vd,
533 vs2,
534 zvexx_carry_helpers::OpSrc::Vreg(vs1),
535 sew,
536 );
537 }
538 }
539
540 Self::VsbcVxm { vd, vs2, rs1: _ } => {
541 if !env.vector_instructions_allowed() {
542 ::core::hint::cold_path();
543 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
544 address: PackedAddress::new(
545 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
546 ),
547 });
548 }
549 let Some(vtype) = env.vtype() else {
550 ::core::hint::cold_path();
551 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
552 address: PackedAddress::new(
553 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
554 ),
555 });
556 };
557 let group_regs = vtype.vlmul().register_count();
558 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
559 program_counter,
560 vd,
561 group_regs,
562 )?;
563 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
564 program_counter,
565 vs2,
566 group_regs,
567 )?;
568 if vd == VReg::V0 {
569 ::core::hint::cold_path();
570 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
571 address: PackedAddress::new(
572 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
573 ),
574 });
575 }
576 let sew = vtype.vsew();
577 let scalar = rs1_value.as_i64().cast_unsigned();
578 unsafe {
580 zvexx_carry_helpers::execute_carry_sub::<Reg, _>(
581 env,
582 vd,
583 vs2,
584 zvexx_carry_helpers::OpSrc::Scalar(scalar),
585 sew,
586 );
587 }
588 }
589
590 Self::VmsbcVvm { vd, vs2, vs1 } => {
592 if !env.vector_instructions_allowed() {
593 ::core::hint::cold_path();
594 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
595 address: PackedAddress::new(
596 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
597 ),
598 });
599 }
600 let Some(vtype) = env.vtype() else {
601 ::core::hint::cold_path();
602 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
603 address: PackedAddress::new(
604 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
605 ),
606 });
607 };
608 let group_regs = vtype.vlmul().register_count();
609 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
610 program_counter,
611 vs2,
612 group_regs,
613 )?;
614 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
615 program_counter,
616 vs1,
617 group_regs,
618 )?;
619 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
620 program_counter,
621 vd,
622 vs2,
623 group_regs,
624 )?;
625 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
626 program_counter,
627 vd,
628 vs1,
629 group_regs,
630 )?;
631 let sew = vtype.vsew();
632 unsafe {
634 zvexx_carry_helpers::execute_carry_sub_mask::<true, Reg, _>(
635 env,
636 vd,
637 vs2,
638 zvexx_carry_helpers::OpSrc::Vreg(vs1),
639 sew,
640 );
641 }
642 }
643
644 Self::VmsbcVxm { vd, vs2, rs1: _ } => {
645 if !env.vector_instructions_allowed() {
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(vtype) = env.vtype() 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 group_regs = vtype.vlmul().register_count();
662 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
663 program_counter,
664 vs2,
665 group_regs,
666 )?;
667 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
668 program_counter,
669 vd,
670 vs2,
671 group_regs,
672 )?;
673 let sew = vtype.vsew();
674 let scalar = rs1_value.as_i64().cast_unsigned();
675 unsafe {
677 zvexx_carry_helpers::execute_carry_sub_mask::<true, Reg, _>(
678 env,
679 vd,
680 vs2,
681 zvexx_carry_helpers::OpSrc::Scalar(scalar),
682 sew,
683 );
684 }
685 }
686
687 Self::VmsbcVv { vd, vs2, vs1 } => {
688 if !env.vector_instructions_allowed() {
689 ::core::hint::cold_path();
690 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
691 address: PackedAddress::new(
692 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
693 ),
694 });
695 }
696 let Some(vtype) = env.vtype() else {
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 group_regs = vtype.vlmul().register_count();
705 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
706 program_counter,
707 vs2,
708 group_regs,
709 )?;
710 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
711 program_counter,
712 vs1,
713 group_regs,
714 )?;
715 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
716 program_counter,
717 vd,
718 vs2,
719 group_regs,
720 )?;
721 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
722 program_counter,
723 vd,
724 vs1,
725 group_regs,
726 )?;
727 let sew = vtype.vsew();
728 unsafe {
730 zvexx_carry_helpers::execute_carry_sub_mask::<false, Reg, _>(
731 env,
732 vd,
733 vs2,
734 zvexx_carry_helpers::OpSrc::Vreg(vs1),
735 sew,
736 );
737 }
738 }
739
740 Self::VmsbcVx { vd, vs2, rs1: _ } => {
741 if !env.vector_instructions_allowed() {
742 ::core::hint::cold_path();
743 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
744 address: PackedAddress::new(
745 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
746 ),
747 });
748 }
749 let Some(vtype) = env.vtype() else {
750 ::core::hint::cold_path();
751 return ExecutionResult::Err(ExecutionError::IllegalInstruction {
752 address: PackedAddress::new(
753 program_counter.old_pc(zvexx_helpers::INSTRUCTION_SIZE),
754 ),
755 });
756 };
757 let group_regs = vtype.vlmul().register_count();
758 zvexx_carry_helpers::check_vreg_group_alignment::<Reg, _, _>(
759 program_counter,
760 vs2,
761 group_regs,
762 )?;
763 zvexx_carry_helpers::check_mask_dest_overlap::<Reg, _, _>(
764 program_counter,
765 vd,
766 vs2,
767 group_regs,
768 )?;
769 let sew = vtype.vsew();
770 let scalar = rs1_value.as_i64().cast_unsigned();
771 unsafe {
773 zvexx_carry_helpers::execute_carry_sub_mask::<false, Reg, _>(
774 env,
775 vd,
776 vs2,
777 zvexx_carry_helpers::OpSrc::Scalar(scalar),
778 sew,
779 );
780 }
781 }
782 }
783
784 ExecutionResult::ContinueNoWrite
785 }
786}