1#[cfg(test)]
4mod tests;
5pub mod zve64x_fixed_point_helpers;
6
7use crate::v::vector_registers::VectorRegistersExt;
8use crate::v::zve64x::zve64x_helpers;
9use crate::{ExecutableInstruction, ExecutionError, ProgramCounter, RegisterFile, VirtualMemory};
10use ab_riscv_macros::instruction_execution;
11use ab_riscv_primitives::prelude::*;
12use core::fmt;
13use core::ops::ControlFlow;
14
15#[instruction_execution]
16impl<Reg, Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
17 ExecutableInstruction<Regs, ExtState, Memory, PC, InstructionHandler, CustomError>
18 for Zve64xFixedPointInstruction<Reg>
19where
20 Reg: Register,
21 Regs: RegisterFile<Reg>,
22 ExtState: VectorRegistersExt<Reg, CustomError>,
23 [(); ExtState::ELEN as usize]:,
24 [(); ExtState::VLEN as usize]:,
25 [(); ExtState::VLENB as usize]:,
26 Memory: VirtualMemory,
27 PC: ProgramCounter<Reg::Type, Memory, CustomError>,
28 CustomError: fmt::Debug,
29{
30 #[inline(always)]
31 fn execute(
32 self,
33 regs: &mut Regs,
34 ext_state: &mut ExtState,
35 _memory: &mut Memory,
36 program_counter: &mut PC,
37 _system_instruction_handler: &mut InstructionHandler,
38 ) -> Result<ControlFlow<()>, ExecutionError<Reg::Type, CustomError>> {
39 match self {
40 Self::VsadduVv { vd, vs2, vs1, vm } => {
42 if !ext_state.vector_instructions_allowed() {
43 Err(ExecutionError::IllegalInstruction {
44 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
45 })?;
46 }
47 let vtype = ext_state
48 .vtype()
49 .ok_or(ExecutionError::IllegalInstruction {
50 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
51 })?;
52 let group_regs = vtype.vlmul().register_count();
53 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
54 program_counter,
55 vd,
56 group_regs,
57 )?;
58 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
59 program_counter,
60 vs2,
61 group_regs,
62 )?;
63 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
64 program_counter,
65 vs1,
66 group_regs,
67 )?;
68 if !vm && vd.bits() == 0 {
69 Err(ExecutionError::IllegalInstruction {
70 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
71 })?;
72 }
73 let sew = vtype.vsew();
74 let vl = ext_state.vl();
75 let vstart = u32::from(ext_state.vstart());
76 unsafe {
78 zve64x_fixed_point_helpers::execute_fixed_point_op(
79 ext_state,
80 vd,
81 vs2,
82 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
83 vm,
84 vl,
85 vstart,
86 sew,
87 |a, b, sew, _vxrm, vxsat| {
88 zve64x_fixed_point_helpers::sat_addu(a, b, sew, vxsat)
89 },
90 );
91 }
92 }
93 Self::VsadduVx { vd, vs2, rs1, vm } => {
94 if !ext_state.vector_instructions_allowed() {
95 Err(ExecutionError::IllegalInstruction {
96 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
97 })?;
98 }
99 let vtype = ext_state
100 .vtype()
101 .ok_or(ExecutionError::IllegalInstruction {
102 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
103 })?;
104 let group_regs = vtype.vlmul().register_count();
105 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
106 program_counter,
107 vd,
108 group_regs,
109 )?;
110 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
111 program_counter,
112 vs2,
113 group_regs,
114 )?;
115 if !vm && vd.bits() == 0 {
116 Err(ExecutionError::IllegalInstruction {
117 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
118 })?;
119 }
120 let sew = vtype.vsew();
121 let vl = ext_state.vl();
122 let vstart = u32::from(ext_state.vstart());
123 let scalar = regs.read(rs1).as_u64();
124 unsafe {
126 zve64x_fixed_point_helpers::execute_fixed_point_op(
127 ext_state,
128 vd,
129 vs2,
130 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
131 vm,
132 vl,
133 vstart,
134 sew,
135 |a, b, sew, _vxrm, vxsat| {
136 zve64x_fixed_point_helpers::sat_addu(a, b, sew, vxsat)
137 },
138 );
139 }
140 }
141 Self::VsadduVi { vd, vs2, imm, vm } => {
142 if !ext_state.vector_instructions_allowed() {
143 Err(ExecutionError::IllegalInstruction {
144 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
145 })?;
146 }
147 let vtype = ext_state
148 .vtype()
149 .ok_or(ExecutionError::IllegalInstruction {
150 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
151 })?;
152 let group_regs = vtype.vlmul().register_count();
153 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
154 program_counter,
155 vd,
156 group_regs,
157 )?;
158 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
159 program_counter,
160 vs2,
161 group_regs,
162 )?;
163 if !vm && vd.bits() == 0 {
164 Err(ExecutionError::IllegalInstruction {
165 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
166 })?;
167 }
168 let sew = vtype.vsew();
169 let vl = ext_state.vl();
170 let vstart = u32::from(ext_state.vstart());
171 let scalar = i64::from(imm).cast_unsigned();
175 unsafe {
176 zve64x_fixed_point_helpers::execute_fixed_point_op(
177 ext_state,
178 vd,
179 vs2,
180 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
181 vm,
182 vl,
183 vstart,
184 sew,
185 |a, b, sew, _vxrm, vxsat| {
186 zve64x_fixed_point_helpers::sat_addu(a, b, sew, vxsat)
187 },
188 );
189 }
190 }
191 Self::VsaddVv { vd, vs2, vs1, vm } => {
193 if !ext_state.vector_instructions_allowed() {
194 Err(ExecutionError::IllegalInstruction {
195 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
196 })?;
197 }
198 let vtype = ext_state
199 .vtype()
200 .ok_or(ExecutionError::IllegalInstruction {
201 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
202 })?;
203 let group_regs = vtype.vlmul().register_count();
204 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
205 program_counter,
206 vd,
207 group_regs,
208 )?;
209 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
210 program_counter,
211 vs2,
212 group_regs,
213 )?;
214 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
215 program_counter,
216 vs1,
217 group_regs,
218 )?;
219 if !vm && vd.bits() == 0 {
220 Err(ExecutionError::IllegalInstruction {
221 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
222 })?;
223 }
224 let sew = vtype.vsew();
225 let vl = ext_state.vl();
226 let vstart = u32::from(ext_state.vstart());
227 unsafe {
229 zve64x_fixed_point_helpers::execute_fixed_point_op(
230 ext_state,
231 vd,
232 vs2,
233 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
234 vm,
235 vl,
236 vstart,
237 sew,
238 |a, b, sew, _vxrm, vxsat| {
239 zve64x_fixed_point_helpers::sat_add(a, b, sew, vxsat)
240 },
241 );
242 }
243 }
244 Self::VsaddVx { vd, vs2, rs1, vm } => {
245 if !ext_state.vector_instructions_allowed() {
246 Err(ExecutionError::IllegalInstruction {
247 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
248 })?;
249 }
250 let vtype = ext_state
251 .vtype()
252 .ok_or(ExecutionError::IllegalInstruction {
253 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
254 })?;
255 let group_regs = vtype.vlmul().register_count();
256 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
257 program_counter,
258 vd,
259 group_regs,
260 )?;
261 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
262 program_counter,
263 vs2,
264 group_regs,
265 )?;
266 if !vm && vd.bits() == 0 {
267 Err(ExecutionError::IllegalInstruction {
268 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
269 })?;
270 }
271 let sew = vtype.vsew();
272 let vl = ext_state.vl();
273 let vstart = u32::from(ext_state.vstart());
274 let scalar = regs.read(rs1).as_u64();
275 unsafe {
277 zve64x_fixed_point_helpers::execute_fixed_point_op(
278 ext_state,
279 vd,
280 vs2,
281 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
282 vm,
283 vl,
284 vstart,
285 sew,
286 |a, b, sew, _vxrm, vxsat| {
287 zve64x_fixed_point_helpers::sat_add(a, b, sew, vxsat)
288 },
289 );
290 }
291 }
292 Self::VsaddVi { vd, vs2, imm, vm } => {
293 if !ext_state.vector_instructions_allowed() {
294 Err(ExecutionError::IllegalInstruction {
295 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
296 })?;
297 }
298 let vtype = ext_state
299 .vtype()
300 .ok_or(ExecutionError::IllegalInstruction {
301 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
302 })?;
303 let group_regs = vtype.vlmul().register_count();
304 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
305 program_counter,
306 vd,
307 group_regs,
308 )?;
309 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
310 program_counter,
311 vs2,
312 group_regs,
313 )?;
314 if !vm && vd.bits() == 0 {
315 Err(ExecutionError::IllegalInstruction {
316 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
317 })?;
318 }
319 let sew = vtype.vsew();
320 let vl = ext_state.vl();
321 let vstart = u32::from(ext_state.vstart());
322 let scalar = i64::from(imm).cast_unsigned();
324 unsafe {
326 zve64x_fixed_point_helpers::execute_fixed_point_op(
327 ext_state,
328 vd,
329 vs2,
330 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
331 vm,
332 vl,
333 vstart,
334 sew,
335 |a, b, sew, _vxrm, vxsat| {
336 zve64x_fixed_point_helpers::sat_add(a, b, sew, vxsat)
337 },
338 );
339 }
340 }
341 Self::VssubuVv { vd, vs2, vs1, vm } => {
343 if !ext_state.vector_instructions_allowed() {
344 Err(ExecutionError::IllegalInstruction {
345 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
346 })?;
347 }
348 let vtype = ext_state
349 .vtype()
350 .ok_or(ExecutionError::IllegalInstruction {
351 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
352 })?;
353 let group_regs = vtype.vlmul().register_count();
354 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
355 program_counter,
356 vd,
357 group_regs,
358 )?;
359 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
360 program_counter,
361 vs2,
362 group_regs,
363 )?;
364 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
365 program_counter,
366 vs1,
367 group_regs,
368 )?;
369 if !vm && vd.bits() == 0 {
370 Err(ExecutionError::IllegalInstruction {
371 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
372 })?;
373 }
374 let sew = vtype.vsew();
375 let vl = ext_state.vl();
376 let vstart = u32::from(ext_state.vstart());
377 unsafe {
379 zve64x_fixed_point_helpers::execute_fixed_point_op(
380 ext_state,
381 vd,
382 vs2,
383 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
384 vm,
385 vl,
386 vstart,
387 sew,
388 |a, b, sew, _vxrm, vxsat| {
389 zve64x_fixed_point_helpers::sat_subu(a, b, sew, vxsat)
390 },
391 );
392 }
393 }
394 Self::VssubuVx { vd, vs2, rs1, vm } => {
395 if !ext_state.vector_instructions_allowed() {
396 Err(ExecutionError::IllegalInstruction {
397 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
398 })?;
399 }
400 let vtype = ext_state
401 .vtype()
402 .ok_or(ExecutionError::IllegalInstruction {
403 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
404 })?;
405 let group_regs = vtype.vlmul().register_count();
406 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
407 program_counter,
408 vd,
409 group_regs,
410 )?;
411 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
412 program_counter,
413 vs2,
414 group_regs,
415 )?;
416 if !vm && vd.bits() == 0 {
417 Err(ExecutionError::IllegalInstruction {
418 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
419 })?;
420 }
421 let sew = vtype.vsew();
422 let vl = ext_state.vl();
423 let vstart = u32::from(ext_state.vstart());
424 let scalar = regs.read(rs1).as_u64();
425 unsafe {
427 zve64x_fixed_point_helpers::execute_fixed_point_op(
428 ext_state,
429 vd,
430 vs2,
431 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
432 vm,
433 vl,
434 vstart,
435 sew,
436 |a, b, sew, _vxrm, vxsat| {
437 zve64x_fixed_point_helpers::sat_subu(a, b, sew, vxsat)
438 },
439 );
440 }
441 }
442 Self::VssubVv { vd, vs2, vs1, vm } => {
444 if !ext_state.vector_instructions_allowed() {
445 Err(ExecutionError::IllegalInstruction {
446 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
447 })?;
448 }
449 let vtype = ext_state
450 .vtype()
451 .ok_or(ExecutionError::IllegalInstruction {
452 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
453 })?;
454 let group_regs = vtype.vlmul().register_count();
455 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
456 program_counter,
457 vd,
458 group_regs,
459 )?;
460 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
461 program_counter,
462 vs2,
463 group_regs,
464 )?;
465 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
466 program_counter,
467 vs1,
468 group_regs,
469 )?;
470 if !vm && vd.bits() == 0 {
471 Err(ExecutionError::IllegalInstruction {
472 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
473 })?;
474 }
475 let sew = vtype.vsew();
476 let vl = ext_state.vl();
477 let vstart = u32::from(ext_state.vstart());
478 unsafe {
480 zve64x_fixed_point_helpers::execute_fixed_point_op(
481 ext_state,
482 vd,
483 vs2,
484 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
485 vm,
486 vl,
487 vstart,
488 sew,
489 |a, b, sew, _vxrm, vxsat| {
490 zve64x_fixed_point_helpers::sat_sub(a, b, sew, vxsat)
491 },
492 );
493 }
494 }
495 Self::VssubVx { vd, vs2, rs1, vm } => {
496 if !ext_state.vector_instructions_allowed() {
497 Err(ExecutionError::IllegalInstruction {
498 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
499 })?;
500 }
501 let vtype = ext_state
502 .vtype()
503 .ok_or(ExecutionError::IllegalInstruction {
504 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
505 })?;
506 let group_regs = vtype.vlmul().register_count();
507 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
508 program_counter,
509 vd,
510 group_regs,
511 )?;
512 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
513 program_counter,
514 vs2,
515 group_regs,
516 )?;
517 if !vm && vd.bits() == 0 {
518 Err(ExecutionError::IllegalInstruction {
519 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
520 })?;
521 }
522 let sew = vtype.vsew();
523 let vl = ext_state.vl();
524 let vstart = u32::from(ext_state.vstart());
525 let scalar = regs.read(rs1).as_u64();
526 unsafe {
528 zve64x_fixed_point_helpers::execute_fixed_point_op(
529 ext_state,
530 vd,
531 vs2,
532 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
533 vm,
534 vl,
535 vstart,
536 sew,
537 |a, b, sew, _vxrm, vxsat| {
538 zve64x_fixed_point_helpers::sat_sub(a, b, sew, vxsat)
539 },
540 );
541 }
542 }
543 Self::VaadduVv { vd, vs2, vs1, vm } => {
545 if !ext_state.vector_instructions_allowed() {
546 Err(ExecutionError::IllegalInstruction {
547 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
548 })?;
549 }
550 let vtype = ext_state
551 .vtype()
552 .ok_or(ExecutionError::IllegalInstruction {
553 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
554 })?;
555 let group_regs = vtype.vlmul().register_count();
556 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
557 program_counter,
558 vd,
559 group_regs,
560 )?;
561 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
562 program_counter,
563 vs2,
564 group_regs,
565 )?;
566 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
567 program_counter,
568 vs1,
569 group_regs,
570 )?;
571 if !vm && vd.bits() == 0 {
572 Err(ExecutionError::IllegalInstruction {
573 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
574 })?;
575 }
576 let sew = vtype.vsew();
577 let vl = ext_state.vl();
578 let vstart = u32::from(ext_state.vstart());
579 unsafe {
581 zve64x_fixed_point_helpers::execute_fixed_point_op(
582 ext_state,
583 vd,
584 vs2,
585 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
586 vm,
587 vl,
588 vstart,
589 sew,
590 |a, b, sew, vxrm, _vxsat| {
591 zve64x_fixed_point_helpers::avg_addu(a, b, sew, vxrm)
592 },
593 );
594 }
595 }
596 Self::VaadduVx { vd, vs2, rs1, vm } => {
597 if !ext_state.vector_instructions_allowed() {
598 Err(ExecutionError::IllegalInstruction {
599 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
600 })?;
601 }
602 let vtype = ext_state
603 .vtype()
604 .ok_or(ExecutionError::IllegalInstruction {
605 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
606 })?;
607 let group_regs = vtype.vlmul().register_count();
608 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
609 program_counter,
610 vd,
611 group_regs,
612 )?;
613 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
614 program_counter,
615 vs2,
616 group_regs,
617 )?;
618 if !vm && vd.bits() == 0 {
619 Err(ExecutionError::IllegalInstruction {
620 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
621 })?;
622 }
623 let sew = vtype.vsew();
624 let vl = ext_state.vl();
625 let vstart = u32::from(ext_state.vstart());
626 let scalar = regs.read(rs1).as_u64();
627 unsafe {
629 zve64x_fixed_point_helpers::execute_fixed_point_op(
630 ext_state,
631 vd,
632 vs2,
633 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
634 vm,
635 vl,
636 vstart,
637 sew,
638 |a, b, sew, vxrm, _vxsat| {
639 zve64x_fixed_point_helpers::avg_addu(a, b, sew, vxrm)
640 },
641 );
642 }
643 }
644 Self::VaaddVv { vd, vs2, vs1, vm } => {
646 if !ext_state.vector_instructions_allowed() {
647 Err(ExecutionError::IllegalInstruction {
648 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
649 })?;
650 }
651 let vtype = ext_state
652 .vtype()
653 .ok_or(ExecutionError::IllegalInstruction {
654 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
655 })?;
656 let group_regs = vtype.vlmul().register_count();
657 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
658 program_counter,
659 vd,
660 group_regs,
661 )?;
662 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
663 program_counter,
664 vs2,
665 group_regs,
666 )?;
667 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
668 program_counter,
669 vs1,
670 group_regs,
671 )?;
672 if !vm && vd.bits() == 0 {
673 Err(ExecutionError::IllegalInstruction {
674 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
675 })?;
676 }
677 let sew = vtype.vsew();
678 let vl = ext_state.vl();
679 let vstart = u32::from(ext_state.vstart());
680 unsafe {
682 zve64x_fixed_point_helpers::execute_fixed_point_op(
683 ext_state,
684 vd,
685 vs2,
686 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
687 vm,
688 vl,
689 vstart,
690 sew,
691 |a, b, sew, vxrm, _vxsat| {
692 zve64x_fixed_point_helpers::avg_add(a, b, sew, vxrm)
693 },
694 );
695 }
696 }
697 Self::VaaddVx { vd, vs2, rs1, vm } => {
698 if !ext_state.vector_instructions_allowed() {
699 Err(ExecutionError::IllegalInstruction {
700 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
701 })?;
702 }
703 let vtype = ext_state
704 .vtype()
705 .ok_or(ExecutionError::IllegalInstruction {
706 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
707 })?;
708 let group_regs = vtype.vlmul().register_count();
709 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
710 program_counter,
711 vd,
712 group_regs,
713 )?;
714 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
715 program_counter,
716 vs2,
717 group_regs,
718 )?;
719 if !vm && vd.bits() == 0 {
720 Err(ExecutionError::IllegalInstruction {
721 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
722 })?;
723 }
724 let sew = vtype.vsew();
725 let vl = ext_state.vl();
726 let vstart = u32::from(ext_state.vstart());
727 let scalar = regs.read(rs1).as_u64();
728 unsafe {
730 zve64x_fixed_point_helpers::execute_fixed_point_op(
731 ext_state,
732 vd,
733 vs2,
734 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
735 vm,
736 vl,
737 vstart,
738 sew,
739 |a, b, sew, vxrm, _vxsat| {
740 zve64x_fixed_point_helpers::avg_add(a, b, sew, vxrm)
741 },
742 );
743 }
744 }
745 Self::VasubuVv { vd, vs2, vs1, vm } => {
747 if !ext_state.vector_instructions_allowed() {
748 Err(ExecutionError::IllegalInstruction {
749 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
750 })?;
751 }
752 let vtype = ext_state
753 .vtype()
754 .ok_or(ExecutionError::IllegalInstruction {
755 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
756 })?;
757 let group_regs = vtype.vlmul().register_count();
758 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
759 program_counter,
760 vd,
761 group_regs,
762 )?;
763 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
764 program_counter,
765 vs2,
766 group_regs,
767 )?;
768 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
769 program_counter,
770 vs1,
771 group_regs,
772 )?;
773 if !vm && vd.bits() == 0 {
774 Err(ExecutionError::IllegalInstruction {
775 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
776 })?;
777 }
778 let sew = vtype.vsew();
779 let vl = ext_state.vl();
780 let vstart = u32::from(ext_state.vstart());
781 unsafe {
783 zve64x_fixed_point_helpers::execute_fixed_point_op(
784 ext_state,
785 vd,
786 vs2,
787 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
788 vm,
789 vl,
790 vstart,
791 sew,
792 |a, b, sew, vxrm, _vxsat| {
793 zve64x_fixed_point_helpers::avg_subu(a, b, sew, vxrm)
794 },
795 );
796 }
797 }
798 Self::VasubuVx { vd, vs2, rs1, vm } => {
799 if !ext_state.vector_instructions_allowed() {
800 Err(ExecutionError::IllegalInstruction {
801 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
802 })?;
803 }
804 let vtype = ext_state
805 .vtype()
806 .ok_or(ExecutionError::IllegalInstruction {
807 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
808 })?;
809 let group_regs = vtype.vlmul().register_count();
810 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
811 program_counter,
812 vd,
813 group_regs,
814 )?;
815 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
816 program_counter,
817 vs2,
818 group_regs,
819 )?;
820 if !vm && vd.bits() == 0 {
821 Err(ExecutionError::IllegalInstruction {
822 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
823 })?;
824 }
825 let sew = vtype.vsew();
826 let vl = ext_state.vl();
827 let vstart = u32::from(ext_state.vstart());
828 let scalar = regs.read(rs1).as_u64();
829 unsafe {
831 zve64x_fixed_point_helpers::execute_fixed_point_op(
832 ext_state,
833 vd,
834 vs2,
835 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
836 vm,
837 vl,
838 vstart,
839 sew,
840 |a, b, sew, vxrm, _vxsat| {
841 zve64x_fixed_point_helpers::avg_subu(a, b, sew, vxrm)
842 },
843 );
844 }
845 }
846 Self::VasubVv { vd, vs2, vs1, vm } => {
848 if !ext_state.vector_instructions_allowed() {
849 Err(ExecutionError::IllegalInstruction {
850 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
851 })?;
852 }
853 let vtype = ext_state
854 .vtype()
855 .ok_or(ExecutionError::IllegalInstruction {
856 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
857 })?;
858 let group_regs = vtype.vlmul().register_count();
859 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
860 program_counter,
861 vd,
862 group_regs,
863 )?;
864 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
865 program_counter,
866 vs2,
867 group_regs,
868 )?;
869 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
870 program_counter,
871 vs1,
872 group_regs,
873 )?;
874 if !vm && vd.bits() == 0 {
875 Err(ExecutionError::IllegalInstruction {
876 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
877 })?;
878 }
879 let sew = vtype.vsew();
880 let vl = ext_state.vl();
881 let vstart = u32::from(ext_state.vstart());
882 unsafe {
884 zve64x_fixed_point_helpers::execute_fixed_point_op(
885 ext_state,
886 vd,
887 vs2,
888 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
889 vm,
890 vl,
891 vstart,
892 sew,
893 |a, b, sew, vxrm, _vxsat| {
894 zve64x_fixed_point_helpers::avg_sub(a, b, sew, vxrm)
895 },
896 );
897 }
898 }
899 Self::VasubVx { vd, vs2, rs1, vm } => {
900 if !ext_state.vector_instructions_allowed() {
901 Err(ExecutionError::IllegalInstruction {
902 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
903 })?;
904 }
905 let vtype = ext_state
906 .vtype()
907 .ok_or(ExecutionError::IllegalInstruction {
908 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
909 })?;
910 let group_regs = vtype.vlmul().register_count();
911 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
912 program_counter,
913 vd,
914 group_regs,
915 )?;
916 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
917 program_counter,
918 vs2,
919 group_regs,
920 )?;
921 if !vm && vd.bits() == 0 {
922 Err(ExecutionError::IllegalInstruction {
923 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
924 })?;
925 }
926 let sew = vtype.vsew();
927 let vl = ext_state.vl();
928 let vstart = u32::from(ext_state.vstart());
929 let scalar = regs.read(rs1).as_u64();
930 unsafe {
932 zve64x_fixed_point_helpers::execute_fixed_point_op(
933 ext_state,
934 vd,
935 vs2,
936 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
937 vm,
938 vl,
939 vstart,
940 sew,
941 |a, b, sew, vxrm, _vxsat| {
942 zve64x_fixed_point_helpers::avg_sub(a, b, sew, vxrm)
943 },
944 );
945 }
946 }
947 Self::VsmulVv { vd, vs2, vs1, vm } => {
949 if !ext_state.vector_instructions_allowed() {
950 Err(ExecutionError::IllegalInstruction {
951 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
952 })?;
953 }
954 let vtype = ext_state
955 .vtype()
956 .ok_or(ExecutionError::IllegalInstruction {
957 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
958 })?;
959 let group_regs = vtype.vlmul().register_count();
960 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
961 program_counter,
962 vd,
963 group_regs,
964 )?;
965 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
966 program_counter,
967 vs2,
968 group_regs,
969 )?;
970 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
971 program_counter,
972 vs1,
973 group_regs,
974 )?;
975 if !vm && vd.bits() == 0 {
976 Err(ExecutionError::IllegalInstruction {
977 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
978 })?;
979 }
980 let sew = vtype.vsew();
981 let vl = ext_state.vl();
982 let vstart = u32::from(ext_state.vstart());
983 unsafe {
985 zve64x_fixed_point_helpers::execute_fixed_point_op(
986 ext_state,
987 vd,
988 vs2,
989 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
990 vm,
991 vl,
992 vstart,
993 sew,
994 |a, b, sew, vxrm, vxsat| {
995 zve64x_fixed_point_helpers::smul(a, b, sew, vxrm, vxsat)
996 },
997 );
998 }
999 }
1000 Self::VsmulVx { vd, vs2, rs1, vm } => {
1001 if !ext_state.vector_instructions_allowed() {
1002 Err(ExecutionError::IllegalInstruction {
1003 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1004 })?;
1005 }
1006 let vtype = ext_state
1007 .vtype()
1008 .ok_or(ExecutionError::IllegalInstruction {
1009 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1010 })?;
1011 let group_regs = vtype.vlmul().register_count();
1012 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1013 program_counter,
1014 vd,
1015 group_regs,
1016 )?;
1017 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
1018 program_counter,
1019 vs2,
1020 group_regs,
1021 )?;
1022 if !vm && vd.bits() == 0 {
1023 Err(ExecutionError::IllegalInstruction {
1024 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1025 })?;
1026 }
1027 let sew = vtype.vsew();
1028 let vl = ext_state.vl();
1029 let vstart = u32::from(ext_state.vstart());
1030 let scalar = regs.read(rs1).as_u64();
1031 unsafe {
1033 zve64x_fixed_point_helpers::execute_fixed_point_op(
1034 ext_state,
1035 vd,
1036 vs2,
1037 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
1038 vm,
1039 vl,
1040 vstart,
1041 sew,
1042 |a, b, sew, vxrm, vxsat| {
1043 zve64x_fixed_point_helpers::smul(a, b, sew, vxrm, vxsat)
1044 },
1045 );
1046 }
1047 }
1048 Self::VssrlVv { vd, vs2, vs1, vm } => {
1050 if !ext_state.vector_instructions_allowed() {
1051 Err(ExecutionError::IllegalInstruction {
1052 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1053 })?;
1054 }
1055 let vtype = ext_state
1056 .vtype()
1057 .ok_or(ExecutionError::IllegalInstruction {
1058 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1059 })?;
1060 let group_regs = vtype.vlmul().register_count();
1061 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1062 program_counter,
1063 vd,
1064 group_regs,
1065 )?;
1066 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
1067 program_counter,
1068 vs2,
1069 group_regs,
1070 )?;
1071 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
1072 program_counter,
1073 vs1,
1074 group_regs,
1075 )?;
1076 if !vm && vd.bits() == 0 {
1077 Err(ExecutionError::IllegalInstruction {
1078 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1079 })?;
1080 }
1081 let sew = vtype.vsew();
1082 let vl = ext_state.vl();
1083 let vstart = u32::from(ext_state.vstart());
1084 unsafe {
1086 zve64x_fixed_point_helpers::execute_fixed_point_op(
1087 ext_state,
1088 vd,
1089 vs2,
1090 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
1091 vm,
1092 vl,
1093 vstart,
1094 sew,
1095 |a, b, sew, vxrm, _vxsat| {
1096 let shamt = (b & u64::from(sew.bits() - 1)) as u32;
1098 let masked_a = a & zve64x_fixed_point_helpers::sew_mask(sew);
1099 zve64x_fixed_point_helpers::rounded_srl(masked_a, shamt, vxrm)
1100 & zve64x_fixed_point_helpers::sew_mask(sew)
1101 },
1102 );
1103 }
1104 }
1105 Self::VssrlVx { vd, vs2, rs1, vm } => {
1106 if !ext_state.vector_instructions_allowed() {
1107 Err(ExecutionError::IllegalInstruction {
1108 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1109 })?;
1110 }
1111 let vtype = ext_state
1112 .vtype()
1113 .ok_or(ExecutionError::IllegalInstruction {
1114 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1115 })?;
1116 let group_regs = vtype.vlmul().register_count();
1117 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1118 program_counter,
1119 vd,
1120 group_regs,
1121 )?;
1122 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
1123 program_counter,
1124 vs2,
1125 group_regs,
1126 )?;
1127 if !vm && vd.bits() == 0 {
1128 Err(ExecutionError::IllegalInstruction {
1129 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1130 })?;
1131 }
1132 let sew = vtype.vsew();
1133 let vl = ext_state.vl();
1134 let vstart = u32::from(ext_state.vstart());
1135 let scalar = regs.read(rs1).as_u64();
1136 unsafe {
1138 zve64x_fixed_point_helpers::execute_fixed_point_op(
1139 ext_state,
1140 vd,
1141 vs2,
1142 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
1143 vm,
1144 vl,
1145 vstart,
1146 sew,
1147 |a, b, sew, vxrm, _vxsat| {
1148 let shamt = (b & u64::from(sew.bits() - 1)) as u32;
1149 let masked_a = a & zve64x_fixed_point_helpers::sew_mask(sew);
1150 zve64x_fixed_point_helpers::rounded_srl(masked_a, shamt, vxrm)
1151 & zve64x_fixed_point_helpers::sew_mask(sew)
1152 },
1153 );
1154 }
1155 }
1156 Self::VssrlVi { vd, vs2, imm, vm } => {
1157 if !ext_state.vector_instructions_allowed() {
1158 Err(ExecutionError::IllegalInstruction {
1159 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1160 })?;
1161 }
1162 let vtype = ext_state
1163 .vtype()
1164 .ok_or(ExecutionError::IllegalInstruction {
1165 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1166 })?;
1167 let group_regs = vtype.vlmul().register_count();
1168 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1169 program_counter,
1170 vd,
1171 group_regs,
1172 )?;
1173 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
1174 program_counter,
1175 vs2,
1176 group_regs,
1177 )?;
1178 if !vm && vd.bits() == 0 {
1179 Err(ExecutionError::IllegalInstruction {
1180 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1181 })?;
1182 }
1183 let sew = vtype.vsew();
1184 let vl = ext_state.vl();
1185 let vstart = u32::from(ext_state.vstart());
1186 let shamt = (u64::from(imm) & u64::from(sew.bits() - 1)) as u32;
1188 unsafe {
1190 zve64x_fixed_point_helpers::execute_fixed_point_op(
1191 ext_state,
1192 vd,
1193 vs2,
1194 zve64x_fixed_point_helpers::OpSrc::Scalar(u64::from(shamt)),
1195 vm,
1196 vl,
1197 vstart,
1198 sew,
1199 |a, b, sew, vxrm, _vxsat| {
1200 let shamt = b as u32;
1201 let masked_a = a & zve64x_fixed_point_helpers::sew_mask(sew);
1202 zve64x_fixed_point_helpers::rounded_srl(masked_a, shamt, vxrm)
1203 & zve64x_fixed_point_helpers::sew_mask(sew)
1204 },
1205 );
1206 }
1207 }
1208 Self::VssraVv { vd, vs2, vs1, vm } => {
1210 if !ext_state.vector_instructions_allowed() {
1211 Err(ExecutionError::IllegalInstruction {
1212 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1213 })?;
1214 }
1215 let vtype = ext_state
1216 .vtype()
1217 .ok_or(ExecutionError::IllegalInstruction {
1218 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1219 })?;
1220 let group_regs = vtype.vlmul().register_count();
1221 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1222 program_counter,
1223 vd,
1224 group_regs,
1225 )?;
1226 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
1227 program_counter,
1228 vs2,
1229 group_regs,
1230 )?;
1231 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
1232 program_counter,
1233 vs1,
1234 group_regs,
1235 )?;
1236 if !vm && vd.bits() == 0 {
1237 Err(ExecutionError::IllegalInstruction {
1238 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1239 })?;
1240 }
1241 let sew = vtype.vsew();
1242 let vl = ext_state.vl();
1243 let vstart = u32::from(ext_state.vstart());
1244 unsafe {
1246 zve64x_fixed_point_helpers::execute_fixed_point_op(
1247 ext_state,
1248 vd,
1249 vs2,
1250 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
1251 vm,
1252 vl,
1253 vstart,
1254 sew,
1255 |a, b, sew, vxrm, _vxsat| {
1256 let shamt = (b & u64::from(sew.bits() - 1)) as u32;
1257 zve64x_fixed_point_helpers::rounded_sra(a, shamt, vxrm, sew)
1258 & zve64x_fixed_point_helpers::sew_mask(sew)
1259 },
1260 );
1261 }
1262 }
1263 Self::VssraVx { vd, vs2, rs1, vm } => {
1264 if !ext_state.vector_instructions_allowed() {
1265 Err(ExecutionError::IllegalInstruction {
1266 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1267 })?;
1268 }
1269 let vtype = ext_state
1270 .vtype()
1271 .ok_or(ExecutionError::IllegalInstruction {
1272 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1273 })?;
1274 let group_regs = vtype.vlmul().register_count();
1275 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1276 program_counter,
1277 vd,
1278 group_regs,
1279 )?;
1280 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
1281 program_counter,
1282 vs2,
1283 group_regs,
1284 )?;
1285 if !vm && vd.bits() == 0 {
1286 Err(ExecutionError::IllegalInstruction {
1287 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1288 })?;
1289 }
1290 let sew = vtype.vsew();
1291 let vl = ext_state.vl();
1292 let vstart = u32::from(ext_state.vstart());
1293 let scalar = regs.read(rs1).as_u64();
1294 unsafe {
1296 zve64x_fixed_point_helpers::execute_fixed_point_op(
1297 ext_state,
1298 vd,
1299 vs2,
1300 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
1301 vm,
1302 vl,
1303 vstart,
1304 sew,
1305 |a, b, sew, vxrm, _vxsat| {
1306 let shamt = (b & u64::from(sew.bits() - 1)) as u32;
1307 zve64x_fixed_point_helpers::rounded_sra(a, shamt, vxrm, sew)
1308 & zve64x_fixed_point_helpers::sew_mask(sew)
1309 },
1310 );
1311 }
1312 }
1313 Self::VssraVi { vd, vs2, imm, vm } => {
1314 if !ext_state.vector_instructions_allowed() {
1315 Err(ExecutionError::IllegalInstruction {
1316 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1317 })?;
1318 }
1319 let vtype = ext_state
1320 .vtype()
1321 .ok_or(ExecutionError::IllegalInstruction {
1322 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1323 })?;
1324 let group_regs = vtype.vlmul().register_count();
1325 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1326 program_counter,
1327 vd,
1328 group_regs,
1329 )?;
1330 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
1331 program_counter,
1332 vs2,
1333 group_regs,
1334 )?;
1335 if !vm && vd.bits() == 0 {
1336 Err(ExecutionError::IllegalInstruction {
1337 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1338 })?;
1339 }
1340 let sew = vtype.vsew();
1341 let vl = ext_state.vl();
1342 let vstart = u32::from(ext_state.vstart());
1343 let shamt = (u64::from(imm) & u64::from(sew.bits() - 1)) as u32;
1344 unsafe {
1346 zve64x_fixed_point_helpers::execute_fixed_point_op(
1347 ext_state,
1348 vd,
1349 vs2,
1350 zve64x_fixed_point_helpers::OpSrc::Scalar(u64::from(shamt)),
1351 vm,
1352 vl,
1353 vstart,
1354 sew,
1355 |a, b, sew, vxrm, _vxsat| {
1356 let shamt = b as u32;
1357 zve64x_fixed_point_helpers::rounded_sra(a, shamt, vxrm, sew)
1358 & zve64x_fixed_point_helpers::sew_mask(sew)
1359 },
1360 );
1361 }
1362 }
1363 Self::VnclipuWv { vd, vs2, vs1, vm } => {
1365 if !ext_state.vector_instructions_allowed() {
1366 Err(ExecutionError::IllegalInstruction {
1367 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1368 })?;
1369 }
1370 let vtype = ext_state
1371 .vtype()
1372 .ok_or(ExecutionError::IllegalInstruction {
1373 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1374 })?;
1375 let sew = vtype.vsew();
1377 zve64x_fixed_point_helpers::check_narrowing_sew::<Reg, _, _, _>(
1378 program_counter,
1379 sew,
1380 )?;
1381 let group_regs = vtype.vlmul().register_count();
1382 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1383 program_counter,
1384 vd,
1385 group_regs,
1386 )?;
1387 zve64x_fixed_point_helpers::check_vs2_narrowing_alignment::<Reg, _, _, _>(
1389 program_counter,
1390 vs2,
1391 group_regs,
1392 )?;
1393 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
1395 program_counter,
1396 vs1,
1397 group_regs,
1398 )?;
1399 if !vm && vd.bits() == 0 {
1400 Err(ExecutionError::IllegalInstruction {
1401 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1402 })?;
1403 }
1404 let vl = ext_state.vl();
1405 let vstart = u32::from(ext_state.vstart());
1406 unsafe {
1408 zve64x_fixed_point_helpers::execute_narrowing_clip_op(
1409 ext_state,
1410 vd,
1411 vs2,
1412 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
1413 vm,
1414 vl,
1415 vstart,
1416 sew,
1417 |wide, shamt, sew, vxrm, vxsat| {
1418 zve64x_fixed_point_helpers::nclipu(wide, shamt, sew, vxrm, vxsat)
1419 },
1420 );
1421 }
1422 }
1423 Self::VnclipuWx { vd, vs2, rs1, vm } => {
1424 if !ext_state.vector_instructions_allowed() {
1425 Err(ExecutionError::IllegalInstruction {
1426 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1427 })?;
1428 }
1429 let vtype = ext_state
1430 .vtype()
1431 .ok_or(ExecutionError::IllegalInstruction {
1432 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1433 })?;
1434 let sew = vtype.vsew();
1435 zve64x_fixed_point_helpers::check_narrowing_sew::<Reg, _, _, _>(
1436 program_counter,
1437 sew,
1438 )?;
1439 let group_regs = vtype.vlmul().register_count();
1440 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1441 program_counter,
1442 vd,
1443 group_regs,
1444 )?;
1445 zve64x_fixed_point_helpers::check_vs2_narrowing_alignment::<Reg, _, _, _>(
1446 program_counter,
1447 vs2,
1448 group_regs,
1449 )?;
1450 if !vm && vd.bits() == 0 {
1451 Err(ExecutionError::IllegalInstruction {
1452 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1453 })?;
1454 }
1455 let vl = ext_state.vl();
1456 let vstart = u32::from(ext_state.vstart());
1457 let scalar = regs.read(rs1).as_u64();
1458 unsafe {
1460 zve64x_fixed_point_helpers::execute_narrowing_clip_op(
1461 ext_state,
1462 vd,
1463 vs2,
1464 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
1465 vm,
1466 vl,
1467 vstart,
1468 sew,
1469 |wide, shamt, sew, vxrm, vxsat| {
1470 zve64x_fixed_point_helpers::nclipu(wide, shamt, sew, vxrm, vxsat)
1471 },
1472 );
1473 }
1474 }
1475 Self::VnclipuWi { vd, vs2, imm, vm } => {
1476 if !ext_state.vector_instructions_allowed() {
1477 Err(ExecutionError::IllegalInstruction {
1478 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1479 })?;
1480 }
1481 let vtype = ext_state
1482 .vtype()
1483 .ok_or(ExecutionError::IllegalInstruction {
1484 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1485 })?;
1486 let sew = vtype.vsew();
1487 zve64x_fixed_point_helpers::check_narrowing_sew::<Reg, _, _, _>(
1488 program_counter,
1489 sew,
1490 )?;
1491 let group_regs = vtype.vlmul().register_count();
1492 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1493 program_counter,
1494 vd,
1495 group_regs,
1496 )?;
1497 zve64x_fixed_point_helpers::check_vs2_narrowing_alignment::<Reg, _, _, _>(
1498 program_counter,
1499 vs2,
1500 group_regs,
1501 )?;
1502 if !vm && vd.bits() == 0 {
1503 Err(ExecutionError::IllegalInstruction {
1504 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1505 })?;
1506 }
1507 let vl = ext_state.vl();
1508 let vstart = u32::from(ext_state.vstart());
1509 unsafe {
1511 zve64x_fixed_point_helpers::execute_narrowing_clip_op(
1512 ext_state,
1513 vd,
1514 vs2,
1515 zve64x_fixed_point_helpers::OpSrc::Scalar(u64::from(imm)),
1517 vm,
1518 vl,
1519 vstart,
1520 sew,
1521 |wide, shamt, sew, vxrm, vxsat| {
1522 zve64x_fixed_point_helpers::nclipu(wide, shamt, sew, vxrm, vxsat)
1523 },
1524 );
1525 }
1526 }
1527 Self::VnclipWv { vd, vs2, vs1, vm } => {
1529 if !ext_state.vector_instructions_allowed() {
1530 Err(ExecutionError::IllegalInstruction {
1531 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1532 })?;
1533 }
1534 let vtype = ext_state
1535 .vtype()
1536 .ok_or(ExecutionError::IllegalInstruction {
1537 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1538 })?;
1539 let sew = vtype.vsew();
1540 zve64x_fixed_point_helpers::check_narrowing_sew::<Reg, _, _, _>(
1541 program_counter,
1542 sew,
1543 )?;
1544 let group_regs = vtype.vlmul().register_count();
1545 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1546 program_counter,
1547 vd,
1548 group_regs,
1549 )?;
1550 zve64x_fixed_point_helpers::check_vs2_narrowing_alignment::<Reg, _, _, _>(
1551 program_counter,
1552 vs2,
1553 group_regs,
1554 )?;
1555 zve64x_fixed_point_helpers::check_vs::<Reg, _, _, _>(
1556 program_counter,
1557 vs1,
1558 group_regs,
1559 )?;
1560 if !vm && vd.bits() == 0 {
1561 Err(ExecutionError::IllegalInstruction {
1562 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1563 })?;
1564 }
1565 let vl = ext_state.vl();
1566 let vstart = u32::from(ext_state.vstart());
1567 unsafe {
1569 zve64x_fixed_point_helpers::execute_narrowing_clip_op(
1570 ext_state,
1571 vd,
1572 vs2,
1573 zve64x_fixed_point_helpers::OpSrc::Vreg(vs1.bits()),
1574 vm,
1575 vl,
1576 vstart,
1577 sew,
1578 |wide, shamt, sew, vxrm, vxsat| {
1579 zve64x_fixed_point_helpers::nclip(wide, shamt, sew, vxrm, vxsat)
1580 },
1581 );
1582 }
1583 }
1584 Self::VnclipWx { vd, vs2, rs1, vm } => {
1585 if !ext_state.vector_instructions_allowed() {
1586 Err(ExecutionError::IllegalInstruction {
1587 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1588 })?;
1589 }
1590 let vtype = ext_state
1591 .vtype()
1592 .ok_or(ExecutionError::IllegalInstruction {
1593 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1594 })?;
1595 let sew = vtype.vsew();
1596 zve64x_fixed_point_helpers::check_narrowing_sew::<Reg, _, _, _>(
1597 program_counter,
1598 sew,
1599 )?;
1600 let group_regs = vtype.vlmul().register_count();
1601 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1602 program_counter,
1603 vd,
1604 group_regs,
1605 )?;
1606 zve64x_fixed_point_helpers::check_vs2_narrowing_alignment::<Reg, _, _, _>(
1607 program_counter,
1608 vs2,
1609 group_regs,
1610 )?;
1611 if !vm && vd.bits() == 0 {
1612 Err(ExecutionError::IllegalInstruction {
1613 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1614 })?;
1615 }
1616 let vl = ext_state.vl();
1617 let vstart = u32::from(ext_state.vstart());
1618 let scalar = regs.read(rs1).as_u64();
1619 unsafe {
1621 zve64x_fixed_point_helpers::execute_narrowing_clip_op(
1622 ext_state,
1623 vd,
1624 vs2,
1625 zve64x_fixed_point_helpers::OpSrc::Scalar(scalar),
1626 vm,
1627 vl,
1628 vstart,
1629 sew,
1630 |wide, shamt, sew, vxrm, vxsat| {
1631 zve64x_fixed_point_helpers::nclip(wide, shamt, sew, vxrm, vxsat)
1632 },
1633 );
1634 }
1635 }
1636 Self::VnclipWi { vd, vs2, imm, vm } => {
1637 if !ext_state.vector_instructions_allowed() {
1638 Err(ExecutionError::IllegalInstruction {
1639 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1640 })?;
1641 }
1642 let vtype = ext_state
1643 .vtype()
1644 .ok_or(ExecutionError::IllegalInstruction {
1645 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1646 })?;
1647 let sew = vtype.vsew();
1648 zve64x_fixed_point_helpers::check_narrowing_sew::<Reg, _, _, _>(
1649 program_counter,
1650 sew,
1651 )?;
1652 let group_regs = vtype.vlmul().register_count();
1653 zve64x_fixed_point_helpers::check_vd::<Reg, _, _, _>(
1654 program_counter,
1655 vd,
1656 group_regs,
1657 )?;
1658 zve64x_fixed_point_helpers::check_vs2_narrowing_alignment::<Reg, _, _, _>(
1659 program_counter,
1660 vs2,
1661 group_regs,
1662 )?;
1663 if !vm && vd.bits() == 0 {
1664 Err(ExecutionError::IllegalInstruction {
1665 address: program_counter.old_pc(zve64x_helpers::INSTRUCTION_SIZE),
1666 })?;
1667 }
1668 let vl = ext_state.vl();
1669 let vstart = u32::from(ext_state.vstart());
1670 unsafe {
1672 zve64x_fixed_point_helpers::execute_narrowing_clip_op(
1673 ext_state,
1674 vd,
1675 vs2,
1676 zve64x_fixed_point_helpers::OpSrc::Scalar(u64::from(imm)),
1677 vm,
1678 vl,
1679 vstart,
1680 sew,
1681 |wide, shamt, sew, vxrm, vxsat| {
1682 zve64x_fixed_point_helpers::nclip(wide, shamt, sew, vxrm, vxsat)
1683 },
1684 );
1685 }
1686 }
1687 }
1688
1689 Ok(ControlFlow::Continue(()))
1690 }
1691}