@@ -20,8 +20,15 @@ Bits<32> SP_NEG_ZERO = 32'b1_00000000_00000000000000000000000;
20
20
Bits<32> SP_CANONICAL_NAN = 32'b0_11111111_10000000000000000000000;
21
21
Bits<16> HP_CANONICAL_NAN = 16'b0_11111_1000000000;
22
22
23
- Bits<32> WORD_NEG_OVERFLOW = 32'h8000_0000; # minimum 32-bit integer
24
- Bits<32> WORD_POS_OVERFLOW = 32'h7FFF_FFFF; # maximum 32-bit integer
23
+ Bits<32> WORD_NEG_OVERFLOW = 32'h8000_0000; # minimum signed 32-bit integer
24
+ Bits<32> WORD_POS_OVERFLOW = 32'h7FFF_FFFF; # maximum signed 32-bit integer
25
+
26
+ Bits<32> UI32_NEG_OVERFLOW = 32'h0000_0000; # minimum unsigned 32-bit integer
27
+ Bits<32> UI32_POS_OVERFLOW = 32'hFFFF_FFFF; # maximum unsigned 32-bit integer
28
+
29
+ Bits<32> UI32_NAN = 32'hFFFF_FFFF; # NaN to unsigned 32-bit integer
30
+ Bits<32> I32_NAN = 32'h7FFF_FFFF; # NaN to signed 32-bit integer
31
+
25
32
26
33
enum RoundingMode {
27
34
RNE 0b000 # Round to Nearest, ties to Even
@@ -331,7 +338,7 @@ function softfloat_roundToI32 {
331
338
Bits<64> sig,
332
339
RoundingMode roundingMode
333
340
description {
334
- Round to unsigned 32-bit integer, using +rounding_mode+
341
+ Round to signed 32-bit integer, using +rounding_mode+
335
342
}
336
343
body {
337
344
Bits<16> roundIncrement = 0x800;
@@ -375,6 +382,58 @@ function softfloat_roundToI32 {
375
382
}
376
383
}
377
384
385
+ function softfloat_roundToUI32 {
386
+ returns Bits<32>
387
+ arguments
388
+ Bits<1> sign,
389
+ Bits<64> sig,
390
+ RoundingMode roundingMode
391
+ description {
392
+ Round to unsigned 32-bit integer, using +rounding_mode+
393
+ }
394
+ body {
395
+ Bits<16> roundIncrement = 0x800;
396
+ if (
397
+ (roundingMode != RoundingMode::RMM)
398
+ && (roundingMode != RoundingMode::RNE)
399
+ ) {
400
+ roundIncrement = 0;
401
+ if ( sign == 1) {
402
+ if (sig == 0) { return 0; }
403
+ if (roundingMode == RoundingMode::RDN) { set_fp_flag(FpFlag::NV); }
404
+ } else {
405
+ if (roundingMode == RoundingMode::RUP) { roundIncrement = 0xFFF; }
406
+ }
407
+ }
408
+
409
+ Bits<16> roundBits = sig & 0xFFF;
410
+ sig = sig + roundIncrement;
411
+ if ((sig & 0xFFFFF00000000000) != 0) {
412
+ set_fp_flag(FpFlag::NV);
413
+ return sign == 1 ? UI32_NEG_OVERFLOW : UI32_POS_OVERFLOW;
414
+ }
415
+
416
+ Bits<32> z = sig >> 12;
417
+ if (
418
+ (roundBits == 0x800 && (roundingMode == RoundingMode::RNE))
419
+ ) {
420
+ z = z & ~32'b1;
421
+ }
422
+
423
+
424
+
425
+ if ((z != 0) && (sign == 1)) {
426
+ set_fp_flag(FpFlag::NV);
427
+ return sign == 1 ? UI32_NEG_OVERFLOW : UI32_POS_OVERFLOW;
428
+ }
429
+
430
+ if (roundBits != 0) {
431
+ set_fp_flag(FpFlag::NX);
432
+ }
433
+ return z;
434
+ }
435
+ }
436
+
378
437
function packToF32UI {
379
438
returns Bits<32>
380
439
arguments
@@ -875,7 +934,7 @@ function i32_to_f32 {
875
934
U32 a,
876
935
RoundingMode mode
877
936
description {
878
- Converts 32-bit signed integer to 32-bit floating point
937
+ Converts 32-bit signed integer to 32-bit floating point number
879
938
}
880
939
body {
881
940
# sign of integer, it is 1 when negative
@@ -894,7 +953,7 @@ function ui32_to_f32 {
894
953
U32 a,
895
954
RoundingMode mode
896
955
description {
897
- Converts 32-bit unsigned integer to 32-bit floating point
956
+ Converts 32-bit unsigned integer to 32-bit floating point number
898
957
}
899
958
body {
900
959
# sign of integer, it is 1 when negative
@@ -908,3 +967,77 @@ function ui32_to_f32 {
908
967
}
909
968
}
910
969
}
970
+
971
+ function f32_to_i32 {
972
+ returns U32
973
+ arguments
974
+ U32 a,
975
+ RoundingMode mode
976
+ description {
977
+ Converts 32-bit floating point number to a signed 32-bit integer
978
+ }
979
+ body {
980
+ Bits<1> sign = signF32UI(a);
981
+ Bits<8> exp = expF32UI(a);
982
+ Bits<23> sig = fracF32UI(a);
983
+ Bits<8> shiftDist;
984
+ U64 sig64;
985
+ # for NaN return the highest positive value and set floating-point flag to invalid.
986
+ if ((exp == 8'hFF) && (sig != 0)) {
987
+ sign = 0;
988
+ set_fp_flag(FpFlag::NV);
989
+ return I32_NAN;
990
+ }
991
+
992
+ # MSB of significand is set to 1 because minimum 32-bit integer in IEEE 754 is 32'h80000000
993
+ if (exp != 0) {
994
+ sig = sig | 32'h00800000;
995
+ }
996
+
997
+ sig64 = sig `<< 32;
998
+ shiftDist = 8'hAA - exp;
999
+
1000
+ if (shiftDist > 0) {
1001
+ sig64 = softfloat_shiftRightJam64( sig64, shiftDist);
1002
+ }
1003
+
1004
+ return softfloat_roundToI32(sign, sig64, mode);
1005
+ }
1006
+ }
1007
+
1008
+ function f32_to_ui32 {
1009
+ returns U32
1010
+ arguments
1011
+ U32 a,
1012
+ RoundingMode mode
1013
+ description {
1014
+ Converts 32-bit floating point number to an unsigned 32-bit integer
1015
+ }
1016
+ body {
1017
+ Bits<1> sign = signF32UI(a);
1018
+ Bits<8> exp = expF32UI(a);
1019
+ Bits<23> sig = fracF32UI(a);
1020
+ Bits<8> shiftDist;
1021
+ U64 sig64;
1022
+ # for NaN return the highest positive value and set floating-point flag to invalid.
1023
+ if ((exp == 8'hFF) && (sig != 0)) {
1024
+ sign = 0;
1025
+ set_fp_flag(FpFlag::NV);
1026
+ return UI32_NAN;
1027
+ }
1028
+
1029
+ # MSB of significand is set to 1 because minimum 32-bit integer in IEEE 754 is 32'h80000000
1030
+ if (exp != 0) {
1031
+ sig = sig | 32'h00800000;
1032
+ }
1033
+
1034
+ sig64 = sig `<< 32;
1035
+ shiftDist = 8'hAA - exp;
1036
+
1037
+ if (shiftDist > 0) {
1038
+ sig64 = softfloat_shiftRightJam64( sig64, shiftDist);
1039
+ }
1040
+
1041
+ return softfloat_roundToUI32(sign, sig64, mode);
1042
+ }
1043
+ }
0 commit comments