Skip to content

Commit 1d7d655

Browse files
committed
Typo fix in IDL doc and add functions in fp.idl
1 parent c8170c8 commit 1d7d655

File tree

2 files changed

+307
-2
lines changed

2 files changed

+307
-2
lines changed

arch/isa/fp.idl

Lines changed: 306 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,4 +484,309 @@ function softfloat_normRoundPackToF32 {
484484
return softfloat_roundPackToF32(sign, exp, sig << shiftDist, mode);
485485
}
486486
}
487-
}
487+
}
488+
489+
function signF32UI {
490+
returns Bits<1>
491+
arguments
492+
Bits<32> a,
493+
description {
494+
Extract sign-bit of a 32-bit floating point number
495+
}
496+
body {
497+
return a[31];
498+
}
499+
}
500+
501+
function expF32UI {
502+
returns Bits<8>
503+
arguments
504+
Bits<32> a,
505+
description {
506+
Extract exponent of a 32-bit floating point number
507+
}
508+
body {
509+
return a[30:23];
510+
}
511+
}
512+
513+
function fracF32UI {
514+
returns Bits<23>
515+
arguments
516+
Bits<32> a,
517+
description {
518+
Extract significand of a 32-bit floating point number
519+
}
520+
body {
521+
return a[22:0];
522+
}
523+
}
524+
525+
function returnNonSignalingNaN {
526+
returns U32
527+
arguments
528+
U32 a
529+
description {
530+
Returns a non-signalling NaN version of the floating-point number
531+
Does not modify the input
532+
}
533+
body {
534+
U32 a_copy = a;
535+
a_copy[22] = 1'b1;
536+
return a_copy;
537+
}
538+
}
539+
540+
function returnMag {
541+
returns U32
542+
arguments
543+
U32 a
544+
description {
545+
Returns magnitude of the given number
546+
Does not modify the input
547+
}
548+
body {
549+
U32 a_copy = a;
550+
# make sign bit zero
551+
a_copy[31] = 1'b0;
552+
return a_copy;
553+
}
554+
}
555+
556+
function returnLargerMag {
557+
returns U32
558+
arguments
559+
U32 a,
560+
U32 b
561+
description {
562+
Returns the larger number between a and b by magnitude
563+
If either number is signaling NaN then that is made quiet
564+
}
565+
body {
566+
U32 mag_a = returnMag(a);
567+
U32 mag_b = returnMag(b);
568+
U32 nonsig_a = returnNonSignalingNaN(a);
569+
U32 nonsig_b = returnNonSignalingNaN(b);
570+
if (mag_a < mag_b) {
571+
return nonsig_b;
572+
}
573+
if (mag_b < mag_a) {
574+
return nonsig_a;
575+
}
576+
return (nonsig_a < nonsig_b) ? nonsig_a : nonsig_b;
577+
}
578+
}
579+
580+
function softfloat_propagateNaNF32UI {
581+
returns U32
582+
arguments
583+
U32 a,
584+
U32 b
585+
description {
586+
Interpreting 'a' and 'b' as the bit patterns of two 32-bit floating-
587+
| point values, at least one of which is a NaN, returns the bit pattern of
588+
| the combined NaN result. If either 'a' or 'b' has the pattern of a
589+
| signaling NaN, the invalid exception is raised.
590+
}
591+
body {
592+
# 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);
595+
596+
# get non Signalling versions of a and b
597+
U32 nonsig_a = returnNonSignalingNaN(a);
598+
U32 nonsig_b = returnNonSignalingNaN(b);
599+
600+
if (isSigNaN_a | isSigNaN_b) {
601+
# raise invalid flag if either number is NaN
602+
set_fp_flag(FpFlag::NV);
603+
if ( isSigNaN_a ) {
604+
if ( isSigNaN_b ) {
605+
# if both numbers are NaN return larger magnitude and remove NaN signaling
606+
return returnLargerMag(a, b);
607+
}
608+
# if b is NaN return non signaling value of b
609+
return is_sp_nan(b) ? nonsig_b : nonsig_a;
610+
} else {
611+
return is_sp_nan(a) ? nonsig_a : nonsig_b;
612+
}
613+
}
614+
615+
}
616+
}
617+
618+
function softfloat_addMagsF32 {
619+
returns U32
620+
arguments
621+
U32 a,
622+
U32 b,
623+
RoundingMode mode
624+
description {
625+
Returns sum of the magnitudes of 2 floating point numbers
626+
}
627+
body {
628+
629+
# extract exponents and significands of a and b
630+
Bits<8> expA = expF32UI(a);
631+
Bits<23> sigA = fracF32UI(a);
632+
Bits<8> expB = expF32UI(b);
633+
Bits<23> sigB = fracF32UI(b);
634+
635+
# declare a variable to store significand of sum
636+
U32 sigZ;
637+
# declare a variable to store sum of the magnitudes of the 2 numbers
638+
U32 z;
639+
# declare a variable to store sign of sum
640+
Bits<1> signZ;
641+
642+
# declare a variable to store the exponent part of sum
643+
Bits<8> expZ;
644+
645+
# calculate difference of exponents
646+
Bits<8> expDiff = expA - expB
647+
648+
if (expDiff == 8'd0) {
649+
if (expA == 8'd0) {
650+
z = a + b;
651+
return z; # if exponents of both numbers are zero, then return sum of both numbers
652+
}
653+
654+
# check if A is infinity or NaN
655+
if (expA == 8'hFF) {
656+
# 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);
659+
}
660+
# return infinity if A is infinity
661+
return a;
662+
}
663+
664+
signZ = signF32UI(a);
665+
expZ = expA;
666+
sigZ = 32'h01000000 + sigA + sigB;
667+
668+
# check if significand is even and exponent is less than 8'FE
669+
if (((sigZ & 0x1) == 0) && (expZ < 8'hFE)) {
670+
# if significand is even, remove trailing zero
671+
sigZ = sigZ >> 1;
672+
# pack the sign, exponent and significand
673+
return (32'h0 + (signZ << 31) + (expZ << 23) + sigZ);
674+
}
675+
676+
sigZ = sigZ << 6;
677+
} else {
678+
679+
signZ = signF32UI(a);
680+
681+
U32 sigA_32 = 32'h0 + (sigA << 6);
682+
U32 sigB_32 = 32'h0 + (sigA << 6);
683+
684+
# check if B has a bigger exponent value than A
685+
if (expDiff < 0) {
686+
# check if B is infinity or NaN
687+
if (expB == 8'hFF) {
688+
# B is NaN if exponent is 8'hFF and significand is non-zero
689+
if (sigB != 0) {
690+
softfloat_propagateNaNF32UI(a, b);
691+
}
692+
# return infinity with same sign as A
693+
return packToF32UI(signZ, 8'hFF, 23'h0);
694+
}
695+
expZ = expB;
696+
697+
sigA_32 = (expA == 0) ? 2*sigA_32 : (sigA_32 + 0x20000000);
698+
sigA_32 = softfloat_shiftRightJam32(sigA_32, (32'h0 - expDiff));
699+
} else {
700+
# check if A is infinity or NaN
701+
if (expA == 8'hFF) {
702+
# A is NaN if exponent is 8'hFF and significand is non-zero
703+
if (sigA != 0) {
704+
softfloat_propagateNaNF32UI(a, b);
705+
}
706+
# return infinity with same sign as A
707+
return a;
708+
}
709+
710+
expZ = expA;
711+
sigB_32 = (expB == 0) ? 2*sigB_32 : (sigB_32 + 0x20000000);
712+
sigB_32 = softfloat_shiftRightJam32(sigB_32, (32'h0 + expDiff));
713+
}
714+
715+
U32 sigZ = 0x20000000 + sigA + sigB;
716+
if ( sigZ < 0x40000000 ) {
717+
expZ = expZ - 1;
718+
sigZ = sigZ << 1;
719+
}
720+
}
721+
return softfloat_roundPackToF32(signZ, expZ, sigZ[22:0], mode);
722+
}
723+
}
724+
725+
function softfloat_subMagsF32 {
726+
returns U32
727+
arguments
728+
U32 a,
729+
U32 b,
730+
RoundingMode mode
731+
description {
732+
Returns difference of the magnitudes of 2 floating point numbers
733+
}
734+
body {
735+
736+
# extract exponents and significands of a and b
737+
Bits<8> expA = expF32UI(a);
738+
Bits<23> sigA = fracF32UI(a);
739+
Bits<8> expB = expF32UI(b);
740+
Bits<23> sigB = fracF32UI(b);
741+
742+
# declare a variable to store significand of difference
743+
U32 sigZ;
744+
# declare a variable to store difference of the magnitudes of the 2 numbers
745+
U32 z;
746+
# declare a variable to store sign of difference
747+
Bits<1> signZ;
748+
749+
# declare a variable to store the exponent part of difference
750+
Bits<8> expZ;
751+
752+
# declare a variable to store the difference in significand
753+
U32 sigDiff;
754+
755+
# declare a variable to store shift distance
756+
Bits<8> shiftDist;
757+
758+
# calculate difference of exponents
759+
Bits<8> expDiff = expA - expB
760+
761+
if (expDiff == 8'd0) {
762+
763+
# check if A is infinity or NaN
764+
if (expA == 8'hFF) {
765+
# 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);
768+
}
769+
# return infinity if A is infinity
770+
return a;
771+
}
772+
773+
sigDiff = sigA - sigB;
774+
775+
# check if no difference in significand
776+
if (sigDiff == 0) {
777+
# return -0 if rounding mode is round down, else return +0
778+
return packToF32UI((mode == RoundingMode::RDN),0,0);
779+
}
780+
781+
if (expA != 0) {
782+
expA = expA - 1;
783+
}
784+
785+
signZ = signF32UI(a);
786+
if (sigDiff < 0) {
787+
signZ != signZ;
788+
sigDiff = -32'hs1 * sigDiff;
789+
}
790+
791+
792+

arch/prose/idl.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ Two builtin variables exist:
560560

561561
=== Constants
562562

563-
Constants are declared like mutable variables, execpt that their name starts with an uppercase letter.
563+
Constants are declared like mutable variables, except that their name starts with an uppercase letter.
564564

565565
Constant names must start with an uppercase letter and can be followed by any number of letters (any case), numbers, or an underscore. Constants must be initialized when declared, and cannot be assigned after declaration. Constants must be initialized with a value known at compile time (_i.e._, initialization cannot reference variables).
566566

0 commit comments

Comments
 (0)