From b14cd67bef61c2f05c9a21499d34d83723089250 Mon Sep 17 00:00:00 2001 From: "James E. Stine" Date: Sun, 14 Jan 2024 22:08:42 -0600 Subject: [PATCH] Values for IEEE 754 vs. RISC-V Table 11.4 in the RISC-V Unprivileged ISA --- src/fpu/postproc/specialcase.sv | 63 +++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/src/fpu/postproc/specialcase.sv b/src/fpu/postproc/specialcase.sv index c8442595a..5161bc645 100644 --- a/src/fpu/postproc/specialcase.sv +++ b/src/fpu/postproc/specialcase.sv @@ -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