@@ -617,6 +617,8 @@ static uint32_t *csr_get_ptr(struct riscv_t *rv, uint32_t csr)
617617 case CSR_MIP :
618618 return (uint32_t * ) (& rv -> csr_mip );
619619#ifdef ENABLE_RV32F
620+ case CSR_FFLAGS :
621+ return (uint32_t * ) (& rv -> csr_fcsr );
620622 case CSR_FCSR :
621623 return (uint32_t * ) (& rv -> csr_fcsr );
622624#endif
@@ -637,7 +639,11 @@ static uint32_t csr_csrrw(struct riscv_t *rv, uint32_t csr, uint32_t val)
637639 if (!c )
638640 return 0 ;
639641
640- const uint32_t out = * c ;
642+ uint32_t out = * c ;
643+ #ifdef ENABLE_RV32F
644+ if (csr == CSR_FFLAGS )
645+ out &= FFLAG_MASK ;
646+ #endif
641647 if (csr_is_writable (csr ))
642648 * c = val ;
643649
@@ -651,7 +657,11 @@ static uint32_t csr_csrrs(struct riscv_t *rv, uint32_t csr, uint32_t val)
651657 if (!c )
652658 return 0 ;
653659
654- const uint32_t out = * c ;
660+ uint32_t out = * c ;
661+ #ifdef ENABLE_RV32F
662+ if (csr == CSR_FFLAGS )
663+ out &= FFLAG_MASK ;
664+ #endif
655665 if (csr_is_writable (csr ))
656666 * c |= val ;
657667
@@ -665,7 +675,11 @@ static uint32_t csr_csrrc(struct riscv_t *rv, uint32_t csr, uint32_t val)
665675 if (!c )
666676 return 0 ;
667677
668- const uint32_t out = * c ;
678+ uint32_t out = * c ;
679+ #ifdef ENABLE_RV32F
680+ if (csr == CSR_FFLAGS )
681+ out &= FFLAG_MASK ;
682+ #endif
669683 if (csr_is_writable (csr ))
670684 * c &= ~val ;
671685 return out ;
@@ -901,10 +915,25 @@ static bool op_fp(struct riscv_t *rv, uint32_t insn)
901915 /* dispatch based on func7 (low 2 bits are width) */
902916 switch (funct7 ) {
903917 case 0b0000000 : /* FADD */
904- rv -> F [rd ] = rv -> F [rs1 ] + rv -> F [rs2 ];
918+ if (isnan (rv -> F [rs1 ]) || isnan (rv -> F [rs2 ]) ||
919+ isnan (rv -> F [rs1 ] + rv -> F [rs2 ])) {
920+ /* raise invalid operation */
921+ * ((uint32_t * ) & rv -> F [rd ]) = RV_NAN ;
922+ rv -> csr_fcsr |= FFLAG_INVALID_OP ;
923+ } else {
924+ rv -> F [rd ] = rv -> F [rs1 ] + rv -> F [rs2 ];
925+ }
926+ if (isinff (rv -> F [rd ])) {
927+ rv -> csr_fcsr |= FFLAG_OVERFLOW ;
928+ rv -> csr_fcsr |= FFLAG_INEXACT ;
929+ }
905930 break ;
906931 case 0b0000100 : /* FSUB */
907- rv -> F [rd ] = rv -> F [rs1 ] - rv -> F [rs2 ];
932+ if (isnan (rv -> F [rs1 ]) || isnan (rv -> F [rs2 ])) {
933+ * ((uint32_t * ) & rv -> F [rd ]) = RV_NAN ;
934+ } else {
935+ rv -> F [rd ] = rv -> F [rs1 ] - rv -> F [rs2 ];
936+ }
908937 break ;
909938 case 0b0001000 : /* FMUL */
910939 rv -> F [rd ] = rv -> F [rs1 ] * rv -> F [rs2 ];
0 commit comments