Skip to content

Commit 8ab0ce0

Browse files
committed
Add functions for 32-bit floating point addition
Also adds operation for 32-bit floating point addition instruction.
1 parent 1d7d655 commit 8ab0ce0

File tree

2 files changed

+93
-23
lines changed

2 files changed

+93
-23
lines changed

arch/inst/F/fadd.s.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,8 @@ access:
2626
vu: always
2727
data_independent_timing: true
2828
operation(): |
29-
30-
31-
29+
RoundingMode mode = rm_to_mode(X[rm], $encoding);
30+
X[fd] = f32_add(X[fs1], X[fs2], mode);
3231
3332
sail(): |
3433
{

arch/isa/fp.idl

Lines changed: 91 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ function softfloat_normRoundPackToF32 {
489489
function signF32UI {
490490
returns Bits<1>
491491
arguments
492-
Bits<32> a,
492+
Bits<32> a
493493
description {
494494
Extract sign-bit of a 32-bit floating point number
495495
}
@@ -501,7 +501,7 @@ function signF32UI {
501501
function expF32UI {
502502
returns Bits<8>
503503
arguments
504-
Bits<32> a,
504+
Bits<32> a
505505
description {
506506
Extract exponent of a 32-bit floating point number
507507
}
@@ -513,7 +513,7 @@ function expF32UI {
513513
function fracF32UI {
514514
returns Bits<23>
515515
arguments
516-
Bits<32> a,
516+
Bits<32> a
517517
description {
518518
Extract significand of a 32-bit floating point number
519519
}
@@ -590,14 +590,14 @@ function softfloat_propagateNaNF32UI {
590590
}
591591
body {
592592
# check if a and b are signalling
593-
Boolean isSigNaN_a = is_sp_signaling_nan(a);
594-
Boolean isSigNaN_b = is_sp_signaling_nan(b);
593+
Boolean isSigNaN_a = is_sp_signaling_nan?(a);
594+
Boolean isSigNaN_b = is_sp_signaling_nan?(b);
595595

596596
# get non Signalling versions of a and b
597597
U32 nonsig_a = returnNonSignalingNaN(a);
598598
U32 nonsig_b = returnNonSignalingNaN(b);
599599

600-
if (isSigNaN_a | isSigNaN_b) {
600+
if (isSigNaN_a || isSigNaN_b) {
601601
# raise invalid flag if either number is NaN
602602
set_fp_flag(FpFlag::NV);
603603
if ( isSigNaN_a ) {
@@ -606,9 +606,9 @@ function softfloat_propagateNaNF32UI {
606606
return returnLargerMag(a, b);
607607
}
608608
# if b is NaN return non signaling value of b
609-
return is_sp_nan(b) ? nonsig_b : nonsig_a;
609+
return is_sp_nan?(b) ? nonsig_b : nonsig_a;
610610
} else {
611-
return is_sp_nan(a) ? nonsig_a : nonsig_b;
611+
return is_sp_nan?(a) ? nonsig_a : nonsig_b;
612612
}
613613
}
614614

@@ -643,7 +643,7 @@ function softfloat_addMagsF32 {
643643
Bits<8> expZ;
644644

645645
# calculate difference of exponents
646-
Bits<8> expDiff = expA - expB
646+
Bits<8> expDiff = expA - expB;
647647

648648
if (expDiff == 8'd0) {
649649
if (expA == 8'd0) {
@@ -654,8 +654,8 @@ function softfloat_addMagsF32 {
654654
# check if A is infinity or NaN
655655
if (expA == 8'hFF) {
656656
# A is NaN if significand is non-zero and exponent is 8'hFF
657-
if ((sigA != 8'd0) | (sigB != 8'd0)) {
658-
softfloat_propagateNaNF32UI(a, b);
657+
if ((sigA != 8'd0) || (sigB != 8'd0)) {
658+
return softfloat_propagateNaNF32UI(a, b);
659659
}
660660
# return infinity if A is infinity
661661
return a;
@@ -687,7 +687,7 @@ function softfloat_addMagsF32 {
687687
if (expB == 8'hFF) {
688688
# B is NaN if exponent is 8'hFF and significand is non-zero
689689
if (sigB != 0) {
690-
softfloat_propagateNaNF32UI(a, b);
690+
return softfloat_propagateNaNF32UI(a, b);
691691
}
692692
# return infinity with same sign as A
693693
return packToF32UI(signZ, 8'hFF, 23'h0);
@@ -701,7 +701,7 @@ function softfloat_addMagsF32 {
701701
if (expA == 8'hFF) {
702702
# A is NaN if exponent is 8'hFF and significand is non-zero
703703
if (sigA != 0) {
704-
softfloat_propagateNaNF32UI(a, b);
704+
return softfloat_propagateNaNF32UI(a, b);
705705
}
706706
# return infinity with same sign as A
707707
return a;
@@ -752,19 +752,27 @@ function softfloat_subMagsF32 {
752752
# declare a variable to store the difference in significand
753753
U32 sigDiff;
754754

755+
# declare a sigX and sigY
756+
U32 sigX;
757+
U32 sigY;
758+
759+
# declare a U32 sigA and sigB
760+
U32 sigA_32;
761+
U32 sigB_32;
762+
755763
# declare a variable to store shift distance
756764
Bits<8> shiftDist;
757765

758766
# calculate difference of exponents
759-
Bits<8> expDiff = expA - expB
767+
Bits<8> expDiff = expA - expB;
760768

761769
if (expDiff == 8'd0) {
762770

763771
# check if A is infinity or NaN
764772
if (expA == 8'hFF) {
765773
# A is NaN if significand is non-zero and exponent is 8'hFF
766-
if ((sigA != 8'd0) | (sigB != 8'd0)) {
767-
softfloat_propagateNaNF32UI(a, b);
774+
if ((sigA != 8'd0) || (sigB != 8'd0)) {
775+
return softfloat_propagateNaNF32UI(a, b);
768776
}
769777
# return infinity if A is infinity
770778
return a;
@@ -775,18 +783,81 @@ function softfloat_subMagsF32 {
775783
# check if no difference in significand
776784
if (sigDiff == 0) {
777785
# return -0 if rounding mode is round down, else return +0
778-
return packToF32UI((mode == RoundingMode::RDN),0,0);
786+
return packToF32UI(((mode == RoundingMode::RDN) ? 1 : 0),0,0);
779787
}
780788

781789
if (expA != 0) {
782790
expA = expA - 1;
783791
}
784792

785793
signZ = signF32UI(a);
794+
795+
# if difference is negative, change the sign of the result
786796
if (sigDiff < 0) {
787-
signZ != signZ;
788-
sigDiff = -32'hs1 * sigDiff;
797+
signZ = ~signZ;
798+
sigDiff = -32'sh1 * sigDiff;
789799
}
790800

791-
801+
shiftDist = count_leading_zeros<32>(sigDiff) - 8;
802+
expZ = expA - shiftDist;
803+
804+
if (expZ < 0) {
805+
shiftDist = expA;
806+
expZ = 0;
807+
}
808+
809+
return packToF32UI(signZ, expZ, sigDiff << shiftDist);
810+
811+
} else {
812+
# when difference in exponents are not zero
813+
signZ = signF32UI(a);
814+
sigA_32 = 32'h0 + (sigA << 7);
815+
sigB_32 = 32'h0 + (sigB << 7);
816+
if (expDiff < 0) {
817+
signZ = ~signZ;
818+
if (expB == 0xFF) {
819+
if (sigB_32 != 0) {
820+
return softfloat_propagateNaNF32UI(a, b);
821+
}
822+
return packToF32UI(signZ, expB, 0);
823+
}
824+
expZ = expB - 1;
825+
sigX = sigB_32 | 0x40000000;
826+
sigY = sigA_32 + ((expA != 0) ? 0x40000000 : sigA_32);
827+
expDiff = - expDiff;
828+
} else {
829+
if (expA == 0xFF) {
830+
if (sigA_32 != 0) {
831+
return softfloat_propagateNaNF32UI(a, b);
832+
}
833+
return a;
834+
}
835+
expZ = expA - 1;
836+
sigX = sigA_32 | 0x40000000;
837+
sigY = sigB_32 + ((expB != 0) ? 0x40000000 : sigB_32);
838+
}
839+
return softfloat_normRoundPackToF32(signZ, expZ, sigX - softfloat_shiftRightJam32(sigY, expDiff), mode);
840+
}
841+
}
842+
}
792843

844+
function f32_add {
845+
returns U32
846+
arguments
847+
U32 a,
848+
U32 b,
849+
RoundingMode mode
850+
description {
851+
Returns sum of 2 floating point numbers
852+
}
853+
body {
854+
U32 a_xor_b = a ^ b;
855+
if (signF32UI(a_xor_b) == 1) {
856+
# subtract if signs are different
857+
return softfloat_subMagsF32(a,b,mode);
858+
} else {
859+
# add if signs are the same
860+
return softfloat_addMagsF32(a,b,mode);
861+
}
862+
}
863+
}

0 commit comments

Comments
 (0)