mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge pull request #572 from stineje/main
Update for fp to int conversion for IEEE 754 vs. RISC-V
This commit is contained in:
commit
bf0d02b9b6
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user