Merge pull request #572 from stineje/main

Update for fp to int conversion for IEEE 754 vs. RISC-V
This commit is contained in:
David Harris 2024-01-15 07:12:11 -08:00 committed by GitHub
commit bf0d02b9b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 74 additions and 18 deletions

View File

@ -6,7 +6,7 @@ LFLAGS = -L.
# Link against the riscv-isa-sim version of SoftFloat rather than
# the regular version to get RISC-V NaN behavior
#IFLAGS = -I$(RISCV)/riscv-isa-sim/softfloat
#LIBS = $(RISCV)/riscv-isa-sim/build/libsoftfloat.a
#LIBS = $(RISCV)/riscv-isa-sim/build/libsoftfloat.a -lm -lquadmath
IFLAGS = -I../../../addins/SoftFloat-3e/source/include/
LIBS = ../../../addins/SoftFloat-3e/build/Linux-x86_64-GCC/softfloat.a -lm -lquadmath
SRCS = $(wildcard *.c)

View File

@ -38,16 +38,19 @@ void printF64 (char *msg, float64_t d) {
int i, j;
conv.v = d.v; // use union to convert between hexadecimal and floating-point views
printf("%s: ", msg); // print out nicely
printf("0x%08x_%08x = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d);
printf("0x%08lx_%08lx = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d);
}
void printF128 (char *msg, float128_t q) {
qp conv;
int i, j;
char buf[64];
conv.v[0] = q.v[0]; // use union to convert between hexadecimal and floating-point views
conv.v[1] = q.v[1]; // use union to convert between hexadecimal and floating-point views
printf("%s: ", msg); // print out nicely
printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q);
//printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q);
quadmath_snprintf (buf, sizeof buf, "%1.15Qe", conv.q);
printf("0x%016" PRIx64 "_%016" PRIx64 " = %s\n", q.v[1], q.v[0], buf);
}
void printFlags(void) {

View File

@ -38,16 +38,23 @@ void printF64 (char *msg, float64_t d) {
int i, j;
conv.v = d.v; // use union to convert between hexadecimal and floating-point views
printf("%s: ", msg); // print out nicely
printf("0x%08x_%08x = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d);
printf("0x%08lx_%08lx = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d);
}
void printF128 (char *msg, float128_t q) {
qp conv;
int i, j;
char buf[64];
conv.v[0] = q.v[0]; // use union to convert between hexadecimal and floating-point views
conv.v[1] = q.v[1]; // use union to convert between hexadecimal and floating-point views
printf("%s: ", msg); // print out nicely
printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q);
// Some compilers can understand %Q for printf on quad precision instead of the
// API call of quadmath_snprintf
// printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q);
quadmath_snprintf (buf, sizeof buf, "%1.15Qe", conv.q);
printf("0x%016" PRIx64 "_%016" PRIx64 " = %s\n", q.v[1], q.v[0], buf);
}
void printFlags(void) {
@ -74,6 +81,8 @@ int main() {
float128_t x, y, z;
float128_t r;
uint32_t u, v, w;
int32_t a, b, c;
x.v[1] = 0xBFFF988ECE97DFEB;
x.v[0] = 0xC3BBA082445B4836;

View File

@ -38,16 +38,19 @@ void printF64 (char *msg, float64_t d) {
int i, j;
conv.v = d.v; // use union to convert between hexadecimal and floating-point views
printf("%s: ", msg); // print out nicely
printf("0x%08x_%08x = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d);
printf("0x%08lx_%08lx = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d);
}
void printF128 (char *msg, float128_t q) {
qp conv;
int i, j;
char buf[64];
conv.v[0] = q.v[0]; // use union to convert between hexadecimal and floating-point views
conv.v[1] = q.v[1]; // use union to convert between hexadecimal and floating-point views
printf("%s: ", msg); // print out nicely
printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q);
//printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q);
quadmath_snprintf (buf, sizeof buf, "%1.15Qe", conv.q);
printf("0x%016" PRIx64 "_%016" PRIx64 " = %s\n", q.v[1], q.v[0], buf);
}
void printFlags(void) {

View File

@ -266,6 +266,30 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
// integer result selection
///////////////////////////////////////////////////////////////////////////////////////
// Causes undefined behavior for invalid:
// Invalid cases are different for IEEE 754 vs. RISC-V. For RISC-V, typical results are used
// unsigned: if invalid (e.g., negative fp to unsigned int, result should overflow and
// overflows to the maximum value
// signed: if invalid, result should overflow to maximum negative value
// but is undefined and used for information only
// Note: The IEEE 754 result comes from values in TestFloat for x86_64
// IEEE 754
// select the overflow integer res
// - negitive infinity and out of range negitive input
// | int | long |
// signed | -2^31 | -2^63 |
// unsigned | 2^32-1 | 2^64-1 |
//
// - positive infinity and out of range positive input and NaNs
// | int | long |
// signed | -2^31 |-2^63 |
// unsigned | 2^32-1 | 2^64-1 |
//
// other: 32 bit unsigned res should be sign extended as if it were a signed number
// RISC-V
// select the overflow integer res
// - negitive infinity and out of range negitive input
// | int | long |
@ -278,17 +302,34 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
// unsigned | 2^32-1 | 2^64-1 |
//
// other: 32 bit unsinged res should be sign extended as if it were a signed number
always_comb
if(Signed)
if(Xs&~NaNIn) // signed negitive
if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}};
else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
else // signed positive
if(Int64) OfIntRes = {1'b0, {P.XLEN-1{1'b1}}};
else OfIntRes = {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}};
else
if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive
else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
if(P.IEEE754) begin
always_comb
if(Signed)
if(Xs&~NaNIn) // signed negitive
if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}};
else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
else // signed positive
if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}};
else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
else
if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b1}}; // unsigned negitive
else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
end // if (P.IEEE754)
else begin
always_comb
if(Signed)
if(Xs&~NaNIn) // signed negitive
if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}};
else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
else // signed positive
if(Int64) OfIntRes = {1'b0, {P.XLEN-1{1'b1}}};
else OfIntRes = {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}};
else
if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive
else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
end // else: !if(P.IEEE754)
// select the integer output
// - if the input is invalid (out of bounds NaN or Inf) then output overflow res