(
op: &FMacOp,
fmt: u8,
rm: u8,
rd: usize,
rs1: usize,
rs2: usize,
rs3: usize,
regs: &Registers,
csrs: &CsrFile,
pc: u64,
)
| 816 | } |
| 817 | |
| 818 | fn exec_fmac( |
| 819 | op: &FMacOp, |
| 820 | fmt: u8, |
| 821 | rm: u8, |
| 822 | rd: usize, |
| 823 | rs1: usize, |
| 824 | rs2: usize, |
| 825 | rs3: usize, |
| 826 | regs: &Registers, |
| 827 | csrs: &CsrFile, |
| 828 | pc: u64, |
| 829 | ) -> Result<ExecResult, VmError> { |
| 830 | let rm = if rm == RM_DYN { |
| 831 | csrs.rounding_mode() |
| 832 | } else { |
| 833 | rm |
| 834 | }; |
| 835 | let next_pc = pc.wrapping_add(4); |
| 836 | |
| 837 | let (bits, fflags) = match fmt { |
| 838 | 0 => { |
| 839 | let a = regs.read_f32(rs1); |
| 840 | let b = regs.read_f32(rs2); |
| 841 | let c = regs.read_f32(rs3); |
| 842 | match op { |
| 843 | FMacOp::Fmadd => alu::fp_fmadd_s(a, b, c, rm), |
| 844 | FMacOp::Fmsub => alu::fp_fmsub_s(a, b, c, rm), |
| 845 | FMacOp::Fnmsub => alu::fp_fnmsub_s(a, b, c, rm), |
| 846 | FMacOp::Fnmadd => alu::fp_fnmadd_s(a, b, c, rm), |
| 847 | } |
| 848 | } |
| 849 | 1 => { |
| 850 | let a = regs.read_f64(rs1); |
| 851 | let b = regs.read_f64(rs2); |
| 852 | let c = regs.read_f64(rs3); |
| 853 | match op { |
| 854 | FMacOp::Fmadd => alu::fp_fmadd_d(a, b, c, rm), |
| 855 | FMacOp::Fmsub => alu::fp_fmsub_d(a, b, c, rm), |
| 856 | FMacOp::Fnmsub => alu::fp_fnmsub_d(a, b, c, rm), |
| 857 | FMacOp::Fnmadd => alu::fp_fnmadd_d(a, b, c, rm), |
| 858 | } |
| 859 | } |
| 860 | _ => return Err(VmError::IllegalInstruction(fmt as u32)), |
| 861 | }; |
| 862 | |
| 863 | Ok(ExecResult::WriteFpFlags { |
| 864 | rd, |
| 865 | bits, |
| 866 | fflags, |
| 867 | next_pc, |
| 868 | }) |
| 869 | } |
| 870 | |
| 871 | // --- FP -> integer saturation helpers --- |
| 872 |
no test coverage detected