@@ -617,6 +617,8 @@ static uint32_t *csr_get_ptr(struct riscv_t *rv, uint32_t csr)
617
617
case CSR_MIP :
618
618
return (uint32_t * ) (& rv -> csr_mip );
619
619
#ifdef ENABLE_RV32F
620
+ case CSR_FFLAGS :
621
+ return (uint32_t * ) (& rv -> csr_fcsr );
620
622
case CSR_FCSR :
621
623
return (uint32_t * ) (& rv -> csr_fcsr );
622
624
#endif
@@ -637,7 +639,11 @@ static uint32_t csr_csrrw(struct riscv_t *rv, uint32_t csr, uint32_t val)
637
639
if (!c )
638
640
return 0 ;
639
641
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
641
647
if (csr_is_writable (csr ))
642
648
* c = val ;
643
649
@@ -651,7 +657,11 @@ static uint32_t csr_csrrs(struct riscv_t *rv, uint32_t csr, uint32_t val)
651
657
if (!c )
652
658
return 0 ;
653
659
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
655
665
if (csr_is_writable (csr ))
656
666
* c |= val ;
657
667
@@ -665,7 +675,11 @@ static uint32_t csr_csrrc(struct riscv_t *rv, uint32_t csr, uint32_t val)
665
675
if (!c )
666
676
return 0 ;
667
677
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
669
683
if (csr_is_writable (csr ))
670
684
* c &= ~val ;
671
685
return out ;
@@ -901,10 +915,25 @@ static bool op_fp(struct riscv_t *rv, uint32_t insn)
901
915
/* dispatch based on func7 (low 2 bits are width) */
902
916
switch (funct7 ) {
903
917
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
+ }
905
930
break ;
906
931
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
+ }
908
937
break ;
909
938
case 0b0001000 : /* FMUL */
910
939
rv -> F [rd ] = rv -> F [rs1 ] * rv -> F [rs2 ];
0 commit comments