From d00c02502096d0e74cd1a674426b7b3f65d2d9f7 Mon Sep 17 00:00:00 2001 From: Jordan Carlin Date: Wed, 5 Jun 2024 23:47:23 -0700 Subject: [PATCH] Add quad floating point to float lib --- lib/float/common.sail | 19 ++++++++++++----- test/float/eq_test.sail | 14 +++++++++++++ test/float/inf_test.sail | 11 ++++++++++ test/float/nan_test.sail | 41 +++++++++++++++++++++++++++++++++++++ test/float/ne_test.sail | 14 +++++++++++++ test/float/normal_test.sail | 22 ++++++++++++++++++++ test/float/sign_test.sail | 20 ++++++++++++++++++ test/float/zero_test.sail | 9 ++++++++ 8 files changed, 145 insertions(+), 5 deletions(-) diff --git a/lib/float/common.sail b/lib/float/common.sail index b66a03fe2..b903f0061 100644 --- a/lib/float/common.sail +++ b/lib/float/common.sail @@ -32,8 +32,8 @@ $define _FLOAT_COMMON /* Floating point types definition */ type fp_exception_flags = bits(5) /* Floating-point exception flags. */ -type fp_bits = { 'n, 'n in {16, 32, 64}. bits('n) } /* Floating-point in bits. */ -type fp_bits_x2 = { 'n, 'n in {16, 32, 64}. (bits('n), bits('n)) } /* Floating point x2 tuple */ +type fp_bits = { 'n, 'n in {16, 32, 64, 128}. bits('n) } /* Floating-point in bits. */ +type fp_bits_x2 = { 'n, 'n in {16, 32, 64, 128}. (bits('n), bits('n)) } /* Floating point x2 tuple */ type fp_bool_and_flags = (bool, fp_exception_flags) /* Floating point bool and exception flags tuple */ /* Floating point constants */ @@ -47,16 +47,20 @@ struct float_bits('n : Int) = { then 5 else (if 'n == 32 then 8 - else 11)), + else (if 'n == 64 + then 11 + else 15))), mantissa : bits(if 'n == 16 then 10 else (if 'n == 32 then 23 - else 52)), + else (if 'n == 64 + then 52 + else 112))), } /* The val func implementations */ -val float_decompose : forall 'n, 'n in { 16, 32, 64 }. bits('n) -> float_bits('n) +val float_decompose : forall 'n, 'n in { 16, 32, 64, 128 }. bits('n) -> float_bits('n) function float_decompose(op) = { match 'n { 16 => struct { @@ -73,6 +77,11 @@ function float_decompose(op) = { sign = op[63..63], exp = op[62..52], mantissa = op[51..0], + }, + 128 => struct { + sign = op[127..127], + exp = op[126..112], + mantissa = op[111..0], } } } diff --git a/test/float/eq_test.sail b/test/float/eq_test.sail index bc4c3e4ed..7b8d2c562 100644 --- a/test/float/eq_test.sail +++ b/test/float/eq_test.sail @@ -75,6 +75,20 @@ function test_float_is_eq () -> unit = { assert(float_is_eq((0x7ff7000000000000, 0x0000234db0000000)) == (false, fp_eflag_invalid)); assert(float_is_eq((0x7ff0000000000001, 0xfff0000003000001)) == (false, fp_eflag_invalid)); + + /* Quad floating point */ + assert(float_is_eq((0x00000000000000000000000000000001, 0x00000000000000000000000000000001)) == (true, fp_eflag_none)); + assert(float_is_eq((0x0f00000000000000000000000000000f, 0x0f00000000000000000000000000000f)) == (true, fp_eflag_none)); + assert(float_is_eq((0x80000000000000000000000000000000, 0x00000000000000000000000000000000)) == (true, fp_eflag_none)); + assert(float_is_eq((0x7fff0000000000000000000000000000, 0x7fff0000000000000000000000000000)) == (true, fp_eflag_none)); + + assert(float_is_eq((0x00000000000000000000000000000001, 0x80000000000000000000000000000001)) == (false, fp_eflag_none)); + assert(float_is_eq((0x0f00000000000000000000000000000f, 0x3f00000000000000000000000000000f)) == (false, fp_eflag_none)); + assert(float_is_eq((0x7fff8000000000000000000000000000, 0x0000234db00000000000000000000000)) == (false, fp_eflag_none)); + assert(float_is_eq((0x7fff8000000000000000000000000000, 0xffff8000000000000000000000000000)) == (false, fp_eflag_none)); + + assert(float_is_eq((0x7fff7000000000000000000000000000, 0x0000234db00000000000000000000000)) == (false, fp_eflag_invalid)); + assert(float_is_eq((0x7fff0000000000000000000000000001, 0xfff00000030000000000000000000001)) == (false, fp_eflag_invalid)); } function main () -> unit = { diff --git a/test/float/inf_test.sail b/test/float/inf_test.sail index 24f25977a..764dc5d69 100644 --- a/test/float/inf_test.sail +++ b/test/float/inf_test.sail @@ -65,6 +65,17 @@ function test_float_is_inf () -> unit = { assert(float_is_inf(0xfff8000000000000) == false); assert(float_is_inf(0xfff0000000000001) == false); assert(float_is_inf(0xffc0000000000000) == false); + + /* Quad floating point */ + assert(float_is_inf(0x7fff0000000000000000000000000000)); + assert(float_is_inf(0xffff0000000000000000000000000000)); + + assert(float_is_inf(0x7fff8000000000000000000000000000) == false); + assert(float_is_inf(0x7fff0000000000000000000000000001) == false); + assert(float_is_inf(0x7ffc0000000000000000000000000000) == false); + assert(float_is_inf(0xffff8000000000000000000000000000) == false); + assert(float_is_inf(0xffff0000000000000000000000000001) == false); + assert(float_is_inf(0xfffc0000000000000000000000000000) == false); } function main () -> unit = { diff --git a/test/float/nan_test.sail b/test/float/nan_test.sail index 69feb682e..e86cba966 100644 --- a/test/float/nan_test.sail +++ b/test/float/nan_test.sail @@ -86,6 +86,24 @@ function test_float_is_nan () -> unit = { assert(float_is_nan(0xfff0000000000000) == false); assert(float_is_nan(0xffe0000000000000) == false); assert(float_is_nan(0xffc0000000000000) == false); + + /* Quad floating point */ + assert(float_is_nan(0x7fff8000000000000000000000000000)); + assert(float_is_nan(0x7fff0000000000000000000000000001)); + assert(float_is_nan(0x7fff8000000000000000000000000100)); + assert(float_is_nan(0x7fffc000000000001000000000000000)); + + assert(float_is_nan(0xffff8000000000000000000000000000)); + assert(float_is_nan(0xffff0000000000000000000000000001)); + assert(float_is_nan(0xffff8000000000000000000000000100)); + assert(float_is_nan(0xffffc000000000001000000000000000)); + + assert(float_is_nan(0x7fff0000000000000000000000000000) == false); + assert(float_is_nan(0x7ffe0000000000000000000000000000) == false); + assert(float_is_nan(0x7ffc0000000000000000000000000000) == false); + assert(float_is_nan(0xffff0000000000000000000000000000) == false); + assert(float_is_nan(0xfffe0000000000000000000000000000) == false); + assert(float_is_nan(0xfffc0000000000000000000000000000) == false); } function test_float_is_snan () -> unit = { @@ -121,6 +139,18 @@ function test_float_is_snan () -> unit = { assert(float_is_snan(0x7ff8000000000000) == false); assert(float_is_snan(0xfff8000000000000) == false); assert(float_is_snan(0xfef8000000000001) == false); + + /* Quad floating point */ + assert(float_is_snan(0x7fff7000000000000000000000000000)); + assert(float_is_snan(0x7fff7000000000000000000000000001)); + + assert(float_is_snan(0xffff7000000000000000000000000000)); + assert(float_is_snan(0xffff7000000000000000000000000001)); + + assert(float_is_snan(0x7fff8000000000000000000000000000) == false); + assert(float_is_snan(0xffff8000000000000000000000000000) == false); + assert(float_is_snan(0xfeff8000000000000000000000000001) == false); + } function test_float_is_qnan () -> unit = { @@ -156,6 +186,17 @@ function test_float_is_qnan () -> unit = { assert(float_is_qnan(0x7ff7000000000000) == false); assert(float_is_qnan(0xfff7000000000000) == false); assert(float_is_qnan(0xfef7000000000001) == false); + + /* Quad floating point */ + assert(float_is_qnan(0x7fff8000000000000000000000000000)); + assert(float_is_qnan(0x7fff8000000000000000000000000001)); + + assert(float_is_qnan(0xffff8000000000000000000000000000)); + assert(float_is_qnan(0xffff8000000000000000000000000001)); + + assert(float_is_qnan(0x7fff7000000000000000000000000000) == false); + assert(float_is_qnan(0xffff7000000000000000000000000000) == false); + assert(float_is_qnan(0xfeff7000000000000000000000000001) == false); } function main () -> unit = { diff --git a/test/float/ne_test.sail b/test/float/ne_test.sail index a712bc0bb..fe1aca723 100644 --- a/test/float/ne_test.sail +++ b/test/float/ne_test.sail @@ -75,6 +75,20 @@ function test_float_is_ne () -> unit = { assert(float_is_ne((0x7ff7000000000000, 0x0000234db0000000)) == (false, fp_eflag_invalid)); assert(float_is_ne((0x7ff0000000000001, 0xfff0000003000001)) == (false, fp_eflag_invalid)); + + /* Quad floating point */ + assert(float_is_ne((0x80000000000000000000000000000001, 0x00000000000000000000000000000001)) == (true, fp_eflag_none)); + assert(float_is_ne((0x8f00000000000000000000000000000f, 0x0f00000000000000000000000000000f)) == (true, fp_eflag_none)); + assert(float_is_ne((0x80000000000000000000000000000000, 0x00000000000000000000000000000001)) == (true, fp_eflag_none)); + assert(float_is_ne((0x7fff0000000000000000000000000000, 0xffff0000000000000000000000000000)) == (true, fp_eflag_none)); + + assert(float_is_ne((0x00000000000000000000000000000011, 0x00000000000000000000000000000011)) == (false, fp_eflag_none)); + assert(float_is_ne((0x0ffff00000000000000000000000000f, 0x0ffff00000000000000000000000000f)) == (false, fp_eflag_none)); + assert(float_is_ne((0x00000000000000000000000000000000, 0x80000000000000000000000000000000)) == (false, fp_eflag_none)); + assert(float_is_ne((0x7fff8000000000000000000000000100, 0x7fff8000000000000000000000000100)) == (false, fp_eflag_none)); + + assert(float_is_ne((0x7fff7000000000000000000000000000, 0x0000000000000234db00000000000000)) == (false, fp_eflag_invalid)); + assert(float_is_ne((0x7fff0000000000000000000000000001, 0xffff0000000000000000000003000001)) == (false, fp_eflag_invalid)); } function main () -> unit = { diff --git a/test/float/normal_test.sail b/test/float/normal_test.sail index 8e29cd9ef..35cb59aef 100644 --- a/test/float/normal_test.sail +++ b/test/float/normal_test.sail @@ -65,6 +65,17 @@ function test_float_is_normal () -> unit = { assert(float_is_normal(0x7ff0000000000000) == false); assert(float_is_normal(0x0008000000000000) == false); assert(float_is_normal(0x8008000000000000) == false); + + /* Quad floating point */ + assert(float_is_normal(0x7ffe0000000000000000000000000000)); + assert(float_is_normal(0x7ffe0000000000000000000000000001)); + assert(float_is_normal(0xfffc000000000000000000000000000f)); + assert(float_is_normal(0x80030000000000000001000000000000)); + + assert(float_is_normal(0x7fff8000000000000000000000000000) == false); + assert(float_is_normal(0x7fff0000000000000000000000000000) == false); + assert(float_is_normal(0x00008000000000000000000000000000) == false); + assert(float_is_normal(0x80008000000000000000000000000000) == false); } function test_float_is_denormal () -> unit = { @@ -100,6 +111,17 @@ function test_float_is_denormal () -> unit = { assert(float_is_denormal(0x7ff0000000000000) == false); assert(float_is_denormal(0xffc000000000000f) == false); assert(float_is_denormal(0x8030000000100000) == false); + + /* Quad floating point */ + assert(float_is_denormal(0x00008000000000000000000000000000)); + assert(float_is_denormal(0x80008000000000000000000000000000)); + assert(float_is_denormal(0x80000000000000000000000000000001)); + assert(float_is_denormal(0x80008000000000000001000000000000)); + + assert(float_is_denormal(0x7fff8000000000000000000000000000) == false); + assert(float_is_denormal(0x7fff0000000000000000000000000000) == false); + assert(float_is_denormal(0xfffc000000000000000000000000000f) == false); + assert(float_is_denormal(0x80030000000000000001000000000000) == false); } function main () -> unit = { diff --git a/test/float/sign_test.sail b/test/float/sign_test.sail index 1a9cbdc4e..c548c28f5 100644 --- a/test/float/sign_test.sail +++ b/test/float/sign_test.sail @@ -62,6 +62,16 @@ function test_float_is_positive () -> unit = { assert(float_is_positive(0xf8f0000000023000) == false); assert(float_is_positive(0xfce0000000000000) == false); assert(float_is_positive(0xe8c0000000000000) == false); + + /* Quad floating point */ + assert(float_is_positive(0x7ff080000f0f00000000000000000000)); + assert(float_is_positive(0x0000000000000fedc000000000000001)); + assert(float_is_positive(0x7fffffffffffffffffffffffffffffff)); + assert(float_is_positive(0x00000000003000000000010000000000)); + + assert(float_is_positive(0xf8ff0000000000000023000000000000) == false); + assert(float_is_positive(0xffce0000000000000000000000000000) == false); + assert(float_is_positive(0xe88c0000000000000000000000000000) == false); } function test_float_is_negative () -> unit = { @@ -94,6 +104,16 @@ function test_float_is_negative () -> unit = { assert(float_is_negative(0x78f0000000023000) == false); assert(float_is_negative(0x7ce0000000000000) == false); assert(float_is_negative(0x68c0000000000000) == false); + + /* Quad floating point */ + assert(float_is_negative(0xfff0000000800000000f0f0000000000)); + assert(float_is_negative(0x8000000000000fedc000000000000001)); + assert(float_is_negative(0xffffffffffffffffffffffffffffffff)); + assert(float_is_negative(0x80000000003000000000010000000000)); + + assert(float_is_negative(0x78ff0000000000000000023000000000) == false); + assert(float_is_negative(0x7fce0000000000000000000000000000) == false); + assert(float_is_negative(0x688c0000000000000000000000000000) == false); } function main () -> unit = { diff --git a/test/float/zero_test.sail b/test/float/zero_test.sail index ba7192324..64aeb843c 100644 --- a/test/float/zero_test.sail +++ b/test/float/zero_test.sail @@ -59,6 +59,15 @@ function test_float_is_zero () -> unit = { assert(float_is_zero(0x7ff0000000000001) == false); assert(float_is_zero(0xfff8000000000000) == false); assert(float_is_zero(0xfff0000000000001) == false); + + /* Quad floating point */ + assert(float_is_zero(0x80000000000000000000000000000000)); + assert(float_is_zero(0x00000000000000000000000000000000)); + + assert(float_is_zero(0x7fff8000000000000000000000000000) == false); + assert(float_is_zero(0x7fff0000000000000000000000000001) == false); + assert(float_is_zero(0xffff8000000000000000000000000000) == false); + assert(float_is_zero(0xffff0000000000000000000000000001) == false); } function main () -> unit = {