From: Andrew Waterman Date: Wed, 2 Mar 2016 00:24:05 +0000 (-0800) Subject: Upgrade to latest SoftFloat X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a95b44df9d142a49f3e1bfe4a60d259ed41ca247;p=riscv-isa-sim.git Upgrade to latest SoftFloat --- diff --git a/riscv/decode.h b/riscv/decode.h index 5be6398..f525ff1 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -200,6 +200,10 @@ private: #define PC_SERIALIZE 3 /* sentinel value indicating simulator pipeline flush */ +/* Convenience wrappers to simplify softfloat code sequences */ +#define f32(x) ((float32_t){(uint32_t)x}) +#define f64(x) ((float64_t){(uint64_t)x}) + #define validate_csr(which, write) ({ \ if (!STATE.serialized) return PC_SERIALIZE; \ STATE.serialized = false; \ diff --git a/riscv/insn_template.h b/riscv/insn_template.h index f632872..0dd0aa1 100644 --- a/riscv/insn_template.h +++ b/riscv/insn_template.h @@ -3,7 +3,6 @@ #include "mmu.h" #include "mulhi.h" #include "softfloat.h" +#include "internals.h" #include "tracer.h" -#include "platform.h" // softfloat isNaNF32UI, etc. -#include "internals.h" // ditto #include diff --git a/riscv/insns/fadd_d.h b/riscv/insns/fadd_d.h index 3e5963d..9990174 100644 --- a/riscv/insns/fadd_d.h +++ b/riscv/insns/fadd_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(FRS1, 0x3ff0000000000000ULL, FRS2)); +WRITE_FRD(f64_add(f64(FRS1), f64(FRS2)).v); set_fp_exceptions; diff --git a/riscv/insns/fadd_s.h b/riscv/insns/fadd_s.h index a35a524..cdef36a 100644 --- a/riscv/insns/fadd_s.h +++ b/riscv/insns/fadd_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(FRS1, 0x3f800000, FRS2)); +WRITE_FRD(f32_add(f32(FRS1), f32(FRS2)).v); set_fp_exceptions; diff --git a/riscv/insns/fclass_d.h b/riscv/insns/fclass_d.h index f4883ef..9456123 100644 --- a/riscv/insns/fclass_d.h +++ b/riscv/insns/fclass_d.h @@ -1,3 +1,3 @@ require_extension('D'); require_fp; -WRITE_RD(f64_classify(FRS1)); +WRITE_RD(f64_classify(f64(FRS1))); diff --git a/riscv/insns/fclass_s.h b/riscv/insns/fclass_s.h index a2d5b63..a392db8 100644 --- a/riscv/insns/fclass_s.h +++ b/riscv/insns/fclass_s.h @@ -1,3 +1,3 @@ require_extension('F'); require_fp; -WRITE_RD(f32_classify(FRS1)); +WRITE_RD(f32_classify(f32(FRS1))); diff --git a/riscv/insns/fcvt_d_l.h b/riscv/insns/fcvt_d_l.h index 08716cf..fece227 100644 --- a/riscv/insns/fcvt_d_l.h +++ b/riscv/insns/fcvt_d_l.h @@ -2,5 +2,5 @@ require_extension('D'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i64_to_f64(RS1)); +WRITE_FRD(i64_to_f64(RS1).v); set_fp_exceptions; diff --git a/riscv/insns/fcvt_d_lu.h b/riscv/insns/fcvt_d_lu.h index 306d7fe..775c7ae 100644 --- a/riscv/insns/fcvt_d_lu.h +++ b/riscv/insns/fcvt_d_lu.h @@ -2,5 +2,5 @@ require_extension('D'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui64_to_f64(RS1)); +WRITE_FRD(ui64_to_f64(RS1).v); set_fp_exceptions; diff --git a/riscv/insns/fcvt_d_s.h b/riscv/insns/fcvt_d_s.h index 177e77c..ec778cc 100644 --- a/riscv/insns/fcvt_d_s.h +++ b/riscv/insns/fcvt_d_s.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_to_f64(FRS1)); +WRITE_FRD(f32_to_f64(f32(FRS1)).v); set_fp_exceptions; diff --git a/riscv/insns/fcvt_d_w.h b/riscv/insns/fcvt_d_w.h index 4c4861c..753250d 100644 --- a/riscv/insns/fcvt_d_w.h +++ b/riscv/insns/fcvt_d_w.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i32_to_f64((int32_t)RS1)); +WRITE_FRD(i32_to_f64((int32_t)RS1).v); set_fp_exceptions; diff --git a/riscv/insns/fcvt_d_wu.h b/riscv/insns/fcvt_d_wu.h index 1dbf218..af893b3 100644 --- a/riscv/insns/fcvt_d_wu.h +++ b/riscv/insns/fcvt_d_wu.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui32_to_f64((uint32_t)RS1)); +WRITE_FRD(ui32_to_f64((uint32_t)RS1).v); set_fp_exceptions; diff --git a/riscv/insns/fcvt_l_d.h b/riscv/insns/fcvt_l_d.h index ee323f3..c09e6c4 100644 --- a/riscv/insns/fcvt_l_d.h +++ b/riscv/insns/fcvt_l_d.h @@ -2,5 +2,5 @@ require_extension('D'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_RD(f64_to_i64(FRS1, RM, true)); +WRITE_RD(f64_to_i64(f64(FRS1), RM, true)); set_fp_exceptions; diff --git a/riscv/insns/fcvt_l_s.h b/riscv/insns/fcvt_l_s.h index 6079a69..267e0eb 100644 --- a/riscv/insns/fcvt_l_s.h +++ b/riscv/insns/fcvt_l_s.h @@ -2,5 +2,5 @@ require_extension('F'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_RD(f32_to_i64(FRS1, RM, true)); +WRITE_RD(f32_to_i64(f32(FRS1), RM, true)); set_fp_exceptions; diff --git a/riscv/insns/fcvt_lu_d.h b/riscv/insns/fcvt_lu_d.h index b6004ea..3a02120 100644 --- a/riscv/insns/fcvt_lu_d.h +++ b/riscv/insns/fcvt_lu_d.h @@ -2,5 +2,5 @@ require_extension('D'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_RD(f64_to_ui64(FRS1, RM, true)); +WRITE_RD(f64_to_ui64(f64(FRS1), RM, true)); set_fp_exceptions; diff --git a/riscv/insns/fcvt_lu_s.h b/riscv/insns/fcvt_lu_s.h index af8e1ab..94115a3 100644 --- a/riscv/insns/fcvt_lu_s.h +++ b/riscv/insns/fcvt_lu_s.h @@ -2,5 +2,5 @@ require_extension('F'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_RD(f32_to_ui64(FRS1, RM, true)); +WRITE_RD(f32_to_ui64(f32(FRS1), RM, true)); set_fp_exceptions; diff --git a/riscv/insns/fcvt_s_d.h b/riscv/insns/fcvt_s_d.h index c1c9f0c..211bbba 100644 --- a/riscv/insns/fcvt_s_d.h +++ b/riscv/insns/fcvt_s_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_to_f32(FRS1)); +WRITE_FRD(f64_to_f32(f64(FRS1)).v); set_fp_exceptions; diff --git a/riscv/insns/fcvt_s_l.h b/riscv/insns/fcvt_s_l.h index 9abcc80..1c0581a 100644 --- a/riscv/insns/fcvt_s_l.h +++ b/riscv/insns/fcvt_s_l.h @@ -2,5 +2,5 @@ require_extension('F'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i64_to_f32(RS1)); +WRITE_FRD(i64_to_f32(RS1).v); set_fp_exceptions; diff --git a/riscv/insns/fcvt_s_lu.h b/riscv/insns/fcvt_s_lu.h index 70c676e..e9bf78e 100644 --- a/riscv/insns/fcvt_s_lu.h +++ b/riscv/insns/fcvt_s_lu.h @@ -2,5 +2,5 @@ require_extension('F'); require_rv64; require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui64_to_f32(RS1)); +WRITE_FRD(ui64_to_f32(RS1).v); set_fp_exceptions; diff --git a/riscv/insns/fcvt_s_w.h b/riscv/insns/fcvt_s_w.h index 1ddabd8..9411cbd 100644 --- a/riscv/insns/fcvt_s_w.h +++ b/riscv/insns/fcvt_s_w.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(i32_to_f32((int32_t)RS1)); +WRITE_FRD(i32_to_f32((int32_t)RS1).v); set_fp_exceptions; diff --git a/riscv/insns/fcvt_s_wu.h b/riscv/insns/fcvt_s_wu.h index c1394c3..a6cf836 100644 --- a/riscv/insns/fcvt_s_wu.h +++ b/riscv/insns/fcvt_s_wu.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(ui32_to_f32((uint32_t)RS1)); +WRITE_FRD(ui32_to_f32((uint32_t)RS1).v); set_fp_exceptions; diff --git a/riscv/insns/fcvt_w_d.h b/riscv/insns/fcvt_w_d.h index bac8a9b..28eb245 100644 --- a/riscv/insns/fcvt_w_d.h +++ b/riscv/insns/fcvt_w_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_RD(sext32(f64_to_i32(FRS1, RM, true))); +WRITE_RD(sext32(f64_to_i32(f64(FRS1), RM, true))); set_fp_exceptions; diff --git a/riscv/insns/fcvt_w_s.h b/riscv/insns/fcvt_w_s.h index 81bc89f..d30f1b4 100644 --- a/riscv/insns/fcvt_w_s.h +++ b/riscv/insns/fcvt_w_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_RD(sext32(f32_to_i32(FRS1, RM, true))); +WRITE_RD(sext32(f32_to_i32(f32(FRS1), RM, true))); set_fp_exceptions; diff --git a/riscv/insns/fcvt_wu_d.h b/riscv/insns/fcvt_wu_d.h index 353ae6d..5cdc004 100644 --- a/riscv/insns/fcvt_wu_d.h +++ b/riscv/insns/fcvt_wu_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_RD(sext32(f64_to_ui32(FRS1, RM, true))); +WRITE_RD(sext32(f64_to_ui32(f64(FRS1), RM, true))); set_fp_exceptions; diff --git a/riscv/insns/fcvt_wu_s.h b/riscv/insns/fcvt_wu_s.h index 2c1ff00..034d681 100644 --- a/riscv/insns/fcvt_wu_s.h +++ b/riscv/insns/fcvt_wu_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_RD(sext32(f32_to_ui32(FRS1, RM, true))); +WRITE_RD(sext32(f32_to_ui32(f32(FRS1), RM, true))); set_fp_exceptions; diff --git a/riscv/insns/fdiv_d.h b/riscv/insns/fdiv_d.h index d52ac66..d8943de 100644 --- a/riscv/insns/fdiv_d.h +++ b/riscv/insns/fdiv_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_div(FRS1, FRS2)); +WRITE_FRD(f64_div(f64(FRS1), f64(FRS2)).v); set_fp_exceptions; diff --git a/riscv/insns/fdiv_s.h b/riscv/insns/fdiv_s.h index cf54c57..66ac48d 100644 --- a/riscv/insns/fdiv_s.h +++ b/riscv/insns/fdiv_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_div(FRS1, FRS2)); +WRITE_FRD(f32_div(f32(FRS1), f32(FRS2)).v); set_fp_exceptions; diff --git a/riscv/insns/feq_d.h b/riscv/insns/feq_d.h index 43d9c1c..541ed5b 100644 --- a/riscv/insns/feq_d.h +++ b/riscv/insns/feq_d.h @@ -1,4 +1,4 @@ require_extension('D'); require_fp; -WRITE_RD(f64_eq(FRS1, FRS2)); +WRITE_RD(f64_eq(f64(FRS1), f64(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/feq_s.h b/riscv/insns/feq_s.h index 7d42634..489bea6 100644 --- a/riscv/insns/feq_s.h +++ b/riscv/insns/feq_s.h @@ -1,4 +1,4 @@ require_extension('F'); require_fp; -WRITE_RD(f32_eq(FRS1, FRS2)); +WRITE_RD(f32_eq(f32(FRS1), f32(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/fle_d.h b/riscv/insns/fle_d.h index 7f6a84d..419a36f 100644 --- a/riscv/insns/fle_d.h +++ b/riscv/insns/fle_d.h @@ -1,4 +1,4 @@ require_extension('D'); require_fp; -WRITE_RD(f64_le(FRS1, FRS2)); +WRITE_RD(f64_le(f64(FRS1), f64(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/fle_s.h b/riscv/insns/fle_s.h index 0884c51..5c0124e 100644 --- a/riscv/insns/fle_s.h +++ b/riscv/insns/fle_s.h @@ -1,4 +1,4 @@ require_extension('F'); require_fp; -WRITE_RD(f32_le(FRS1, FRS2)); +WRITE_RD(f32_le(f32(FRS1), f32(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/flt_d.h b/riscv/insns/flt_d.h index 9fda98d..7176a96 100644 --- a/riscv/insns/flt_d.h +++ b/riscv/insns/flt_d.h @@ -1,4 +1,4 @@ require_extension('D'); require_fp; -WRITE_RD(f64_lt(FRS1, FRS2)); +WRITE_RD(f64_lt(f64(FRS1), f64(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/flt_s.h b/riscv/insns/flt_s.h index 830b0a0..40acc34 100644 --- a/riscv/insns/flt_s.h +++ b/riscv/insns/flt_s.h @@ -1,4 +1,4 @@ require_extension('F'); require_fp; -WRITE_RD(f32_lt(FRS1, FRS2)); +WRITE_RD(f32_lt(f32(FRS1), f32(FRS2))); set_fp_exceptions; diff --git a/riscv/insns/fmadd_d.h b/riscv/insns/fmadd_d.h index 8605e0b..98f1cbc 100644 --- a/riscv/insns/fmadd_d.h +++ b/riscv/insns/fmadd_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(FRS1, FRS2, FRS3)); +WRITE_FRD(f64_mulAdd(f64(FRS1), f64(FRS2), f64(FRS3)).v); set_fp_exceptions; diff --git a/riscv/insns/fmadd_s.h b/riscv/insns/fmadd_s.h index 95196b7..a78ed25 100644 --- a/riscv/insns/fmadd_s.h +++ b/riscv/insns/fmadd_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(FRS1, FRS2, FRS3)); +WRITE_FRD(f32_mulAdd(f32(FRS1), f32(FRS2), f32(FRS3)).v); set_fp_exceptions; diff --git a/riscv/insns/fmax_d.h b/riscv/insns/fmax_d.h index eb156de..f0bea9b 100644 --- a/riscv/insns/fmax_d.h +++ b/riscv/insns/fmax_d.h @@ -1,5 +1,4 @@ require_extension('D'); require_fp; -WRITE_FRD(isNaNF64UI(FRS2) || f64_le_quiet(FRS2,FRS1) /* && FRS1 not NaN */ - ? FRS1 : FRS2); +WRITE_FRD(isNaNF64UI(FRS2) || f64_le_quiet(f64(FRS2), f64(FRS1)) ? FRS1 : FRS2); set_fp_exceptions; diff --git a/riscv/insns/fmax_s.h b/riscv/insns/fmax_s.h index 215a6d1..33b2bc6 100644 --- a/riscv/insns/fmax_s.h +++ b/riscv/insns/fmax_s.h @@ -1,5 +1,4 @@ require_extension('F'); require_fp; -WRITE_FRD(isNaNF32UI(FRS2) || f32_le_quiet(FRS2,FRS1) /* && FRS1 not NaN */ - ? FRS1 : FRS2); +WRITE_FRD(isNaNF32UI(FRS2) || f32_le_quiet(f32(FRS2), f32(FRS1)) ? FRS1 : FRS2); set_fp_exceptions; diff --git a/riscv/insns/fmin_d.h b/riscv/insns/fmin_d.h index 02ea681..e22b6ea 100644 --- a/riscv/insns/fmin_d.h +++ b/riscv/insns/fmin_d.h @@ -1,5 +1,4 @@ require_extension('D'); require_fp; -WRITE_FRD(isNaNF64UI(FRS2) || f64_lt_quiet(FRS1,FRS2) /* && FRS1 not NaN */ - ? FRS1 : FRS2); +WRITE_FRD(isNaNF64UI(FRS2) || f64_lt_quiet(f64(FRS1), f64(FRS2)) ? FRS1 : FRS2); set_fp_exceptions; diff --git a/riscv/insns/fmin_s.h b/riscv/insns/fmin_s.h index cc673a0..0ebb3a8 100644 --- a/riscv/insns/fmin_s.h +++ b/riscv/insns/fmin_s.h @@ -1,5 +1,4 @@ require_extension('F'); require_fp; -WRITE_FRD(isNaNF32UI(FRS2) || f32_lt_quiet(FRS1,FRS2) /* && FRS1 not NaN */ - ? FRS1 : FRS2); +WRITE_FRD(isNaNF32UI(FRS2) || f32_lt_quiet(f32(FRS1), f32(FRS2)) ? FRS1 : FRS2); set_fp_exceptions; diff --git a/riscv/insns/fmsub_d.h b/riscv/insns/fmsub_d.h index 696f822..afcea88 100644 --- a/riscv/insns/fmsub_d.h +++ b/riscv/insns/fmsub_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(FRS1, FRS2, FRS3 ^ (uint64_t)INT64_MIN)); +WRITE_FRD(f64_mulAdd(f64(FRS1), f64(FRS2), f64(FRS3 ^ (uint64_t)INT64_MIN)).v); set_fp_exceptions; diff --git a/riscv/insns/fmsub_s.h b/riscv/insns/fmsub_s.h index 9251277..45945da 100644 --- a/riscv/insns/fmsub_s.h +++ b/riscv/insns/fmsub_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(FRS1, FRS2, FRS3 ^ (uint32_t)INT32_MIN)); +WRITE_FRD(f32_mulAdd(f32(FRS1), f32(FRS2), f32(FRS3 ^ (uint32_t)INT32_MIN)).v); set_fp_exceptions; diff --git a/riscv/insns/fmul_d.h b/riscv/insns/fmul_d.h index d74c316..04e7402 100644 --- a/riscv/insns/fmul_d.h +++ b/riscv/insns/fmul_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(FRS1, FRS2, (FRS1 ^ FRS2) & (uint64_t)INT64_MIN)); +WRITE_FRD(f64_mul(f64(FRS1), f64(FRS2)).v); set_fp_exceptions; diff --git a/riscv/insns/fmul_s.h b/riscv/insns/fmul_s.h index 284aeb3..9ae7b3c 100644 --- a/riscv/insns/fmul_s.h +++ b/riscv/insns/fmul_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(FRS1, FRS2, (FRS1 ^ FRS2) & (uint32_t)INT32_MIN)); +WRITE_FRD(f32_mul(f32(FRS1), f32(FRS2)).v); set_fp_exceptions; diff --git a/riscv/insns/fnmadd_d.h b/riscv/insns/fnmadd_d.h index bed6172..d6e1f04 100644 --- a/riscv/insns/fnmadd_d.h +++ b/riscv/insns/fnmadd_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(FRS1 ^ (uint64_t)INT64_MIN, FRS2, FRS3 ^ (uint64_t)INT64_MIN)); +WRITE_FRD(f64_mulAdd(f64(FRS1 ^ (uint64_t)INT64_MIN), f64(FRS2), f64(FRS3 ^ (uint64_t)INT64_MIN)).v); set_fp_exceptions; diff --git a/riscv/insns/fnmadd_s.h b/riscv/insns/fnmadd_s.h index 1378ae3..0d0b2e9 100644 --- a/riscv/insns/fnmadd_s.h +++ b/riscv/insns/fnmadd_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(FRS1 ^ (uint32_t)INT32_MIN, FRS2, FRS3 ^ (uint32_t)INT32_MIN)); +WRITE_FRD(f32_mulAdd(f32(FRS1 ^ (uint32_t)INT32_MIN), f32(FRS2), f32(FRS3 ^ (uint32_t)INT32_MIN)).v); set_fp_exceptions; diff --git a/riscv/insns/fnmsub_d.h b/riscv/insns/fnmsub_d.h index 340090a..ee74cab 100644 --- a/riscv/insns/fnmsub_d.h +++ b/riscv/insns/fnmsub_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(FRS1 ^ (uint64_t)INT64_MIN, FRS2, FRS3)); +WRITE_FRD(f64_mulAdd(f64(FRS1 ^ (uint64_t)INT64_MIN), f64(FRS2), f64(FRS3)).v); set_fp_exceptions; diff --git a/riscv/insns/fnmsub_s.h b/riscv/insns/fnmsub_s.h index 3be27d0..3e0b8ea 100644 --- a/riscv/insns/fnmsub_s.h +++ b/riscv/insns/fnmsub_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(FRS1 ^ (uint32_t)INT32_MIN, FRS2, FRS3)); +WRITE_FRD(f32_mulAdd(f32(FRS1 ^ (uint32_t)INT32_MIN), f32(FRS2), f32(FRS3)).v); set_fp_exceptions; diff --git a/riscv/insns/fsqrt_d.h b/riscv/insns/fsqrt_d.h index 812438c..45f37ce 100644 --- a/riscv/insns/fsqrt_d.h +++ b/riscv/insns/fsqrt_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_sqrt(FRS1)); +WRITE_FRD(f64_sqrt(f64(FRS1)).v); set_fp_exceptions; diff --git a/riscv/insns/fsqrt_s.h b/riscv/insns/fsqrt_s.h index d77acab..f3b3956 100644 --- a/riscv/insns/fsqrt_s.h +++ b/riscv/insns/fsqrt_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_sqrt(FRS1)); +WRITE_FRD(f32_sqrt(f32(FRS1)).v); set_fp_exceptions; diff --git a/riscv/insns/fsub_d.h b/riscv/insns/fsub_d.h index 6ffc6b3..487743e 100644 --- a/riscv/insns/fsub_d.h +++ b/riscv/insns/fsub_d.h @@ -1,5 +1,5 @@ require_extension('D'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f64_mulAdd(FRS1, 0x3ff0000000000000ULL, FRS2 ^ (uint64_t)INT64_MIN)); +WRITE_FRD(f64_sub(f64(FRS1), f64(FRS2)).v); set_fp_exceptions; diff --git a/riscv/insns/fsub_s.h b/riscv/insns/fsub_s.h index 6a0f853..e7a7cf1 100644 --- a/riscv/insns/fsub_s.h +++ b/riscv/insns/fsub_s.h @@ -1,5 +1,5 @@ require_extension('F'); require_fp; softfloat_roundingMode = RM; -WRITE_FRD(f32_mulAdd(FRS1, 0x3f800000, FRS2 ^ (uint32_t)INT32_MIN)); +WRITE_FRD(f32_sub(f32(FRS1), f32(FRS2)).v); set_fp_exceptions; diff --git a/softfloat/8086/OLD-specialize.c b/softfloat/8086/OLD-specialize.c deleted file mode 100755 index ffb306d..0000000 --- a/softfloat/8086/OLD-specialize.c +++ /dev/null @@ -1,40 +0,0 @@ - -/*============================================================================ - -*** FIX. - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -| Underflow tininess-detection mode, statically initialized to default value. -| (The declaration in `softfloat.h' must match the `int8' type here.) -*----------------------------------------------------------------------------*/ -bool float_detectTininess = float_tininess_afterRounding; - diff --git a/softfloat/8086/OLD-specialize.h b/softfloat/8086/OLD-specialize.h deleted file mode 100755 index 9e4461c..0000000 --- a/softfloat/8086/OLD-specialize.h +++ /dev/null @@ -1,379 +0,0 @@ - -/*============================================================================ - -*** FIX. - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -| Internal canonical NaN format. -*----------------------------------------------------------------------------*/ -*** COMMON -typedef struct { - flag sign; - uint128_t bits; -} commonNaNT; - -/*---------------------------------------------------------------------------- -| The pattern for a default generated single-precision NaN. -*----------------------------------------------------------------------------*/ -#define float32Bits_defaultNaN 0xFFC00000 - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is a NaN; -| otherwise, returns 0. -*----------------------------------------------------------------------------*/ -*** COMMON -#define softfloat_isNaNFloat32Bits( a ) ( 0xFF000000 < (uint32_t) ( a )<<1 ) - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is a signaling -| NaN; otherwise, returns 0. -*----------------------------------------------------------------------------*/ -inline bool softfloat_isSigNaNFloat32Bits( uint32_t a ) - { return ( ( a>>22 & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); } - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -commonNaNT softfloat_NaNFromFloat32Bits( uint32_t ); -uint32_t softfloat_float32BitsFromNaN( commonNaNT ); -uint32_t softfloat_propNaNFloat32Bits( uint32_t, uint32_t ); - -/*---------------------------------------------------------------------------- -| The pattern for a default generated double-precision NaN. -*----------------------------------------------------------------------------*/ -#define float64Bits_defaultNaN 0xFFF8000000000000 - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is a NaN; -| otherwise, returns 0. -*----------------------------------------------------------------------------*/ -*** COMMON -#define softfloat_isNaNFloat64Bits( a ) ( 0xFFE0000000000000 < (uint64_t) ( a )<<1 ) - - - - - - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is a signaling -| NaN; otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -flag float64_is_signaling_nan( float64 a ) -{ - - return - ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) - && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -static commonNaNT float64ToCommonNaN( float64 a ) -{ - commonNaNT z; - - if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); - z.sign = a>>63; - z.low = 0; - z.high = a<<12; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the double- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -static float64 commonNaNToFloat64( commonNaNT a ) -{ - - return - ( ( (bits64) a.sign )<<63 ) - | LIT64( 0x7FF8000000000000 ) - | ( a.high>>12 ); - -} - -/*---------------------------------------------------------------------------- -| Takes two double-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static float64 propagateFloat64NaN( float64 a, float64 b ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = float64_is_nan( a ); - aIsSignalingNaN = float64_is_signaling_nan( a ); - bIsNaN = float64_is_nan( b ); - bIsSignalingNaN = float64_is_signaling_nan( b ); - a |= LIT64( 0x0008000000000000 ); - b |= LIT64( 0x0008000000000000 ); - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); - if ( aIsSignalingNaN ) { - if ( bIsSignalingNaN ) goto returnLargerSignificand; - return bIsNaN ? b : a; - } - else if ( aIsNaN ) { - if ( bIsSignalingNaN | ! bIsNaN ) return a; - returnLargerSignificand: - if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b; - if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a; - return ( a < b ) ? a : b; - } - else { - return b; - } - -} - -#ifdef FLOATX80 - -/*---------------------------------------------------------------------------- -| The pattern for a default generated extended double-precision NaN. The -| `high' and `low' values hold the most- and least-significant bits, -| respectively. -*----------------------------------------------------------------------------*/ -#define floatx80_default_nan_high 0xFFFF -#define floatx80_default_nan_low LIT64( 0xC000000000000000 ) - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is a -| NaN; otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -flag floatx80_is_nan( floatx80 a ) -{ - - return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the extended double-precision floating-point value `a' is a -| signaling NaN; otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -flag floatx80_is_signaling_nan( floatx80 a ) -{ - bits64 aLow; - - aLow = a.low & ~ LIT64( 0x4000000000000000 ); - return - ( ( a.high & 0x7FFF ) == 0x7FFF ) - && (bits64) ( aLow<<1 ) - && ( a.low == aLow ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the extended double-precision floating- -| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the -| invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static commonNaNT floatx80ToCommonNaN( floatx80 a ) -{ - commonNaNT z; - - if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); - z.sign = a.high>>15; - z.low = 0; - z.high = a.low<<1; - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the extended -| double-precision floating-point format. -*----------------------------------------------------------------------------*/ - -static floatx80 commonNaNToFloatx80( commonNaNT a ) -{ - floatx80 z; - - z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); - z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; - return z; - -} - -/*---------------------------------------------------------------------------- -| Takes two extended double-precision floating-point values `a' and `b', one -| of which is a NaN, and returns the appropriate NaN result. If either `a' or -| `b' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = floatx80_is_nan( a ); - aIsSignalingNaN = floatx80_is_signaling_nan( a ); - bIsNaN = floatx80_is_nan( b ); - bIsSignalingNaN = floatx80_is_signaling_nan( b ); - a.low |= LIT64( 0xC000000000000000 ); - b.low |= LIT64( 0xC000000000000000 ); - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); - if ( aIsSignalingNaN ) { - if ( bIsSignalingNaN ) goto returnLargerSignificand; - return bIsNaN ? b : a; - } - else if ( aIsNaN ) { - if ( bIsSignalingNaN | ! bIsNaN ) return a; - returnLargerSignificand: - if ( a.low < b.low ) return b; - if ( b.low < a.low ) return a; - return ( a.high < b.high ) ? a : b; - } - else { - return b; - } - -} - -#endif - -#ifdef FLOAT128 - -/*---------------------------------------------------------------------------- -| The pattern for a default generated quadruple-precision NaN. The `high' and -| `low' values hold the most- and least-significant bits, respectively. -*----------------------------------------------------------------------------*/ -#define float128_default_nan_high LIT64( 0xFFFF800000000000 ) -#define float128_default_nan_low LIT64( 0x0000000000000000 ) - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is a NaN; -| otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -flag float128_is_nan( float128 a ) -{ - - return - ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) - && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns 1 if the quadruple-precision floating-point value `a' is a -| signaling NaN; otherwise, returns 0. -*----------------------------------------------------------------------------*/ - -flag float128_is_signaling_nan( float128 a ) -{ - - return - ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) - && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the quadruple-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ - -static commonNaNT float128ToCommonNaN( float128 a ) -{ - commonNaNT z; - - if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid ); - z.sign = a.high>>63; - shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); - return z; - -} - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the quadruple- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -static float128 commonNaNToFloat128( commonNaNT a ) -{ - float128 z; - - shift128Right( a.high, a.low, 16, &z.high, &z.low ); - z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); - return z; - -} - -/*---------------------------------------------------------------------------- -| Takes two quadruple-precision floating-point values `a' and `b', one of -| which is a NaN, and returns the appropriate NaN result. If either `a' or -| `b' is a signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -static float128 propagateFloat128NaN( float128 a, float128 b ) -{ - flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; - - aIsNaN = float128_is_nan( a ); - aIsSignalingNaN = float128_is_signaling_nan( a ); - bIsNaN = float128_is_nan( b ); - bIsSignalingNaN = float128_is_signaling_nan( b ); - a.high |= LIT64( 0x0000800000000000 ); - b.high |= LIT64( 0x0000800000000000 ); - if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid ); - if ( aIsSignalingNaN ) { - if ( bIsSignalingNaN ) goto returnLargerSignificand; - return bIsNaN ? b : a; - } - else if ( aIsNaN ) { - if ( bIsSignalingNaN | ! bIsNaN ) return a; - returnLargerSignificand: - if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b; - if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a; - return ( a.high < b.high ) ? a : b; - } - else { - return b; - } - -} - -#endif - diff --git a/softfloat/8086/platform.h b/softfloat/8086/platform.h deleted file mode 100755 index 9355edf..0000000 --- a/softfloat/8086/platform.h +++ /dev/null @@ -1,38 +0,0 @@ - -/*============================================================================ - -*** FIX. - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define LITTLEENDIAN - diff --git a/softfloat/8086/s_commonNaNToF32UI.c b/softfloat/8086/s_commonNaNToF32UI.c deleted file mode 100755 index 3b96c41..0000000 --- a/softfloat/8086/s_commonNaNToF32UI.c +++ /dev/null @@ -1,17 +0,0 @@ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the single- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -uint_fast32_t softfloat_commonNaNToF32UI( struct commonNaN a ) -{ - - return (uint_fast32_t) a.sign<<31 | 0x7FC00000 | a.v64>>41; - -} - diff --git a/softfloat/8086/s_commonNaNToF64UI.c b/softfloat/8086/s_commonNaNToF64UI.c deleted file mode 100755 index 474ceee..0000000 --- a/softfloat/8086/s_commonNaNToF64UI.c +++ /dev/null @@ -1,19 +0,0 @@ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the double- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -uint_fast64_t softfloat_commonNaNToF64UI( struct commonNaN a ) -{ - - return - (uint_fast64_t) a.sign<<63 | UINT64_C( 0x7FF8000000000000 ) - | a.v64>>12; - -} - diff --git a/softfloat/8086/s_f32UIToCommonNaN.c b/softfloat/8086/s_f32UIToCommonNaN.c deleted file mode 100755 index 067e8da..0000000 --- a/softfloat/8086/s_f32UIToCommonNaN.c +++ /dev/null @@ -1,25 +0,0 @@ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct commonNaN softfloat_f32UIToCommonNaN( uint_fast32_t uiA ) -{ - struct commonNaN z; - - if ( softfloat_isSigNaNF32UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - z.sign = uiA>>31; - z.v64 = (uint_fast64_t) uiA<<41; - z.v0 = 0; - return z; - -} - diff --git a/softfloat/8086/s_f64UIToCommonNaN.c b/softfloat/8086/s_f64UIToCommonNaN.c deleted file mode 100755 index f933ded..0000000 --- a/softfloat/8086/s_f64UIToCommonNaN.c +++ /dev/null @@ -1,25 +0,0 @@ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct commonNaN softfloat_f64UIToCommonNaN( uint_fast64_t uiA ) -{ - struct commonNaN z; - - if ( softfloat_isSigNaNF64UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - z.sign = uiA>>63; - z.v64 = uiA<<12; - z.v0 = 0; - return z; - -} - diff --git a/softfloat/8086/s_isSigNaNF32UI.c b/softfloat/8086/s_isSigNaNF32UI.c deleted file mode 100755 index 0a9c33f..0000000 --- a/softfloat/8086/s_isSigNaNF32UI.c +++ /dev/null @@ -1,13 +0,0 @@ - -#include -#include -#include "platform.h" -#include "specialize.h" - -bool softfloat_isSigNaNF32UI( uint_fast32_t ui ) -{ - - return ( ( ui>>22 & 0x1FF ) == 0x1FE ) && ( ui & 0x003FFFFF ); - -} - diff --git a/softfloat/8086/s_isSigNaNF64UI.c b/softfloat/8086/s_isSigNaNF64UI.c deleted file mode 100755 index d255213..0000000 --- a/softfloat/8086/s_isSigNaNF64UI.c +++ /dev/null @@ -1,15 +0,0 @@ - -#include -#include -#include "platform.h" -#include "specialize.h" - -bool softfloat_isSigNaNF64UI( uint_fast64_t ui ) -{ - - return - ( ( ui>>51 & 0xFFF ) == 0xFFE ) - && ( ui & UINT64_C( 0x0007FFFFFFFFFFFF ) ); - -} - diff --git a/softfloat/8086/s_propagateNaNF32UI.c b/softfloat/8086/s_propagateNaNF32UI.c deleted file mode 100755 index 07774e8..0000000 --- a/softfloat/8086/s_propagateNaNF32UI.c +++ /dev/null @@ -1,55 +0,0 @@ - -/*** UPDATE COMMENTS. ***/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Takes two single-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -uint_fast32_t - softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ) -{ - bool isNaNA, isSigNaNA, isNaNB, isSigNaNB; - uint_fast32_t uiMagA, uiMagB; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - isNaNA = isNaNF32UI( uiA ); - isSigNaNA = softfloat_isSigNaNF32UI( uiA ); - isNaNB = isNaNF32UI( uiB ); - isSigNaNB = softfloat_isSigNaNF32UI( uiB ); - /*------------------------------------------------------------------------ - | Make NaNs non-signaling. - *------------------------------------------------------------------------*/ - uiA |= 0x00400000; - uiB |= 0x00400000; - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isSigNaNA | isSigNaNB ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - if ( isSigNaNA ) { - if ( isSigNaNB ) goto returnLargerSignificand; - return isNaNB ? uiB : uiA; - } else if ( isNaNA ) { - if ( isSigNaNB || ! isNaNB ) return uiA; - returnLargerSignificand: - uiMagA = uiA<<1; - uiMagB = uiB<<1; - if ( uiMagA < uiMagB ) return uiB; - if ( uiMagB < uiMagA ) return uiA; - return ( uiA < uiB ) ? uiA : uiB; - } else { - return uiB; - } - -} - diff --git a/softfloat/8086/s_propagateNaNF64UI.c b/softfloat/8086/s_propagateNaNF64UI.c deleted file mode 100755 index 0ff6446..0000000 --- a/softfloat/8086/s_propagateNaNF64UI.c +++ /dev/null @@ -1,55 +0,0 @@ - -/*** UPDATE COMMENTS. ***/ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Takes two double-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -uint_fast64_t - softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ) -{ - bool isNaNA, isSigNaNA, isNaNB, isSigNaNB; - uint_fast64_t uiMagA, uiMagB; - - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - isNaNA = isNaNF64UI( uiA ); - isSigNaNA = softfloat_isSigNaNF64UI( uiA ); - isNaNB = isNaNF64UI( uiB ); - isSigNaNB = softfloat_isSigNaNF64UI( uiB ); - /*------------------------------------------------------------------------ - | Make NaNs non-signaling. - *------------------------------------------------------------------------*/ - uiA |= UINT64_C( 0x0008000000000000 ); - uiB |= UINT64_C( 0x0008000000000000 ); - /*------------------------------------------------------------------------ - *------------------------------------------------------------------------*/ - if ( isSigNaNA | isSigNaNB ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - if ( isSigNaNA ) { - if ( isSigNaNB ) goto returnLargerSignificand; - return isNaNB ? uiB : uiA; - } else if ( isNaNA ) { - if ( isSigNaNB || ! isNaNB ) return uiA; - returnLargerSignificand: - uiMagA = uiA & UINT64_C( 0x7FFFFFFFFFFFFFFF ); - uiMagB = uiB & UINT64_C( 0x7FFFFFFFFFFFFFFF ); - if ( uiMagA < uiMagB ) return uiB; - if ( uiMagB < uiMagA ) return uiA; - return ( uiA < uiB ) ? uiA : uiB; - } else { - return uiB; - } - -} - diff --git a/softfloat/8086/softfloat_raiseFlags.c b/softfloat/8086/softfloat_raiseFlags.c deleted file mode 100755 index c0c0dc8..0000000 --- a/softfloat/8086/softfloat_raiseFlags.c +++ /dev/null @@ -1,51 +0,0 @@ - -/*============================================================================ - -*** FIX. - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -#include "platform.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Raises the exceptions specified by `flags'. Floating-point traps can be -| defined here if desired. It is currently not possible for such a trap -| to substitute a result value. If traps are not implemented, this routine -| should be simply `float_exception_flags |= flags;'. -*----------------------------------------------------------------------------*/ - -void softfloat_raiseFlags( int_fast8_t flags ) -{ - - softfloat_exceptionFlags |= flags; - -} - diff --git a/softfloat/8086/softfloat_types.h b/softfloat/8086/softfloat_types.h deleted file mode 100755 index b5c1828..0000000 --- a/softfloat/8086/softfloat_types.h +++ /dev/null @@ -1,16 +0,0 @@ - -#ifndef softfloat_types_h -#define softfloat_types_h - -/*** COMMENTS. ***/ - -#include -#include - -typedef struct { uint32_t v; } float32_t; -typedef struct { uint64_t v; } float64_t; -typedef struct { uint64_t v; uint16_t x; } floatx80_t; -typedef struct { uint64_t v[ 2 ]; } float128_t; - -#endif - diff --git a/softfloat/8086/specialize.h b/softfloat/8086/specialize.h deleted file mode 100755 index ca0bb1d..0000000 --- a/softfloat/8086/specialize.h +++ /dev/null @@ -1,113 +0,0 @@ - -/*============================================================================ - -*** FIX. - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -#include -#include - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define init_detectTininess softfloat_tininess_afterRounding; - -/*---------------------------------------------------------------------------- -| Structure used to transfer NaN representations from one format to another. -*----------------------------------------------------------------------------*/ -struct commonNaN { - bool sign; - uint64_t v64, v0; -}; - -/*---------------------------------------------------------------------------- -| The pattern for a default generated single-precision NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF32UI 0xFFC00000 - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is a signaling -| NaN; otherwise, returns 0. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 1 <= INLINE_LEVEL ) -INLINE bool softfloat_isSigNaNF32UI( uint_fast32_t ui ) - { return ( ( ui>>22 & 0x1FF ) == 0x1FE ) && ( ui & 0x003FFFFF ); } -#else -bool softfloat_isSigNaNF32UI( uint_fast32_t ); -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -struct commonNaN softfloat_f32UIToCommonNaN( uint_fast32_t ); -#if defined INLINE_LEVEL && ( 1 <= INLINE_LEVEL ) -INLINE uint_fast32_t softfloat_commonNaNToF32UI( struct commonNaN a ) - { return (uint_fast32_t) a.sign<<31 | 0x7FC00000 | a.v64>>41; } -#else -uint_fast32_t softfloat_commonNaNToF32UI( struct commonNaN ); -#endif - -/*---------------------------------------------------------------------------- -| Takes two single-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast32_t softfloat_propagateNaNF32UI( uint_fast32_t, uint_fast32_t ); - -/*---------------------------------------------------------------------------- -| The pattern for a default generated double-precision NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF64UI UINT64_C(0xFFF8000000000000) - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 1 <= INLINE_LEVEL ) -INLINE bool softfloat_isSigNaNF64UI( uint_fast64_t ui ) -{ - return - ( ( ui>>51 & 0xFFF ) == 0xFFE ) - && ( ui & UINT64_C( 0x0007FFFFFFFFFFFF ) ); -} -#else -bool softfloat_isSigNaNF64UI( uint_fast64_t ); -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -/*** MIGHT BE INLINE'D. ***/ -struct commonNaN softfloat_f64UIToCommonNaN( uint_fast64_t ); -uint_fast64_t softfloat_commonNaNToF64UI( struct commonNaN ); - -/*---------------------------------------------------------------------------- -| Takes two double-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast64_t softfloat_propagateNaNF64UI( uint_fast64_t, uint_fast64_t ); - diff --git a/softfloat/f32_add.c b/softfloat/f32_add.c old mode 100755 new mode 100644 index dc53d68..5b5a09e --- a/softfloat/f32_add.c +++ b/softfloat/f32_add.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -13,7 +48,9 @@ float32_t f32_add( float32_t a, float32_t b ) union ui32_f32 uB; uint_fast32_t uiB; bool signB; - float32_t ( *magsRoutine )( uint_fast32_t, uint_fast32_t, bool ); +#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1) + float32_t (*magsFuncPtr)( uint_fast32_t, uint_fast32_t, bool ); +#endif uA.f = a; uiA = uA.ui; @@ -21,9 +58,17 @@ float32_t f32_add( float32_t a, float32_t b ) uB.f = b; uiB = uB.ui; signB = signF32UI( uiB ); - magsRoutine = - ( signA == signB ) ? softfloat_addMagsF32 : softfloat_subMagsF32; - return magsRoutine( uiA, uiB, signA ); +#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) + if ( signA == signB ) { + return softfloat_addMagsF32( uiA, uiB, signA ); + } else { + return softfloat_subMagsF32( uiA, uiB, signA ); + } +#else + magsFuncPtr = + (signA == signB) ? softfloat_addMagsF32 : softfloat_subMagsF32; + return (*magsFuncPtr)( uiA, uiB, signA ); +#endif } diff --git a/softfloat/f32_div.c b/softfloat/f32_div.c old mode 100755 new mode 100644 index 958b140..2321d20 --- a/softfloat/f32_div.c +++ b/softfloat/f32_div.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -21,21 +56,31 @@ float32_t f32_div( float32_t a, float32_t b ) bool signZ; struct exp16_sig32 normExpSig; int_fast16_t expZ; +#ifdef SOFTFLOAT_FAST_DIV64TO32 + uint_fast64_t sig64A; uint_fast32_t sigZ; +#else + uint_fast32_t sigZ; + uint_fast64_t rem; +#endif uint_fast32_t uiZ; union ui32_f32 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; signA = signF32UI( uiA ); - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); + expA = expF32UI( uiA ); + sigA = fracF32UI( uiA ); uB.f = b; uiB = uB.ui; signB = signF32UI( uiB ); - expB = expF32UI( uiB ); - sigB = fracF32UI( uiB ); + expB = expF32UI( uiB ); + sigB = fracF32UI( uiB ); signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( expA == 0xFF ) { if ( sigA ) goto propagateNaN; if ( expB == 0xFF ) { @@ -48,10 +93,12 @@ float32_t f32_div( float32_t a, float32_t b ) if ( sigB ) goto propagateNaN; goto zero; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( ! expB ) { if ( ! sigB ) { - if ( ! ( expA | sigA ) ) goto invalid; - softfloat_raiseFlags( softfloat_flag_infinity ); + if ( ! (expA | sigA) ) goto invalid; + softfloat_raiseFlags( softfloat_flag_infinite ); goto infinity; } normExpSig = softfloat_normSubnormalF32Sig( sigB ); @@ -64,28 +111,65 @@ float32_t f32_div( float32_t a, float32_t b ) expA = normExpSig.exp; sigA = normExpSig.sig; } - expZ = expA - expB + 0x7D; - sigA = ( sigA | 0x00800000 )<<7; - sigB = ( sigB | 0x00800000 )<<8; - if ( sigB <= ( sigA + sigA ) ) { - ++expZ; - sigA >>= 1; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA - expB + 0x7E; + sigA |= 0x00800000; + sigB |= 0x00800000; +#ifdef SOFTFLOAT_FAST_DIV64TO32 + if ( sigA < sigB ) { + --expZ; + sig64A = (uint_fast64_t) sigA<<31; + } else { + sig64A = (uint_fast64_t) sigA<<30; + } + sigZ = sig64A / sigB; + if ( ! (sigZ & 0x3F) ) sigZ |= ((uint_fast64_t) sigB * sigZ != sig64A); +#else + if ( sigA < sigB ) { + --expZ; + sigA <<= 8; + } else { + sigA <<= 7; } - sigZ = ( (uint_fast64_t) sigA<<32 ) / sigB; - if ( ! ( sigZ & 0x3F ) ) { - sigZ |= ( (uint_fast64_t) sigB * sigZ != (uint_fast64_t) sigA<<32 ); + sigB <<= 8; + sigZ = ((uint_fast64_t) sigA * softfloat_approxRecip32_1( sigB ))>>32; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sigZ += 2; + if ( (sigZ & 0x3F) < 2 ) { + sigZ &= ~3; +#ifdef SOFTFLOAT_FAST_INT64 + rem = ((uint_fast64_t) sigA<<31) - (uint_fast64_t) sigZ * sigB; +#else + rem = ((uint_fast64_t) sigA<<32) - (uint_fast64_t) (sigZ<<1) * sigB; +#endif + if ( rem & UINT64_C( 0x8000000000000000 ) ) { + sigZ -= 4; + } else { + if ( rem ) sigZ |= 1; + } } +#endif return softfloat_roundPackToF32( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); uiZ = defaultNaNF32UI; goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ infinity: uiZ = packToF32UI( signZ, 0xFF, 0 ); goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ zero: uiZ = packToF32UI( signZ, 0, 0 ); uiZ: diff --git a/softfloat/f32_eq.c b/softfloat/f32_eq.c old mode 100755 new mode 100644 index 8f2306b..ee0918f --- a/softfloat/f32_eq.c +++ b/softfloat/f32_eq.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -17,10 +52,7 @@ bool f32_eq( float32_t a, float32_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF32UI( uiA ) == 0xFF ) && fracF32UI( uiA ) ) - || ( ( expF32UI( uiB ) == 0xFF ) && fracF32UI( uiB ) ) - ) { + if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { if ( softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB ) ) { @@ -28,7 +60,7 @@ bool f32_eq( float32_t a, float32_t b ) } return false; } - return ( uiA == uiB ) || ! (uint32_t) ( ( uiA | uiB )<<1 ); + return (uiA == uiB) || ! (uint32_t) ((uiA | uiB)<<1); } diff --git a/softfloat/f32_eq_signaling.c b/softfloat/f32_eq_signaling.c old mode 100755 new mode 100644 index bfba48a..52b1dd7 --- a/softfloat/f32_eq_signaling.c +++ b/softfloat/f32_eq_signaling.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -16,14 +51,11 @@ bool f32_eq_signaling( float32_t a, float32_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF32UI( uiA ) == 0xFF ) && fracF32UI( uiA ) ) - || ( ( expF32UI( uiB ) == 0xFF ) && fracF32UI( uiB ) ) - ) { + if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); return false; } - return ( uiA == uiB ) || ! (uint32_t) ( ( uiA | uiB )<<1 ); + return (uiA == uiB) || ! (uint32_t) ((uiA | uiB)<<1); } diff --git a/softfloat/f32_isSignalingNaN.c b/softfloat/f32_isSignalingNaN.c old mode 100755 new mode 100644 index 09aaa82..479c287 --- a/softfloat/f32_isSignalingNaN.c +++ b/softfloat/f32_isSignalingNaN.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include "platform.h" #include "internals.h" diff --git a/softfloat/f32_le.c b/softfloat/f32_le.c old mode 100755 new mode 100644 index 5f47be5..fb30c3c --- a/softfloat/f32_le.c +++ b/softfloat/f32_le.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -17,18 +52,15 @@ bool f32_le( float32_t a, float32_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF32UI( uiA ) == 0xFF ) && fracF32UI( uiA ) ) - || ( ( expF32UI( uiB ) == 0xFF ) && fracF32UI( uiB ) ) - ) { + if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); return false; } signA = signF32UI( uiA ); signB = signF32UI( uiB ); return - ( signA != signB ) ? signA || ! (uint32_t) ( ( uiA | uiB )<<1 ) - : ( uiA == uiB ) || ( signA ^ ( uiA < uiB ) ); + (signA != signB) ? signA || ! (uint32_t) ((uiA | uiB)<<1) + : (uiA == uiB) || (signA ^ (uiA < uiB)); } diff --git a/softfloat/f32_le_quiet.c b/softfloat/f32_le_quiet.c old mode 100755 new mode 100644 index 2b541da..3cb6378 --- a/softfloat/f32_le_quiet.c +++ b/softfloat/f32_le_quiet.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -18,10 +53,7 @@ bool f32_le_quiet( float32_t a, float32_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF32UI( uiA ) == 0xFF ) && fracF32UI( uiA ) ) - || ( ( expF32UI( uiB ) == 0xFF ) && fracF32UI( uiB ) ) - ) { + if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { if ( softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB ) ) { @@ -32,8 +64,8 @@ bool f32_le_quiet( float32_t a, float32_t b ) signA = signF32UI( uiA ); signB = signF32UI( uiB ); return - ( signA != signB ) ? signA || ! (uint32_t) ( ( uiA | uiB )<<1 ) - : ( uiA == uiB ) || ( signA ^ ( uiA < uiB ) ); + (signA != signB) ? signA || ! (uint32_t) ((uiA | uiB)<<1) + : (uiA == uiB) || (signA ^ (uiA < uiB)); } diff --git a/softfloat/f32_lt.c b/softfloat/f32_lt.c old mode 100755 new mode 100644 index 753b28a..73af423 --- a/softfloat/f32_lt.c +++ b/softfloat/f32_lt.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -17,18 +52,15 @@ bool f32_lt( float32_t a, float32_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF32UI( uiA ) == 0xFF ) && fracF32UI( uiA ) ) - || ( ( expF32UI( uiB ) == 0xFF ) && fracF32UI( uiB ) ) - ) { + if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); return false; } signA = signF32UI( uiA ); signB = signF32UI( uiB ); return - ( signA != signB ) ? signA && ( (uint32_t) ( ( uiA | uiB )<<1 ) != 0 ) - : ( uiA != uiB ) && ( signA ^ ( uiA < uiB ) ); + (signA != signB) ? signA && ((uint32_t) ((uiA | uiB)<<1) != 0) + : (uiA != uiB) && (signA ^ (uiA < uiB)); } diff --git a/softfloat/f32_lt_quiet.c b/softfloat/f32_lt_quiet.c old mode 100755 new mode 100644 index ecd90bf..0bab973 --- a/softfloat/f32_lt_quiet.c +++ b/softfloat/f32_lt_quiet.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -18,10 +53,7 @@ bool f32_lt_quiet( float32_t a, float32_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF32UI( uiA ) == 0xFF ) && fracF32UI( uiA ) ) - || ( ( expF32UI( uiB ) == 0xFF ) && fracF32UI( uiB ) ) - ) { + if ( isNaNF32UI( uiA ) || isNaNF32UI( uiB ) ) { if ( softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB ) ) { @@ -32,8 +64,8 @@ bool f32_lt_quiet( float32_t a, float32_t b ) signA = signF32UI( uiA ); signB = signF32UI( uiB ); return - ( signA != signB ) ? signA && ( (uint32_t) ( ( uiA | uiB )<<1 ) != 0 ) - : ( uiA != uiB ) && ( signA ^ ( uiA < uiB ) ); + (signA != signB) ? signA && ((uint32_t) ((uiA | uiB)<<1) != 0) + : (uiA != uiB) && (signA ^ (uiA < uiB)); } diff --git a/softfloat/f32_mul.c b/softfloat/f32_mul.c old mode 100755 new mode 100644 index d49c1dd..941eb39 --- a/softfloat/f32_mul.c +++ b/softfloat/f32_mul.c @@ -1,89 +1,123 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t f32_mul( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool signA; - int_fast16_t expA; - uint_fast32_t sigA; - union ui32_f32 uB; - uint_fast32_t uiB; - bool signB; - int_fast16_t expB; - uint_fast32_t sigB; - bool signZ; - uint_fast32_t magBits; - struct exp16_sig32 normExpSig; - int_fast16_t expZ; - uint_fast32_t sigZ, uiZ; - union ui32_f32 uZ; - - uA.f = a; - uiA = uA.ui; - signA = signF32UI( uiA ); - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); - uB.f = b; - uiB = uB.ui; - signB = signF32UI( uiB ); - expB = expF32UI( uiB ); - sigB = fracF32UI( uiB ); - signZ = signA ^ signB; - if ( expA == 0xFF ) { - if ( sigA || ( ( expB == 0xFF ) && sigB ) ) goto propagateNaN; - magBits = expB | sigB; - goto infArg; - } - if ( expB == 0xFF ) { - if ( sigB ) goto propagateNaN; - magBits = expA | sigA; - goto infArg; - } - if ( ! expA ) { - if ( ! sigA ) goto zero; - normExpSig = softfloat_normSubnormalF32Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! sigB ) goto zero; - normExpSig = softfloat_normSubnormalF32Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - expZ = expA + expB - 0x7F; - sigA = ( sigA | 0x00800000 )<<7; - sigB = ( sigB | 0x00800000 )<<8; - sigZ = softfloat_shortShift64RightJam( (uint_fast64_t) sigA * sigB, 32 ); - if ( sigZ < 0x40000000 ) { - --expZ; - sigZ <<= 1; - } - return softfloat_roundPackToF32( signZ, expZ, sigZ ); - propagateNaN: - uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); - goto uiZ; - infArg: - if ( ! magBits ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF32UI; - } else { - uiZ = packToF32UI( signZ, 0xFF, 0 ); - } - goto uiZ; - zero: - uiZ = packToF32UI( signZ, 0, 0 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float32_t f32_mul( float32_t a, float32_t b ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + bool signA; + int_fast16_t expA; + uint_fast32_t sigA; + union ui32_f32 uB; + uint_fast32_t uiB; + bool signB; + int_fast16_t expB; + uint_fast32_t sigB; + bool signZ; + uint_fast32_t magBits; + struct exp16_sig32 normExpSig; + int_fast16_t expZ; + uint_fast32_t sigZ, uiZ; + union ui32_f32 uZ; + + uA.f = a; + uiA = uA.ui; + signA = signF32UI( uiA ); + expA = expF32UI( uiA ); + sigA = fracF32UI( uiA ); + uB.f = b; + uiB = uB.ui; + signB = signF32UI( uiB ); + expB = expF32UI( uiB ); + sigB = fracF32UI( uiB ); + signZ = signA ^ signB; + if ( expA == 0xFF ) { + if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN; + magBits = expB | sigB; + goto infArg; + } + if ( expB == 0xFF ) { + if ( sigB ) goto propagateNaN; + magBits = expA | sigA; + goto infArg; + } + if ( ! expA ) { + if ( ! sigA ) goto zero; + normExpSig = softfloat_normSubnormalF32Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if ( ! expB ) { + if ( ! sigB ) goto zero; + normExpSig = softfloat_normSubnormalF32Sig( sigB ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + expZ = expA + expB - 0x7F; + sigA = (sigA | 0x00800000)<<7; + sigB = (sigB | 0x00800000)<<8; + sigZ = softfloat_shortShiftRightJam64( (uint_fast64_t) sigA * sigB, 32 ); + if ( sigZ < 0x40000000 ) { + --expZ; + sigZ <<= 1; + } + return softfloat_roundPackToF32( signZ, expZ, sigZ ); + propagateNaN: + uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); + goto uiZ; + infArg: + if ( ! magBits ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF32UI; + } else { + uiZ = packToF32UI( signZ, 0xFF, 0 ); + } + goto uiZ; + zero: + uiZ = packToF32UI( signZ, 0, 0 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f32_mulAdd.c b/softfloat/f32_mulAdd.c old mode 100755 new mode 100644 index 3d4cee9..5bf77fe --- a/softfloat/f32_mulAdd.c +++ b/softfloat/f32_mulAdd.c @@ -1,25 +1,60 @@ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float32_t f32_mulAdd( float32_t a, float32_t b, float32_t c ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - union ui32_f32 uB; - uint_fast32_t uiB; - union ui32_f32 uC; - uint_fast32_t uiC; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - uC.f = c; - uiC = uC.ui; - return softfloat_mulAddF32( 0, uiA, uiB, uiC ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float32_t f32_mulAdd( float32_t a, float32_t b, float32_t c ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + union ui32_f32 uB; + uint_fast32_t uiB; + union ui32_f32 uC; + uint_fast32_t uiC; + + uA.f = a; + uiA = uA.ui; + uB.f = b; + uiB = uB.ui; + uC.f = c; + uiC = uC.ui; + return softfloat_mulAddF32( uiA, uiB, uiC, 0 ); + +} + diff --git a/softfloat/f32_rem.c b/softfloat/f32_rem.c old mode 100755 new mode 100644 index d29b840..b1997ef --- a/softfloat/f32_rem.c +++ b/softfloat/f32_rem.c @@ -1,8 +1,42 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" -#include "primitives.h" #include "internals.h" #include "specialize.h" #include "softfloat.h" @@ -16,37 +50,39 @@ float32_t f32_rem( float32_t a, float32_t b ) uint_fast32_t sigA; union ui32_f32 uB; uint_fast32_t uiB; - bool signB; int_fast16_t expB; uint_fast32_t sigB; struct exp16_sig32 normExpSig; + uint32_t rem; int_fast16_t expDiff; - uint_fast32_t q; - uint_fast64_t sigA64, sigB64, q64; - uint_fast32_t alternateSigA; - uint32_t sigMean; - bool signZ; + uint32_t q, recip32, altRem, meanRem; + bool signRem; uint_fast32_t uiZ; union ui32_f32 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; signA = signF32UI( uiA ); - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); + expA = expF32UI( uiA ); + sigA = fracF32UI( uiA ); uB.f = b; uiB = uB.ui; - signB = signF32UI( uiB ); expB = expF32UI( uiB ); sigB = fracF32UI( uiB ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( expA == 0xFF ) { - if ( sigA || ( ( expB == 0xFF ) && sigB ) ) goto propagateNaN; + if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN; goto invalid; } if ( expB == 0xFF ) { if ( sigB ) goto propagateNaN; return a; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( ! expB ) { if ( ! sigB ) goto invalid; normExpSig = softfloat_normSubnormalF32Sig( sigB ); @@ -59,57 +95,65 @@ float32_t f32_rem( float32_t a, float32_t b ) expA = normExpSig.exp; sigA = normExpSig.sig; } - expDiff = expA - expB; - sigA |= 0x00800000; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + rem = sigA | 0x00800000; sigB |= 0x00800000; - if ( expDiff < 32 ) { - sigA <<= 8; - sigB <<= 8; - if ( expDiff < 0 ) { - if ( expDiff < -1 ) return a; - sigA >>= 1; - } - q = ( sigB <= sigA ); - if ( q ) sigA -= sigB; - if ( 0 < expDiff ) { - q = ( (uint_fast64_t) sigA<<32 ) / sigB; - q >>= 32 - expDiff; - sigB >>= 2; - sigA = ( ( sigA>>1 )<<( expDiff - 1 ) ) - sigB * q; + expDiff = expA - expB; + if ( expDiff < 1 ) { + if ( expDiff < -1 ) return a; + sigB <<= 6; + if ( expDiff ) { + rem <<= 5; + q = 0; } else { - sigA >>= 2; - sigB >>= 2; + rem <<= 6; + q = (sigB <= rem); + if ( q ) rem -= sigB; } } else { - if ( sigB <= sigA ) sigA -= sigB; - sigA64 = (uint_fast64_t) sigA<<40; - sigB64 = (uint_fast64_t) sigB<<40; - expDiff -= 64; - while ( 0 < expDiff ) { - q64 = softfloat_estimateDiv128To64( sigA64, 0, sigB64 ); - q64 = ( 2 < q64 ) ? q64 - 2 : 0; - sigA64 = - ( ( sigB * q64 )<<38 ); - expDiff -= 62; - } - expDiff += 64; - q64 = softfloat_estimateDiv128To64( sigA64, 0, sigB64 ); - q64 = ( 2 < q64 ) ? q64 - 2 : 0; - q = q64>>( 64 - expDiff ); + recip32 = softfloat_approxRecip32_1( sigB<<8 ); + /*-------------------------------------------------------------------- + | Changing the shift of `rem' here requires also changing the initial + | subtraction from `expDiff'. + *--------------------------------------------------------------------*/ + rem <<= 7; + expDiff -= 31; + /*-------------------------------------------------------------------- + | The scale of `sigB' affects how many bits are obtained during each + | cycle of the loop. Currently this is 29 bits per loop iteration, + | which is believed to be the maximum possible. + *--------------------------------------------------------------------*/ sigB <<= 6; - sigA = ( ( sigA64>>33 )<<( expDiff - 1 ) ) - sigB * q; + for (;;) { + q = (rem * (uint_fast64_t) recip32)>>32; + if ( expDiff < 0 ) break; + rem = -(q * (uint32_t) sigB); + expDiff -= 29; + } + /*-------------------------------------------------------------------- + | (`expDiff' cannot be less than -30 here.) + *--------------------------------------------------------------------*/ + q >>= ~expDiff & 31; + rem = (rem<<(expDiff + 30)) - q * (uint32_t) sigB; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ do { - alternateSigA = sigA; + altRem = rem; ++q; - sigA -= sigB; - } while ( sigA < 0x80000000 ); - sigMean = sigA + alternateSigA; - if ( ( 0x80000000 <= sigMean ) || ( ! sigMean && ( q & 1 ) ) ) { - sigA = alternateSigA; + rem -= sigB; + } while ( ! (rem & 0x80000000) ); + meanRem = rem + altRem; + if ( (meanRem & 0x80000000) || (! meanRem && (q & 1)) ) rem = altRem; + signRem = signA; + if ( 0x80000000 <= rem ) { + signRem = ! signRem; + rem = -rem; } - signZ = ( 0x80000000 <= sigA ); - if ( signZ ) sigA = - sigA; - return softfloat_normRoundPackToF32( signA ^ signZ, expB, sigA ); + return softfloat_normRoundPackToF32( signRem, expB, rem ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); goto uiZ; diff --git a/softfloat/f32_roundToInt.c b/softfloat/f32_roundToInt.c old mode 100755 new mode 100644 index f8f9114..314747e --- a/softfloat/f32_roundToInt.c +++ b/softfloat/f32_roundToInt.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -6,68 +41,66 @@ #include "specialize.h" #include "softfloat.h" -float32_t f32_roundToInt( float32_t a, int_fast8_t roundingMode, bool exact ) +float32_t f32_roundToInt( float32_t a, uint_fast8_t roundingMode, bool exact ) { union ui32_f32 uA; uint_fast32_t uiA; - int_fast16_t expA; - uint_fast32_t uiZ; - bool signA; - uint_fast32_t lastBitMask, roundBitsMask; + int_fast16_t exp; + uint_fast32_t uiZ, lastBitMask, roundBitsMask; union ui32_f32 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; - expA = expF32UI( uiA ); - if ( 0x96 <= expA ) { - if ( ( expA == 0xFF ) && fracF32UI( uiA ) ) { - uiZ = softfloat_propagateNaNF32UI( uiA, 0 ); - goto uiZ; - } - return a; - } - if ( expA <= 0x7E ) { - if ( ! (uint32_t) ( uiA<<1 ) ) return a; + exp = expF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp <= 0x7E ) { + if ( ! (uint32_t) (uiA<<1) ) return a; if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - signA = signF32UI( uiA ); + uiZ = uiA & packToF32UI( 1, 0, 0 ); switch ( roundingMode ) { - case softfloat_round_nearest_even: - if ( ( expA == 0x7E ) && fracF32UI( uiA ) ) { - uiZ = packToF32UI( signA, 0x7F, 0 ); - goto uiZ; - } + case softfloat_round_near_even: + if ( ! fracF32UI( uiA ) ) break; + case softfloat_round_near_maxMag: + if ( exp == 0x7E ) uiZ |= packToF32UI( 0, 0x7F, 0 ); break; case softfloat_round_min: - uiZ = signA ? 0xBF800000 : 0; - goto uiZ; + if ( uiZ ) uiZ = packToF32UI( 1, 0x7F, 0 ); + break; case softfloat_round_max: - uiZ = signA ? 0x80000000 : 0x3F800000; - goto uiZ; - case softfloat_round_nearest_maxMag: - if ( expA == 0x7E ) { - uiZ = packToF32UI( signA, 0x7F, 0 ); - goto uiZ; - } + if ( ! uiZ ) uiZ = packToF32UI( 0, 0x7F, 0 ); break; } - uiZ = packToF32UI( signA, 0, 0 ); goto uiZ; } - lastBitMask = (uint_fast32_t) 1<<( 0x96 - expA ); - roundBitsMask = lastBitMask - 1; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( 0x96 <= exp ) { + if ( (exp == 0xFF) && fracF32UI( uiA ) ) { + uiZ = softfloat_propagateNaNF32UI( uiA, 0 ); + goto uiZ; + } + return a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uiZ = uiA; - if ( roundingMode == softfloat_round_nearest_maxMag ) { + lastBitMask = (uint_fast32_t) 1<<(0x96 - exp); + roundBitsMask = lastBitMask - 1; + if ( roundingMode == softfloat_round_near_maxMag ) { uiZ += lastBitMask>>1; - } else if ( roundingMode == softfloat_round_nearest_even ) { + } else if ( roundingMode == softfloat_round_near_even ) { uiZ += lastBitMask>>1; - if ( ! ( uiZ & roundBitsMask ) ) uiZ &= ~ lastBitMask; + if ( ! (uiZ & roundBitsMask) ) uiZ &= ~lastBitMask; } else if ( roundingMode != softfloat_round_minMag ) { - if ( signF32UI( uiZ ) ^ ( roundingMode == softfloat_round_max ) ) { + if ( signF32UI( uiZ ) ^ (roundingMode == softfloat_round_max) ) { uiZ += roundBitsMask; } } - uiZ &= ~ roundBitsMask; - if ( exact && ( uiZ != uiA ) ) { + uiZ &= ~roundBitsMask; + if ( exact && (uiZ != uiA) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } uiZ: diff --git a/softfloat/f32_sqrt.c b/softfloat/f32_sqrt.c old mode 100755 new mode 100644 index c9eb907..d0b489c --- a/softfloat/f32_sqrt.c +++ b/softfloat/f32_sqrt.c @@ -1,74 +1,121 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t f32_sqrt( float32_t a ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool signA; - int_fast16_t expA; - uint_fast32_t sigA, uiZ; - struct exp16_sig32 normExpSig; - int_fast16_t expZ; - uint_fast32_t sigZ; - uint_fast64_t term, rem; - union ui32_f32 uZ; - - uA.f = a; - uiA = uA.ui; - signA = signF32UI( uiA ); - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); - if ( expA == 0xFF ) { - if ( sigA ) { - uiZ = softfloat_propagateNaNF32UI( uiA, 0 ); - goto uiZ; - } - if ( ! signA ) return a; - goto invalid; - } - if ( signA ) { - if ( ! ( expA | sigA ) ) return a; - goto invalid; - } - if ( ! expA ) { - if ( ! sigA ) return a; - normExpSig = softfloat_normSubnormalF32Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - expZ = ( ( expA - 0x7F )>>1 ) + 0x7E; - sigA = ( sigA | 0x00800000 )<<8; - sigZ = softfloat_estimateSqrt32( expA, sigA ) + 2; - if ( ( sigZ & 0x7F ) <= 5 ) { - if ( sigZ < 2 ) { - sigZ = 0x7FFFFFFF; - goto roundPack; - } - sigA >>= expA & 1; - term = (uint_fast64_t) sigZ * sigZ; - rem = ( (uint_fast64_t) sigA<<32 ) - term; - while ( UINT64_C( 0x8000000000000000 ) <= rem ) { - --sigZ; - rem += ( (uint_fast64_t) sigZ<<1 ) | 1; - } - sigZ |= ( rem != 0 ); - } - sigZ = softfloat_shortShift32Right1Jam( sigZ ); - roundPack: - return softfloat_roundPackToF32( 0, expZ, sigZ ); - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF32UI; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float32_t f32_sqrt( float32_t a ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + bool signA; + int_fast16_t expA; + uint_fast32_t sigA, uiZ; + struct exp16_sig32 normExpSig; + int_fast16_t expZ; + uint_fast32_t sigZ, shiftedSigZ; + uint32_t negRem; + union ui32_f32 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + signA = signF32UI( uiA ); + expA = expF32UI( uiA ); + sigA = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0xFF ) { + if ( sigA ) { + uiZ = softfloat_propagateNaNF32UI( uiA, 0 ); + goto uiZ; + } + if ( ! signA ) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( signA ) { + if ( ! (expA | sigA) ) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expA ) { + if ( ! sigA ) return a; + normExpSig = softfloat_normSubnormalF32Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = ((expA - 0x7F)>>1) + 0x7E; + expA &= 1; + sigA = (sigA | 0x00800000)<<8; + sigZ = + ((uint_fast64_t) sigA * softfloat_approxRecipSqrt32_1( expA, sigA )) + >>32; + if ( expA ) sigZ >>= 1; + sigZ += 2; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( (sigZ & 0x3F) < 2 ) { + shiftedSigZ = sigZ>>2; + negRem = shiftedSigZ * shiftedSigZ; + sigZ = shiftedSigZ<<2; + if ( negRem & 0x80000000 ) { + sigZ |= 1; + } else { + if ( negRem ) --sigZ; + } + } + return softfloat_roundPackToF32( 0, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF32UI; + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f32_sub.c b/softfloat/f32_sub.c old mode 100755 new mode 100644 index c64df8e..eae436c --- a/softfloat/f32_sub.c +++ b/softfloat/f32_sub.c @@ -1,29 +1,74 @@ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float32_t f32_sub( float32_t a, float32_t b ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool signA; - union ui32_f32 uB; - uint_fast32_t uiB; - bool signB; - float32_t ( *magsRoutine )( uint_fast32_t, uint_fast32_t, bool ); - - uA.f = a; - uiA = uA.ui; - signA = signF32UI( uiA ); - uB.f = b; - uiB = uB.ui; - signB = signF32UI( uiB ); - magsRoutine = - ( signA == signB ) ? softfloat_subMagsF32 : softfloat_addMagsF32; - return magsRoutine( uiA, uiB ^ 0x80000000, signA ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float32_t f32_sub( float32_t a, float32_t b ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + bool signA; + union ui32_f32 uB; + uint_fast32_t uiB; + bool signB; +#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 1) + float32_t (*magsFuncPtr)( uint_fast32_t, uint_fast32_t, bool ); +#endif + + uA.f = a; + uiA = uA.ui; + signA = signF32UI( uiA ); + uB.f = b; + uiB = uB.ui; + signB = signF32UI( uiB ); +#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) + if ( signA == signB ) { + return softfloat_subMagsF32( uiA, uiB, signA ); + } else { + return softfloat_addMagsF32( uiA, uiB, signA ); + } +#else + magsFuncPtr = + (signA == signB) ? softfloat_subMagsF32 : softfloat_addMagsF32; + return (*magsFuncPtr)( uiA, uiB, signA ); +#endif + +} + diff --git a/softfloat/f32_to_f64.c b/softfloat/f32_to_f64.c old mode 100755 new mode 100644 index 9f0ae5c..30b0923 --- a/softfloat/f32_to_f64.c +++ b/softfloat/f32_to_f64.c @@ -1,47 +1,85 @@ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t f32_to_f64( float32_t a ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t sig; - uint_fast64_t uiZ; - struct exp16_sig32 normExpSig; - union ui64_f64 uZ; - - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - if ( exp == 0xFF ) { - uiZ = - sig ? softfloat_commonNaNToF64UI( - softfloat_f32UIToCommonNaN( uiA ) ) - : packToF64UI( sign, 0x7FF, 0 ); - goto uiZ; - } - if ( ! exp ) { - if ( ! sig ) { - uiZ = packToF64UI( sign, 0, 0 ); - goto uiZ; - } - normExpSig = softfloat_normSubnormalF32Sig( sig ); - exp = normExpSig.exp - 1; - sig = normExpSig.sig; - } - uiZ = packToF64UI( sign, exp + 0x380, (uint_fast64_t) sig<<29 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float64_t f32_to_f64( float32_t a ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + bool sign; + int_fast16_t exp; + uint_fast32_t sig; + struct commonNaN commonNaN; + uint_fast64_t uiZ; + struct exp16_sig32 normExpSig; + union ui64_f64 uZ; + + uA.f = a; + uiA = uA.ui; + sign = signF32UI( uiA ); + exp = expF32UI( uiA ); + sig = fracF32UI( uiA ); + if ( exp == 0xFF ) { + if ( sig ) { + softfloat_f32UIToCommonNaN( uiA, &commonNaN ); + uiZ = softfloat_commonNaNToF64UI( &commonNaN ); + } else { + uiZ = packToF64UI( sign, 0x7FF, 0 ); + } + goto uiZ; + } + if ( ! exp ) { + if ( ! sig ) { + uiZ = packToF64UI( sign, 0, 0 ); + goto uiZ; + } + normExpSig = softfloat_normSubnormalF32Sig( sig ); + exp = normExpSig.exp - 1; + sig = normExpSig.sig; + } + uiZ = packToF64UI( sign, exp + 0x380, (uint_fast64_t) sig<<29 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f32_to_i32.c b/softfloat/f32_to_i32.c old mode 100755 new mode 100644 index bbbaee0..c80649a --- a/softfloat/f32_to_i32.c +++ b/softfloat/f32_to_i32.c @@ -1,34 +1,84 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -int_fast32_t f32_to_i32( float32_t a, int_fast8_t roundingMode, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t sig; - uint_fast64_t sig64; - int_fast16_t shiftCount; - - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - if ( ( exp == 0xFF ) && sig ) sign = 0; - if ( exp ) sig |= 0x00800000; - sig64 = (uint_fast64_t) sig<<32; - shiftCount = 0xAF - exp; - if ( 0 < shiftCount ) { - sig64 = softfloat_shift64RightJam( sig64, shiftCount ); - } - return softfloat_roundPackToI32( sign, sig64, roundingMode, exact ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast32_t f32_to_i32( float32_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + bool sign; + int_fast16_t exp; + uint_fast32_t sig; + uint_fast64_t sig64; + int_fast16_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF32UI( uiA ); + exp = expF32UI( uiA ); + sig = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) + if ( (exp == 0xFF) && sig ) { +#if (i32_fromNaN == i32_fromPosOverflow) + sign = 0; +#elif (i32_fromNaN == i32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags( softfloat_flag_invalid ); + return i32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp ) sig |= 0x00800000; + sig64 = (uint_fast64_t) sig<<32; + shiftDist = 0xAF - exp; + if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); + return softfloat_roundPackToI32( sign, sig64, roundingMode, exact ); + +} + diff --git a/softfloat/f32_to_i32_r_minMag.c b/softfloat/f32_to_i32_r_minMag.c old mode 100755 new mode 100644 index 63ff1e2..d2e4b92 --- a/softfloat/f32_to_i32_r_minMag.c +++ b/softfloat/f32_to_i32_r_minMag.c @@ -1,45 +1,89 @@ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -int_fast32_t f32_to_i32_r_minMag( float32_t a, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - int_fast16_t exp; - uint_fast32_t sig; - bool sign; - int_fast16_t shiftCount; - int_fast32_t absZ; - - uA.f = a; - uiA = uA.ui; - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - if ( exp < 0x7F ) { - if ( exact && ( exp | sig ) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - sign = signF32UI( uiA ); - shiftCount = 0x9E - exp; - if ( shiftCount <= 0 ) { - if ( uiA != packToF32UI( 1, 0x9E, 0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! sign || ( ( exp == 0xFF ) && sig ) ) return 0x7FFFFFFF; - } - return -0x7FFFFFFF - 1; - } - sig = ( sig | 0x00800000 )<<8; - absZ = sig>>shiftCount; - if ( exact && (uint32_t) ( sig<<( ( - shiftCount ) & 31 ) ) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return sign ? - absZ : absZ; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast32_t f32_to_i32_r_minMag( float32_t a, bool exact ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + int_fast16_t exp; + uint_fast32_t sig; + int_fast16_t shiftDist; + bool sign; + int_fast32_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF32UI( uiA ); + sig = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x9E - exp; + if ( 32 <= shiftDist ) { + if ( exact && (exp | sig) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI( uiA ); + if ( shiftDist <= 0 ) { + if ( uiA == packToF32UI( 1, 0x9E, 0 ) ) return -0x7FFFFFFF - 1; + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0xFF) && sig ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig = (sig | 0x00800000)<<8; + absZ = sig>>shiftDist; + if ( exact && ((uint_fast32_t) absZ< -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -int_fast64_t f32_to_i64( float32_t a, int_fast8_t roundingMode, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t sig; - int_fast16_t shiftCount; - uint_fast64_t sig64, extra; - struct uint64_extra sig64Extra; - - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - shiftCount = 0xBE - exp; - if ( shiftCount < 0 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! sign || ( ( exp == 0xFF ) && sig ) ) { - return INT64_C( 0x7FFFFFFFFFFFFFFF ); - } - return - INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; - } - if ( exp ) sig |= 0x00800000; - sig64 = (uint_fast64_t) sig<<40; - extra = 0; - if ( shiftCount ) { - sig64Extra = softfloat_shift64ExtraRightJam( sig64, 0, shiftCount ); - sig64 = sig64Extra.v; - extra = sig64Extra.extra; - } - return softfloat_roundPackToI64( sign, sig64, extra, roundingMode, exact ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast64_t f32_to_i64( float32_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + bool sign; + int_fast16_t exp; + uint_fast32_t sig; + int_fast16_t shiftDist; +#ifdef SOFTFLOAT_FAST_INT64 + uint_fast64_t sig64, extra; + struct uint64_extra sig64Extra; +#else + uint32_t extSig[3]; +#endif + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF32UI( uiA ); + exp = expF32UI( uiA ); + sig = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if ( shiftDist < 0 ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0xFF) && sig ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp ) sig |= 0x00800000; +#ifdef SOFTFLOAT_FAST_INT64 + sig64 = (uint_fast64_t) sig<<40; + extra = 0; + if ( shiftDist ) { + sig64Extra = softfloat_shiftRightJam64Extra( sig64, 0, shiftDist ); + sig64 = sig64Extra.v; + extra = sig64Extra.extra; + } + return softfloat_roundPackToI64( sign, sig64, extra, roundingMode, exact ); +#else + extSig[indexWord( 3, 2 )] = sig<<8; + extSig[indexWord( 3, 1 )] = 0; + extSig[indexWord( 3, 0 )] = 0; + if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); + return softfloat_roundPackMToI64( sign, extSig, roundingMode, exact ); +#endif + +} + diff --git a/softfloat/f32_to_i64_r_minMag.c b/softfloat/f32_to_i64_r_minMag.c old mode 100755 new mode 100644 index 33bff93..af2b28b --- a/softfloat/f32_to_i64_r_minMag.c +++ b/softfloat/f32_to_i64_r_minMag.c @@ -1,52 +1,94 @@ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -int_fast64_t f32_to_i64_r_minMag( float32_t a, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - int_fast16_t exp; - uint_fast32_t sig; - bool sign; - int_fast16_t shiftCount; - uint_fast64_t sig64; - int_fast64_t absZ; - - uA.f = a; - uiA = uA.ui; - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - if ( exp < 0x7F ) { - if ( exact && ( exp | sig ) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - sign = signF32UI( uiA ); - shiftCount = 0xBE - exp; - if ( shiftCount <= 0 ) { - if ( uiA != packToF32UI( 1, 0xBE, 0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! sign || ( ( exp == 0xFF ) && sig ) ) { - return INT64_C( 0x7FFFFFFFFFFFFFFF ); - } - } - return - INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; - } - sig |= 0x00800000; - sig64 = (uint_fast64_t) sig<<40; - absZ = sig64>>shiftCount; - shiftCount = 40 - shiftCount; - if ( - exact && ( shiftCount < 0 ) && (uint32_t) ( sig<<( shiftCount & 31 ) ) - ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return sign ? - absZ : absZ; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast64_t f32_to_i64_r_minMag( float32_t a, bool exact ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + int_fast16_t exp; + uint_fast32_t sig; + int_fast16_t shiftDist; + bool sign; + uint_fast64_t sig64; + int_fast64_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF32UI( uiA ); + sig = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if ( 64 <= shiftDist ) { + if ( exact && (exp | sig) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI( uiA ); + if ( shiftDist <= 0 ) { + if ( uiA == packToF32UI( 1, 0xBE, 0 ) ) { + return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + } + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0xFF) && sig ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig |= 0x00800000; + sig64 = (uint_fast64_t) sig<<40; + absZ = sig64>>shiftDist; + shiftDist = 40 - shiftDist; + if ( exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31)) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return sign ? -absZ : absZ; + +} + diff --git a/softfloat/f32_to_ui32.c b/softfloat/f32_to_ui32.c old mode 100755 new mode 100644 index 3501db8..1979dd5 --- a/softfloat/f32_to_ui32.c +++ b/softfloat/f32_to_ui32.c @@ -1,33 +1,84 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -uint_fast32_t f32_to_ui32( float32_t a, int_fast8_t roundingMode, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t sig; - uint_fast64_t sig64; - int_fast16_t shiftCount; - - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - if ( exp ) sig |= 0x00800000; - sig64 = (uint_fast64_t) sig<<32; - shiftCount = 0xAF - exp; - if ( 0 < shiftCount ) { - sig64 = softfloat_shift64RightJam( sig64, shiftCount ); - } - return softfloat_roundPackToUI32( sign, sig64, roundingMode, exact ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast32_t f32_to_ui32( float32_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + bool sign; + int_fast16_t exp; + uint_fast32_t sig; + uint_fast64_t sig64; + int_fast16_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF32UI( uiA ); + exp = expF32UI( uiA ); + sig = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) + if ( (exp == 0xFF) && sig ) { +#if (ui32_fromNaN == ui32_fromPosOverflow) + sign = 0; +#elif (ui32_fromNaN == ui32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags( softfloat_flag_invalid ); + return ui32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp ) sig |= 0x00800000; + sig64 = (uint_fast64_t) sig<<32; + shiftDist = 0xAF - exp; + if ( 0 < shiftDist ) sig64 = softfloat_shiftRightJam64( sig64, shiftDist ); + return softfloat_roundPackToUI32( sign, sig64, roundingMode, exact ); + +} + diff --git a/softfloat/f32_to_ui32_r_minMag.c b/softfloat/f32_to_ui32_r_minMag.c old mode 100755 new mode 100644 index edd858d..9979b2c --- a/softfloat/f32_to_ui32_r_minMag.c +++ b/softfloat/f32_to_ui32_r_minMag.c @@ -1,41 +1,88 @@ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -uint_fast32_t f32_to_ui32_r_minMag( float32_t a, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - int_fast16_t exp; - uint_fast32_t sig; - int_fast16_t shiftCount; - uint_fast32_t z; - - uA.f = a; - uiA = uA.ui; - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - if ( exp < 0x7F ) { - if ( exact && ( exp | sig ) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - if ( signF32UI( uiA ) ) goto invalid; - shiftCount = 0x9E - exp; - if ( shiftCount < 0 ) goto invalid; - sig = ( sig | 0x00800000 )<<8; - z = sig>>shiftCount; - if ( exact && ( sig & ( ( (uint_fast32_t) 1< +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast32_t f32_to_ui32_r_minMag( float32_t a, bool exact ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + int_fast16_t exp; + uint_fast32_t sig; + int_fast16_t shiftDist; + bool sign; + uint_fast32_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF32UI( uiA ); + sig = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x9E - exp; + if ( 32 <= shiftDist ) { + if ( exact && (exp | sig) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI( uiA ); + if ( sign || (shiftDist < 0) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0xFF) && sig ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig = (sig | 0x00800000)<<8; + z = sig>>shiftDist; + if ( exact && (z< -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -uint_fast64_t f32_to_ui64( float32_t a, int_fast8_t roundingMode, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - bool sign; - int_fast16_t exp; - uint_fast32_t sig; - int_fast16_t shiftCount; - uint_fast64_t sig64, extra; - struct uint64_extra sig64Extra; - - uA.f = a; - uiA = uA.ui; - sign = signF32UI( uiA ); - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - shiftCount = 0xBE - exp; - if ( shiftCount < 0 ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); - } - if ( exp ) sig |= 0x00800000; - sig64 = (uint_fast64_t) sig<<40; - extra = 0; - if ( shiftCount ) { - sig64Extra = softfloat_shift64ExtraRightJam( sig64, 0, shiftCount ); - sig64 = sig64Extra.v; - extra = sig64Extra.extra; - } - return - softfloat_roundPackToUI64( sign, sig64, extra, roundingMode, exact ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast64_t f32_to_ui64( float32_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + bool sign; + int_fast16_t exp; + uint_fast32_t sig; + int_fast16_t shiftDist; +#ifdef SOFTFLOAT_FAST_INT64 + uint_fast64_t sig64, extra; + struct uint64_extra sig64Extra; +#else + uint32_t extSig[3]; +#endif + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF32UI( uiA ); + exp = expF32UI( uiA ); + sig = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if ( shiftDist < 0 ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0xFF) && sig ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp ) sig |= 0x00800000; +#ifdef SOFTFLOAT_FAST_INT64 + sig64 = (uint_fast64_t) sig<<40; + extra = 0; + if ( shiftDist ) { + sig64Extra = softfloat_shiftRightJam64Extra( sig64, 0, shiftDist ); + sig64 = sig64Extra.v; + extra = sig64Extra.extra; + } + return + softfloat_roundPackToUI64( sign, sig64, extra, roundingMode, exact ); +#else + extSig[indexWord( 3, 2 )] = sig<<8; + extSig[indexWord( 3, 1 )] = 0; + extSig[indexWord( 3, 0 )] = 0; + if ( shiftDist ) softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); + return softfloat_roundPackMToUI64( sign, extSig, roundingMode, exact ); +#endif + +} + diff --git a/softfloat/f32_to_ui64_r_minMag.c b/softfloat/f32_to_ui64_r_minMag.c old mode 100755 new mode 100644 index 738d6b1..0d5fe5b --- a/softfloat/f32_to_ui64_r_minMag.c +++ b/softfloat/f32_to_ui64_r_minMag.c @@ -1,45 +1,90 @@ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -uint_fast64_t f32_to_ui64_r_minMag( float32_t a, bool exact ) -{ - union ui32_f32 uA; - uint_fast32_t uiA; - int_fast16_t exp; - uint_fast32_t sig; - int_fast16_t shiftCount; - uint_fast64_t sig64, z; - - uA.f = a; - uiA = uA.ui; - exp = expF32UI( uiA ); - sig = fracF32UI( uiA ); - if ( exp < 0x7F ) { - if ( exact && ( exp | sig ) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - if ( signF32UI( uiA ) ) goto invalid; - shiftCount = 0xBE - exp; - if ( shiftCount < 0 ) goto invalid; - sig |= 0x00800000; - sig64 = (uint_fast64_t) sig<<40; - z = sig64>>shiftCount; - shiftCount = 40 - shiftCount; - if ( - exact && ( shiftCount < 0 ) && (uint32_t) ( sig<<( shiftCount & 31 ) ) - ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return z; - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast64_t f32_to_ui64_r_minMag( float32_t a, bool exact ) +{ + union ui32_f32 uA; + uint_fast32_t uiA; + int_fast16_t exp; + uint_fast32_t sig; + int_fast16_t shiftDist; + bool sign; + uint_fast64_t sig64, z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF32UI( uiA ); + sig = fracF32UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0xBE - exp; + if ( 64 <= shiftDist ) { + if ( exact && (exp | sig) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF32UI( uiA ); + if ( sign || (shiftDist < 0) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0xFF) && sig ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig |= 0x00800000; + sig64 = (uint_fast64_t) sig<<40; + z = sig64>>shiftDist; + shiftDist = 40 - shiftDist; + if ( exact && (shiftDist < 0) && (uint32_t) (sig<<(shiftDist & 31)) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return z; + +} + diff --git a/softfloat/f64_add.c b/softfloat/f64_add.c old mode 100755 new mode 100644 index 9ec4b5f..5bbb1b5 --- a/softfloat/f64_add.c +++ b/softfloat/f64_add.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -13,7 +48,9 @@ float64_t f64_add( float64_t a, float64_t b ) union ui64_f64 uB; uint_fast64_t uiB; bool signB; - float64_t ( *magsRoutine )( uint_fast64_t, uint_fast64_t, bool ); +#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) + float64_t (*magsFuncPtr)( uint_fast64_t, uint_fast64_t, bool ); +#endif uA.f = a; uiA = uA.ui; @@ -21,9 +58,17 @@ float64_t f64_add( float64_t a, float64_t b ) uB.f = b; uiB = uB.ui; signB = signF64UI( uiB ); - magsRoutine = - ( signA == signB ) ? softfloat_addMagsF64 : softfloat_subMagsF64; - return magsRoutine( uiA, uiB, signA ); +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) + if ( signA == signB ) { + return softfloat_addMagsF64( uiA, uiB, signA ); + } else { + return softfloat_subMagsF64( uiA, uiB, signA ); + } +#else + magsFuncPtr = + (signA == signB) ? softfloat_addMagsF64 : softfloat_subMagsF64; + return (*magsFuncPtr)( uiA, uiB, signA ); +#endif } diff --git a/softfloat/f64_div.c b/softfloat/f64_div.c old mode 100755 new mode 100644 index 9bc72b3..96523f0 --- a/softfloat/f64_div.c +++ b/softfloat/f64_div.c @@ -1,8 +1,42 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" -#include "primitives.h" #include "internals.h" #include "specialize.h" #include "softfloat.h" @@ -22,22 +56,28 @@ float64_t f64_div( float64_t a, float64_t b ) bool signZ; struct exp16_sig64 normExpSig; int_fast16_t expZ; + uint32_t recip32, sig32Z, doubleTerm; + uint_fast64_t rem; + uint32_t q; uint_fast64_t sigZ; - struct uint128 term, rem; uint_fast64_t uiZ; union ui64_f64 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; signA = signF64UI( uiA ); - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); + expA = expF64UI( uiA ); + sigA = fracF64UI( uiA ); uB.f = b; uiB = uB.ui; signB = signF64UI( uiB ); - expB = expF64UI( uiB ); - sigB = fracF64UI( uiB ); + expB = expF64UI( uiB ); + sigB = fracF64UI( uiB ); signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( expA == 0x7FF ) { if ( sigA ) goto propagateNaN; if ( expB == 0x7FF ) { @@ -50,10 +90,12 @@ float64_t f64_div( float64_t a, float64_t b ) if ( sigB ) goto propagateNaN; goto zero; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( ! expB ) { if ( ! sigB ) { - if ( ! ( expA | sigA ) ) goto invalid; - softfloat_raiseFlags( softfloat_flag_infinity ); + if ( ! (expA | sigA) ) goto invalid; + softfloat_raiseFlags( softfloat_flag_infinite ); goto infinity; } normExpSig = softfloat_normSubnormalF64Sig( sigB ); @@ -66,34 +108,60 @@ float64_t f64_div( float64_t a, float64_t b ) expA = normExpSig.exp; sigA = normExpSig.sig; } - expZ = expA - expB + 0x3FD; - sigA = ( sigA | UINT64_C( 0x0010000000000000 ) )<<10; - sigB = ( sigB | UINT64_C( 0x0010000000000000 ) )<<11; - if ( sigB <= ( sigA + sigA ) ) { - ++expZ; - sigA >>= 1; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA - expB + 0x3FE; + sigA |= UINT64_C( 0x0010000000000000 ); + sigB |= UINT64_C( 0x0010000000000000 ); + if ( sigA < sigB ) { + --expZ; + sigA <<= 11; + } else { + sigA <<= 10; } - sigZ = softfloat_estimateDiv128To64( sigA, 0, sigB ); - if ( ( sigZ & 0x1FF ) <= 2 ) { - term = softfloat_mul64To128( sigB, sigZ ); - rem = softfloat_sub128( sigA, 0, term.v64, term.v0 ); - while ( UINT64_C( 0x8000000000000000 ) <= rem.v64 ) { - --sigZ; - rem = softfloat_add128( rem.v64, rem.v0, 0, sigB ); + sigB <<= 11; + recip32 = softfloat_approxRecip32_1( sigB>>32 ) - 2; + sig32Z = ((uint32_t) (sigA>>32) * (uint_fast64_t) recip32)>>32; + doubleTerm = sig32Z<<1; + rem = + ((sigA - (uint_fast64_t) doubleTerm * (uint32_t) (sigB>>32))<<28) + - (uint_fast64_t) doubleTerm * ((uint32_t) sigB>>4); + q = (((uint32_t) (rem>>32) * (uint_fast64_t) recip32)>>32) + 4; + sigZ = ((uint_fast64_t) sig32Z<<32) + ((uint_fast64_t) q<<4); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( (sigZ & 0x1FF) < 4<<4 ) { + q &= ~7; + sigZ &= ~(uint_fast64_t) 0x7F; + doubleTerm = q<<1; + rem = + ((rem - (uint_fast64_t) doubleTerm * (uint32_t) (sigB>>32))<<28) + - (uint_fast64_t) doubleTerm * ((uint32_t) sigB>>4); + if ( rem & UINT64_C( 0x8000000000000000 ) ) { + sigZ -= 1<<7; + } else { + if ( rem ) sigZ |= 1; } - sigZ |= ( rem.v0 != 0 ); } return softfloat_roundPackToF64( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); uiZ = defaultNaNF64UI; goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ infinity: uiZ = packToF64UI( signZ, 0x7FF, 0 ); goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ zero: uiZ = packToF64UI( signZ, 0, 0 ); uiZ: diff --git a/softfloat/f64_eq.c b/softfloat/f64_eq.c old mode 100755 new mode 100644 index 925aabc..6d69e03 --- a/softfloat/f64_eq.c +++ b/softfloat/f64_eq.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -17,10 +52,7 @@ bool f64_eq( float64_t a, float64_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF64UI( uiA ) == 0x7FF ) && fracF64UI( uiA ) ) - || ( ( expF64UI( uiB ) == 0x7FF ) && fracF64UI( uiB ) ) - ) { + if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { if ( softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB ) ) { @@ -28,8 +60,7 @@ bool f64_eq( float64_t a, float64_t b ) } return false; } - return - ( uiA == uiB ) || ! ( ( uiA | uiB ) & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ); + return (uiA == uiB) || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )); } diff --git a/softfloat/f64_eq_signaling.c b/softfloat/f64_eq_signaling.c old mode 100755 new mode 100644 index 7a54dc1..2f77bbd --- a/softfloat/f64_eq_signaling.c +++ b/softfloat/f64_eq_signaling.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -16,15 +51,11 @@ bool f64_eq_signaling( float64_t a, float64_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF64UI( uiA ) == 0x7FF ) && fracF64UI( uiA ) ) - || ( ( expF64UI( uiB ) == 0x7FF ) && fracF64UI( uiB ) ) - ) { + if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); return false; } - return - ( uiA == uiB ) || ! ( ( uiA | uiB ) & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ); + return (uiA == uiB) || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )); } diff --git a/softfloat/f64_isSignalingNaN.c b/softfloat/f64_isSignalingNaN.c old mode 100755 new mode 100644 index d720ac1..2858ded --- a/softfloat/f64_isSignalingNaN.c +++ b/softfloat/f64_isSignalingNaN.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include "platform.h" #include "internals.h" diff --git a/softfloat/f64_le.c b/softfloat/f64_le.c old mode 100755 new mode 100644 index e6c5caf..7462215 --- a/softfloat/f64_le.c +++ b/softfloat/f64_le.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -17,19 +52,16 @@ bool f64_le( float64_t a, float64_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF64UI( uiA ) == 0x7FF ) && fracF64UI( uiA ) ) - || ( ( expF64UI( uiB ) == 0x7FF ) && fracF64UI( uiB ) ) - ) { + if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); return false; } signA = signF64UI( uiA ); signB = signF64UI( uiB ); return - ( signA != signB ) - ? signA || ! ( ( uiA | uiB ) & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) - : ( uiA == uiB ) || ( signA ^ ( uiA < uiB ) ); + (signA != signB) + ? signA || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + : (uiA == uiB) || (signA ^ (uiA < uiB)); } diff --git a/softfloat/f64_le_quiet.c b/softfloat/f64_le_quiet.c old mode 100755 new mode 100644 index e9b7ede..907c5ec --- a/softfloat/f64_le_quiet.c +++ b/softfloat/f64_le_quiet.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -18,10 +53,7 @@ bool f64_le_quiet( float64_t a, float64_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF64UI( uiA ) == 0x7FF ) && fracF64UI( uiA ) ) - || ( ( expF64UI( uiB ) == 0x7FF ) && fracF64UI( uiB ) ) - ) { + if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { if ( softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB ) ) { @@ -32,9 +64,9 @@ bool f64_le_quiet( float64_t a, float64_t b ) signA = signF64UI( uiA ); signB = signF64UI( uiB ); return - ( signA != signB ) - ? signA || ! ( ( uiA | uiB ) & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) - : ( uiA == uiB ) || ( signA ^ ( uiA < uiB ) ); + (signA != signB) + ? signA || ! ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + : (uiA == uiB) || (signA ^ (uiA < uiB)); } diff --git a/softfloat/f64_lt.c b/softfloat/f64_lt.c old mode 100755 new mode 100644 index 1b2f696..902701f --- a/softfloat/f64_lt.c +++ b/softfloat/f64_lt.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -17,19 +52,16 @@ bool f64_lt( float64_t a, float64_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF64UI( uiA ) == 0x7FF ) && fracF64UI( uiA ) ) - || ( ( expF64UI( uiB ) == 0x7FF ) && fracF64UI( uiB ) ) - ) { + if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); return false; } signA = signF64UI( uiA ); signB = signF64UI( uiB ); return - ( signA != signB ) - ? signA && ( ( uiA | uiB ) & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) - : ( uiA != uiB ) && ( signA ^ ( uiA < uiB ) ); + (signA != signB) + ? signA && ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + : (uiA != uiB) && (signA ^ (uiA < uiB)); } diff --git a/softfloat/f64_lt_quiet.c b/softfloat/f64_lt_quiet.c old mode 100755 new mode 100644 index f27e6da..5d20c48 --- a/softfloat/f64_lt_quiet.c +++ b/softfloat/f64_lt_quiet.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -18,10 +53,7 @@ bool f64_lt_quiet( float64_t a, float64_t b ) uiA = uA.ui; uB.f = b; uiB = uB.ui; - if ( - ( ( expF64UI( uiA ) == 0x7FF ) && fracF64UI( uiA ) ) - || ( ( expF64UI( uiB ) == 0x7FF ) && fracF64UI( uiB ) ) - ) { + if ( isNaNF64UI( uiA ) || isNaNF64UI( uiB ) ) { if ( softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB ) ) { @@ -32,9 +64,9 @@ bool f64_lt_quiet( float64_t a, float64_t b ) signA = signF64UI( uiA ); signB = signF64UI( uiB ); return - ( signA != signB ) - ? signA && ( ( uiA | uiB ) & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) - : ( uiA != uiB ) && ( signA ^ ( uiA < uiB ) ); + (signA != signB) + ? signA && ((uiA | uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + : (uiA != uiB) && (signA ^ (uiA < uiB)); } diff --git a/softfloat/f64_mul.c b/softfloat/f64_mul.c old mode 100755 new mode 100644 index 4b5dc4e..78c4421 --- a/softfloat/f64_mul.c +++ b/softfloat/f64_mul.c @@ -1,91 +1,150 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t f64_mul( float64_t a, float64_t b ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool signA; - int_fast16_t expA; - uint_fast64_t sigA; - union ui64_f64 uB; - uint_fast64_t uiB; - bool signB; - int_fast16_t expB; - uint_fast64_t sigB; - bool signZ; - uint_fast64_t magBits; - struct exp16_sig64 normExpSig; - int_fast16_t expZ; - struct uint128 sigZ128; - uint_fast64_t sigZ, uiZ; - union ui64_f64 uZ; - - uA.f = a; - uiA = uA.ui; - signA = signF64UI( uiA ); - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); - uB.f = b; - uiB = uB.ui; - signB = signF64UI( uiB ); - expB = expF64UI( uiB ); - sigB = fracF64UI( uiB ); - signZ = signA ^ signB; - if ( expA == 0x7FF ) { - if ( sigA || ( ( expB == 0x7FF ) && sigB ) ) goto propagateNaN; - magBits = expB | sigB; - goto infArg; - } - if ( expB == 0x7FF ) { - if ( sigB ) goto propagateNaN; - magBits = expA | sigA; - goto infArg; - } - if ( ! expA ) { - if ( ! sigA ) goto zero; - normExpSig = softfloat_normSubnormalF64Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! sigB ) goto zero; - normExpSig = softfloat_normSubnormalF64Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - expZ = expA + expB - 0x3FF; - sigA = ( sigA | UINT64_C( 0x0010000000000000 ) )<<10; - sigB = ( sigB | UINT64_C( 0x0010000000000000 ) )<<11; - sigZ128 = softfloat_mul64To128( sigA, sigB ); - sigZ = sigZ128.v64 | ( sigZ128.v0 != 0 ); - if ( sigZ < UINT64_C( 0x4000000000000000 ) ) { - --expZ; - sigZ <<= 1; - } - return softfloat_roundPackToF64( signZ, expZ, sigZ ); - propagateNaN: - uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); - goto uiZ; - infArg: - if ( ! magBits ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF64UI; - } else { - uiZ = packToF64UI( signZ, 0x7FF, 0 ); - } - goto uiZ; - zero: - uiZ = packToF64UI( signZ, 0, 0 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float64_t f64_mul( float64_t a, float64_t b ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + bool signA; + int_fast16_t expA; + uint_fast64_t sigA; + union ui64_f64 uB; + uint_fast64_t uiB; + bool signB; + int_fast16_t expB; + uint_fast64_t sigB; + bool signZ; + uint_fast64_t magBits; + struct exp16_sig64 normExpSig; + int_fast16_t expZ; +#ifdef SOFTFLOAT_FAST_INT64 + struct uint128 sig128Z; +#else + uint32_t sig128Z[4]; +#endif + uint_fast64_t sigZ, uiZ; + union ui64_f64 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + signA = signF64UI( uiA ); + expA = expF64UI( uiA ); + sigA = fracF64UI( uiA ); + uB.f = b; + uiB = uB.ui; + signB = signF64UI( uiB ); + expB = expF64UI( uiB ); + sigB = fracF64UI( uiB ); + signZ = signA ^ signB; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x7FF ) { + if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN; + magBits = expB | sigB; + goto infArg; + } + if ( expB == 0x7FF ) { + if ( sigB ) goto propagateNaN; + magBits = expA | sigA; + goto infArg; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expA ) { + if ( ! sigA ) goto zero; + normExpSig = softfloat_normSubnormalF64Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if ( ! expB ) { + if ( ! sigB ) goto zero; + normExpSig = softfloat_normSubnormalF64Sig( sigB ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0x3FF; + sigA = (sigA | UINT64_C( 0x0010000000000000 ))<<10; + sigB = (sigB | UINT64_C( 0x0010000000000000 ))<<11; +#ifdef SOFTFLOAT_FAST_INT64 + sig128Z = softfloat_mul64To128( sigA, sigB ); + sigZ = sig128Z.v64 | (sig128Z.v0 != 0); +#else + softfloat_mul64To128M( sigA, sigB, sig128Z ); + sigZ = + (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 | sig128Z[indexWord( 4, 2 )]; + if ( sig128Z[indexWord( 4, 1 )] || sig128Z[indexWord( 4, 0 )] ) sigZ |= 1; +#endif + if ( sigZ < UINT64_C( 0x4000000000000000 ) ) { + --expZ; + sigZ <<= 1; + } + return softfloat_roundPackToF64( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN: + uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infArg: + if ( ! magBits ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF64UI; + } else { + uiZ = packToF64UI( signZ, 0x7FF, 0 ); + } + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zero: + uiZ = packToF64UI( signZ, 0, 0 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f64_mulAdd.c b/softfloat/f64_mulAdd.c old mode 100755 new mode 100644 index fa1669a..37bd999 --- a/softfloat/f64_mulAdd.c +++ b/softfloat/f64_mulAdd.c @@ -1,25 +1,60 @@ - -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float64_t f64_mulAdd( float64_t a, float64_t b, float64_t c ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - union ui64_f64 uB; - uint_fast64_t uiB; - union ui64_f64 uC; - uint_fast64_t uiC; - - uA.f = a; - uiA = uA.ui; - uB.f = b; - uiB = uB.ui; - uC.f = c; - uiC = uC.ui; - return softfloat_mulAddF64( 0, uiA, uiB, uiC ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float64_t f64_mulAdd( float64_t a, float64_t b, float64_t c ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + union ui64_f64 uB; + uint_fast64_t uiB; + union ui64_f64 uC; + uint_fast64_t uiC; + + uA.f = a; + uiA = uA.ui; + uB.f = b; + uiB = uB.ui; + uC.f = c; + uiC = uC.ui; + return softfloat_mulAddF64( uiA, uiB, uiC, 0 ); + +} + diff --git a/softfloat/f64_rem.c b/softfloat/f64_rem.c old mode 100755 new mode 100644 index 08fcd78..8ae87fc --- a/softfloat/f64_rem.c +++ b/softfloat/f64_rem.c @@ -1,8 +1,42 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" -#include "primitives.h" #include "internals.h" #include "specialize.h" #include "softfloat.h" @@ -16,35 +50,44 @@ float64_t f64_rem( float64_t a, float64_t b ) uint_fast64_t sigA; union ui64_f64 uB; uint_fast64_t uiB; - bool signB; int_fast16_t expB; uint_fast64_t sigB; struct exp16_sig64 normExpSig; + uint64_t rem; int_fast16_t expDiff; - uint_fast64_t q, alternateSigA; - uint64_t sigMean; - bool signZ; + uint32_t q, recip32; + uint_fast64_t q64; + uint64_t altRem, meanRem; + bool signRem; uint_fast64_t uiZ; union ui64_f64 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; signA = signF64UI( uiA ); - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); + expA = expF64UI( uiA ); + sigA = fracF64UI( uiA ); uB.f = b; uiB = uB.ui; - signB = signF64UI( uiB ); expB = expF64UI( uiB ); sigB = fracF64UI( uiB ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( expA == 0x7FF ) { - if ( sigA || ( ( expB == 0x7FF ) && sigB ) ) goto propagateNaN; + if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN; goto invalid; } if ( expB == 0x7FF ) { if ( sigB ) goto propagateNaN; return a; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA < expB - 1 ) return a; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ if ( ! expB ) { if ( ! sigB ) goto invalid; normExpSig = softfloat_normSubnormalF64Sig( sigB ); @@ -57,48 +100,81 @@ float64_t f64_rem( float64_t a, float64_t b ) expA = normExpSig.exp; sigA = normExpSig.sig; } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + rem = sigA | UINT64_C( 0x0010000000000000 ); + sigB |= UINT64_C( 0x0010000000000000 ); expDiff = expA - expB; - sigA = ( sigA | UINT64_C( 0x0010000000000000 ) )<<11; - sigB = ( sigB | UINT64_C( 0x0010000000000000 ) )<<11; - if ( expDiff < 0 ) { + if ( expDiff < 1 ) { if ( expDiff < -1 ) return a; - sigA >>= 1; - } - q = ( sigB <= sigA ); - if ( q ) sigA -= sigB; - expDiff -= 64; - while ( 0 < expDiff ) { - q = softfloat_estimateDiv128To64( sigA, 0, sigB ); - q = ( 2 < q ) ? q - 2 : 0; - sigA = - ( ( sigB>>2 ) * q ); - expDiff -= 62; - } - expDiff += 64; - if ( 0 < expDiff ) { - q = softfloat_estimateDiv128To64( sigA, 0, sigB ); - q = ( 2 < q ) ? q - 2 : 0; - q >>= 64 - expDiff; - sigB >>= 2; - sigA = ( ( sigA>>1 )<<( expDiff - 1 ) ) - sigB * q; + sigB <<= 9; + if ( expDiff ) { + rem <<= 8; + q = 0; + } else { + rem <<= 9; + q = (sigB <= rem); + if ( q ) rem -= sigB; + } } else { - sigA >>= 2; - sigB >>= 2; + recip32 = softfloat_approxRecip32_1( sigB>>21 ); + /*-------------------------------------------------------------------- + | Changing the shift of `rem' here requires also changing the initial + | subtraction from `expDiff'. + *--------------------------------------------------------------------*/ + rem <<= 9; + expDiff -= 30; + /*-------------------------------------------------------------------- + | The scale of `sigB' affects how many bits are obtained during each + | cycle of the loop. Currently this is 29 bits per loop iteration, + | the maximum possible. + *--------------------------------------------------------------------*/ + sigB <<= 9; + for (;;) { + q64 = (uint32_t) (rem>>32) * (uint_fast64_t) recip32; + if ( expDiff < 0 ) break; + q = (q64 + 0x80000000)>>32; +#ifdef SOFTFLOAT_FAST_INT64 + rem <<= 29; +#else + rem = (uint_fast64_t) (uint32_t) (rem>>3)<<32; +#endif + rem -= q * (uint64_t) sigB; + if ( rem & UINT64_C( 0x8000000000000000 ) ) rem += sigB; + expDiff -= 29; + } + /*-------------------------------------------------------------------- + | (`expDiff' cannot be less than -29 here.) + *--------------------------------------------------------------------*/ + q = (uint32_t) (q64>>32)>>(~expDiff & 31); + rem = (rem<<(expDiff + 30)) - q * (uint64_t) sigB; + if ( rem & UINT64_C( 0x8000000000000000 ) ) { + altRem = rem + sigB; + goto selectRem; + } } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ do { - alternateSigA = sigA; + altRem = rem; ++q; - sigA -= sigB; - } while ( sigA < UINT64_C( 0x8000000000000000 ) ); - sigMean = sigA + alternateSigA; + rem -= sigB; + } while ( ! (rem & UINT64_C( 0x8000000000000000 )) ); + selectRem: + meanRem = rem + altRem; if ( - ( UINT64_C( 0x8000000000000000 ) <= sigMean ) - || ( ! sigMean && ( q & 1 ) ) + (meanRem & UINT64_C( 0x8000000000000000 )) || (! meanRem && (q & 1)) ) { - sigA = alternateSigA; + rem = altRem; + } + signRem = signA; + if ( rem & UINT64_C( 0x8000000000000000 ) ) { + signRem = ! signRem; + rem = -rem; } - signZ = ( UINT64_C( 0x8000000000000000 ) <= sigA ); - if ( signZ ) sigA = - sigA; - return softfloat_normRoundPackToF64( signA ^ signZ, expB, sigA ); + return softfloat_normRoundPackToF64( signRem, expB, rem ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ propagateNaN: uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); goto uiZ; diff --git a/softfloat/f64_roundToInt.c b/softfloat/f64_roundToInt.c old mode 100755 new mode 100644 index ef16dfa..94fe40d --- a/softfloat/f64_roundToInt.c +++ b/softfloat/f64_roundToInt.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -6,70 +41,66 @@ #include "specialize.h" #include "softfloat.h" -float64_t f64_roundToInt( float64_t a, int_fast8_t roundingMode, bool exact ) +float64_t f64_roundToInt( float64_t a, uint_fast8_t roundingMode, bool exact ) { union ui64_f64 uA; uint_fast64_t uiA; - int_fast16_t expA; - uint_fast64_t uiZ; - bool signA; - uint_fast64_t lastBitMask, roundBitsMask; + int_fast16_t exp; + uint_fast64_t uiZ, lastBitMask, roundBitsMask; union ui64_f64 uZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uA.f = a; uiA = uA.ui; - expA = expF64UI( uiA ); - if ( 0x433 <= expA ) { - if ( ( expA == 0x7FF ) && fracF64UI( uiA ) ) { - uiZ = softfloat_propagateNaNF64UI( uiA, 0 ); - goto uiZ; - } - return a; - } - if ( expA <= 0x3FE ) { - if ( ! ( uiA & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) ) return a; + exp = expF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp <= 0x3FE ) { + if ( ! (uiA & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) return a; if ( exact ) softfloat_exceptionFlags |= softfloat_flag_inexact; - signA = signF64UI( uiA ); + uiZ = uiA & packToF64UI( 1, 0, 0 ); switch ( roundingMode ) { - case softfloat_round_nearest_even: - if ( ( expA == 0x3FE ) && fracF64UI( uiA ) ) { - uiZ = packToF64UI( signA, 0x3FF, 0 ); - goto uiZ; - } + case softfloat_round_near_even: + if ( ! fracF64UI( uiA ) ) break; + case softfloat_round_near_maxMag: + if ( exp == 0x3FE ) uiZ |= packToF64UI( 0, 0x3FF, 0 ); break; case softfloat_round_min: - uiZ = signA ? UINT64_C( 0xBFF0000000000000 ) : 0; - goto uiZ; + if ( uiZ ) uiZ = packToF64UI( 1, 0x3FF, 0 ); + break; case softfloat_round_max: - uiZ = - signA ? UINT64_C( 0x8000000000000000 ) - : UINT64_C( 0x3FF0000000000000 ); - goto uiZ; - case softfloat_round_nearest_maxMag: - if ( expA == 0x3FE ) { - uiZ = packToF64UI( signA, 0x3FF, 0 ); - goto uiZ; - } + if ( ! uiZ ) uiZ = packToF64UI( 0, 0x3FF, 0 ); break; } - uiZ = packToF64UI( signA, 0, 0 ); goto uiZ; } - lastBitMask = (uint_fast64_t) 1<<( 0x433 - expA ); - roundBitsMask = lastBitMask - 1; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( 0x433 <= exp ) { + if ( (exp == 0x7FF) && fracF64UI( uiA ) ) { + uiZ = softfloat_propagateNaNF64UI( uiA, 0 ); + goto uiZ; + } + return a; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ uiZ = uiA; - if ( roundingMode == softfloat_round_nearest_maxMag ) { + lastBitMask = (uint_fast64_t) 1<<(0x433 - exp); + roundBitsMask = lastBitMask - 1; + if ( roundingMode == softfloat_round_near_maxMag ) { uiZ += lastBitMask>>1; - } else if ( roundingMode == softfloat_round_nearest_even ) { + } else if ( roundingMode == softfloat_round_near_even ) { uiZ += lastBitMask>>1; - if ( ! ( uiZ & roundBitsMask ) ) uiZ &= ~ lastBitMask; + if ( ! (uiZ & roundBitsMask) ) uiZ &= ~lastBitMask; } else if ( roundingMode != softfloat_round_minMag ) { - if ( signF64UI( uiZ ) ^ ( roundingMode == softfloat_round_max ) ) { + if ( signF64UI( uiZ ) ^ (roundingMode == softfloat_round_max) ) { uiZ += roundBitsMask; } } - uiZ &= ~ roundBitsMask; - if ( exact && ( uiZ != uiA ) ) { + uiZ &= ~roundBitsMask; + if ( exact && (uiZ != uiA) ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } uiZ: diff --git a/softfloat/f64_sqrt.c b/softfloat/f64_sqrt.c old mode 100755 new mode 100644 index cd91010..b65c150 --- a/softfloat/f64_sqrt.c +++ b/softfloat/f64_sqrt.c @@ -1,74 +1,133 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t f64_sqrt( float64_t a ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool signA; - int_fast16_t expA; - uint_fast64_t sigA, uiZ; - struct exp16_sig64 normExpSig; - int_fast16_t expZ; - uint_fast32_t sigZ32; - uint_fast64_t sigZ; - struct uint128 term, rem; - union ui64_f64 uZ; - - uA.f = a; - uiA = uA.ui; - signA = signF64UI( uiA ); - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); - if ( expA == 0x7FF ) { - if ( sigA ) { - uiZ = softfloat_propagateNaNF64UI( uiA, 0 ); - goto uiZ; - } - if ( ! signA ) return a; - goto invalid; - } - if ( signA ) { - if ( ! ( expA | sigA ) ) return a; - goto invalid; - } - if ( ! expA ) { - if ( ! sigA ) return a; - normExpSig = softfloat_normSubnormalF64Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - expZ = ( ( expA - 0x3FF )>>1 ) + 0x3FE; - sigA |= UINT64_C( 0x0010000000000000 ); - sigZ32 = softfloat_estimateSqrt32( expA, sigA>>21 ); - sigA <<= 9 - ( expA & 1 ); - sigZ = - softfloat_estimateDiv128To64( sigA, 0, (uint_fast64_t) sigZ32<<32 ) - + ( (uint_fast64_t) sigZ32<<30 ); - if ( ( sigZ & 0x1FF ) <= 5 ) { - term = softfloat_mul64To128( sigZ, sigZ ); - rem = softfloat_sub128( sigA, 0, term.v64, term.v0 ); - while ( UINT64_C( 0x8000000000000000 ) <= rem.v64 ) { - --sigZ; - rem = - softfloat_add128( - rem.v64, rem.v0, sigZ>>63, (uint64_t) ( sigZ<<1 ) ); - } - sigZ |= ( ( rem.v64 | rem.v0 ) != 0 ); - } - return softfloat_roundPackToF64( 0, expZ, sigZ ); - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF64UI; - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float64_t f64_sqrt( float64_t a ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + bool signA; + int_fast16_t expA; + uint_fast64_t sigA, uiZ; + struct exp16_sig64 normExpSig; + int_fast16_t expZ; + uint32_t sig32A, recipSqrt32, sig32Z; + uint_fast64_t rem; + uint32_t q; + uint_fast64_t sigZ, shiftedSigZ; + union ui64_f64 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + signA = signF64UI( uiA ); + expA = expF64UI( uiA ); + sigA = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x7FF ) { + if ( sigA ) { + uiZ = softfloat_propagateNaNF64UI( uiA, 0 ); + goto uiZ; + } + if ( ! signA ) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( signA ) { + if ( ! (expA | sigA) ) return a; + goto invalid; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expA ) { + if ( ! sigA ) return a; + normExpSig = softfloat_normSubnormalF64Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + /*------------------------------------------------------------------------ + | (`sig32Z' is guaranteed to be a lower bound on the square root of + | `sig32A', which makes `sig32Z' also a lower bound on the square root of + | `sigA'.) + *------------------------------------------------------------------------*/ + expZ = ((expA - 0x3FF)>>1) + 0x3FE; + expA &= 1; + sigA |= UINT64_C( 0x0010000000000000 ); + sig32A = sigA>>21; + recipSqrt32 = softfloat_approxRecipSqrt32_1( expA, sig32A ); + sig32Z = ((uint_fast64_t) sig32A * recipSqrt32)>>32; + if ( expA ) { + sigA <<= 8; + sig32Z >>= 1; + } else { + sigA <<= 9; + } + rem = sigA - (uint_fast64_t) sig32Z * sig32Z; + q = ((uint32_t) (rem>>2) * (uint_fast64_t) recipSqrt32)>>32; + sigZ = ((uint_fast64_t) sig32Z<<32 | 1<<5) + ((uint_fast64_t) q<<3); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( (sigZ & 0x1FF) < 1<<5 ) { + sigZ &= ~(uint_fast64_t) 0x3F; + shiftedSigZ = sigZ>>6; + rem = (sigA<<52) - shiftedSigZ * shiftedSigZ; + if ( rem & UINT64_C( 0x8000000000000000 ) ) { + --sigZ; + } else { + if ( rem ) sigZ |= 1; + } + } + return softfloat_roundPackToF64( 0, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF64UI; + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f64_sub.c b/softfloat/f64_sub.c old mode 100755 new mode 100644 index 38bd574..0169ef8 --- a/softfloat/f64_sub.c +++ b/softfloat/f64_sub.c @@ -1,4 +1,39 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" @@ -13,7 +48,9 @@ float64_t f64_sub( float64_t a, float64_t b ) union ui64_f64 uB; uint_fast64_t uiB; bool signB; - float64_t ( *magsRoutine )( uint_fast64_t, uint_fast64_t, bool ); +#if ! defined INLINE_LEVEL || (INLINE_LEVEL < 2) + float64_t (*magsFuncPtr)( uint_fast64_t, uint_fast64_t, bool ); +#endif uA.f = a; uiA = uA.ui; @@ -21,9 +58,17 @@ float64_t f64_sub( float64_t a, float64_t b ) uB.f = b; uiB = uB.ui; signB = signF64UI( uiB ); - magsRoutine = - ( signA == signB ) ? softfloat_subMagsF64 : softfloat_addMagsF64; - return magsRoutine( uiA, uiB, signA ); +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) + if ( signA == signB ) { + return softfloat_subMagsF64( uiA, uiB, signA ); + } else { + return softfloat_addMagsF64( uiA, uiB, signA ); + } +#else + magsFuncPtr = + (signA == signB) ? softfloat_subMagsF64 : softfloat_addMagsF64; + return (*magsFuncPtr)( uiA, uiB, signA ); +#endif } diff --git a/softfloat/f64_to_f32.c b/softfloat/f64_to_f32.c old mode 100755 new mode 100644 index 395d6c6..c08b964 --- a/softfloat/f64_to_f32.c +++ b/softfloat/f64_to_f32.c @@ -1,43 +1,80 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t f64_to_f32( float64_t a ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t sig; - uint_fast32_t uiZ, sig32; - union ui32_f32 uZ; - - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - if ( exp == 0x7FF ) { - uiZ = - sig ? softfloat_commonNaNToF32UI( - softfloat_f64UIToCommonNaN( uiA ) ) - : packToF32UI( sign, 0xFF, 0 ); - goto uiZ; - } - sig32 = softfloat_shortShift64RightJam( sig, 22 ); - if ( ! ( exp | sig32 ) ) { - uiZ = packToF32UI( sign, 0, 0 ); - goto uiZ; - } - return softfloat_roundPackToF32( sign, exp - 0x381, sig32 | 0x40000000 ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float32_t f64_to_f32( float64_t a ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + bool sign; + int_fast16_t exp; + uint_fast64_t sig; + struct commonNaN commonNaN; + uint_fast32_t uiZ, sig32; + union ui32_f32 uZ; + + uA.f = a; + uiA = uA.ui; + sign = signF64UI( uiA ); + exp = expF64UI( uiA ); + sig = fracF64UI( uiA ); + if ( exp == 0x7FF ) { + if ( sig ) { + softfloat_f64UIToCommonNaN( uiA, &commonNaN ); + uiZ = softfloat_commonNaNToF32UI( &commonNaN ); + } else { + uiZ = packToF32UI( sign, 0xFF, 0 ); + } + goto uiZ; + } + sig32 = softfloat_shortShiftRightJam64( sig, 22 ); + if ( ! (exp | sig32) ) { + uiZ = packToF32UI( sign, 0, 0 ); + goto uiZ; + } + return softfloat_roundPackToF32( sign, exp - 0x381, sig32 | 0x40000000 ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/f64_to_i32.c b/softfloat/f64_to_i32.c old mode 100755 new mode 100644 index 0778a86..b41aac6 --- a/softfloat/f64_to_i32.c +++ b/softfloat/f64_to_i32.c @@ -1,30 +1,82 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -int_fast32_t f64_to_i32( float64_t a, int_fast8_t roundingMode, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftCount; - - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - if ( ( exp == 0x7FF ) && sig ) sign = 0; - if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftCount = 0x42C - exp; - if ( 0 < shiftCount ) sig = softfloat_shift64RightJam( sig, shiftCount ); - return softfloat_roundPackToI32( sign, sig, roundingMode, exact ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast32_t f64_to_i32( float64_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + bool sign; + int_fast16_t exp; + uint_fast64_t sig; + int_fast16_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF64UI( uiA ); + exp = expF64UI( uiA ); + sig = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (i32_fromNaN != i32_fromPosOverflow) || (i32_fromNaN != i32_fromNegOverflow) + if ( (exp == 0x7FF) && sig ) { +#if (i32_fromNaN == i32_fromPosOverflow) + sign = 0; +#elif (i32_fromNaN == i32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags( softfloat_flag_invalid ); + return i32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); + shiftDist = 0x42C - exp; + if ( 0 < shiftDist ) sig = softfloat_shiftRightJam64( sig, shiftDist ); + return softfloat_roundPackToI32( sign, sig, roundingMode, exact ); + +} + diff --git a/softfloat/f64_to_i32_r_minMag.c b/softfloat/f64_to_i32_r_minMag.c old mode 100755 new mode 100644 index 39246c2..ae3171e --- a/softfloat/f64_to_i32_r_minMag.c +++ b/softfloat/f64_to_i32_r_minMag.c @@ -1,50 +1,96 @@ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -int_fast32_t f64_to_i32_r_minMag( float64_t a, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - int_fast16_t exp; - uint_fast64_t sig; - bool sign; - int_fast16_t shiftCount; - uint_fast32_t absZ; - union { uint32_t ui; int32_t i; } uZ; - int_fast32_t z; - - uA.f = a; - uiA = uA.ui; - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - if ( exp < 0x3FF ) { - if ( exact && ( exp | sig ) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - sign = signF64UI( uiA ); - if ( 0x41E < exp ) { - if ( ( exp == 0x7FF ) && sig ) sign = 0; - goto invalid; - } - sig |= UINT64_C( 0x0010000000000000 ); - shiftCount = 0x433 - exp; - absZ = sig>>shiftCount; - uZ.ui = sign ? - absZ : absZ; - z = uZ.i; - if ( ( z < 0 ) != sign ) goto invalid; - if ( exact && ( (uint_fast64_t) absZ< +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast32_t f64_to_i32_r_minMag( float64_t a, bool exact ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + int_fast16_t exp; + uint_fast64_t sig; + int_fast16_t shiftDist; + bool sign; + int_fast32_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF64UI( uiA ); + sig = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if ( 53 <= shiftDist ) { + if ( exact && (exp | sig) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI( uiA ); + if ( shiftDist < 22 ) { + if ( + sign && (exp == 0x41E) && (sig < UINT64_C( 0x0000000000200000 )) + ) { + if ( exact && sig ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return -0x7FFFFFFF - 1; + } + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FF) && sig ? i32_fromNaN + : sign ? i32_fromNegOverflow : i32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig |= UINT64_C( 0x0010000000000000 ); + absZ = sig>>shiftDist; + if ( exact && ((uint_fast64_t) (uint_fast32_t) absZ< -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -int_fast64_t f64_to_i64( float64_t a, int_fast8_t roundingMode, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftCount; - struct uint64_extra sigExtra; - - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftCount = 0x433 - exp; - if ( shiftCount <= 0 ) { - if ( 0x43E < exp ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return - ! sign - || ( ( exp == 0x7FF ) - && fracF64UI( uiA ) ) - ? INT64_C( 0x7FFFFFFFFFFFFFFF ) - : - INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; - } - sigExtra.v = sig<<( - shiftCount ); - sigExtra.extra = 0; - } else { - sigExtra = softfloat_shift64ExtraRightJam( sig, 0, shiftCount ); - } - return - softfloat_roundPackToI64( - sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast64_t f64_to_i64( float64_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + bool sign; + int_fast16_t exp; + uint_fast64_t sig; + int_fast16_t shiftDist; +#ifdef SOFTFLOAT_FAST_INT64 + struct uint64_extra sigExtra; +#else + uint32_t extSig[3]; +#endif + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF64UI( uiA ); + exp = expF64UI( uiA ); + sig = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); + shiftDist = 0x433 - exp; +#ifdef SOFTFLOAT_FAST_INT64 + if ( shiftDist <= 0 ) { + if ( shiftDist < -11 ) goto invalid; + sigExtra.v = sig<<-shiftDist; + sigExtra.extra = 0; + } else { + sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); + } + return + softfloat_roundPackToI64( + sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); +#else + extSig[indexWord( 3, 0 )] = 0; + if ( shiftDist <= 0 ) { + if ( shiftDist < -11 ) goto invalid; + sig <<= -shiftDist; + extSig[indexWord( 3, 2 )] = sig>>32; + extSig[indexWord( 3, 1 )] = sig; + } else { + extSig[indexWord( 3, 2 )] = sig>>32; + extSig[indexWord( 3, 1 )] = sig; + softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); + } + return softfloat_roundPackMToI64( sign, extSig, roundingMode, exact ); +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FF) && fracF64UI( uiA ) ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + +} + diff --git a/softfloat/f64_to_i64_r_minMag.c b/softfloat/f64_to_i64_r_minMag.c old mode 100755 new mode 100644 index 525705b..003e165 --- a/softfloat/f64_to_i64_r_minMag.c +++ b/softfloat/f64_to_i64_r_minMag.c @@ -1,52 +1,100 @@ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -int_fast64_t f64_to_i64_r_minMag( float64_t a, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftCount; - int_fast64_t absZ; - - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - shiftCount = exp - 0x433; - if ( 0 <= shiftCount ) { - if ( 0x43E <= exp ) { - if ( uiA != packToF64UI( 1, 0x43E, 0 ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - if ( ! sign || ( ( exp == 0x7FF ) && sig ) ) { - return INT64_C( 0x7FFFFFFFFFFFFFFF ); - } - } - return - INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; - } - sig |= UINT64_C( 0x0010000000000000 ); - absZ = sig<>( - shiftCount ); - if ( exact && (uint64_t) ( sig<<( shiftCount & 63 ) ) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - } - return sign ? - absZ : absZ; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast64_t f64_to_i64_r_minMag( float64_t a, bool exact ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + bool sign; + int_fast16_t exp; + uint_fast64_t sig; + int_fast16_t shiftDist; + int_fast64_t absZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF64UI( uiA ); + exp = expF64UI( uiA ); + sig = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if ( shiftDist <= 0 ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( shiftDist < -10 ) { + if ( uiA == packToF64UI( 1, 0x43E, 0 ) ) { + return -INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1; + } + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FF) && sig ? i64_fromNaN + : sign ? i64_fromNegOverflow : i64_fromPosOverflow; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig |= UINT64_C( 0x0010000000000000 ); + absZ = sig<<-shiftDist; + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( 53 <= shiftDist ) { + if ( exact && (exp | sig) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + sig |= UINT64_C( 0x0010000000000000 ); + absZ = sig>>shiftDist; + if ( exact && (absZ< -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -uint_fast32_t f64_to_ui32( float64_t a, int_fast8_t roundingMode, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftCount; - - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftCount = 0x42C - exp; - if ( 0 < shiftCount ) sig = softfloat_shift64RightJam( sig, shiftCount ); - return softfloat_roundPackToUI32( sign, sig, roundingMode, exact ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast32_t f64_to_ui32( float64_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + bool sign; + int_fast16_t exp; + uint_fast64_t sig; + int_fast16_t shiftDist; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF64UI( uiA ); + exp = expF64UI( uiA ); + sig = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ +#if (ui32_fromNaN != ui32_fromPosOverflow) || (ui32_fromNaN != ui32_fromNegOverflow) + if ( (exp == 0x7FF) && sig ) { +#if (ui32_fromNaN == ui32_fromPosOverflow) + sign = 0; +#elif (ui32_fromNaN == ui32_fromNegOverflow) + sign = 1; +#else + softfloat_raiseFlags( softfloat_flag_invalid ); + return ui32_fromNaN; +#endif + } +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); + shiftDist = 0x42C - exp; + if ( 0 < shiftDist ) sig = softfloat_shiftRightJam64( sig, shiftDist ); + return softfloat_roundPackToUI32( sign, sig, roundingMode, exact ); + +} + diff --git a/softfloat/f64_to_ui32_r_minMag.c b/softfloat/f64_to_ui32_r_minMag.c old mode 100755 new mode 100644 index 9f1dd4d..8d0dc71 --- a/softfloat/f64_to_ui32_r_minMag.c +++ b/softfloat/f64_to_ui32_r_minMag.c @@ -1,40 +1,88 @@ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -uint_fast32_t f64_to_ui32_r_minMag( float64_t a, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftCount; - uint_fast32_t z; - - uA.f = a; - uiA = uA.ui; - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - if ( exp < 0x3FF ) { - if ( exact && ( exp | sig ) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - if ( signF64UI( uiA ) || ( 0x41E < exp ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return 0xFFFFFFFF; - } - sig |= UINT64_C( 0x0010000000000000 ); - shiftCount = 0x433 - exp; - z = sig>>shiftCount; - if ( exact && ( (uint_fast64_t) z< +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast32_t f64_to_ui32_r_minMag( float64_t a, bool exact ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + int_fast16_t exp; + uint_fast64_t sig; + int_fast16_t shiftDist; + bool sign; + uint_fast32_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF64UI( uiA ); + sig = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if ( 53 <= shiftDist ) { + if ( exact && (exp | sig) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI( uiA ); + if ( sign || (shiftDist < 21) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FF) && sig ? ui32_fromNaN + : sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sig |= UINT64_C( 0x0010000000000000 ); + z = sig>>shiftDist; + if ( exact && ((uint_fast64_t) z< -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -uint_fast64_t f64_to_ui64( float64_t a, int_fast8_t roundingMode, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - bool sign; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftCount; - struct uint64_extra sigExtra; - - uA.f = a; - uiA = uA.ui; - sign = signF64UI( uiA ); - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); - shiftCount = 0x433 - exp; - if ( shiftCount <= 0 ) { - if ( 0x43E < exp ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); - } - sigExtra.v = sig<<( - shiftCount ); - sigExtra.extra = 0; - } else { - sigExtra = softfloat_shift64ExtraRightJam( sig, 0, shiftCount ); - } - return - softfloat_roundPackToUI64( - sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast64_t f64_to_ui64( float64_t a, uint_fast8_t roundingMode, bool exact ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + bool sign; + int_fast16_t exp; + uint_fast64_t sig; + int_fast16_t shiftDist; +#ifdef SOFTFLOAT_FAST_INT64 + struct uint64_extra sigExtra; +#else + uint32_t extSig[3]; +#endif + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + sign = signF64UI( uiA ); + exp = expF64UI( uiA ); + sig = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( exp ) sig |= UINT64_C( 0x0010000000000000 ); + shiftDist = 0x433 - exp; +#ifdef SOFTFLOAT_FAST_INT64 + if ( shiftDist <= 0 ) { + if ( shiftDist < -11 ) goto invalid; + sigExtra.v = sig<<-shiftDist; + sigExtra.extra = 0; + } else { + sigExtra = softfloat_shiftRightJam64Extra( sig, 0, shiftDist ); + } + return + softfloat_roundPackToUI64( + sign, sigExtra.v, sigExtra.extra, roundingMode, exact ); +#else + extSig[indexWord( 3, 0 )] = 0; + if ( shiftDist <= 0 ) { + if ( shiftDist < -11 ) goto invalid; + sig <<= -shiftDist; + extSig[indexWord( 3, 2 )] = sig>>32; + extSig[indexWord( 3, 1 )] = sig; + } else { + extSig[indexWord( 3, 2 )] = sig>>32; + extSig[indexWord( 3, 1 )] = sig; + softfloat_shiftRightJam96M( extSig, shiftDist, extSig ); + } + return softfloat_roundPackMToUI64( sign, extSig, roundingMode, exact ); +#endif + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FF) && fracF64UI( uiA ) ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + +} + diff --git a/softfloat/f64_to_ui64_r_minMag.c b/softfloat/f64_to_ui64_r_minMag.c old mode 100755 new mode 100644 index a66d3ff..e54c930 --- a/softfloat/f64_to_ui64_r_minMag.c +++ b/softfloat/f64_to_ui64_r_minMag.c @@ -1,45 +1,93 @@ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -uint_fast64_t f64_to_ui64_r_minMag( float64_t a, bool exact ) -{ - union ui64_f64 uA; - uint_fast64_t uiA; - int_fast16_t exp; - uint_fast64_t sig; - int_fast16_t shiftCount; - uint_fast64_t z; - - uA.f = a; - uiA = uA.ui; - exp = expF64UI( uiA ); - sig = fracF64UI( uiA ); - if ( exp < 0x3FF ) { - if ( exact && ( exp | sig ) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - return 0; - } - if ( signF64UI( uiA ) ) goto invalid; - shiftCount = exp - 0x433; - if ( 0 <= shiftCount ) { - if ( 0x43E < exp ) goto invalid; - z = ( sig | UINT64_C( 0x0010000000000000 ) )<>( - shiftCount ); - if ( exact && (uint64_t) ( sig<<( shiftCount & 63 ) ) ) { - softfloat_exceptionFlags |= softfloat_flag_inexact; - } - } - return z; - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast64_t f64_to_ui64_r_minMag( float64_t a, bool exact ) +{ + union ui64_f64 uA; + uint_fast64_t uiA; + int_fast16_t exp; + uint_fast64_t sig; + int_fast16_t shiftDist; + bool sign; + uint_fast64_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + uA.f = a; + uiA = uA.ui; + exp = expF64UI( uiA ); + sig = fracF64UI( uiA ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + shiftDist = 0x433 - exp; + if ( 53 <= shiftDist ) { + if ( exact && (exp | sig) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return 0; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + sign = signF64UI( uiA ); + if ( sign ) goto invalid; + if ( shiftDist <= 0 ) { + if ( shiftDist < -11 ) goto invalid; + z = (sig | UINT64_C( 0x0010000000000000 ))<<-shiftDist; + } else { + sig |= UINT64_C( 0x0010000000000000 ); + z = sig>>shiftDist; + if ( exact && (uint64_t) (sig<<(-shiftDist & 63)) ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + } + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return + (exp == 0x7FF) && sig ? ui64_fromNaN + : sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + +} + diff --git a/softfloat/i32_to_f32.c b/softfloat/i32_to_f32.c old mode 100755 new mode 100644 index f51facd..bfe8ace --- a/softfloat/i32_to_f32.c +++ b/softfloat/i32_to_f32.c @@ -1,21 +1,58 @@ - -#include -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float32_t i32_to_f32( int_fast32_t a ) -{ - bool sign; - union ui32_f32 uZ; - - sign = ( a < 0 ); - if ( ! ( a & 0x7FFFFFFF ) ) { - uZ.ui = sign ? packToF32UI( 1, 0x9E, 0 ) : 0; - return uZ.f; - } - return softfloat_normRoundPackToF32( sign, 0x9C, sign ? - a : a ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float32_t i32_to_f32( int32_t a ) +{ + bool sign; + union ui32_f32 uZ; + uint_fast32_t absA; + + sign = (a < 0); + if ( ! (a & 0x7FFFFFFF) ) { + uZ.ui = sign ? packToF32UI( 1, 0x9E, 0 ) : 0; + return uZ.f; + } + absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a; + return softfloat_normRoundPackToF32( sign, 0x9C, absA ); + +} + diff --git a/softfloat/i32_to_f64.c b/softfloat/i32_to_f64.c old mode 100755 new mode 100644 index d42cbe8..ac17f78 --- a/softfloat/i32_to_f64.c +++ b/softfloat/i32_to_f64.c @@ -1,31 +1,65 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -float64_t i32_to_f64( int_fast32_t a ) -{ - uint_fast64_t uiZ; - bool sign; - uint_fast32_t absA; - int shiftCount; - union ui64_f64 uZ; - - if ( ! a ) { - uiZ = 0; - } else { - sign = ( a < 0 ); - absA = sign ? - a : a; - shiftCount = softfloat_countLeadingZeros32( absA ) + 21; - uiZ = - packToF64UI( - sign, 0x432 - shiftCount, (uint_fast64_t) absA< +#include +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float64_t i32_to_f64( int32_t a ) +{ + uint_fast64_t uiZ; + bool sign; + uint_fast32_t absA; + int_fast8_t shiftCount; + union ui64_f64 uZ; + + if ( ! a ) { + uiZ = 0; + } else { + sign = (a < 0); + absA = sign ? -(uint_fast32_t) a : (uint_fast32_t) a; + shiftCount = softfloat_countLeadingZeros32( absA ) + 21; + uiZ = + packToF64UI( + sign, 0x432 - shiftCount, (uint_fast64_t) absA< -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -float32_t i64_to_f32( int_fast64_t a ) -{ - bool sign; - uint_fast64_t absA; - int shiftCount; - union ui32_f32 u; - uint_fast32_t sig; - - sign = ( a < 0 ); - absA = sign ? - (uint_fast64_t) a : a; - shiftCount = softfloat_countLeadingZeros64( absA ) - 40; - if ( 0 <= shiftCount ) { - u.ui = - a ? packToF32UI( - sign, 0x95 - shiftCount, (uint_fast32_t) absA< +#include +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float32_t i64_to_f32( int64_t a ) +{ + bool sign; + uint_fast64_t absA; + int_fast8_t shiftCount; + union ui32_f32 u; + uint_fast32_t sig; + + sign = (a < 0); + absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a; + shiftCount = softfloat_countLeadingZeros64( absA ) - 40; + if ( 0 <= shiftCount ) { + u.ui = + a ? packToF32UI( + sign, 0x95 - shiftCount, (uint_fast32_t) absA< -#include -#include "platform.h" -#include "internals.h" -#include "softfloat.h" - -float64_t i64_to_f64( int_fast64_t a ) -{ - bool sign; - union ui64_f64 uZ; - - sign = ( a < 0 ); - if ( ! ( a & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) ) { - uZ.ui = sign ? packToF64UI( 1, 0x43E, 0 ) : 0; - return uZ.f; - } - return softfloat_normRoundPackToF64( sign, 0x43C, sign ? - a : a ); - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float64_t i64_to_f64( int64_t a ) +{ + bool sign; + union ui64_f64 uZ; + uint_fast64_t absA; + + sign = (a < 0); + if ( ! (a & UINT64_C( 0x7FFFFFFFFFFFFFFF )) ) { + uZ.ui = sign ? packToF64UI( 1, 0x43E, 0 ) : 0; + return uZ.f; + } + absA = sign ? -(uint_fast64_t) a : (uint_fast64_t) a; + return softfloat_normRoundPackToF64( sign, 0x43C, absA ); + +} + diff --git a/softfloat/internals.h b/softfloat/internals.h old mode 100755 new mode 100644 index 5e6fd76..cf57bdc --- a/softfloat/internals.h +++ b/softfloat/internals.h @@ -1,232 +1,259 @@ - -/*** UPDATE COMMENTS. ***/ - -#include "softfloat_types.h" - -union ui32_f32 { uint32_t ui; float32_t f; }; -union ui64_f64 { uint64_t ui; float64_t f; }; -#ifdef LITTLEENDIAN -union ui128_f128 { uint64_t ui0, ui64; float128_t f; }; -#else -union ui128_f128 { uint64_t ui64, ui0; float128_t f; }; -#endif - -enum { - softfloat_mulAdd_subC = 1, - softfloat_mulAdd_subProd = 2 -}; - -uint_fast32_t - softfloat_roundPackToUI32( bool, uint_fast64_t, int_fast8_t, bool ); -uint_fast64_t - softfloat_roundPackToUI64( - bool, uint_fast64_t, uint_fast64_t, int_fast8_t, bool ); -/*---------------------------------------------------------------------------- -| Takes a 64-bit fixed-point value `absZ' with binary point between bits 6 -| and 7, and returns the properly rounded 32-bit integer corresponding to the -| input. If `zSign' is 1, the input is negated before being converted to an -| integer. Bit 63 of `absZ' must be zero. Ordinarily, the fixed-point input -| is simply rounded to an integer, with the inexact exception raised if the -| input cannot be represented exactly as an integer. However, if the fixed- -| point input is too large, the invalid exception is raised and the largest -| positive or negative integer is returned. -*----------------------------------------------------------------------------*/ -int_fast32_t - softfloat_roundPackToI32( bool, uint_fast64_t, int_fast8_t, bool ); -/*---------------------------------------------------------------------------- -| Takes the 128-bit fixed-point value formed by concatenating `absZ0' and -| `absZ1', with binary point between bits 63 and 64 (between the input words), -| and returns the properly rounded 64-bit integer corresponding to the input. -| If `zSign' is 1, the input is negated before being converted to an integer. -| Ordinarily, the fixed-point input is simply rounded to an integer, with -| the inexact exception raised if the input cannot be represented exactly as -| an integer. However, if the fixed-point input is too large, the invalid -| exception is raised and the largest positive or negative integer is -| returned. -*----------------------------------------------------------------------------*/ -int_fast64_t - softfloat_roundPackToI64( - bool, uint_fast64_t, uint_fast64_t, int_fast8_t, bool ); - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is a NaN; -| otherwise, returns 0. -*----------------------------------------------------------------------------*/ -#define isNaNF32UI( ui ) (0xFF000000<(uint32_t)((uint_fast32_t)(ui)<<1)) -/*---------------------------------------------------------------------------- -| Returns the sign bit of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ -#define signF32UI( a ) ((bool)((uint32_t)(a)>>31)) -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ -#define expF32UI( a ) ((int_fast16_t)((a)>>23)&0xFF) -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the single-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ -#define fracF32UI( a ) ((a)&0x007FFFFF) -/*---------------------------------------------------------------------------- -| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a -| single-precision floating-point value, returning the result. After being -| shifted into the proper positions, the three fields are simply added -| together to form the result. This means that any integer portion of `zSig' -| will be added into the exponent. Since a properly normalized significand -| will have an integer portion equal to 1, the `zExp' input should be 1 less -| than the desired result exponent whenever `zSig' is a complete, normalized -| significand. -*----------------------------------------------------------------------------*/ -#define packToF32UI( sign, exp, sig ) (((uint32_t)(sign)<<31)+((uint32_t)(exp)<<23)+(sig)) - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal single-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ -struct exp16_sig32 { int_fast16_t exp; uint_fast32_t sig; }; -struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t ); - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper single-precision floating- -| point value corresponding to the abstract input. Ordinarily, the abstract -| value is simply rounded and packed into the single-precision format, with -| the inexact exception raised if the abstract input cannot be represented -| exactly. However, if the abstract value is too large, the overflow and -| inexact exceptions are raised and an infinity or maximal finite value is -| returned. If the abstract value is too small, the input value is rounded to -| a subnormal number, and the underflow and inexact exceptions are raised if -| the abstract input cannot be represented exactly as a subnormal single- -| precision floating-point number. -| The input significand `zSig' has its binary point between bits 30 -| and 29, which is 7 bits to the left of the usual location. This shifted -| significand must be normalized or smaller. If `zSig' is not normalized, -| `zExp' must be 0; in that case, the result returned is a subnormal number, -| and it must not require rounding. In the usual case that `zSig' is -| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent. -| The handling of underflow and overflow follows the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ -float32_t softfloat_roundPackToF32( bool, int_fast16_t, uint_fast32_t ); -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper single-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat32' except that `zSig' does not have to be normalized. -| Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ -float32_t softfloat_normRoundPackToF32( bool, int_fast16_t, uint_fast32_t ); - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the single-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ -float32_t softfloat_addMagsF32( uint_fast32_t, uint_fast32_t, bool ); -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the single- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ -float32_t softfloat_subMagsF32( uint_fast32_t, uint_fast32_t, bool ); -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -float32_t - softfloat_mulAddF32( int, uint_fast32_t, uint_fast32_t, uint_fast32_t ); - -/*---------------------------------------------------------------------------- -| Returns 1 if the double-precision floating-point value `a' is a NaN; -| otherwise, returns 0. -*----------------------------------------------------------------------------*/ -#define isNaNF64UI( ui ) (UINT64_C(0xFFE0000000000000)<(uint64_t)((uint_fast64_t)(ui)<<1)) -/*---------------------------------------------------------------------------- -| Returns the sign bit of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ -#define signF64UI( a ) ((bool)((uint64_t)(a)>>63)) -/*---------------------------------------------------------------------------- -| Returns the exponent bits of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ -#define expF64UI( a ) ((int_fast16_t)((a)>>52)&0x7FF) -/*---------------------------------------------------------------------------- -| Returns the fraction bits of the double-precision floating-point value `a'. -*----------------------------------------------------------------------------*/ -#define fracF64UI( a ) ((a)&UINT64_C(0x000FFFFFFFFFFFFF)) -/*---------------------------------------------------------------------------- -| Packs the sign `zSign', exponent `zExp', and significand `zSig' into a -| double-precision floating-point value, returning the result. After being -| shifted into the proper positions, the three fields are simply added -| together to form the result. This means that any integer portion of `zSig' -| will be added into the exponent. Since a properly normalized significand -| will have an integer portion equal to 1, the `zExp' input should be 1 less -| than the desired result exponent whenever `zSig' is a complete, normalized -| significand. -*----------------------------------------------------------------------------*/ -#define packToF64UI( sign, exp, sig ) (((uint64_t)(sign)<<63)+((uint64_t)(exp)<<52)+(sig)) - -/*---------------------------------------------------------------------------- -| Normalizes the subnormal double-precision floating-point value represented -| by the denormalized significand `aSig'. The normalized exponent and -| significand are stored at the locations pointed to by `zExpPtr' and -| `zSigPtr', respectively. -*----------------------------------------------------------------------------*/ -struct exp16_sig64 { int_fast16_t exp; uint_fast64_t sig; }; -struct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t ); - -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper double-precision floating- -| point value corresponding to the abstract input. Ordinarily, the abstract -| value is simply rounded and packed into the double-precision format, with -| the inexact exception raised if the abstract input cannot be represented -| exactly. However, if the abstract value is too large, the overflow and -| inexact exceptions are raised and an infinity or maximal finite value is -| returned. If the abstract value is too small, the input value is rounded -| to a subnormal number, and the underflow and inexact exceptions are raised -| if the abstract input cannot be represented exactly as a subnormal double- -| precision floating-point number. -| The input significand `zSig' has its binary point between bits 62 -| and 61, which is 10 bits to the left of the usual location. This shifted -| significand must be normalized or smaller. If `zSig' is not normalized, -| `zExp' must be 0; in that case, the result returned is a subnormal number, -| and it must not require rounding. In the usual case that `zSig' is -| normalized, `zExp' must be 1 less than the ``true'' floating-point exponent. -| The handling of underflow and overflow follows the IEC/IEEE Standard for -| Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ -float64_t softfloat_roundPackToF64( bool, int_fast16_t, uint_fast64_t ); -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent `zExp', -| and significand `zSig', and returns the proper double-precision floating- -| point value corresponding to the abstract input. This routine is just like -| `roundAndPackFloat64' except that `zSig' does not have to be normalized. -| Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true'' -| floating-point exponent. -*----------------------------------------------------------------------------*/ -float64_t softfloat_normRoundPackToF64( bool, int_fast16_t, uint_fast64_t ); - -/*---------------------------------------------------------------------------- -| Returns the result of adding the absolute values of the double-precision -| floating-point values `a' and `b'. If `zSign' is 1, the sum is negated -| before being returned. `zSign' is ignored if the result is a NaN. -| The addition is performed according to the IEC/IEEE Standard for Binary -| Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ -float64_t softfloat_addMagsF64( uint_fast64_t, uint_fast64_t, bool ); -/*---------------------------------------------------------------------------- -| Returns the result of subtracting the absolute values of the double- -| precision floating-point values `a' and `b'. If `zSign' is 1, the -| difference is negated before being returned. `zSign' is ignored if the -| result is a NaN. The subtraction is performed according to the IEC/IEEE -| Standard for Binary Floating-Point Arithmetic. -*----------------------------------------------------------------------------*/ -float64_t softfloat_subMagsF64( uint_fast64_t, uint_fast64_t, bool ); -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -float64_t - softfloat_mulAddF64( int, uint_fast64_t, uint_fast64_t, uint_fast64_t ); - + +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#ifndef internals_h +#define internals_h 1 + +#include +#include +#include "primitives.h" +#include "softfloat_types.h" + +union ui32_f32 { uint32_t ui; float32_t f; }; +union ui64_f64 { uint64_t ui; float64_t f; }; + +#ifdef SOFTFLOAT_FAST_INT64 +union extF80M_extF80 { struct extFloat80M fM; extFloat80_t f; }; +union ui128_f128 { struct uint128 ui; float128_t f; }; +#endif + +enum { + softfloat_mulAdd_subC = 1, + softfloat_mulAdd_subProd = 2 +}; + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ +uint_fast32_t + softfloat_roundPackToUI32( bool, uint_fast64_t, uint_fast8_t, bool ); + +#ifdef SOFTFLOAT_FAST_INT64 +uint_fast64_t + softfloat_roundPackToUI64( + bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool ); +#else +uint_fast64_t + softfloat_roundPackMToUI64( bool, uint32_t *, uint_fast8_t, bool ); +#endif + +int_fast32_t + softfloat_roundPackToI32( bool, uint_fast64_t, uint_fast8_t, bool ); + +#ifdef SOFTFLOAT_FAST_INT64 +int_fast64_t + softfloat_roundPackToI64( + bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool ); +#else +int_fast64_t softfloat_roundPackMToI64( bool, uint32_t *, uint_fast8_t, bool ); +#endif + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ +#define signF32UI( a ) ((bool) ((uint32_t) (a)>>31)) +#define expF32UI( a ) ((int_fast16_t) ((a)>>23) & 0xFF) +#define fracF32UI( a ) ((a) & 0x007FFFFF) +#define packToF32UI( sign, exp, sig ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig)) + +#define isNaNF32UI( a ) ((((a) & 0x7F800000) == 0x7F800000) && ((a) & 0x007FFFFF)) + +struct exp16_sig32 { int_fast16_t exp; uint_fast32_t sig; }; +struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t ); + +float32_t softfloat_roundPackToF32( bool, int_fast16_t, uint_fast32_t ); +float32_t softfloat_normRoundPackToF32( bool, int_fast16_t, uint_fast32_t ); + +float32_t softfloat_addMagsF32( uint_fast32_t, uint_fast32_t, bool ); +float32_t softfloat_subMagsF32( uint_fast32_t, uint_fast32_t, bool ); +float32_t + softfloat_mulAddF32( + uint_fast32_t, uint_fast32_t, uint_fast32_t, uint_fast8_t ); + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ +#define signF64UI( a ) ((bool) ((uint64_t) (a)>>63)) +#define expF64UI( a ) ((int_fast16_t) ((a)>>52) & 0x7FF) +#define fracF64UI( a ) ((a) & UINT64_C( 0x000FFFFFFFFFFFFF )) +#define packToF64UI( sign, exp, sig ) ((uint64_t) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<52) + (sig))) + +#define isNaNF64UI( a ) ((((a) & UINT64_C( 0x7FF0000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((a) & UINT64_C( 0x000FFFFFFFFFFFFF ))) + +struct exp16_sig64 { int_fast16_t exp; uint_fast64_t sig; }; +struct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t ); + +float64_t softfloat_roundPackToF64( bool, int_fast16_t, uint_fast64_t ); +float64_t softfloat_normRoundPackToF64( bool, int_fast16_t, uint_fast64_t ); + +float64_t softfloat_addMagsF64( uint_fast64_t, uint_fast64_t, bool ); +float64_t softfloat_subMagsF64( uint_fast64_t, uint_fast64_t, bool ); +float64_t + softfloat_mulAddF64( + uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t ); + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ +#define signExtF80UI64( a64 ) ((bool) ((uint16_t) (a64)>>15)) +#define expExtF80UI64( a64 ) ((a64) & 0x7FFF) +#define packToExtF80UI64( sign, exp ) ((uint_fast16_t) (sign)<<15 | (exp)) + +#define isNaNExtF80UI( a64, a0 ) ((((a64) & 0x7FFF) == 0x7FFF) && ((a0) & UINT64_C( 0x7FFFFFFFFFFFFFFF ))) + +#ifdef SOFTFLOAT_FAST_INT64 + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ + +struct exp32_sig64 { int_fast32_t exp; uint64_t sig; }; +struct exp32_sig64 softfloat_normSubnormalExtF80Sig( uint_fast64_t ); + +extFloat80_t + softfloat_roundPackToExtF80( + bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t ); +extFloat80_t + softfloat_normRoundPackToExtF80( + bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast8_t ); + +extFloat80_t + softfloat_addMagsExtF80( + uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool ); +extFloat80_t + softfloat_subMagsExtF80( + uint_fast16_t, uint_fast64_t, uint_fast16_t, uint_fast64_t, bool ); + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ +#define signF128UI64( a64 ) ((bool) ((uint64_t) (a64)>>63)) +#define expF128UI64( a64 ) ((int_fast32_t) ((a64)>>48) & 0x7FFF) +#define fracF128UI64( a64 ) ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF )) +#define packToF128UI64( sign, exp, sig64 ) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<48) + (sig64)) + +#define isNaNF128UI( a64, a0 ) ((((a64) & UINT64_C( 0x7FFF000000000000 )) == UINT64_C( 0x7FFF000000000000 )) && (a0 || ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF )))) + +struct exp32_sig128 { int_fast32_t exp; struct uint128 sig; }; +struct exp32_sig128 + softfloat_normSubnormalF128Sig( uint_fast64_t, uint_fast64_t ); + +float128_t + softfloat_roundPackToF128( + bool, int_fast32_t, uint_fast64_t, uint_fast64_t, uint_fast64_t ); +float128_t + softfloat_normRoundPackToF128( + bool, int_fast32_t, uint_fast64_t, uint_fast64_t ); + +float128_t + softfloat_addMagsF128( + uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool ); +float128_t + softfloat_subMagsF128( + uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool ); +float128_t + softfloat_mulAddF128( + uint_fast64_t, + uint_fast64_t, + uint_fast64_t, + uint_fast64_t, + uint_fast64_t, + uint_fast64_t, + uint_fast8_t + ); + +#else + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ + +bool + softfloat_tryPropagateNaNExtF80M( + const struct extFloat80M *, + const struct extFloat80M *, + struct extFloat80M * + ); +void softfloat_invalidExtF80M( struct extFloat80M * ); + +int softfloat_normExtF80SigM( uint64_t * ); + +void + softfloat_roundPackMToExtF80M( + bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * ); +void + softfloat_normRoundPackMToExtF80M( + bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * ); + +void + softfloat_addExtF80M( + const struct extFloat80M *, + const struct extFloat80M *, + struct extFloat80M *, + bool + ); + +int + softfloat_compareNonnormExtF80M( + const struct extFloat80M *, const struct extFloat80M * ); + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ +#define signF128UI96( a96 ) ((bool) ((uint32_t) (a96)>>31)) +#define expF128UI96( a96 ) ((int32_t) ((a96)>>16) & 0x7FFF) +#define fracF128UI96( a96 ) ((a96) & 0x0000FFFF) +#define packToF128UI96( sign, exp, sig96 ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<16) + (sig96)) + +bool softfloat_isNaNF128M( const uint32_t * ); + +bool + softfloat_tryPropagateNaNF128M( + const uint32_t *, const uint32_t *, uint32_t * ); +void softfloat_invalidF128M( uint32_t * ); + +int softfloat_shiftNormSigF128M( const uint32_t *, uint_fast8_t, uint32_t * ); + +void softfloat_roundPackMToF128M( bool, int32_t, uint32_t *, uint32_t * ); +void softfloat_normRoundPackMToF128M( bool, int32_t, uint32_t *, uint32_t * ); + +void + softfloat_addF128M( const uint32_t *, const uint32_t *, uint32_t *, bool ); +void + softfloat_mulAddF128M( + const uint32_t *, + const uint32_t *, + const uint32_t *, + uint32_t *, + uint_fast8_t + ); + +#endif + +#endif + diff --git a/softfloat/platform.h b/softfloat/platform.h old mode 100755 new mode 100644 index 6c54313..3d9c431 --- a/softfloat/platform.h +++ b/softfloat/platform.h @@ -1,42 +1,48 @@ /*============================================================================ -*** FIX. - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================*/ /*---------------------------------------------------------------------------- *----------------------------------------------------------------------------*/ -#define LITTLEENDIAN +#define LITTLEENDIAN 1 + +#define INLINE_LEVEL 5 +#define SOFTFLOAT_FAST_INT64 +#define SOFTFLOAT_FAST_DIV64TO32 + +/*---------------------------------------------------------------------------- +*----------------------------------------------------------------------------*/ +#define INLINE extern inline -#ifndef UINT64_C -# define UINT64_C(x) (x ## ULL) -# define INT64_C(x) (x ## LL) -#endif diff --git a/softfloat/primitiveTypes.h b/softfloat/primitiveTypes.h new file mode 100644 index 0000000..b112049 --- /dev/null +++ b/softfloat/primitiveTypes.h @@ -0,0 +1,86 @@ + +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#ifndef primitiveTypes_h +#define primitiveTypes_h 1 + +#include +#include "platform.h" + +#ifdef SOFTFLOAT_FAST_INT64 + +#ifdef LITTLEENDIAN +struct uint128 { uint64_t v0, v64; }; +struct uint64_extra { uint64_t extra, v; }; +struct uint128_extra { uint64_t extra; struct uint128 v; }; +#else +struct uint128 { uint64_t v64, v0; }; +struct uint64_extra { uint64_t v, extra; }; +struct uint128_extra { struct uint128 v; uint64_t extra; }; +#endif + +#endif + +/*---------------------------------------------------------------------------- +| These macros are used to isolate the differences in word order between big- +| endian and little-endian platforms. +*----------------------------------------------------------------------------*/ +#ifdef LITTLEENDIAN +#define wordIncr 1 +#define indexWord( total, n ) (n) +#define indexWordHi( total ) ((total) - 1) +#define indexWordLo( total ) 0 +#define indexMultiword( total, m, n ) (n) +#define indexMultiwordHi( total, n ) ((total) - (n)) +#define indexMultiwordLo( total, n ) 0 +#define indexMultiwordHiBut( total, n ) (n) +#define indexMultiwordLoBut( total, n ) 0 +#define INIT_UINTM4( v3, v2, v1, v0 ) { v0, v1, v2, v3 } +#else +#define wordIncr -1 +#define indexWord( total, n ) ((total) - 1 - (n)) +#define indexWordHi( total ) 0 +#define indexWordLo( total ) ((total) - 1) +#define indexMultiword( total, m, n ) ((total) - 1 - (m)) +#define indexMultiwordHi( total, n ) 0 +#define indexMultiwordLo( total, n ) ((total) - (n)) +#define indexMultiwordHiBut( total, n ) 0 +#define indexMultiwordLoBut( total, n ) (n) +#define INIT_UINTM4( v3, v2, v1, v0 ) { v3, v2, v1, v0 } +#endif + +#endif + diff --git a/softfloat/primitives.h b/softfloat/primitives.h old mode 100755 new mode 100644 index 71038ea..a193555 --- a/softfloat/primitives.h +++ b/softfloat/primitives.h @@ -1,628 +1,1143 @@ /*============================================================================ -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 3. - -*** UPDATE - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. -=============================================================================*/ +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. -#include -#include +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: -/*** CHANGE TO USE `fast' INTEGER TYPES? ***/ -/*** ADD 80-BIT FUNCTIONS? ***/ + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. -#ifdef LITTLEENDIAN -struct uintx80 { uint64_t v0; uint16_t v64; }; -struct uint128 { uint64_t v0, v64; }; -struct uint192 { uint64_t v0, v64, v128; }; -struct uint256 { uint64_t v0, v64, v128, v192; }; -#else -struct uintx80 { uint16_t v64; uint64_t v0; }; -struct uint128 { uint64_t v64, v0; }; -struct uint192 { uint64_t v128, v64, v0; }; -struct uint256 { uint64_t v256, v128, v64, v0; }; -#endif + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. -struct uint64_extra { uint64_t v, extra; }; -struct uint128_extra { uint64_t v64; uint64_t v0; uint64_t extra; }; +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +=============================================================================*/ + +#ifndef primitives_h +#define primitives_h 1 -/*** SHIFT COUNTS CANNOT BE ZERO. MUST CHECK BEFORE CALLING! ***/ +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +#include "primitiveTypes.h" +#ifndef softfloat_shortShiftRightJam64 /*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' -| is equal to the 128-bit value formed by concatenating `b0' and `b1'. -| Otherwise, returns 0. +| Shifts `a' right by the number of bits given in `count', which must be in +| the range 1 to 63. If any nonzero bits are shifted off, they are "jammed" +| into the least-significant bit of the shifted value by setting the least- +| significant bit to 1. This shifted-and-jammed value is returned. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 1 <= INLINE_LEVEL ) -INLINE bool - softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) - { return ( a64 == b64 ) && ( a0 == b0 ); } +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) +INLINE + uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t count ) + { return a>>count | ((a & (((uint_fast64_t) 1<>count | ((uint32_t) (a<<(-count & 31)) != 0) + : (a != 0); +} #else -bool softfloat_le128( uint64_t, uint64_t, uint64_t, uint64_t ); +uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t count ); +#endif #endif +#ifndef softfloat_shiftRightJam64 /*---------------------------------------------------------------------------- -| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less -| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise, -| returns 0. +| Shifts `a' right by the number of bits given in `count', which must not +| be zero. If any nonzero bits are shifted off, they are "jammed" into the +| least-significant bit of the shifted value by setting the least-significant +| bit to 1. This shifted-and-jammed value is returned. +| The value of `count' can be arbitrarily large. In particular, if `count' +| is greater than 64, the result will be either 0 or 1, depending on whether +| `a' is zero or nonzero. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 1 <= INLINE_LEVEL ) -INLINE bool - softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) - { return ( a64 < b64 ) || ( ( a64 == b64 ) && ( a0 < b0 ) ); } +#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) +INLINE uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t count ) +{ + return + (count < 63) ? a>>count | ((uint64_t) (a<<(-count & 63)) != 0) + : (a != 0); +} #else -bool softfloat_lt128( uint64_t, uint64_t, uint64_t, uint64_t ); +uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t count ); +#endif #endif /*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the -| number of bits given in `count'. Any bits shifted off are lost. The value -| of `count' must be less than 64. The result is broken into two 64-bit -| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +| A constant table that translates an 8-bit unsigned integer (the array index) +| into the number of leading 0 bits before the most-significant 1 of that +| integer. For integer zero (index 0), the corresponding table element is 8. +*----------------------------------------------------------------------------*/ +extern const uint_least8_t softfloat_countLeadingZeros8[256]; + +#ifndef softfloat_countLeadingZeros32 +/*---------------------------------------------------------------------------- +| Returns the number of leading 0 bits before the most-significant 1 bit of +| `a'. If `a' is zero, 32 is returned. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL ) -INLINE struct uint128 - softfloat_shortShift128Left( uint64_t a64, uint64_t a0, unsigned int count ) +#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) +INLINE uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ) { - struct uint128 z; - z.v64 = a64<>( ( - count ) & 63 ); - z.v0 = a0<>24]; + return count; } #else -struct uint128 softfloat_shortShift128Left( uint64_t, uint64_t, unsigned int ); +uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ); +#endif #endif +#ifndef softfloat_countLeadingZeros64 /*---------------------------------------------------------------------------- -| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left -| by the number of bits given in `count'. Any bits shifted off are lost. -| The value of `count' must be less than 64. The result is broken into three -| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', -| `z1Ptr', and `z2Ptr'. +| Returns the number of leading 0 bits before the most-significant 1 bit of +| `a'. If `a' is zero, 64 is returned. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 3 <= INLINE_LEVEL ) -INLINE struct uint192 - softfloat_shortShift192Left( - uint64_t a128, uint64_t a64, uint64_t a0, unsigned int count ) -{ - unsigned int negCount = - count; - struct uint192 z; - z.v128 = a128<>( negCount & 63 ); - z.v64 = a64<>( negCount & 63 ); - z.v0 = a0<>count | ( (uint32_t) ( a<<( ( - count ) & 31 ) ) != 0 ) - : ( a != 0 ); -} +uint32_t softfloat_approxRecipSqrt32_1( unsigned int oddExpA, uint32_t a ); +#endif + +#ifdef SOFTFLOAT_FAST_INT64 + +/*---------------------------------------------------------------------------- +| The following functions are needed only when `SOFTFLOAT_FAST_INT64' is +| defined. +*----------------------------------------------------------------------------*/ + +#ifndef softfloat_eq128 +/*---------------------------------------------------------------------------- +| Returns true if the 128-bit unsigned integer formed by concatenating `a64' +| and `a0' is equal to the 128-bit unsigned integer formed by concatenating +| `b64' and `b0'. +*----------------------------------------------------------------------------*/ +#if defined INLINE_LEVEL && (1 <= INLINE_LEVEL) +INLINE + bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) + { return (a64 == b64) && (a0 == b0); } #else -uint32_t softfloat_shift32RightJam( uint32_t, unsigned int ); +bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); +#endif #endif +#ifndef softfloat_le128 /*---------------------------------------------------------------------------- -| Shift count is less than 32. +| Returns true if the 128-bit unsigned integer formed by concatenating `a64' +| and `a0' is less than or equal to the 128-bit unsigned integer formed by +| concatenating `b64' and `b0'. *----------------------------------------------------------------------------*/ -#if defined INLINE -INLINE uint32_t softfloat_shortShift32Right1Jam( uint32_t a ) - { return a>>1 | ( a & 1 ); } +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) +INLINE + bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) + { return (a64 < b64) || ((a64 == b64) && (a0 <= b0)); } #else -uint32_t softfloat_shortShift32Right1Jam( uint32_t ); +bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); +#endif #endif +#ifndef softfloat_lt128 /*---------------------------------------------------------------------------- -| Shifts `a' right by the number of bits given in `count'. If any nonzero -| bits are shifted off, they are ``jammed'' into the least significant bit of -| the result by setting the least significant bit to 1. The value of `count' -| can be arbitrarily large; in particular, if `count' is greater than 64, the -| result will be either 0 or 1, depending on whether `a' is zero or nonzero. -| The result is stored in the location pointed to by `zPtr'. +| Returns true if the 128-bit unsigned integer formed by concatenating `a64' +| and `a0' is less than the 128-bit unsigned integer formed by concatenating +| `b64' and `b0'. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 3 <= INLINE_LEVEL ) -INLINE uint64_t softfloat_shift64RightJam( uint64_t a, unsigned int count ) +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) +INLINE + bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) + { return (a64 < b64) || ((a64 == b64) && (a0 < b0)); } +#else +bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); +#endif +#endif + +#ifndef softfloat_shortShiftLeft128 +/*---------------------------------------------------------------------------- +| Shifts the 128 bits formed by concatenating `a64' and `a0' left by the +| number of bits given in `count', which must be in the range 1 to 63. +*----------------------------------------------------------------------------*/ +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) +INLINE + struct uint128 + softfloat_shortShiftLeft128( uint64_t a64, uint64_t a0, uint_fast8_t count ) { - return - ( count < 64 ) - ? a>>count | ( (uint64_t) ( a<<( ( - count ) & 63 ) ) != 0 ) - : ( a != 0 ); + struct uint128 z; + z.v64 = a64<>(-count & 63); + z.v0 = a0<>count | ( ( a & ( ( (uint64_t) 1<>count; - z.extra = a<<( ( - count ) & 63 ); - } else { - z.v = 0; - z.extra = ( count == 64 ) ? a : ( a != 0 ); - } - z.extra |= ( extra != 0 ); + struct uint128 z; + z.v64 = a64>>count; + z.v0 = a64<<(-count & 63) | a0>>count; return z; } #else -struct uint64_extra - softfloat_shift64ExtraRightJam( uint64_t, uint64_t, unsigned int ); +struct uint128 + softfloat_shortShiftRight128( uint64_t a64, uint64_t a0, uint_fast8_t count ); +#endif #endif +#ifndef softfloat_shortShiftRightJam64Extra /*---------------------------------------------------------------------------- -| Shift count is less than 64. +| This function is the same as `softfloat_shiftRightJam64Extra' (below), +| except that `count' must be in the range 1 to 63. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL ) -INLINE struct uint64_extra - softfloat_shortShift64ExtraRightJam( - uint64_t a, uint64_t extra, unsigned int count ) +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) +INLINE + struct uint64_extra + softfloat_shortShiftRightJam64Extra( + uint64_t a, uint64_t extra, uint_fast8_t count ) { struct uint64_extra z; z.v = a>>count; - z.extra = a<<( ( - count ) & 63 ) | ( extra != 0 ); + z.extra = a<<(-count & 63) | (extra != 0); return z; } #else struct uint64_extra - softfloat_shortShift64ExtraRightJam( uint64_t, uint64_t, unsigned int ); + softfloat_shortShiftRightJam64Extra( + uint64_t a, uint64_t extra, uint_fast8_t count ); +#endif #endif +#ifndef softfloat_shortShiftRightJam128 /*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the -| number of bits given in `count'. Any bits shifted off are lost. The value -| of `count' can be arbitrarily large; in particular, if `count' is greater -| than 128, the result will be 0. The result is broken into two 64-bit pieces -| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +| Shifts the 128 bits formed by concatenating `a64' and `a0' right by the +| number of bits given in `count', which must be in the range 1 to 63. If any +| nonzero bits are shifted off, they are "jammed" into the least-significant +| bit of the shifted value by setting the least-significant bit to 1. This +| shifted-and-jammed value is returned. *----------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------- -| Shift count is less than 64. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL ) -INLINE struct uint128 - softfloat_shortShift128Right( uint64_t a64, uint64_t a0, unsigned int count ) +#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) +INLINE + struct uint128 + softfloat_shortShiftRightJam128( + uint64_t a64, uint64_t a0, uint_fast8_t count ) { + uint_fast8_t negCount = -count; struct uint128 z; z.v64 = a64>>count; - z.v0 = a64<<( ( - count ) & 63 ) | a0>>count; + z.v0 = + a64<<(negCount & 63) | a0>>count + | ((uint64_t) (a0<<(negCount & 63)) != 0); return z; } #else struct uint128 - softfloat_shortShift128Right( uint64_t, uint64_t, unsigned int ); + softfloat_shortShiftRightJam128( + uint64_t a64, uint64_t a0, uint_fast8_t count ); +#endif #endif +#ifndef softfloat_shortShiftRightJam128Extra /*---------------------------------------------------------------------------- -| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the -| number of bits given in `count'. If any nonzero bits are shifted off, they -| are ``jammed'' into the least significant bit of the result by setting the -| least significant bit to 1. The value of `count' can be arbitrarily large; -| in particular, if `count' is greater than 128, the result will be either -| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or -| nonzero. The result is broken into two 64-bit pieces which are stored at -| the locations pointed to by `z0Ptr' and `z1Ptr'. +| This function is the same as `softfloat_shiftRightJam128Extra' (below), +| except that `count' must be in the range 1 to 63. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 4 <= INLINE_LEVEL ) -INLINE struct uint128 - softfloat_shift128RightJam( uint64_t a64, uint64_t a0, unsigned int count ) +#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) +INLINE + struct uint128_extra + softfloat_shortShiftRightJam128Extra( + uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t count ) { - unsigned int negCount; - struct uint128 z; - if ( count < 64 ) { - negCount = - count; - z.v64 = a64>>( count & 63 ); - z.v0 = - a64<<( negCount & 63 ) | a0>>count - | ( (uint64_t) ( a0<<( negCount & 63 ) ) != 0 ); - } else { - z.v64 = 0; - z.v0 = - ( count < 128 ) - ? a64>>( count & 63 ) - | ( ( ( a64 & ( ( (uint64_t) 1<<( count & 63 ) ) - 1 ) ) - | a0 ) - != 0 ) - : ( ( a64 | a0 ) != 0 ); - } + uint_fast8_t negCount = -count; + struct uint128_extra z; + z.v.v64 = a64>>count; + z.v.v0 = a64<<(negCount & 63) | a0>>count; + z.extra = a0<<(negCount & 63) | (extra != 0); return z; } #else -struct uint128 - softfloat_shift128RightJam( uint64_t, uint64_t, unsigned int ); -#endif - -/*---------------------------------------------------------------------------- -| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right -| by 64 _plus_ the number of bits given in `count'. The shifted result is -| at most 128 nonzero bits; these are broken into two 64-bit pieces which are -| stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted -| off form a third 64-bit result as follows: The _last_ bit shifted off is -| the most-significant bit of the extra result, and the other 63 bits of the -| extra result are all zero if and only if _all_but_the_last_ bits shifted off -| were all zero. This extra result is stored in the location pointed to by -| `z2Ptr'. The value of `count' can be arbitrarily large. -| (This routine makes more sense if `a0', `a1', and `a2' are considered -| to form a fixed-point value with binary point between `a1' and `a2'. This -| fixed-point value is shifted right by the number of bits given in `count', -| and the integer part of the result is returned at the locations pointed to -| by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly -| corrupted as described above, and is returned at the location pointed to by -| `z2Ptr'.) -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 5 <= INLINE_LEVEL ) -INLINE struct uint128_extra - softfloat_shift128ExtraRightJam( - uint64_t a64, uint64_t a0, uint64_t extra, unsigned int count ) +struct uint128_extra + softfloat_shortShiftRightJam128Extra( + uint64_t a64, uint64_t a0, uint64_t extra, uint_fast8_t count ); +#endif +#endif + +#ifndef softfloat_shiftRightJam64Extra +/*---------------------------------------------------------------------------- +| Shifts the 128 bits formed by concatenating `a' and `extra' right by 64 +| _plus_ the number of bits given in `count', which must not be zero. This +| shifted value is at most 64 nonzero bits and is returned in the `v' field +| of the `struct uint64_extra' result. The 64-bit `extra' field of the result +| contains a value formed as follows from the bits that were shifted off: The +| _last_ bit shifted off is the most-significant bit of the `extra' field, and +| the other 63 bits of the `extra' field are all zero if and only if _all_but_ +| _the_last_ bits shifted off were all zero. +| (This function makes more sense if `a' and `extra' are considered to form +| an unsigned fixed-point number with binary point between `a' and `extra'. +| This fixed-point value is shifted right by the number of bits given in +| `count', and the integer part of this shifted value is returned in the `v' +| field of the result. The fractional part of the shifted value is modified +| as described above and returned in the `extra' field of the result.) +*----------------------------------------------------------------------------*/ +#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL) +INLINE + struct uint64_extra + softfloat_shiftRightJam64Extra( + uint64_t a, uint64_t extra, uint_fast32_t count ) { - unsigned int negCount = - count; - struct uint128_extra z; + struct uint64_extra z; if ( count < 64 ) { - z.v64 = a64>>count; - z.v0 = a64<<( negCount & 63 ) | a0>>count; - z.extra = a0<<( negCount & 63 ); + z.v = a>>count; + z.extra = a<<(-count & 63); } else { - z.v64 = 0; - if ( count == 64 ) { - z.v0 = a64; - z.extra = a0; - } else { - extra |= a0; - if ( count < 128 ) { - z.v0 = a64>>( count & 63 ); - z.extra = a64<<( negCount & 63 ); - } else { - z.v0 = 0; - z.extra = ( count == 128 ) ? a64 : ( a64 != 0 ); - } - } + z.v = 0; + z.extra = (count == 64) ? a : (a != 0); } - z.extra |= ( extra != 0 ); + z.extra |= (extra != 0); return z; } #else -struct uint128_extra - softfloat_shift128ExtraRightJam( uint64_t, uint64_t, uint64_t, unsigned int ); +struct uint64_extra + softfloat_shiftRightJam64Extra( + uint64_t a, uint64_t extra, uint_fast32_t count ); +#endif #endif +#ifndef softfloat_shiftRightJam128 /*---------------------------------------------------------------------------- -| Shift count is less than 64. +| Shifts the 128 bits formed by concatenating `a64' and `a0' right by the +| number of bits given in `count', which must not be zero. If any nonzero +| bits are shifted off, they are "jammed" into the least-significant bit of +| the shifted value by setting the least-significant bit to 1. This shifted- +| and-jammed value is returned. +| The value of `count' can be arbitrarily large. In particular, if `count' +| is greater than 128, the result will be either 0 or 1, depending on whether +| the original 128 bits are all zeros. +*----------------------------------------------------------------------------*/ +struct uint128 + softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t count ); +#endif + +#ifndef softfloat_shiftRightJam128Extra +/*---------------------------------------------------------------------------- +| Shifts the 192 bits formed by concatenating `a64', `a0', and `extra' right +| by 64 _plus_ the number of bits given in `count', which must not be zero. +| This shifted value is at most 128 nonzero bits and is returned in the `v' +| field of the `struct uint128_extra' result. The 64-bit `extra' field of the +| result contains a value formed as follows from the bits that were shifted +| off: The _last_ bit shifted off is the most-significant bit of the `extra' +| field, and the other 63 bits of the `extra' field are all zero if and only +| if _all_but_the_last_ bits shifted off were all zero. +| (This function makes more sense if `a64', `a0', and `extra' are considered +| to form an unsigned fixed-point number with binary point between `a0' and +| `extra'. This fixed-point value is shifted right by the number of bits +| given in `count', and the integer part of this shifted value is returned +| in the `v' field of the result. The fractional part of the shifted value +| is modified as described above and returned in the `extra' field of the +| result.) *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 3 <= INLINE_LEVEL ) -INLINE struct uint128_extra - softfloat_shortShift128ExtraRightJam( - uint64_t a64, uint64_t a0, uint64_t extra, unsigned int count ) -{ - unsigned int negCount = - count; - struct uint128_extra z; - z.v64 = a64>>count; - z.v0 = a64<<( negCount & 63 ) | a0>>count; - z.extra = a0<<( negCount & 63 ) | ( extra != 0 ); - return z; -} -#else struct uint128_extra - softfloat_shortShift128ExtraRightJam( - uint64_t, uint64_t, uint64_t, unsigned int ); + softfloat_shiftRightJam128Extra( + uint64_t a64, uint64_t a0, uint64_t extra, uint_fast32_t count ); #endif -extern const uint8_t softfloat_countLeadingZeros8[ 256 ]; +#ifndef softfloat_shiftRightJam256M +/*---------------------------------------------------------------------------- +| Shifts the 256-bit unsigned integer pointed to by `aPtr' right by the number +| of bits given in `count', which must not be zero. If any nonzero bits are +| shifted off, they are "jammed" into the least-significant bit of the shifted +| value by setting the least-significant bit to 1. This shifted-and-jammed +| value is stored at the location pointed to by `zPtr'. Each of `aPtr' and +| `zPtr' points to an array of four 64-bit elements that concatenate in the +| platform's normal endian order to form a 256-bit integer. +| The value of `count' can be arbitrarily large. In particular, if `count' +| is greater than 256, the stored result will be either 0 or 1, depending on +| whether the original 256 bits are all zeros. +*----------------------------------------------------------------------------*/ +void + softfloat_shiftRightJam256M( + const uint64_t *aPtr, uint_fast32_t count, uint64_t *zPtr ); +#endif +#ifndef softfloat_add128 /*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 32 is returned. +| Returns the sum of the 128-bit integer formed by concatenating `a64' and +| `a0' and the 128-bit integer formed by concatenating `b64' and `b0'. The +| addition is modulo 2^128, so any carry out is lost. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL ) -INLINE int softfloat_countLeadingZeros32( uint32_t a ) +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) +INLINE + struct uint128 + softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) { - int count = 0; - if ( a < 0x10000 ) { - count = 16; - a <<= 16; - } - if ( a < 0x1000000 ) { - count += 8; - a <<= 8; - } - count += softfloat_countLeadingZeros8[ a>>24 ]; - return count; + struct uint128 z; + z.v0 = a0 + b0; + z.v64 = a64 + b64 + (z.v0 < a0); + return z; } #else -int softfloat_countLeadingZeros32( uint32_t ); +struct uint128 + softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); +#endif #endif +#ifndef softfloat_add256M /*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 64 is returned. +| Adds the two 256-bit integers pointed to by `aPtr' and `bPtr'. The addition +| is modulo 2^256, so any carry out is lost. The sum is stored at the +| location pointed to by `zPtr'. Each of `aPtr', `bPtr', and `zPtr' points to +| an array of four 64-bit elements that concatenate in the platform's normal +| endian order to form a 256-bit integer. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 4 <= INLINE_LEVEL ) -INLINE int softfloat_countLeadingZeros64( uint64_t a ) -{ - int count = 32; - uint32_t a32 = a; - if ( UINT64_C( 0x100000000 ) <= a ) { - count = 0; - a32 = a>>32; - } - /*------------------------------------------------------------------------ - | From here, result is current count + count leading zeros of `a32'. - *------------------------------------------------------------------------*/ - if ( a32 < 0x10000 ) { - count += 16; - a32 <<= 16; - } - if ( a32 < 0x1000000 ) { - count += 8; - a32 <<= 8; - } - count += softfloat_countLeadingZeros8[ a32>>24 ]; - return count; -} -#else -int softfloat_countLeadingZeros64( uint64_t ); +void + softfloat_add256M( + const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr ); #endif +#ifndef softfloat_sub128 /*---------------------------------------------------------------------------- -| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit -| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so -| any carry out is lost. The result is broken into two 64-bit pieces which -| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +| Returns the difference of the 128-bit integer formed by concatenating `a64' +| and `a0' and the 128-bit integer formed by concatenating `b64' and `b0'. +| The subtraction is modulo 2^128, so any borrow out (carry out) is lost. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL ) -INLINE struct uint128 - softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) +INLINE + struct uint128 + softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) { struct uint128 z; - z.v0 = a0 + b0; - z.v64 = a64 + b64; - z.v64 += ( z.v0 < a0 ); + z.v0 = a0 - b0; + z.v64 = a64 - b64; + z.v64 -= (a0 < b0); return z; } #else -struct uint128 softfloat_add128( uint64_t, uint64_t, uint64_t, uint64_t ); -#endif - -/*---------------------------------------------------------------------------- -| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the -| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is -| modulo 2^192, so any carry out is lost. The result is broken into three -| 64-bit pieces which are stored at the locations pointed to by `z0Ptr', -| `z1Ptr', and `z2Ptr'. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 3 <= INLINE_LEVEL ) -INLINE struct uint192 - softfloat_add192( - uint64_t a128, - uint64_t a64, - uint64_t a0, - uint64_t b128, - uint64_t b64, - uint64_t b0 - ) +struct uint128 + softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ); +#endif +#endif + +#ifndef softfloat_sub256M +/*---------------------------------------------------------------------------- +| Subtracts the 256-bit integer pointed to by `bPtr' from the 256-bit integer +| pointed to by `aPtr'. The addition is modulo 2^256, so any borrow out +| (carry out) is lost. The difference is stored at the location pointed to +| by `zPtr'. Each of `aPtr', `bPtr', and `zPtr' points to an array of four +| 64-bit elements that concatenate in the platform's normal endian order to +| form a 256-bit integer. +*----------------------------------------------------------------------------*/ +void + softfloat_sub256M( + const uint64_t *aPtr, const uint64_t *bPtr, uint64_t *zPtr ); +#endif + +#ifndef softfloat_mul64ByShifted32To128 +/*---------------------------------------------------------------------------- +| Returns the 128-bit product of `a', `b', and 2^32. +*----------------------------------------------------------------------------*/ +#if defined INLINE_LEVEL && (3 <= INLINE_LEVEL) +INLINE struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ) { - struct uint192 z; - unsigned int carry64, carry128; - z.v0 = a0 + b0; - carry64 = ( z.v0 < a0 ); - z.v64 = a64 + b64; - carry128 = ( z.v64 < a64 ); - z.v128 = a128 + b128; - z.v64 += carry64; - carry128 += ( z.v64 < carry64 ); - z.v128 += carry128; + uint_fast64_t mid; + struct uint128 z; + mid = (uint_fast64_t) (uint32_t) a * b; + z.v0 = mid<<32; + z.v64 = (uint_fast64_t) (uint32_t) (a>>32) * b + (mid>>32); return z; } #else -struct uint192 - softfloat_add192( - uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t ); +struct uint128 softfloat_mul64ByShifted32To128( uint64_t a, uint32_t b ); +#endif +#endif + +#ifndef softfloat_mul64To128 +/*---------------------------------------------------------------------------- +| Returns the 128-bit product of `a' and `b'. +*----------------------------------------------------------------------------*/ +struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b ); #endif +#ifndef softfloat_mul128By32 /*---------------------------------------------------------------------------- -| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the -| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo -| 2^128, so any borrow out (carry out) is lost. The result is broken into two -| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and -| `z1Ptr'. +| Returns the product of the 128-bit integer formed by concatenating `a64' and +| `a0', multiplied by `b'. The multiplication is modulo 2^128; any overflow +| bits are discarded. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 2 <= INLINE_LEVEL ) -INLINE struct uint128 - softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +#if defined INLINE_LEVEL && (4 <= INLINE_LEVEL) +INLINE + struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ) { struct uint128 z; - z.v0 = a0 - b0; - z.v64 = a64 - b64; - z.v64 -= ( a0 < b0 ); + uint_fast64_t mid; + uint_fast32_t carry; + z.v0 = a0 * b; + mid = (uint_fast64_t) (uint32_t) (a0>>32) * b; + carry = (uint32_t) ((uint_fast32_t) (z.v0>>32) - (uint_fast32_t) mid); + z.v64 = a64 * b + (uint_fast32_t) ((mid + carry)>>32); return z; } #else -struct uint128 softfloat_sub128( uint64_t, uint64_t, uint64_t, uint64_t ); -#endif - -/*---------------------------------------------------------------------------- -| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2' -| from the 192-bit value formed by concatenating `a0', `a1', and `a2'. -| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The -| result is broken into three 64-bit pieces which are stored at the locations -| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 3 <= INLINE_LEVEL ) -INLINE struct uint192 - softfloat_sub192( - uint64_t a128, - uint64_t a64, - uint64_t a0, - uint64_t b128, - uint64_t b64, - uint64_t b0 - ) -{ - struct uint192 z; - unsigned int borrow64, borrow128; - z.v0 = a0 - b0; - borrow64 = ( a0 < b0 ); - z.v64 = a64 - b64; - borrow128 = ( a64 < b64 ); - z.v128 = a128 - b128; - borrow128 += ( z.v64 < borrow64 ); - z.v64 -= borrow64; - z.v128 -= borrow128; - return z; -} +struct uint128 softfloat_mul128By32( uint64_t a64, uint64_t a0, uint32_t b ); +#endif +#endif + +#ifndef softfloat_mul128To256M +/*---------------------------------------------------------------------------- +| Multiplies the 128-bit unsigned integer formed by concatenating `a64' and +| `a0' by the 128-bit unsigned integer formed by concatenating `b64' and +| `b0'. The 256-bit product is stored at the location pointed to by `zPtr'. +| Argument `zPtr' points to an array of four 64-bit elements that concatenate +| in the platform's normal endian order to form a 256-bit integer. +*----------------------------------------------------------------------------*/ +void + softfloat_mul128To256M( + uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0, uint64_t *zPtr ); +#endif + #else -struct uint192 - softfloat_sub192( - uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t ); + +/*---------------------------------------------------------------------------- +| The following functions are needed only when `SOFTFLOAT_FAST_INT64' is not +| defined. +*----------------------------------------------------------------------------*/ + +#ifndef softfloat_compare96M +/*---------------------------------------------------------------------------- +| Compares the two 96-bit unsigned integers pointed to by `aPtr' and `bPtr'. +| Returns -1 if the first integer (A) is less than the second (B); returns 0 +| if the two integers are equal; and returns +1 if the first integer (A) +| is greater than the second (B). (The result is thus the signum of A - B.) +| Each of `aPtr' and `bPtr' points to an array of three 32-bit elements that +| concatenate in the platform's normal endian order to form a 96-bit integer. +*----------------------------------------------------------------------------*/ +int_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr ); +#endif + +#ifndef softfloat_compare128M +/*---------------------------------------------------------------------------- +| Compares the two 128-bit unsigned integers pointed to by `aPtr' and `bPtr'. +| Returns -1 if the first integer (A) is less than the second (B); returns 0 +| if the two integers are equal; and returns +1 if the first integer (A) +| is greater than the second (B). (The result is thus the signum of A - B.) +| Each of `aPtr' and `bPtr' points to an array of four 32-bit elements that +| concatenate in the platform's normal endian order to form a 128-bit integer. +*----------------------------------------------------------------------------*/ +int_fast8_t + softfloat_compare128M( const uint32_t *aPtr, const uint32_t *bPtr ); #endif +#ifndef softfloat_shortShiftLeft64To96M /*---------------------------------------------------------------------------- -| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken -| into two 64-bit pieces which are stored at the locations pointed to by -| `z0Ptr' and `z1Ptr'. +| Extends `a' to 96 bits and shifts the value left by the number of bits given +| in `count', which must be in the range 1 to 31. The result is stored at the +| location pointed to by `zPtr'. Argument `zPtr' points to an array of three +| 32-bit elements that concatenate in the platform's normal endian order to +| form a 96-bit integer. *----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 4 <= INLINE_LEVEL ) -INLINE struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b ) +#if defined INLINE_LEVEL && (2 <= INLINE_LEVEL) +INLINE + void + softfloat_shortShiftLeft64To96M( + uint64_t a, uint_fast8_t count, uint32_t *zPtr ) { - uint32_t a32 = a>>32; - uint32_t a0 = a; - uint32_t b32 = b>>32; - uint32_t b0 = b; - struct uint128 z; - uint64_t mid1, mid2, mid; - z.v0 = (uint64_t) a0 * b0; - mid1 = (uint64_t) a32 * b0; - mid2 = (uint64_t) a0 * b32; - z.v64 = (uint64_t) a32 * b32; - mid = mid1 + mid2; - z.v64 += ( (uint64_t) ( mid < mid1 ) )<<32 | mid>>32; - mid <<= 32; - z.v0 += mid; - z.v64 += ( z.v0 < mid ); - return z; + zPtr[indexWord( 3, 0 )] = (uint32_t) a<>= 32 - count; + zPtr[indexWord( 3, 2 )] = a>>32; + zPtr[indexWord( 3, 1 )] = a; } #else -struct uint128 softfloat_mul64To128( uint64_t, uint64_t ); +void + softfloat_shortShiftLeft64To96M( + uint64_t a, uint_fast8_t count, uint32_t *zPtr ); +#endif +#endif + +#ifndef softfloat_shortShiftLeftM +/*---------------------------------------------------------------------------- +| Shifts the N-bit unsigned integer pointed to by `aPtr' left by the number +| of bits given in `count', where N = `size_words' * 32. The value of `count' +| must be in the range 1 to 31. Any nonzero bits shifted off are lost. The +| shifted N-bit result is stored at the location pointed to by `zPtr'. Each +| of `aPtr' and `zPtr' points to a `size_words'-long array of 32-bit elements +| that concatenate in the platform's normal endian order to form an N-bit +| integer. +*----------------------------------------------------------------------------*/ +void + softfloat_shortShiftLeftM( + uint_fast8_t size_words, + const uint32_t *aPtr, + uint_fast8_t count, + uint32_t *zPtr + ); +#endif + +#ifndef softfloat_shortShiftLeft96M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shortShiftLeftM' with +| `size_words' = 3 (N = 96). +*----------------------------------------------------------------------------*/ +#define softfloat_shortShiftLeft96M( aPtr, count, zPtr ) softfloat_shortShiftLeftM( 3, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shortShiftLeft128M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shortShiftLeftM' with +| `size_words' = 4 (N = 128). +*----------------------------------------------------------------------------*/ +#define softfloat_shortShiftLeft128M( aPtr, count, zPtr ) softfloat_shortShiftLeftM( 4, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shortShiftLeft160M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shortShiftLeftM' with +| `size_words' = 5 (N = 160). +*----------------------------------------------------------------------------*/ +#define softfloat_shortShiftLeft160M( aPtr, count, zPtr ) softfloat_shortShiftLeftM( 5, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shiftLeftM +/*---------------------------------------------------------------------------- +| Shifts the N-bit unsigned integer pointed to by `aPtr' left by the number +| of bits given in `count', where N = `size_words' * 32. The value of `count' +| must not be zero. Any nonzero bits shifted off are lost. The shifted +| N-bit result is stored at the location pointed to by `zPtr'. Each of `aPtr' +| and `zPtr' points to a `size_words'-long array of 32-bit elements that +| concatenate in the platform's normal endian order to form an N-bit integer. +| The value of `count' can be arbitrarily large. In particular, if `count' +| is greater than N, the stored result will be 0. +*----------------------------------------------------------------------------*/ +void + softfloat_shiftLeftM( + uint_fast8_t size_words, + const uint32_t *aPtr, + uint32_t count, + uint32_t *zPtr + ); +#endif + +#ifndef softfloat_shiftLeft96M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shiftLeftM' with +| `size_words' = 3 (N = 96). +*----------------------------------------------------------------------------*/ +#define softfloat_shiftLeft96M( aPtr, count, zPtr ) softfloat_shiftLeftM( 3, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shiftLeft128M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shiftLeftM' with +| `size_words' = 4 (N = 128). +*----------------------------------------------------------------------------*/ +#define softfloat_shiftLeft128M( aPtr, count, zPtr ) softfloat_shiftLeftM( 4, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shiftLeft160M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shiftLeftM' with +| `size_words' = 5 (N = 160). +*----------------------------------------------------------------------------*/ +#define softfloat_shiftLeft160M( aPtr, count, zPtr ) softfloat_shiftLeftM( 5, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shortShiftRightM +/*---------------------------------------------------------------------------- +| Shifts the N-bit unsigned integer pointed to by `aPtr' right by the number +| of bits given in `count', where N = `size_words' * 32. The value of `count' +| must be in the range 1 to 31. Any nonzero bits shifted off are lost. The +| shifted N-bit result is stored at the location pointed to by `zPtr'. Each +| of `aPtr' and `zPtr' points to a `size_words'-long array of 32-bit elements +| that concatenate in the platform's normal endian order to form an N-bit +| integer. +*----------------------------------------------------------------------------*/ +void + softfloat_shortShiftRightM( + uint_fast8_t size_words, + const uint32_t *aPtr, + uint_fast8_t count, + uint32_t *zPtr + ); +#endif + +#ifndef softfloat_shortShiftRight128M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shortShiftRightM' with +| `size_words' = 4 (N = 128). +*----------------------------------------------------------------------------*/ +#define softfloat_shortShiftRight128M( aPtr, count, zPtr ) softfloat_shortShiftRightM( 4, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shortShiftRight160M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shortShiftRightM' with +| `size_words' = 5 (N = 160). +*----------------------------------------------------------------------------*/ +#define softfloat_shortShiftRight160M( aPtr, count, zPtr ) softfloat_shortShiftRightM( 5, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shortShiftRightJamM +/*---------------------------------------------------------------------------- +| Shifts the N-bit unsigned integer pointed to by `aPtr' right by the number +| of bits given in `count', where N = `size_words' * 32. The value of `count' +| must be in the range 1 to 31. If any nonzero bits are shifted off, they are +| "jammed" into the least-significant bit of the shifted value by setting the +| least-significant bit to 1. This shifted-and-jammed N-bit result is stored +| at the location pointed to by `zPtr'. Each of `aPtr' and `zPtr' points +| to a `size_words'-long array of 32-bit elements that concatenate in the +| platform's normal endian order to form an N-bit integer. +*----------------------------------------------------------------------------*/ +void + softfloat_shortShiftRightJamM( + uint_fast8_t, const uint32_t *, uint_fast8_t, uint32_t * ); +#endif + +#ifndef softfloat_shortShiftRightJam160M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shortShiftRightJamM' with +| `size_words' = 5 (N = 160). +*----------------------------------------------------------------------------*/ +#define softfloat_shortShiftRightJam160M( aPtr, count, zPtr ) softfloat_shortShiftRightJamM( 5, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shiftRightM +/*---------------------------------------------------------------------------- +| Shifts the N-bit unsigned integer pointed to by `aPtr' right by the number +| of bits given in `count', where N = `size_words' * 32. The value of `count' +| must not be zero. Any nonzero bits shifted off are lost. The shifted +| N-bit result is stored at the location pointed to by `zPtr'. Each of `aPtr' +| and `zPtr' points to a `size_words'-long array of 32-bit elements that +| concatenate in the platform's normal endian order to form an N-bit integer. +| The value of `count' can be arbitrarily large. In particular, if `count' +| is greater than N, the stored result will be 0. +*----------------------------------------------------------------------------*/ +void + softfloat_shiftRightM( + uint_fast8_t size_words, + const uint32_t *aPtr, + uint32_t count, + uint32_t *zPtr + ); +#endif + +#ifndef softfloat_shiftRight96M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shiftRightM' with +| `size_words' = 3 (N = 96). +*----------------------------------------------------------------------------*/ +#define softfloat_shiftRight96M( aPtr, count, zPtr ) softfloat_shiftRightM( 3, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shiftRightJamM +/*---------------------------------------------------------------------------- +| Shifts the N-bit unsigned integer pointed to by `aPtr' right by the number +| of bits given in `count', where N = `size_words' * 32. The value of `count' +| must not be zero. If any nonzero bits are shifted off, they are "jammed" +| into the least-significant bit of the shifted value by setting the least- +| significant bit to 1. This shifted-and-jammed N-bit result is stored +| at the location pointed to by `zPtr'. Each of `aPtr' and `zPtr' points +| to a `size_words'-long array of 32-bit elements that concatenate in the +| platform's normal endian order to form an N-bit integer. +| The value of `count' can be arbitrarily large. In particular, if `count' +| is greater than N, the stored result will be either 0 or 1, depending on +| whether the original N bits are all zeros. +*----------------------------------------------------------------------------*/ +void + softfloat_shiftRightJamM( + uint_fast8_t size_words, + const uint32_t *aPtr, + uint32_t count, + uint32_t *zPtr + ); +#endif + +#ifndef softfloat_shiftRightJam96M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shiftRightJamM' with +| `size_words' = 3 (N = 96). +*----------------------------------------------------------------------------*/ +#define softfloat_shiftRightJam96M( aPtr, count, zPtr ) softfloat_shiftRightJamM( 3, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shiftRightJam128M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shiftRightJamM' with +| `size_words' = 4 (N = 128). +*----------------------------------------------------------------------------*/ +#define softfloat_shiftRightJam128M( aPtr, count, zPtr ) softfloat_shiftRightJamM( 4, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_shiftRightJam160M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_shiftRightJamM' with +| `size_words' = 5 (N = 160). +*----------------------------------------------------------------------------*/ +#define softfloat_shiftRightJam160M( aPtr, count, zPtr ) softfloat_shiftRightJamM( 5, aPtr, count, zPtr ) +#endif + +#ifndef softfloat_addM +/*---------------------------------------------------------------------------- +| Adds the two N-bit integers pointed to by `aPtr' and `bPtr', where N = +| `size_words' * 32. The addition is modulo 2^N, so any carry out is lost. +| The N-bit sum is stored at the location pointed to by `zPtr'. Each of +| `aPtr', `bPtr', and `zPtr' points to a `size_words'-long array of 32-bit +| elements that concatenate in the platform's normal endian order to form an +| N-bit integer. +*----------------------------------------------------------------------------*/ +void + softfloat_addM( + uint_fast8_t size_words, + const uint32_t *aPtr, + const uint32_t *bPtr, + uint32_t *zPtr + ); #endif +#ifndef softfloat_add96M /*---------------------------------------------------------------------------- -| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by -| `b' to obtain a 192-bit product. The product is broken into three 64-bit -| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and -| `z2Ptr'. +| This function or macro is the same as `softfloat_addM' with `size_words' +| = 3 (N = 96). *----------------------------------------------------------------------------*/ -struct uint192 softfloat_mul128By64To192( uint64_t, uint64_t, uint64_t ); +#define softfloat_add96M( aPtr, bPtr, zPtr ) softfloat_addM( 3, aPtr, bPtr, zPtr ) +#endif + +#ifndef softfloat_add128M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_addM' with `size_words' +| = 4 (N = 128). +*----------------------------------------------------------------------------*/ +#define softfloat_add128M( aPtr, bPtr, zPtr ) softfloat_addM( 4, aPtr, bPtr, zPtr ) +#endif + +#ifndef softfloat_add160M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_addM' with `size_words' +| = 5 (N = 160). +*----------------------------------------------------------------------------*/ +#define softfloat_add160M( aPtr, bPtr, zPtr ) softfloat_addM( 5, aPtr, bPtr, zPtr ) +#endif + +#ifndef softfloat_addCarryM +/*---------------------------------------------------------------------------- +| Adds the two N-bit unsigned integers pointed to by `aPtr' and `bPtr', where +| N = `size_words' * 32, plus `carry', which must be either 0 or 1. The N-bit +| sum (modulo 2^N) is stored at the location pointed to by `zPtr', and any +| carry out is returned as the result. Each of `aPtr', `bPtr', and `zPtr' +| points to a `size_words'-long array of 32-bit elements that concatenate in +| the platform's normal endian order to form an N-bit integer. +*----------------------------------------------------------------------------*/ +uint_fast8_t + softfloat_addCarryM( + uint_fast8_t size_words, + const uint32_t *aPtr, + const uint32_t *bPtr, + uint_fast8_t carry, + uint32_t *zPtr + ); +#endif + +#ifndef softfloat_addComplCarryM +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_addCarryM', except that +| the value of the unsigned integer pointed to by `bPtr' is bit-wise completed +| before the addition. +*----------------------------------------------------------------------------*/ +uint_fast8_t + softfloat_addComplCarryM( + uint_fast8_t size_words, + const uint32_t *aPtr, + const uint32_t *bPtr, + uint_fast8_t carry, + uint32_t *zPtr + ); +#endif + +#ifndef softfloat_addComplCarry96M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_addComplCarryM' with +| `size_words' = 3 (N = 96). +*----------------------------------------------------------------------------*/ +#define softfloat_addComplCarry96M( aPtr, bPtr, carry, zPtr ) softfloat_addComplCarryM( 3, aPtr, bPtr, carry, zPtr ) +#endif + +#ifndef softfloat_negXM +/*---------------------------------------------------------------------------- +| Replaces the N-bit unsigned integer pointed to by `zPtr' by the +| 2s-complement of itself, where N = `size_words' * 32. Argument `zPtr' +| points to a `size_words'-long array of 32-bit elements that concatenate in +| the platform's normal endian order to form an N-bit integer. +*----------------------------------------------------------------------------*/ +void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr ); +#endif + +#ifndef softfloat_negX96M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_negXM' with `size_words' +| = 3 (N = 96). +*----------------------------------------------------------------------------*/ +#define softfloat_negX96M( zPtr ) softfloat_negXM( 3, zPtr ) +#endif + +#ifndef softfloat_negX128M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_negXM' with `size_words' +| = 4 (N = 128). +*----------------------------------------------------------------------------*/ +#define softfloat_negX128M( zPtr ) softfloat_negXM( 4, zPtr ) +#endif + +#ifndef softfloat_negX160M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_negXM' with `size_words' +| = 5 (N = 160). +*----------------------------------------------------------------------------*/ +#define softfloat_negX160M( zPtr ) softfloat_negXM( 5, zPtr ) +#endif + +#ifndef softfloat_negX256M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_negXM' with `size_words' +| = 8 (N = 256). +*----------------------------------------------------------------------------*/ +#define softfloat_negX256M( zPtr ) softfloat_negXM( 8, zPtr ) +#endif + +#ifndef softfloat_sub1XM +/*---------------------------------------------------------------------------- +| Subtracts 1 from the N-bit integer pointed to by `zPtr', where N = +| `size_words' * 32. The subtraction is modulo 2^N, so any borrow out (carry +| out) is lost. Argument `zPtr' points to a `size_words'-long array of 32-bit +| elements that concatenate in the platform's normal endian order to form an +| N-bit integer. +*----------------------------------------------------------------------------*/ +void softfloat_sub1XM( uint_fast8_t size_words, uint32_t *zPtr ); +#endif + +#ifndef softfloat_sub1X96M /*---------------------------------------------------------------------------- -| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the -| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit -| product. The product is broken into four 64-bit pieces which are stored at -| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. +| This function or macro is the same as `softfloat_sub1XM' with `size_words' +| = 3 (N = 96). *----------------------------------------------------------------------------*/ -struct uint256 softfloat_mul128To256( uint64_t, uint64_t, uint64_t, uint64_t ); +#define softfloat_sub1X96M( zPtr ) softfloat_sub1XM( 3, zPtr ) +#endif + +#ifndef softfloat_sub1X160M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_sub1XM' with `size_words' +| = 5 (N = 160). +*----------------------------------------------------------------------------*/ +#define softfloat_sub1X160M( zPtr ) softfloat_sub1XM( 5, zPtr ) +#endif + +#ifndef softfloat_subM +/*---------------------------------------------------------------------------- +| Subtracts the two N-bit integers pointed to by `aPtr' and `bPtr', where N = +| `size_words' * 32. The subtraction is modulo 2^N, so any borrow out (carry +| out) is lost. The N-bit difference is stored at the location pointed to by +| `zPtr'. Each of `aPtr', `bPtr', and `zPtr' points to a `size_words'-long +| array of 32-bit elements that concatenate in the platform's normal endian +| order to form an N-bit integer. +*----------------------------------------------------------------------------*/ +void + softfloat_subM( + uint_fast8_t size_words, + const uint32_t *aPtr, + const uint32_t *bPtr, + uint32_t *zPtr + ); +#endif + +#ifndef softfloat_sub96M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_subM' with `size_words' +| = 3 (N = 96). +*----------------------------------------------------------------------------*/ +#define softfloat_sub96M( aPtr, bPtr, zPtr ) softfloat_subM( 3, aPtr, bPtr, zPtr ) +#endif + +#ifndef softfloat_sub128M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_subM' with `size_words' +| = 4 (N = 128). +*----------------------------------------------------------------------------*/ +#define softfloat_sub128M( aPtr, bPtr, zPtr ) softfloat_subM( 4, aPtr, bPtr, zPtr ) +#endif + +#ifndef softfloat_sub160M +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_subM' with `size_words' +| = 5 (N = 160). +*----------------------------------------------------------------------------*/ +#define softfloat_sub160M( aPtr, bPtr, zPtr ) softfloat_subM( 5, aPtr, bPtr, zPtr ) +#endif + +#ifndef softfloat_mul64To128M +/*---------------------------------------------------------------------------- +| Multiplies `a' and `b' and stores the 128-bit product at the location +| pointed to by `zPtr'. Argument `zPtr' points to an array of four 32-bit +| elements that concatenate in the platform's normal endian order to form a +| 128-bit integer. +*----------------------------------------------------------------------------*/ +void softfloat_mul64To128M( uint64_t a, uint64_t b, uint32_t *zPtr ); +#endif + +#ifndef softfloat_mul128MTo256M +/*---------------------------------------------------------------------------- +| Multiplies the two 128-bit unsigned integers pointed to by `aPtr' and +| `bPtr', and stores the 256-bit product at the location pointed to by `zPtr'. +| Each of `aPtr' and `bPtr' points to an array of four 32-bit elements that +| concatenate in the platform's normal endian order to form a 128-bit integer. +| Argument `zPtr' points to an array of eight 32-bit elements that concatenate +| to form a 256-bit integer. +*----------------------------------------------------------------------------*/ +void + softfloat_mul128MTo256M( + const uint32_t *aPtr, const uint32_t *bPtr, uint32_t *zPtr ); +#endif +#ifndef softfloat_remStepMBy32 /*---------------------------------------------------------------------------- -| Returns an approximation to the 64-bit integer quotient obtained by dividing -| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The -| divisor `b' must be at least 2^63. If q is the exact quotient truncated -| toward zero, the approximation returned lies between q and q + 2 inclusive. -| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit -| unsigned integer is returned. +| Performs a "remainder reduction step" as follows: Arguments `remPtr' and +| `bPtr' both point to N-bit unsigned integers, where N = `size_words' * 32. +| Defining R and B as the values of those integers, the expression (R<<`count') +| - B * q is computed modulo 2^N, and the N-bit result is stored at the +| location pointed to by `zPtr'. Each of `remPtr', `bPtr', and `zPtr' points +| to a `size_words'-long array of 32-bit elements that concatenate in the +| platform's normal endian order to form an N-bit integer. *----------------------------------------------------------------------------*/ -uint64_t softfloat_estimateDiv128To64( uint64_t, uint64_t, uint64_t ); +void + softfloat_remStepMBy32( + uint_fast8_t size_words, + const uint32_t *remPtr, + uint_fast8_t count, + const uint32_t *bPtr, + uint32_t q, + uint32_t *zPtr + ); +#endif + +#ifndef softfloat_remStep96MBy32 +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_remStepMBy32' with +| `size_words' = 3 (N = 96). +*----------------------------------------------------------------------------*/ +#define softfloat_remStep96MBy32( remPtr, count, bPtr, q, zPtr ) softfloat_remStepMBy32( 3, remPtr, count, bPtr, q, zPtr ) +#endif +#ifndef softfloat_remStep128MBy32 /*---------------------------------------------------------------------------- -| Returns an approximation to the square root of the 32-bit significand given -| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of -| `aExp' (the least significant bit) is 1, the integer returned approximates -| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' -| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either -| case, the approximation returned lies strictly within +/-2 of the exact -| value. +| This function or macro is the same as `softfloat_remStepMBy32' with +| `size_words' = 4 (N = 128). *----------------------------------------------------------------------------*/ -uint32_t softfloat_estimateSqrt32( unsigned int, uint32_t ); +#define softfloat_remStep128MBy32( remPtr, count, bPtr, q, zPtr ) softfloat_remStepMBy32( 4, remPtr, count, bPtr, q, zPtr ) +#endif + +#ifndef softfloat_remStep160MBy32 +/*---------------------------------------------------------------------------- +| This function or macro is the same as `softfloat_remStepMBy32' with +| `size_words' = 5 (N = 160). +*----------------------------------------------------------------------------*/ +#define softfloat_remStep160MBy32( remPtr, count, bPtr, q, zPtr ) softfloat_remStepMBy32( 5, remPtr, count, bPtr, q, zPtr ) +#endif + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/softfloat/s_add128.c b/softfloat/s_add128.c old mode 100755 new mode 100644 index 59c0348..cabbb73 --- a/softfloat/s_add128.c +++ b/softfloat/s_add128.c @@ -1,17 +1,55 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint128 - softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - struct uint128 z; - - z.v0 = a0 + b0; - z.v64 = a64 + b64; - z.v64 += ( z.v0 < a0 ); - return z; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_add128 + +struct uint128 + softfloat_add128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +{ + struct uint128 z; + + z.v0 = a0 + b0; + z.v64 = a64 + b64 + (z.v0 < a0); + return z; + +} + +#endif + diff --git a/softfloat/s_add192.c b/softfloat/s_add192.c deleted file mode 100755 index 543eb5d..0000000 --- a/softfloat/s_add192.c +++ /dev/null @@ -1,30 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint192 - softfloat_add192( - uint64_t a128, - uint64_t a64, - uint64_t a0, - uint64_t b128, - uint64_t b64, - uint64_t b0 - ) -{ - struct uint192 z; - unsigned int carry64, carry128; - - z.v0 = a0 + b0; - carry64 = ( z.v0 < a0 ); - z.v64 = a64 + b64; - carry128 = ( z.v64 < a64 ); - z.v128 = a128 + b128; - z.v64 += carry64; - carry128 += ( z.v64 < carry64 ); - z.v128 += carry128; - return z; - -} - diff --git a/softfloat/s_addCarryM.c b/softfloat/s_addCarryM.c new file mode 100644 index 0000000..0f3c997 --- /dev/null +++ b/softfloat/s_addCarryM.c @@ -0,0 +1,70 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_addCarryM + +uint_fast8_t + softfloat_addCarryM( + uint_fast8_t size_words, + const uint32_t *aPtr, + const uint32_t *bPtr, + uint_fast8_t carry, + uint32_t *zPtr + ) +{ + unsigned int index, lastIndex; + uint32_t wordA, wordZ; + + index = indexWordLo( size_words ); + lastIndex = indexWordHi( size_words ); + for (;;) { + wordA = aPtr[index]; + wordZ = wordA + bPtr[index] + carry; + zPtr[index] = wordZ; + carry = carry ? (wordZ <= wordA) : (wordZ < wordA); + if ( index == lastIndex ) break; + index += wordIncr; + } + return carry; + +} + +#endif + diff --git a/softfloat/s_addComplCarryM.c b/softfloat/s_addComplCarryM.c new file mode 100644 index 0000000..6f22273 --- /dev/null +++ b/softfloat/s_addComplCarryM.c @@ -0,0 +1,70 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_addComplCarryM + +uint_fast8_t + softfloat_addComplCarryM( + uint_fast8_t size_words, + const uint32_t *aPtr, + const uint32_t *bPtr, + uint_fast8_t carry, + uint32_t *zPtr + ) +{ + unsigned int index, lastIndex; + uint32_t wordA, wordZ; + + index = indexWordLo( size_words ); + lastIndex = indexWordHi( size_words ); + for (;;) { + wordA = aPtr[index]; + wordZ = wordA + ~bPtr[index] + carry; + zPtr[index] = wordZ; + carry = carry ? (wordZ <= wordA) : (wordZ < wordA); + if ( index == lastIndex ) break; + index += wordIncr; + } + return carry; + +} + +#endif + diff --git a/softfloat/s_addM.c b/softfloat/s_addM.c new file mode 100644 index 0000000..f01be48 --- /dev/null +++ b/softfloat/s_addM.c @@ -0,0 +1,70 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_addM + +void + softfloat_addM( + uint_fast8_t size_words, + const uint32_t *aPtr, + const uint32_t *bPtr, + uint32_t *zPtr + ) +{ + unsigned int index, lastIndex; + uint_fast8_t carry; + uint32_t wordA, wordZ; + + index = indexWordLo( size_words ); + lastIndex = indexWordHi( size_words ); + carry = 0; + for (;;) { + wordA = aPtr[index]; + wordZ = wordA + bPtr[index] + carry; + zPtr[index] = wordZ; + if ( index == lastIndex ) break; + carry = carry ? (wordZ <= wordA) : (wordZ < wordA); + index += wordIncr; + } + +} + +#endif + diff --git a/softfloat/s_addMagsF32.c b/softfloat/s_addMagsF32.c old mode 100755 new mode 100644 index f361e2b..c1b6b2d --- a/softfloat/s_addMagsF32.c +++ b/softfloat/s_addMagsF32.c @@ -1,75 +1,109 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "specialize.h" - -float32_t - softfloat_addMagsF32( uint_fast32_t uiA, uint_fast32_t uiB, bool signZ ) -{ - int_fast16_t expA; - uint_fast32_t sigA; - int_fast16_t expB; - uint_fast32_t sigB; - int_fast16_t expDiff; - uint_fast32_t uiZ; - int_fast16_t expZ; - uint_fast32_t sigZ; - union ui32_f32 uZ; - - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); - expB = expF32UI( uiB ); - sigB = fracF32UI( uiB ); - expDiff = expA - expB; - sigA <<= 6; - sigB <<= 6; - if ( ! expDiff ) { - if ( expA == 0xFF ) { - if ( sigA | sigB ) goto propagateNaN; - uiZ = uiA; - goto uiZ; - } - if ( ! expA ) { - uiZ = packToF32UI( signZ, 0, ( uiA + uiB ) & 0x7FFFFFFF ); - goto uiZ; - } - expZ = expA; - sigZ = 0x40000000 + sigA + sigB; - } else { - if ( expDiff < 0 ) { - if ( expB == 0xFF ) { - if ( sigB ) goto propagateNaN; - uiZ = packToF32UI( signZ, 0xFF, 0 ); - goto uiZ; - } - expZ = expB; - sigA += expA ? 0x20000000 : sigA; - sigA = softfloat_shift32RightJam( sigA, - expDiff ); - } else { - if ( expA == 0xFF ) { - if ( sigA ) goto propagateNaN; - uiZ = uiA; - goto uiZ; - } - expZ = expA; - sigB += expB ? 0x20000000 : sigB; - sigB = softfloat_shift32RightJam( sigB, expDiff ); - } - sigZ = 0x20000000 + sigA + sigB; - if ( sigZ < 0x40000000 ) { - --expZ; - sigZ <<= 1; - } - } - return softfloat_roundPackToF32( signZ, expZ, sigZ ); - propagateNaN: - uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" + +float32_t + softfloat_addMagsF32( uint_fast32_t uiA, uint_fast32_t uiB, bool signZ ) +{ + int_fast16_t expA; + uint_fast32_t sigA; + int_fast16_t expB; + uint_fast32_t sigB; + int_fast16_t expDiff; + uint_fast32_t uiZ; + int_fast16_t expZ; + uint_fast32_t sigZ; + union ui32_f32 uZ; + + expA = expF32UI( uiA ); + sigA = fracF32UI( uiA ); + expB = expF32UI( uiB ); + sigB = fracF32UI( uiB ); + expDiff = expA - expB; + sigA <<= 6; + sigB <<= 6; + if ( ! expDiff ) { + if ( expA == 0xFF ) { + if ( sigA | sigB ) goto propagateNaN; + uiZ = uiA; + goto uiZ; + } + if ( ! expA ) { + uiZ = packToF32UI( signZ, 0, (uiA + uiB) & 0x7FFFFFFF ); + goto uiZ; + } + expZ = expA; + sigZ = 0x40000000 + sigA + sigB; + } else { + if ( expDiff < 0 ) { + if ( expB == 0xFF ) { + if ( sigB ) goto propagateNaN; + uiZ = packToF32UI( signZ, 0xFF, 0 ); + goto uiZ; + } + expZ = expB; + sigA += expA ? 0x20000000 : sigA; + sigA = softfloat_shiftRightJam32( sigA, -expDiff ); + } else { + if ( expA == 0xFF ) { + if ( sigA ) goto propagateNaN; + uiZ = uiA; + goto uiZ; + } + expZ = expA; + sigB += expB ? 0x20000000 : sigB; + sigB = softfloat_shiftRightJam32( sigB, expDiff ); + } + sigZ = 0x20000000 + sigA + sigB; + if ( sigZ < 0x40000000 ) { + --expZ; + sigZ <<= 1; + } + } + return softfloat_roundPackToF32( signZ, expZ, sigZ ); + propagateNaN: + uiZ = softfloat_propagateNaNF32UI( uiA, uiB ); + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + diff --git a/softfloat/s_addMagsF64.c b/softfloat/s_addMagsF64.c old mode 100755 new mode 100644 index a81c3e4..ba67e7c --- a/softfloat/s_addMagsF64.c +++ b/softfloat/s_addMagsF64.c @@ -1,8 +1,42 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" -#include "primitives.h" #include "internals.h" #include "specialize.h" @@ -35,7 +69,7 @@ float64_t if ( ! expA ) { uiZ = packToF64UI( - signZ, 0, ( uiA + uiB ) & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ); + signZ, 0, (uiA + uiB) & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ); goto uiZ; } expZ = expA; @@ -49,7 +83,7 @@ float64_t } expZ = expB; sigA += expA ? UINT64_C( 0x2000000000000000 ) : sigA; - sigA = softfloat_shift64RightJam( sigA, - expDiff ); + sigA = softfloat_shiftRightJam64( sigA, -expDiff ); } else { if ( expA == 0x7FF ) { if ( sigA ) goto propagateNaN; @@ -58,7 +92,7 @@ float64_t } expZ = expA; sigB += expB ? UINT64_C( 0x2000000000000000 ) : sigB; - sigB = softfloat_shift64RightJam( sigB, expDiff ); + sigB = softfloat_shiftRightJam64( sigB, expDiff ); } sigZ = UINT64_C( 0x2000000000000000 ) + sigA + sigB; if ( sigZ < UINT64_C( 0x4000000000000000 ) ) { diff --git a/softfloat/s_approxRecip32_1.c b/softfloat/s_approxRecip32_1.c new file mode 100644 index 0000000..14ddd95 --- /dev/null +++ b/softfloat/s_approxRecip32_1.c @@ -0,0 +1,71 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" + +#ifndef softfloat_approxRecip32_1 + +uint32_t softfloat_approxRecip32_1( uint32_t a ) +{ + int index; + uint16_t eps; + static const uint16_t k0s[] = { + 0xFFC4, 0xF0BE, 0xE363, 0xD76F, 0xCCAD, 0xC2F0, 0xBA16, 0xB201, + 0xAA97, 0xA3C6, 0x9D7A, 0x97A6, 0x923C, 0x8D32, 0x887E, 0x8417 + }; + static const uint16_t k1s[] = { + 0xF0F1, 0xD62C, 0xBFA1, 0xAC77, 0x9C0A, 0x8DDB, 0x8185, 0x76BA, + 0x6D3B, 0x64D4, 0x5D5C, 0x56B1, 0x50B6, 0x4B55, 0x4679, 0x4211 + }; + uint16_t r0; + uint32_t delta0; + uint_fast32_t r; + uint32_t sqrDelta0; + + index = a>>27 & 0xF; + eps = (uint16_t) (a>>11); + r0 = k0s[index] - ((k1s[index] * (uint_fast32_t) eps)>>20); + delta0 = ~(uint_fast32_t) ((r0 * (uint_fast64_t) a)>>7); + r = ((uint_fast32_t) r0<<16) + ((r0 * (uint_fast64_t) delta0)>>24); + sqrDelta0 = ((uint_fast64_t) delta0 * delta0)>>32; + r += ((uint32_t) r * (uint_fast64_t) sqrDelta0)>>48; + return r; + +} + +#endif + diff --git a/softfloat/s_approxRecipSqrt32_1.c b/softfloat/s_approxRecipSqrt32_1.c new file mode 100644 index 0000000..a318673 --- /dev/null +++ b/softfloat/s_approxRecipSqrt32_1.c @@ -0,0 +1,77 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" + +#ifndef softfloat_approxRecipSqrt32_1 + +uint32_t softfloat_approxRecipSqrt32_1( unsigned int oddExpA, uint32_t a ) +{ + int index; + uint16_t eps; + static const uint16_t k0s[] = { + 0xB4C9, 0xFFAB, 0xAA7D, 0xF11C, 0xA1C5, 0xE4C7, 0x9A43, 0xDA29, + 0x93B5, 0xD0E5, 0x8DED, 0xC8B7, 0x88C6, 0xC16D, 0x8424, 0xBAE1 + }; + static const uint16_t k1s[] = { + 0xA5A5, 0xEA42, 0x8C21, 0xC62D, 0x788F, 0xAA7F, 0x6928, 0x94B6, + 0x5CC7, 0x8335, 0x52A6, 0x74E2, 0x4A3E, 0x68FE, 0x432B, 0x5EFD + }; + uint16_t r0; + uint_fast32_t ESqrR0; + uint32_t delta0; + uint_fast32_t r; + uint32_t sqrDelta0; + + index = (a>>27 & 0xE) + oddExpA; + eps = (uint16_t) (a>>12); + r0 = k0s[index] - ((k1s[index] * (uint_fast32_t) eps)>>20); + ESqrR0 = (uint_fast32_t) r0 * r0; + if ( ! oddExpA ) ESqrR0 <<= 1; + delta0 = ~(uint_fast32_t) (((uint32_t) ESqrR0 * (uint_fast64_t) a)>>23); + r = ((uint_fast32_t) r0<<16) + ((r0 * (uint_fast64_t) delta0)>>25); + sqrDelta0 = ((uint_fast64_t) delta0 * delta0)>>32; + r += ((uint32_t) ((r>>1) + (r>>3) - ((uint_fast32_t) r0<<14)) + * (uint_fast64_t) sqrDelta0) + >>48; + if ( ! (r & 0x80000000) ) r = 0x80000000; + return r; + +} + +#endif + diff --git a/softfloat/s_commonNaNToF32UI.c b/softfloat/s_commonNaNToF32UI.c old mode 100755 new mode 100644 index e16950c..8b13789 --- a/softfloat/s_commonNaNToF32UI.c +++ b/softfloat/s_commonNaNToF32UI.c @@ -1,17 +1 @@ - -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the single- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -uint_fast32_t softfloat_commonNaNToF32UI( struct commonNaN a ) -{ - - return defaultNaNF32UI; - -} - + diff --git a/softfloat/s_commonNaNToF64UI.c b/softfloat/s_commonNaNToF64UI.c old mode 100755 new mode 100644 index 0555e1f..8b13789 --- a/softfloat/s_commonNaNToF64UI.c +++ b/softfloat/s_commonNaNToF64UI.c @@ -1,17 +1 @@ -#include -#include "platform.h" -#include "specialize.h" - -/*---------------------------------------------------------------------------- -| Returns the result of converting the canonical NaN `a' to the double- -| precision floating-point format. -*----------------------------------------------------------------------------*/ - -uint_fast64_t softfloat_commonNaNToF64UI( struct commonNaN a ) -{ - - return defaultNaNF64UI; - -} - diff --git a/softfloat/s_compare96M.c b/softfloat/s_compare96M.c new file mode 100644 index 0000000..5ec6965 --- /dev/null +++ b/softfloat/s_compare96M.c @@ -0,0 +1,62 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_compare96M + +int_fast8_t softfloat_compare96M( const uint32_t *aPtr, const uint32_t *bPtr ) +{ + unsigned int index, lastIndex; + uint32_t wordA, wordB; + + index = indexWordHi( 3 ); + lastIndex = indexWordLo( 3 ); + for (;;) { + wordA = aPtr[index]; + wordB = bPtr[index]; + if ( wordA != wordB ) return (wordA < wordB) ? -1 : 1; + if ( index == lastIndex ) break; + index -= wordIncr; + } + return 0; + +} + +#endif + diff --git a/softfloat/s_countLeadingZeros32.c b/softfloat/s_countLeadingZeros32.c old mode 100755 new mode 100644 index 0bd17e1..4446b47 --- a/softfloat/s_countLeadingZeros32.c +++ b/softfloat/s_countLeadingZeros32.c @@ -1,10 +1,50 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include +#include "platform.h" + +#ifndef softfloat_countLeadingZeros32 + +#define softfloat_countLeadingZeros32 softfloat_countLeadingZeros32 #include "primitives.h" -int softfloat_countLeadingZeros32( uint32_t a ) +uint_fast8_t softfloat_countLeadingZeros32( uint32_t a ) { - int count; + uint_fast8_t count; count = 0; if ( a < 0x10000 ) { @@ -15,8 +55,10 @@ int softfloat_countLeadingZeros32( uint32_t a ) count += 8; a <<= 8; } - count += softfloat_countLeadingZeros8[ a>>24 ]; + count += softfloat_countLeadingZeros8[a>>24]; return count; } +#endif + diff --git a/softfloat/s_countLeadingZeros64.c b/softfloat/s_countLeadingZeros64.c old mode 100755 new mode 100644 index 79f4280..505dc0f --- a/softfloat/s_countLeadingZeros64.c +++ b/softfloat/s_countLeadingZeros64.c @@ -1,18 +1,57 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include -#include "primitives.h" #include "platform.h" -int softfloat_countLeadingZeros64( uint64_t a ) +#ifndef softfloat_countLeadingZeros64 + +#define softfloat_countLeadingZeros64 softfloat_countLeadingZeros64 +#include "primitives.h" + +uint_fast8_t softfloat_countLeadingZeros64( uint64_t a ) { - int count; + uint_fast8_t count; uint32_t a32; - count = 32; - a32 = a; - if ( UINT64_C( 0x100000000 ) <= a ) { - count = 0; - a32 = a>>32; + count = 0; + a32 = a>>32; + if ( ! a32 ) { + count = 32; + a32 = a; } /*------------------------------------------------------------------------ | From here, result is current count + count leading zeros of `a32'. @@ -25,8 +64,10 @@ int softfloat_countLeadingZeros64( uint64_t a ) count += 8; a32 <<= 8; } - count += softfloat_countLeadingZeros8[ a32>>24 ]; + count += softfloat_countLeadingZeros8[a32>>24]; return count; } +#endif + diff --git a/softfloat/s_countLeadingZeros8.c b/softfloat/s_countLeadingZeros8.c old mode 100755 new mode 100644 index 4eca7e9..ed84ffa --- a/softfloat/s_countLeadingZeros8.c +++ b/softfloat/s_countLeadingZeros8.c @@ -1,9 +1,44 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include "platform.h" #include "primitives.h" -const uint8_t softfloat_countLeadingZeros8[ 256 ] = { +const uint_least8_t softfloat_countLeadingZeros8[256] = { 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, diff --git a/softfloat/s_eq128.c b/softfloat/s_eq128.c deleted file mode 100755 index 7261dc4..0000000 --- a/softfloat/s_eq128.c +++ /dev/null @@ -1,13 +0,0 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" - -bool softfloat_eq128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - - return ( a64 == b64 ) && ( a0 == b0 ); - -} - diff --git a/softfloat/s_estimateDiv128To64.c b/softfloat/s_estimateDiv128To64.c deleted file mode 100755 index f8610a2..0000000 --- a/softfloat/s_estimateDiv128To64.c +++ /dev/null @@ -1,28 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -uint64_t softfloat_estimateDiv128To64( uint64_t a64, uint64_t a0, uint64_t b ) -{ - uint32_t b32; - uint64_t z; - struct uint128 term, rem; - uint64_t rem32; - - if ( b <= a64 ) return UINT64_C( 0xFFFFFFFFFFFFFFFF ); - b32 = b>>32; - z = ( (uint64_t) b32<<32 <= a64 ) ? UINT64_C( 0xFFFFFFFF00000000 ) - : ( a64 / b32 )<<32; - term = softfloat_mul64To128( b, z ); - rem = softfloat_sub128( a64, a0, term.v64, term.v0 ); - while ( UINT64_C( 0x8000000000000000 ) <= rem.v64 ) { - z -= UINT64_C( 0x100000000 ); - rem = softfloat_add128( rem.v64, rem.v0, b32, (uint64_t) ( b<<32 ) ); - } - rem32 = ( rem.v64<<32 ) | ( rem.v0>>32 ); - z |= ( (uint64_t) b32<<32 <= rem32 ) ? 0xFFFFFFFF : rem32 / b32; - return z; - -} - diff --git a/softfloat/s_estimateSqrt32.c b/softfloat/s_estimateSqrt32.c deleted file mode 100755 index e22a9dc..0000000 --- a/softfloat/s_estimateSqrt32.c +++ /dev/null @@ -1,37 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -uint32_t softfloat_estimateSqrt32( unsigned int expA, uint32_t a ) -{ - static const uint16_t sqrtOddAdjustments[] = { - 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, - 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 - }; - static const uint16_t sqrtEvenAdjustments[] = { - 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, - 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 - }; - int index; - uint32_t z; - union { uint32_t ui; int32_t i; } u32; - - index = ( a>>27 ) & 15; - if ( expA & 1 ) { - z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ]; - z = ( ( a / z )<<14 ) + ( z<<15 ); - a >>= 1; - } else { - z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ]; - z = a / z + z; - z = ( 0x20000 <= z ) ? 0xFFFF8000 : z<<15; - if ( z <= a ) { - u32.ui = a; - return u32.i>>1; - } - } - return (uint32_t) ( ( (uint64_t) a<<31 ) / z ) + ( z>>1 ); - -} - diff --git a/softfloat/s_f32UIToCommonNaN.c b/softfloat/s_f32UIToCommonNaN.c old mode 100755 new mode 100644 index 9ee0db9..8b13789 --- a/softfloat/s_f32UIToCommonNaN.c +++ b/softfloat/s_f32UIToCommonNaN.c @@ -1,25 +1 @@ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Returns the result of converting the single-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct commonNaN softfloat_f32UIToCommonNaN( uint_fast32_t uiA ) -{ - struct commonNaN z; - - if ( softfloat_isSigNaNF32UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - z.sign = uiA>>31; - z.v64 = (uint_fast64_t) 0x7FFFF <<41; - z.v0 = 0; - return z; - -} - + diff --git a/softfloat/s_f64UIToCommonNaN.c b/softfloat/s_f64UIToCommonNaN.c old mode 100755 new mode 100644 index 84d8ca0..8b13789 --- a/softfloat/s_f64UIToCommonNaN.c +++ b/softfloat/s_f64UIToCommonNaN.c @@ -1,25 +1 @@ - -#include -#include "platform.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Returns the result of converting the double-precision floating-point NaN -| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid -| exception is raised. -*----------------------------------------------------------------------------*/ -struct commonNaN softfloat_f64UIToCommonNaN( uint_fast64_t uiA ) -{ - struct commonNaN z; - - if ( softfloat_isSigNaNF64UI( uiA ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - z.sign = uiA>>63; - z.v64 = (uint_fast64_t) 0xFFFFFFFFFFFFF <<12; - z.v0 = 0; - return z; - -} - + diff --git a/softfloat/s_isSigNaNF32UI.c b/softfloat/s_isSigNaNF32UI.c deleted file mode 100755 index 0a9c33f..0000000 --- a/softfloat/s_isSigNaNF32UI.c +++ /dev/null @@ -1,13 +0,0 @@ - -#include -#include -#include "platform.h" -#include "specialize.h" - -bool softfloat_isSigNaNF32UI( uint_fast32_t ui ) -{ - - return ( ( ui>>22 & 0x1FF ) == 0x1FE ) && ( ui & 0x003FFFFF ); - -} - diff --git a/softfloat/s_isSigNaNF64UI.c b/softfloat/s_isSigNaNF64UI.c deleted file mode 100755 index d255213..0000000 --- a/softfloat/s_isSigNaNF64UI.c +++ /dev/null @@ -1,15 +0,0 @@ - -#include -#include -#include "platform.h" -#include "specialize.h" - -bool softfloat_isSigNaNF64UI( uint_fast64_t ui ) -{ - - return - ( ( ui>>51 & 0xFFF ) == 0xFFE ) - && ( ui & UINT64_C( 0x0007FFFFFFFFFFFF ) ); - -} - diff --git a/softfloat/s_le128.c b/softfloat/s_le128.c deleted file mode 100755 index 83b1d7f..0000000 --- a/softfloat/s_le128.c +++ /dev/null @@ -1,13 +0,0 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" - -bool softfloat_le128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - - return ( a64 < b64 ) || ( ( a64 == b64 ) && ( a0 <= b0 ) ); - -} - diff --git a/softfloat/s_lt128.c b/softfloat/s_lt128.c deleted file mode 100755 index 33a3df4..0000000 --- a/softfloat/s_lt128.c +++ /dev/null @@ -1,13 +0,0 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" - -bool softfloat_lt128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - - return ( a64 < b64 ) || ( ( a64 == b64 ) && ( a0 < b0 ) ); - -} - diff --git a/softfloat/s_mul128By64To192.c b/softfloat/s_mul128By64To192.c deleted file mode 100755 index dfa8825..0000000 --- a/softfloat/s_mul128By64To192.c +++ /dev/null @@ -1,20 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint192 - softfloat_mul128By64To192( uint64_t a64, uint64_t a0, uint64_t b ) -{ - struct uint128 p0, p64; - struct uint192 z; - - p0 = softfloat_mul64To128( a0, b ); - z.v0 = p0.v0; - p64 = softfloat_mul64To128( a64, b ); - z.v64 = p64.v0 + p0.v64; - z.v128 = p64.v64 + ( z.v64 < p64.v0 ); - return z; - -} - diff --git a/softfloat/s_mul128To256.c b/softfloat/s_mul128To256.c deleted file mode 100755 index a96cd94..0000000 --- a/softfloat/s_mul128To256.c +++ /dev/null @@ -1,28 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint256 - softfloat_mul128To256( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - struct uint128 p0, p64, p128; - struct uint256 z; - - p0 = softfloat_mul64To128( a0, b0 ); - z.v0 = p0.v0; - p64 = softfloat_mul64To128( a64, b0 ); - z.v64 = p64.v0 + p0.v64; - z.v128 = p64.v64 + ( z.v64 < p64.v0 ); - p128 = softfloat_mul64To128( a64, b64 ); - z.v128 += p128.v0; - z.v192 = p128.v64 + ( z.v128 < p128.v0 ); - p64 = softfloat_mul64To128( a0, b64 ); - z.v64 += p64.v0; - p64.v64 += ( z.v64 < p64.v0 ); - z.v128 += p64.v64; - z.v192 += ( z.v128 < p64.v64 ); - return z; - -} - diff --git a/softfloat/s_mul64To128.c b/softfloat/s_mul64To128.c old mode 100755 new mode 100644 index c17780b..06beec8 --- a/softfloat/s_mul64To128.c +++ b/softfloat/s_mul64To128.c @@ -1,28 +1,66 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b ) -{ - uint32_t a32, a0, b32, b0; - struct uint128 z; - uint64_t mid1, mid2, mid; - - a32 = a>>32; - a0 = a; - b32 = b>>32; - b0 = b; - z.v0 = (uint64_t) a0 * b0; - mid1 = (uint64_t) a32 * b0; - mid2 = (uint64_t) a0 * b32; - z.v64 = (uint64_t) a32 * b32; - mid = mid1 + mid2; - z.v64 += ( (uint64_t) ( mid < mid1 ) )<<32 | mid>>32; - mid <<= 32; - z.v0 += mid; - z.v64 += ( z.v0 < mid ); - return z; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_mul64To128 + +struct uint128 softfloat_mul64To128( uint64_t a, uint64_t b ) +{ + uint32_t a32, a0, b32, b0; + struct uint128 z; + uint64_t mid1, mid; + + a32 = a>>32; + a0 = a; + b32 = b>>32; + b0 = b; + z.v0 = (uint_fast64_t) a0 * b0; + mid1 = (uint_fast64_t) a32 * b0; + mid = mid1 + (uint_fast64_t) a0 * b32; + z.v64 = (uint_fast64_t) a32 * b32; + z.v64 += (uint_fast64_t) (mid < mid1)<<32 | mid>>32; + mid <<= 32; + z.v0 += mid; + z.v64 += (z.v0 < mid); + return z; + +} + +#endif + diff --git a/softfloat/s_mulAddF32.c b/softfloat/s_mulAddF32.c old mode 100755 new mode 100644 index e55a0ba..7b0ac6f --- a/softfloat/s_mulAddF32.c +++ b/softfloat/s_mulAddF32.c @@ -1,171 +1,204 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float32_t - softfloat_mulAddF32( - int op, uint_fast32_t uiA, uint_fast32_t uiB, uint_fast32_t uiC ) -{ - bool signA; - int_fast16_t expA; - uint_fast32_t sigA; - bool signB; - int_fast16_t expB; - uint_fast32_t sigB; - bool signC; - int_fast16_t expC; - uint_fast32_t sigC; - bool signProd; - uint_fast32_t magBits, uiZ; - struct exp16_sig32 normExpSig; - int_fast16_t expProd; - uint_fast64_t sigProd; - bool signZ; - int_fast16_t expZ; - uint_fast32_t sigZ; - int_fast16_t expDiff; - uint_fast64_t sigZ64, sigC64; - int shiftCount; - union ui32_f32 uZ; - - signA = signF32UI( uiA ); - expA = expF32UI( uiA ); - sigA = fracF32UI( uiA ); - signB = signF32UI( uiB ); - expB = expF32UI( uiB ); - sigB = fracF32UI( uiB ); - signC = signF32UI( uiC ) ^ ( op == softfloat_mulAdd_subC ); - expC = expF32UI( uiC ); - sigC = fracF32UI( uiC ); - signProd = signA ^ signB ^ ( op == softfloat_mulAdd_subProd ); - if ( expA == 0xFF ) { - if ( sigA || ( ( expB == 0xFF ) && sigB ) ) goto propagateNaN_ABC; - magBits = expB | sigB; - goto infProdArg; - } - if ( expB == 0xFF ) { - if ( sigB ) goto propagateNaN_ABC; - magBits = expA | sigA; - goto infProdArg; - } - if ( expC == 0xFF ) { - if ( sigC ) { - uiZ = 0; - goto propagateNaN_ZC; - } - uiZ = uiC; - goto uiZ; - } - if ( ! expA ) { - if ( ! sigA ) goto zeroProd; - normExpSig = softfloat_normSubnormalF32Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! sigB ) goto zeroProd; - normExpSig = softfloat_normSubnormalF32Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - expProd = expA + expB - 0x7E; - sigA = ( sigA | 0x00800000 )<<7; - sigB = ( sigB | 0x00800000 )<<7; - sigProd = (uint_fast64_t) sigA * sigB; - if ( sigProd < UINT64_C( 0x2000000000000000 ) ) { - --expProd; - sigProd <<= 1; - } - signZ = signProd; - if ( ! expC ) { - if ( ! sigC ) { - expZ = expProd - 1; - sigZ = softfloat_shortShift64RightJam( sigProd, 31 ); - goto roundPack; - } - normExpSig = softfloat_normSubnormalF32Sig( sigC ); - expC = normExpSig.exp; - sigC = normExpSig.sig; - } - sigC = ( sigC | 0x00800000 )<<6; - expDiff = expProd - expC; - if ( signProd == signC ) { - if ( expDiff <= 0 ) { - expZ = expC; - sigZ = sigC + softfloat_shift64RightJam( sigProd, 32 - expDiff ); - } else { - expZ = expProd; - sigZ64 = - sigProd - + softfloat_shift64RightJam( - (uint_fast64_t) sigC<<32, expDiff ); - sigZ = softfloat_shortShift64RightJam( sigZ64, 32 ); - } - if ( sigZ < 0x40000000 ) { - --expZ; - sigZ <<= 1; - } - } else { -/*** OPTIMIZE BETTER? ***/ - sigC64 = (uint_fast64_t) sigC<<32; - if ( expDiff < 0 ) { - signZ = signC; - expZ = expC; - sigZ64 = sigC64 - softfloat_shift64RightJam( sigProd, - expDiff ); - } else if ( ! expDiff ) { - expZ = expProd; - sigZ64 = sigProd - sigC64; - if ( ! sigZ64 ) goto completeCancellation; - if ( sigZ64 & UINT64_C( 0x8000000000000000 ) ) { - signZ ^= 1; - sigZ64 = - sigZ64; - } - } else { - expZ = expProd; - sigZ64 = sigProd - softfloat_shift64RightJam( sigC64, expDiff ); - } - shiftCount = softfloat_countLeadingZeros64( sigZ64 ) - 1; - expZ -= shiftCount; - shiftCount -= 32; - if ( shiftCount < 0 ) { - sigZ = softfloat_shortShift64RightJam( sigZ64, - shiftCount ); - } else { - sigZ = (uint_fast32_t) sigZ64< +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +float32_t + softfloat_mulAddF32( + uint_fast32_t uiA, uint_fast32_t uiB, uint_fast32_t uiC, uint_fast8_t op ) +{ + bool signA; + int_fast16_t expA; + uint_fast32_t sigA; + bool signB; + int_fast16_t expB; + uint_fast32_t sigB; + bool signC; + int_fast16_t expC; + uint_fast32_t sigC; + bool signProd; + uint_fast32_t magBits, uiZ; + struct exp16_sig32 normExpSig; + int_fast16_t expProd; + uint_fast64_t sigProd; + bool signZ; + int_fast16_t expZ; + uint_fast32_t sigZ; + int_fast16_t expDiff; + uint_fast64_t sig64Z, sig64C; + int_fast8_t shiftCount; + union ui32_f32 uZ; + + signA = signF32UI( uiA ); + expA = expF32UI( uiA ); + sigA = fracF32UI( uiA ); + signB = signF32UI( uiB ); + expB = expF32UI( uiB ); + sigB = fracF32UI( uiB ); + signC = signF32UI( uiC ) ^ (op == softfloat_mulAdd_subC); + expC = expF32UI( uiC ); + sigC = fracF32UI( uiC ); + signProd = signA ^ signB ^ (op == softfloat_mulAdd_subProd); + if ( expA == 0xFF ) { + if ( sigA || ((expB == 0xFF) && sigB) ) goto propagateNaN_ABC; + magBits = expB | sigB; + goto infProdArg; + } + if ( expB == 0xFF ) { + if ( sigB ) goto propagateNaN_ABC; + magBits = expA | sigA; + goto infProdArg; + } + if ( expC == 0xFF ) { + if ( sigC ) { + uiZ = 0; + goto propagateNaN_ZC; + } + uiZ = uiC; + goto uiZ; + } + if ( ! expA ) { + if ( ! sigA ) goto zeroProd; + normExpSig = softfloat_normSubnormalF32Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if ( ! expB ) { + if ( ! sigB ) goto zeroProd; + normExpSig = softfloat_normSubnormalF32Sig( sigB ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + expProd = expA + expB - 0x7E; + sigA = (sigA | 0x00800000)<<7; + sigB = (sigB | 0x00800000)<<7; + sigProd = (uint_fast64_t) sigA * sigB; + if ( sigProd < UINT64_C( 0x2000000000000000 ) ) { + --expProd; + sigProd <<= 1; + } + signZ = signProd; + if ( ! expC ) { + if ( ! sigC ) { + expZ = expProd - 1; + sigZ = softfloat_shortShiftRightJam64( sigProd, 31 ); + goto roundPack; + } + normExpSig = softfloat_normSubnormalF32Sig( sigC ); + expC = normExpSig.exp; + sigC = normExpSig.sig; + } + sigC = (sigC | 0x00800000)<<6; + expDiff = expProd - expC; + if ( signProd == signC ) { + if ( expDiff <= 0 ) { + expZ = expC; + sigZ = sigC + softfloat_shiftRightJam64( sigProd, 32 - expDiff ); + } else { + expZ = expProd; + sig64Z = + sigProd + + softfloat_shiftRightJam64( + (uint_fast64_t) sigC<<32, expDiff ); + sigZ = softfloat_shortShiftRightJam64( sig64Z, 32 ); + } + if ( sigZ < 0x40000000 ) { + --expZ; + sigZ <<= 1; + } + } else { + sig64C = (uint_fast64_t) sigC<<32; + if ( expDiff < 0 ) { + signZ = signC; + expZ = expC; + sig64Z = sig64C - softfloat_shiftRightJam64( sigProd, -expDiff ); + } else if ( ! expDiff ) { + expZ = expProd; + sig64Z = sigProd - sig64C; + if ( ! sig64Z ) goto completeCancellation; + if ( sig64Z & UINT64_C( 0x8000000000000000 ) ) { + signZ ^= 1; + sig64Z = -sig64Z; + } + } else { + expZ = expProd; + sig64Z = sigProd - softfloat_shiftRightJam64( sig64C, expDiff ); + } + shiftCount = softfloat_countLeadingZeros64( sig64Z ) - 1; + expZ -= shiftCount; + shiftCount -= 32; + if ( shiftCount < 0 ) { + sigZ = softfloat_shortShiftRightJam64( sig64Z, -shiftCount ); + } else { + sigZ = (uint_fast32_t) sig64Z< -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -float64_t - softfloat_mulAddF64( - int op, uint_fast64_t uiA, uint_fast64_t uiB, uint_fast64_t uiC ) -{ - bool signA; - int_fast16_t expA; - uint_fast64_t sigA; - bool signB; - int_fast16_t expB; - uint_fast64_t sigB; - bool signC; - int_fast16_t expC; - uint_fast64_t sigC; - bool signProd; - uint_fast64_t magBits, uiZ; - struct exp16_sig64 normExpSig; - int_fast16_t expProd; - struct uint128 sigProd; - bool signZ; - int_fast16_t expZ; - uint_fast64_t sigZ; - int_fast16_t expDiff; - struct uint128 sigC128, sigZ128; - int shiftCount; - union ui64_f64 uZ; - - signA = signF64UI( uiA ); - expA = expF64UI( uiA ); - sigA = fracF64UI( uiA ); - signB = signF64UI( uiB ); - expB = expF64UI( uiB ); - sigB = fracF64UI( uiB ); - signC = signF64UI( uiC ) ^ ( op == softfloat_mulAdd_subC ); - expC = expF64UI( uiC ); - sigC = fracF64UI( uiC ); - signProd = signA ^ signB ^ ( op == softfloat_mulAdd_subProd ); - if ( expA == 0x7FF ) { - if ( sigA || ( ( expB == 0x7FF ) && sigB ) ) goto propagateNaN_ABC; - magBits = expB | sigB; - goto infProdArg; - } - if ( expB == 0x7FF ) { - if ( sigB ) goto propagateNaN_ABC; - magBits = expA | sigA; - goto infProdArg; - } - if ( expC == 0x7FF ) { - if ( sigC ) { - uiZ = 0; - goto propagateNaN_ZC; - } - uiZ = uiC; - goto uiZ; - } - if ( ! expA ) { - if ( ! sigA ) goto zeroProd; - normExpSig = softfloat_normSubnormalF64Sig( sigA ); - expA = normExpSig.exp; - sigA = normExpSig.sig; - } - if ( ! expB ) { - if ( ! sigB ) goto zeroProd; - normExpSig = softfloat_normSubnormalF64Sig( sigB ); - expB = normExpSig.exp; - sigB = normExpSig.sig; - } - expProd = expA + expB - 0x3FE; - sigA = ( sigA | UINT64_C( 0x0010000000000000 ) )<<10; - sigB = ( sigB | UINT64_C( 0x0010000000000000 ) )<<10; - sigProd = softfloat_mul64To128( sigA, sigB ); - if ( sigProd.v64 < UINT64_C( 0x2000000000000000 ) ) { - --expProd; - sigProd = softfloat_shortShift128Left( sigProd.v64, sigProd.v0, 1 ); - } - signZ = signProd; - if ( ! expC ) { - if ( ! sigC ) { - expZ = expProd - 1; - sigZ = sigProd.v64<<1 | ( sigProd.v0 != 0 ); - goto roundPack; - } - normExpSig = softfloat_normSubnormalF64Sig( sigC ); - expC = normExpSig.exp; - sigC = normExpSig.sig; - } - sigC = ( sigC | UINT64_C( 0x0010000000000000 ) )<<9; - expDiff = expProd - expC; - if ( signProd == signC ) { - if ( expDiff <= 0 ) { - expZ = expC; - if ( expDiff ) { - sigProd.v64 = - softfloat_shift64RightJam( sigProd.v64, - expDiff ); - } - sigZ = ( sigC + sigProd.v64 ) | ( sigProd.v0 != 0 ); - } else { - expZ = expProd; - sigC128 = softfloat_shift128RightJam( sigC, 0, expDiff ); - sigZ128 = - softfloat_add128( - sigProd.v64, sigProd.v0, sigC128.v64, sigC128.v0 ); - sigZ = sigZ128.v64 | ( sigZ128.v0 != 0 ); - } - if ( sigZ < UINT64_C( 0x4000000000000000 ) ) { - --expZ; - sigZ <<= 1; - } - } else { -/*** OPTIMIZE BETTER? ***/ - if ( expDiff < 0 ) { - signZ = signC; - expZ = expC; - sigProd = - softfloat_shift128RightJam( - sigProd.v64, sigProd.v0, - expDiff ); - sigZ128 = softfloat_sub128( sigC, 0, sigProd.v64, sigProd.v0 ); - } else if ( ! expDiff ) { - expZ = expProd; - sigZ128 = softfloat_sub128( sigProd.v64, sigProd.v0, sigC, 0 ); - if ( ! ( sigZ128.v64 | sigZ128.v0 ) ) goto completeCancellation; - if ( sigZ128.v64 & UINT64_C( 0x8000000000000000 ) ) { - signZ ^= 1; - sigZ128 = softfloat_sub128( 0, 0, sigZ128.v64, sigZ128.v0 ); - } - } else { - expZ = expProd; - sigC128 = softfloat_shift128RightJam( sigC, 0, expDiff ); - sigZ128 = - softfloat_sub128( - sigProd.v64, sigProd.v0, sigC128.v64, sigC128.v0 ); - } - if ( ! sigZ128.v64 ) { - expZ -= 64; - sigZ128.v64 = sigZ128.v0; - sigZ128.v0 = 0; - } - shiftCount = softfloat_countLeadingZeros64( sigZ128.v64 ) - 1; - expZ -= shiftCount; - if ( shiftCount < 0 ) { - sigZ = softfloat_shortShift64RightJam( sigZ128.v64, - shiftCount ); - } else { - sigZ128 = - softfloat_shortShift128Left( - sigZ128.v64, sigZ128.v0, shiftCount ); - sigZ = sigZ128.v64; - } - sigZ |= ( sigZ128.v0 != 0 ); - } - roundPack: - return softfloat_roundPackToF64( signZ, expZ, sigZ ); - propagateNaN_ABC: - uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); - goto propagateNaN_ZC; - infProdArg: - if ( magBits ) { - uiZ = packToF64UI( signProd, 0x7FF, 0 ); - if ( expC != 0x7FF ) goto uiZ; - if ( sigC ) goto propagateNaN_ZC; - if ( signProd == signC ) goto uiZ; - } - invalid: - softfloat_raiseFlags( softfloat_flag_invalid ); - uiZ = defaultNaNF64UI; - propagateNaN_ZC: - uiZ = softfloat_propagateNaNF64UI( uiZ, uiC ); - goto uiZ; - zeroProd: - uiZ = uiC; - if ( ! ( expC | sigC ) && ( signProd != signC ) ) { - completeCancellation: - uiZ = - packToF64UI( softfloat_roundingMode == softfloat_round_min, 0, 0 ); - } - uiZ: - uZ.ui = uiZ; - return uZ.f; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +#ifdef SOFTFLOAT_FAST_INT64 + +float64_t + softfloat_mulAddF64( + uint_fast64_t uiA, uint_fast64_t uiB, uint_fast64_t uiC, uint_fast8_t op ) +{ + bool signA; + int_fast16_t expA; + uint_fast64_t sigA; + bool signB; + int_fast16_t expB; + uint_fast64_t sigB; + bool signC; + int_fast16_t expC; + uint_fast64_t sigC; + bool signZ; + uint_fast64_t magBits, uiZ; + struct exp16_sig64 normExpSig; + int_fast16_t expZ; + struct uint128 sig128Z; + uint_fast64_t sigZ; + int_fast16_t expDiff; + struct uint128 sig128C; + int_fast8_t shiftCount; + union ui64_f64 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF64UI( uiA ); + expA = expF64UI( uiA ); + sigA = fracF64UI( uiA ); + signB = signF64UI( uiB ); + expB = expF64UI( uiB ); + sigB = fracF64UI( uiB ); + signC = signF64UI( uiC ) ^ (op == softfloat_mulAdd_subC); + expC = expF64UI( uiC ); + sigC = fracF64UI( uiC ); + signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x7FF ) { + if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN_ABC; + magBits = expB | sigB; + goto infProdArg; + } + if ( expB == 0x7FF ) { + if ( sigB ) goto propagateNaN_ABC; + magBits = expA | sigA; + goto infProdArg; + } + if ( expC == 0x7FF ) { + if ( sigC ) { + uiZ = 0; + goto propagateNaN_ZC; + } + uiZ = uiC; + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expA ) { + if ( ! sigA ) goto zeroProd; + normExpSig = softfloat_normSubnormalF64Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if ( ! expB ) { + if ( ! sigB ) goto zeroProd; + normExpSig = softfloat_normSubnormalF64Sig( sigB ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0x3FE; + sigA = (sigA | UINT64_C( 0x0010000000000000 ))<<10; + sigB = (sigB | UINT64_C( 0x0010000000000000 ))<<10; + sig128Z = softfloat_mul64To128( sigA, sigB ); + if ( sig128Z.v64 < UINT64_C( 0x2000000000000000 ) ) { + --expZ; + sig128Z = + softfloat_add128( + sig128Z.v64, sig128Z.v0, sig128Z.v64, sig128Z.v0 ); + } + if ( ! expC ) { + if ( ! sigC ) { + --expZ; + sigZ = sig128Z.v64<<1 | (sig128Z.v0 != 0); + goto roundPack; + } + normExpSig = softfloat_normSubnormalF64Sig( sigC ); + expC = normExpSig.exp; + sigC = normExpSig.sig; + } + sigC = (sigC | UINT64_C( 0x0010000000000000 ))<<9; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expZ - expC; + if ( expDiff < 0 ) { + expZ = expC; + if ( (signZ == signC) || (expDiff < -1) ) { + sig128Z.v64 = softfloat_shiftRightJam64( sig128Z.v64, -expDiff ); + } else { + sig128Z = + softfloat_shortShiftRightJam128( sig128Z.v64, sig128Z.v0, 1 ); + } + } else if ( expDiff ) { + sig128C = softfloat_shiftRightJam128( sigC, 0, expDiff ); + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( signZ == signC ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( expDiff <= 0 ) { + sigZ = (sigC + sig128Z.v64) | (sig128Z.v0 != 0); + } else { + sig128Z = + softfloat_add128( + sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0 ); + sigZ = sig128Z.v64 | (sig128Z.v0 != 0); + } + if ( sigZ < UINT64_C( 0x4000000000000000 ) ) { + --expZ; + sigZ <<= 1; + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( expDiff < 0 ) { + signZ = signC; + sig128Z = softfloat_sub128( sigC, 0, sig128Z.v64, sig128Z.v0 ); + } else if ( ! expDiff ) { + sig128Z.v64 = sig128Z.v64 - sigC; + if ( ! (sig128Z.v64 | sig128Z.v0) ) goto completeCancellation; + if ( sig128Z.v64 & UINT64_C( 0x8000000000000000 ) ) { + signZ ^= 1; + sig128Z = softfloat_sub128( 0, 0, sig128Z.v64, sig128Z.v0 ); + } + } else { + sig128Z = + softfloat_sub128( + sig128Z.v64, sig128Z.v0, sig128C.v64, sig128C.v0 ); + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( ! sig128Z.v64 ) { + expZ -= 64; + sig128Z.v64 = sig128Z.v0; + sig128Z.v0 = 0; + } + shiftCount = softfloat_countLeadingZeros64( sig128Z.v64 ) - 1; + expZ -= shiftCount; + if ( shiftCount < 0 ) { + sigZ = softfloat_shortShiftRightJam64( sig128Z.v64, -shiftCount ); + } else { + sig128Z = + softfloat_shortShiftLeft128( + sig128Z.v64, sig128Z.v0, shiftCount ); + sigZ = sig128Z.v64; + } + sigZ |= (sig128Z.v0 != 0); + } + roundPack: + return softfloat_roundPackToF64( signZ, expZ, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN_ABC: + uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); + goto propagateNaN_ZC; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infProdArg: + if ( magBits ) { + uiZ = packToF64UI( signZ, 0x7FF, 0 ); + if ( expC != 0x7FF ) goto uiZ; + if ( sigC ) goto propagateNaN_ZC; + if ( signZ == signC ) goto uiZ; + } + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF64UI; + propagateNaN_ZC: + uiZ = softfloat_propagateNaNF64UI( uiZ, uiC ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zeroProd: + uiZ = uiC; + if ( ! (expC | sigC) && (signZ != signC) ) { + completeCancellation: + uiZ = + packToF64UI( softfloat_roundingMode == softfloat_round_min, 0, 0 ); + } + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + +#else + +float64_t + softfloat_mulAddF64( + uint_fast64_t uiA, uint_fast64_t uiB, uint_fast64_t uiC, uint_fast8_t op ) +{ + bool signA; + int_fast16_t expA; + uint64_t sigA; + bool signB; + int_fast16_t expB; + uint64_t sigB; + bool signC; + int_fast16_t expC; + uint64_t sigC; + bool signZ; + uint64_t magBits, uiZ; + struct exp16_sig64 normExpSig; + int_fast16_t expZ; + uint32_t sig128Z[4]; + uint64_t sigZ; + int_fast16_t shiftCount, expDiff; + uint32_t sig128C[4]; + union ui64_f64 uZ; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + signA = signF64UI( uiA ); + expA = expF64UI( uiA ); + sigA = fracF64UI( uiA ); + signB = signF64UI( uiB ); + expB = expF64UI( uiB ); + sigB = fracF64UI( uiB ); + signC = signF64UI( uiC ) ^ (op == softfloat_mulAdd_subC); + expC = expF64UI( uiC ); + sigC = fracF64UI( uiC ); + signZ = signA ^ signB ^ (op == softfloat_mulAdd_subProd); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( expA == 0x7FF ) { + if ( sigA || ((expB == 0x7FF) && sigB) ) goto propagateNaN_ABC; + magBits = expB | sigB; + goto infProdArg; + } + if ( expB == 0x7FF ) { + if ( sigB ) goto propagateNaN_ABC; + magBits = expA | sigA; + goto infProdArg; + } + if ( expC == 0x7FF ) { + if ( sigC ) { + uiZ = 0; + goto propagateNaN_ZC; + } + uiZ = uiC; + goto uiZ; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( ! expA ) { + if ( ! sigA ) goto zeroProd; + normExpSig = softfloat_normSubnormalF64Sig( sigA ); + expA = normExpSig.exp; + sigA = normExpSig.sig; + } + if ( ! expB ) { + if ( ! sigB ) goto zeroProd; + normExpSig = softfloat_normSubnormalF64Sig( sigB ); + expB = normExpSig.exp; + sigB = normExpSig.sig; + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expZ = expA + expB - 0x3FE; + sigA = (sigA | UINT64_C( 0x0010000000000000 ))<<10; + sigB = (sigB | UINT64_C( 0x0010000000000000 ))<<11; + softfloat_mul64To128M( sigA, sigB, sig128Z ); + sigZ = + (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 | sig128Z[indexWord( 4, 2 )]; + shiftCount = 0; + if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) { + --expZ; + shiftCount = -1; + } + if ( ! expC ) { + if ( ! sigC ) { + if ( shiftCount ) sigZ <<= 1; + goto sigZ; + } + normExpSig = softfloat_normSubnormalF64Sig( sigC ); + expC = normExpSig.exp; + sigC = normExpSig.sig; + } + sigC = (sigC | UINT64_C( 0x0010000000000000 ))<<10; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + expDiff = expZ - expC; + if ( expDiff < 0 ) { + expZ = expC; + if ( (signZ == signC) || (expDiff < -1) ) { + shiftCount -= expDiff; + if ( shiftCount) { + sigZ = softfloat_shiftRightJam64( sigZ, shiftCount ); + } + } else { + if ( ! shiftCount ) { + softfloat_shortShiftRight128M( sig128Z, 1, sig128Z ); + } + } + } else { + if ( shiftCount ) softfloat_add128M( sig128Z, sig128Z, sig128Z ); + if ( ! expDiff ) { + sigZ = + (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 + | sig128Z[indexWord( 4, 2 )]; + } else { + sig128C[indexWord( 4, 3 )] = sigC>>32; + sig128C[indexWord( 4, 2 )] = sigC; + sig128C[indexWord( 4, 1 )] = 0; + sig128C[indexWord( 4, 0 )] = 0; + softfloat_shiftRightJam128M( sig128C, expDiff, sig128C ); + } + } + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + if ( signZ == signC ) { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( expDiff <= 0 ) { + sigZ += sigC; + } else { + softfloat_add128M( sig128Z, sig128C, sig128Z ); + sigZ = + (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 + | sig128Z[indexWord( 4, 2 )]; + } + if ( sigZ & UINT64_C( 0x8000000000000000 ) ) { + ++expZ; + sigZ = softfloat_shortShiftRightJam64( sigZ, 1 ); + } + } else { + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + if ( expDiff < 0 ) { + signZ = signC; + if ( expDiff < -1 ) { + sigZ = sigC - sigZ; + if ( + sig128Z[indexWord( 4, 1 )] || sig128Z[indexWord( 4, 0 )] + ) { + sigZ = (sigZ - 1) | 1; + } + if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) { + --expZ; + sigZ <<= 1; + } + goto roundPack; + } else { + sig128C[indexWord( 4, 3 )] = sigC>>32; + sig128C[indexWord( 4, 2 )] = sigC; + sig128C[indexWord( 4, 1 )] = 0; + sig128C[indexWord( 4, 0 )] = 0; + softfloat_sub128M( sig128C, sig128Z, sig128Z ); + } + } else if ( ! expDiff ) { + sigZ -= sigC; + if ( + ! sigZ && ! sig128Z[indexWord( 4, 1 )] + && ! sig128Z[indexWord( 4, 0 )] + ) { + goto completeCancellation; + } + sig128Z[indexWord( 4, 3 )] = sigZ>>32; + sig128Z[indexWord( 4, 2 )] = sigZ; + if ( sigZ & UINT64_C( 0x8000000000000000 ) ) { + signZ ^= 1; + softfloat_negX128M( sig128Z ); + } + } else { + softfloat_sub128M( sig128Z, sig128C, sig128Z ); + if ( 1 < expDiff ) { + sigZ = + (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 + | sig128Z[indexWord( 4, 2 )]; + if ( ! (sigZ & UINT64_C( 0x4000000000000000 )) ) { + --expZ; + sigZ <<= 1; + } + goto sigZ; + } + } + /*-------------------------------------------------------------------- + *--------------------------------------------------------------------*/ + shiftCount = 0; + sigZ = + (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 + | sig128Z[indexWord( 4, 2 )]; + if ( ! sigZ ) { + shiftCount = 64; + sigZ = + (uint64_t) sig128Z[indexWord( 4, 1 )]<<32 + | sig128Z[indexWord( 4, 0 )]; + } + shiftCount += softfloat_countLeadingZeros64( sigZ ) - 1; + if ( shiftCount ) { + expZ -= shiftCount; + softfloat_shiftLeft128M( sig128Z, shiftCount, sig128Z ); + sigZ = + (uint64_t) sig128Z[indexWord( 4, 3 )]<<32 + | sig128Z[indexWord( 4, 2 )]; + } + } + sigZ: + if ( sig128Z[indexWord( 4, 1 )] || sig128Z[indexWord( 4, 0 )] ) sigZ |= 1; + roundPack: + return softfloat_roundPackToF64( signZ, expZ - 1, sigZ ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + propagateNaN_ABC: + uiZ = softfloat_propagateNaNF64UI( uiA, uiB ); + goto propagateNaN_ZC; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + infProdArg: + if ( magBits ) { + uiZ = packToF64UI( signZ, 0x7FF, 0 ); + if ( expC != 0x7FF ) goto uiZ; + if ( sigC ) goto propagateNaN_ZC; + if ( signZ == signC ) goto uiZ; + } + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + uiZ = defaultNaNF64UI; + propagateNaN_ZC: + uiZ = softfloat_propagateNaNF64UI( uiZ, uiC ); + goto uiZ; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + zeroProd: + uiZ = uiC; + if ( ! (expC | sigC) && (signZ != signC) ) { + completeCancellation: + uiZ = + packToF64UI( softfloat_roundingMode == softfloat_round_min, 0, 0 ); + } + uiZ: + uZ.ui = uiZ; + return uZ.f; + +} + +#endif + diff --git a/softfloat/s_negXM.c b/softfloat/s_negXM.c new file mode 100644 index 0000000..4c80aa9 --- /dev/null +++ b/softfloat/s_negXM.c @@ -0,0 +1,63 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_negXM + +void softfloat_negXM( uint_fast8_t size_words, uint32_t *zPtr ) +{ + unsigned int index, lastIndex; + uint_fast8_t carry; + uint32_t word; + + index = indexWordLo( size_words ); + lastIndex = indexWordHi( size_words ); + carry = 1; + for (;;) { + word = ~zPtr[index] + carry; + zPtr[index] = word; + if ( index == lastIndex ) break; + index += wordIncr; + if ( word ) carry = 0; + } + +} + +#endif + diff --git a/softfloat/s_normRoundPackToF32.c b/softfloat/s_normRoundPackToF32.c old mode 100755 new mode 100644 index 2e6f4b0..fea073c --- a/softfloat/s_normRoundPackToF32.c +++ b/softfloat/s_normRoundPackToF32.c @@ -1,24 +1,58 @@ - -#include -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" - -float32_t - softfloat_normRoundPackToF32( bool sign, int_fast16_t exp, uint_fast32_t sig ) -{ - int shiftCount; - union ui32_f32 uZ; - - shiftCount = softfloat_countLeadingZeros32( sig ) - 1; - exp -= shiftCount; - if ( ( 7 <= shiftCount ) && ( (uint16_t) exp < 0xFD ) ) { - uZ.ui = packToF32UI( sign, sig ? exp : 0, sig<<( shiftCount - 7 ) ); - return uZ.f; - } else { - return softfloat_roundPackToF32( sign, exp, sig< +#include +#include "platform.h" +#include "internals.h" + +float32_t + softfloat_normRoundPackToF32( bool sign, int_fast16_t exp, uint_fast32_t sig ) +{ + int_fast8_t shiftCount; + union ui32_f32 uZ; + + shiftCount = softfloat_countLeadingZeros32( sig ) - 1; + exp -= shiftCount; + if ( (7 <= shiftCount) && ((uint16_t) exp < 0xFD) ) { + uZ.ui = packToF32UI( sign, sig ? exp : 0, sig<<(shiftCount - 7) ); + return uZ.f; + } else { + return softfloat_roundPackToF32( sign, exp, sig< -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" - -float64_t - softfloat_normRoundPackToF64( bool sign, int_fast16_t exp, uint_fast64_t sig ) -{ - int shiftCount; - union ui64_f64 uZ; - - shiftCount = softfloat_countLeadingZeros64( sig ) - 1; - exp -= shiftCount; - if ( ( 10 <= shiftCount ) && ( (uint16_t) exp < 0x7FD ) ) { - uZ.ui = packToF64UI( sign, sig ? exp : 0, sig<<( shiftCount - 10 ) ); - return uZ.f; - } else { - return softfloat_roundPackToF64( sign, exp, sig< +#include +#include "platform.h" +#include "internals.h" + +float64_t + softfloat_normRoundPackToF64( bool sign, int_fast16_t exp, uint_fast64_t sig ) +{ + int_fast8_t shiftCount; + union ui64_f64 uZ; + + shiftCount = softfloat_countLeadingZeros64( sig ) - 1; + exp -= shiftCount; + if ( (10 <= shiftCount) && ((uint16_t) exp < 0x7FD) ) { + uZ.ui = packToF64UI( sign, sig ? exp : 0, sig<<(shiftCount - 10) ); + return uZ.f; + } else { + return softfloat_roundPackToF64( sign, exp, sig< -#include "platform.h" -#include "primitives.h" -#include "internals.h" - -struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t sig ) -{ - int shiftCount; - struct exp16_sig32 z; - - shiftCount = softfloat_countLeadingZeros32( sig ) - 8; - z.exp = 1 - shiftCount; - z.sig = sig< +#include "platform.h" +#include "internals.h" + +struct exp16_sig32 softfloat_normSubnormalF32Sig( uint_fast32_t sig ) +{ + int_fast8_t shiftCount; + struct exp16_sig32 z; + + shiftCount = softfloat_countLeadingZeros32( sig ) - 8; + z.exp = 1 - shiftCount; + z.sig = sig< -#include "platform.h" -#include "primitives.h" -#include "internals.h" - -struct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t sig ) -{ - int shiftCount; - struct exp16_sig64 z; - - shiftCount = softfloat_countLeadingZeros64( sig ) - 11; - z.exp = 1 - shiftCount; - z.sig = sig< +#include "platform.h" +#include "internals.h" + +struct exp16_sig64 softfloat_normSubnormalF64Sig( uint_fast64_t sig ) +{ + int_fast8_t shiftCount; + struct exp16_sig64 z; + + shiftCount = softfloat_countLeadingZeros64( sig ) - 11; + z.exp = 1 - shiftCount; + z.sig = sig< -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Takes two single-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ - -uint_fast32_t - softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ) -{ - if ( softfloat_isSigNaNF32UI( uiA ) | softfloat_isSigNaNF32UI( uiB ) ) { - softfloat_raiseFlags( softfloat_flag_invalid ); - } - return defaultNaNF32UI; -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "specialize.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Interpreting `uiA' and `uiB' as the bit patterns of two 32-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either `uiA' or `uiB' has the pattern of a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +uint_fast32_t + softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ) +{ + + if ( softfloat_isSigNaNF32UI( uiA ) || softfloat_isSigNaNF32UI( uiB ) ) { + softfloat_raiseFlags( softfloat_flag_invalid ); + } + return defaultNaNF32UI; + +} + diff --git a/softfloat/s_propagateNaNF64UI.c b/softfloat/s_propagateNaNF64UI.c old mode 100755 new mode 100644 index 871989d..5868225 --- a/softfloat/s_propagateNaNF64UI.c +++ b/softfloat/s_propagateNaNF64UI.c @@ -1,25 +1,58 @@ -/*** UPDATE COMMENTS. ***/ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ -#include #include #include "platform.h" -#include "internals.h" #include "specialize.h" #include "softfloat.h" /*---------------------------------------------------------------------------- -| Takes two double-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a +| Interpreting `uiA' and `uiB' as the bit patterns of two 64-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either `uiA' or `uiB' has the pattern of a | signaling NaN, the invalid exception is raised. *----------------------------------------------------------------------------*/ - uint_fast64_t softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ) { - if ( softfloat_isSigNaNF64UI( uiA ) | softfloat_isSigNaNF64UI( uiB ) ) { + + if ( softfloat_isSigNaNF64UI( uiA ) || softfloat_isSigNaNF64UI( uiB ) ) { softfloat_raiseFlags( softfloat_flag_invalid ); } return defaultNaNF64UI; + } diff --git a/softfloat/s_remStepMBy32.c b/softfloat/s_remStepMBy32.c new file mode 100644 index 0000000..429d3dc --- /dev/null +++ b/softfloat/s_remStepMBy32.c @@ -0,0 +1,87 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_remStepMBy32 + +void + softfloat_remStepMBy32( + uint_fast8_t size_words, + const uint32_t *remPtr, + uint_fast8_t count, + const uint32_t *bPtr, + uint32_t q, + uint32_t *zPtr + ) +{ + uint_fast8_t negCount; + unsigned int index, lastIndex; + uint64_t dwordProd; + uint32_t wordRem, wordShiftedRem, wordProd; + uint_fast8_t borrow; + + negCount = -count; + index = indexWordLo( size_words ); + lastIndex = indexWordHi( size_words ); + dwordProd = (uint64_t) bPtr[index] * q; + wordRem = remPtr[index]; + wordShiftedRem = wordRem<>(negCount & 31); + index += wordIncr; + dwordProd = (uint64_t) bPtr[index] * q + (dwordProd>>32); + wordRem = remPtr[index]; + wordShiftedRem |= wordRem< +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +int_fast64_t + softfloat_roundPackMToI64( + bool sign, uint32_t *extSigPtr, uint_fast8_t roundingMode, bool exact ) +{ + bool roundNearEven; + uint32_t sigExtra; + bool doIncrement; + uint64_t sig; + union { uint64_t ui; int64_t i; } uZ; + int64_t z; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); + sigExtra = extSigPtr[indexWordLo( 3 )]; + doIncrement = (0x80000000 <= sigExtra); + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + doIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + && sigExtra; + } + sig = + (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32 + | extSigPtr[indexWord( 3, 1 )]; + if ( doIncrement ) { + ++sig; + if ( ! sig ) goto invalid; + if ( ! (sigExtra & 0x7FFFFFFF) && roundNearEven ) sig &= ~1; + } + uZ.ui = sign ? -sig : sig; + z = uZ.i; + if ( z && ((z < 0) ^ sign) ) goto invalid; + if ( exact && sigExtra ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return sign ? i64_fromNegOverflow : i64_fromPosOverflow; + +} + diff --git a/softfloat/s_roundPackMToUI64.c b/softfloat/s_roundPackMToUI64.c new file mode 100644 index 0000000..1a64fdf --- /dev/null +++ b/softfloat/s_roundPackMToUI64.c @@ -0,0 +1,84 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast64_t + softfloat_roundPackMToUI64( + bool sign, uint32_t *extSigPtr, uint_fast8_t roundingMode, bool exact ) +{ + bool roundNearEven; + uint32_t sigExtra; + bool doIncrement; + uint64_t sig; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); + sigExtra = extSigPtr[indexWordLo( 3 )]; + doIncrement = (0x80000000 <= sigExtra); + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + doIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + && sigExtra; + } + sig = + (uint64_t) extSigPtr[indexWord( 3, 2 )]<<32 + | extSigPtr[indexWord( 3, 1 )]; + if ( doIncrement ) { + ++sig; + if ( ! sig ) goto invalid; + if ( ! (sigExtra & 0x7FFFFFFF) && roundNearEven ) sig &= ~1; + } + if ( sign && sig ) goto invalid; + if ( exact && sigExtra ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } + return sig; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + invalid: + softfloat_raiseFlags( softfloat_flag_invalid ); + return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; + +} + diff --git a/softfloat/s_roundPackToF32.c b/softfloat/s_roundPackToF32.c old mode 100755 new mode 100644 index 11764f1..8b44a03 --- a/softfloat/s_roundPackToF32.c +++ b/softfloat/s_roundPackToF32.c @@ -1,52 +1,80 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" -#include "primitives.h" #include "internals.h" #include "softfloat.h" float32_t softfloat_roundPackToF32( bool sign, int_fast16_t exp, uint_fast32_t sig ) { - int roundingMode; - bool roundNearestEven; - int roundIncrement, roundBits; + uint_fast8_t roundingMode; + bool roundNearEven; + uint_fast8_t roundIncrement, roundBits; bool isTiny; uint_fast32_t uiZ; union ui32_f32 uZ; roundingMode = softfloat_roundingMode; - roundNearestEven = ( roundingMode == softfloat_round_nearest_even ); + roundNearEven = (roundingMode == softfloat_round_near_even); roundIncrement = 0x40; - if ( - ! roundNearestEven - && ( roundingMode != softfloat_round_nearest_maxMag ) - ) { + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { roundIncrement = - ( roundingMode == softfloat_round_minMag ) - || ( roundingMode - == ( sign ? softfloat_round_max : softfloat_round_min ) ) - ? 0 - : 0x7F; + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + ? 0x7F + : 0; } roundBits = sig & 0x7F; if ( 0xFD <= (uint16_t) exp ) { if ( exp < 0 ) { isTiny = - ( softfloat_detectTininess - == softfloat_tininess_beforeRounding ) - || ( exp < -1 ) - || ( sig + roundIncrement < 0x80000000 ); - sig = softfloat_shift32RightJam( sig, - exp ); + (softfloat_detectTininess + == softfloat_tininess_beforeRounding) + || (exp < -1) + || (sig + roundIncrement < 0x80000000); + sig = softfloat_shiftRightJam32( sig, -exp ); exp = 0; roundBits = sig & 0x7F; if ( isTiny && roundBits ) { softfloat_raiseFlags( softfloat_flag_underflow ); } - } else if ( - ( 0xFD < exp ) || ( 0x80000000 <= sig + roundIncrement ) - ) { + } else if ( (0xFD < exp) || (0x80000000 <= sig + roundIncrement) ) { softfloat_raiseFlags( softfloat_flag_overflow | softfloat_flag_inexact ); uiZ = packToF32UI( sign, 0xFF, 0 ) - ! roundIncrement; @@ -54,8 +82,8 @@ float32_t } } if ( roundBits ) softfloat_exceptionFlags |= softfloat_flag_inexact; - sig = ( sig + roundIncrement )>>7; - sig &= ~ ( ! ( roundBits ^ 0x40 ) & roundNearestEven ); + sig = (sig + roundIncrement)>>7; + sig &= ~(uint_fast32_t) (! (roundBits ^ 0x40) & roundNearEven); uiZ = packToF32UI( sign, sig ? exp : 0, sig ); uiZ: uZ.ui = uiZ; diff --git a/softfloat/s_roundPackToF64.c b/softfloat/s_roundPackToF64.c old mode 100755 new mode 100644 index fb0ef1d..e56493e --- a/softfloat/s_roundPackToF64.c +++ b/softfloat/s_roundPackToF64.c @@ -1,52 +1,82 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" -#include "primitives.h" #include "internals.h" #include "softfloat.h" float64_t softfloat_roundPackToF64( bool sign, int_fast16_t exp, uint_fast64_t sig ) { - int roundingMode; - bool roundNearestEven; - int roundIncrement, roundBits; + uint_fast8_t roundingMode; + bool roundNearEven; + uint_fast16_t roundIncrement, roundBits; bool isTiny; uint_fast64_t uiZ; union ui64_f64 uZ; roundingMode = softfloat_roundingMode; - roundNearestEven = ( roundingMode == softfloat_round_nearest_even ); + roundNearEven = (roundingMode == softfloat_round_near_even); roundIncrement = 0x200; - if ( - ! roundNearestEven - && ( roundingMode != softfloat_round_nearest_maxMag ) - ) { + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { roundIncrement = - ( roundingMode == softfloat_round_minMag ) - || ( roundingMode - == ( sign ? softfloat_round_max : softfloat_round_min ) ) - ? 0 - : 0x3FF; + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + ? 0x3FF + : 0; } roundBits = sig & 0x3FF; if ( 0x7FD <= (uint16_t) exp ) { if ( exp < 0 ) { isTiny = - ( softfloat_detectTininess - == softfloat_tininess_beforeRounding ) - || ( exp < -1 ) - || ( sig + roundIncrement < UINT64_C( 0x8000000000000000 ) ); - sig = softfloat_shift64RightJam( sig, - exp ); + (softfloat_detectTininess + == softfloat_tininess_beforeRounding) + || (exp < -1) + || (sig + roundIncrement < UINT64_C( 0x8000000000000000 )); + sig = softfloat_shiftRightJam64( sig, -exp ); exp = 0; roundBits = sig & 0x3FF; if ( isTiny && roundBits ) { softfloat_raiseFlags( softfloat_flag_underflow ); } } else if ( - ( 0x7FD < exp ) - || ( UINT64_C( 0x8000000000000000 ) <= sig + roundIncrement ) + (0x7FD < exp) + || (UINT64_C( 0x8000000000000000 ) <= sig + roundIncrement) ) { softfloat_raiseFlags( softfloat_flag_overflow | softfloat_flag_inexact ); @@ -55,8 +85,8 @@ float64_t } } if ( roundBits ) softfloat_exceptionFlags |= softfloat_flag_inexact; - sig = ( sig + roundIncrement )>>10; - sig &= ~ ( ! ( roundBits ^ 0x200 ) & roundNearestEven ); + sig = (sig + roundIncrement)>>10; + sig &= ~(uint_fast64_t) (! (roundBits ^ 0x200) & roundNearEven); uiZ = packToF64UI( sign, sig ? exp : 0, sig ); uiZ: uZ.ui = uiZ; diff --git a/softfloat/s_roundPackToI32.c b/softfloat/s_roundPackToI32.c old mode 100755 new mode 100644 index 1c91497..3ece8f0 --- a/softfloat/s_roundPackToI32.c +++ b/softfloat/s_roundPackToI32.c @@ -1,48 +1,84 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast32_t softfloat_roundPackToI32( - bool sign, uint_fast64_t sig, int_fast8_t roundingMode, bool exact ) + bool sign, uint_fast64_t sig, uint_fast8_t roundingMode, bool exact ) { - bool roundNearestEven; - int roundIncrement, roundBits; + bool roundNearEven; + uint_fast8_t roundIncrement, roundBits; uint_fast32_t sig32; union { uint32_t ui; int32_t i; } uZ; int_fast32_t z; - roundNearestEven = ( roundingMode == softfloat_round_nearest_even ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); roundIncrement = 0x40; - if ( - ! roundNearestEven - && ( roundingMode != softfloat_round_nearest_maxMag ) - ) { + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { roundIncrement = - ( roundingMode == softfloat_round_minMag ) - || ( roundingMode - == ( sign ? softfloat_round_max : softfloat_round_min ) ) - ? 0 - : 0x7F; + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + ? 0x7F + : 0; } roundBits = sig & 0x7F; sig += roundIncrement; if ( sig & UINT64_C( 0xFFFFFF8000000000 ) ) goto invalid; sig32 = sig>>7; - sig32 &= ~ ( ! ( roundBits ^ 0x40 ) & roundNearestEven ); - uZ.ui = sign ? - sig32 : sig32; + sig32 &= ~(uint_fast32_t) (! (roundBits ^ 0x40) & roundNearEven); + uZ.ui = sign ? -sig32 : sig32; z = uZ.i; - if ( z && ( ( z < 0 ) ^ sign ) ) goto invalid; + if ( z && ((z < 0) ^ sign) ) goto invalid; if ( exact && roundBits ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return sign ? -0x7FFFFFFF - 1 : 0x7FFFFFFF; + return sign ? i32_fromNegOverflow : i32_fromPosOverflow; } diff --git a/softfloat/s_roundPackToI64.c b/softfloat/s_roundPackToI64.c old mode 100755 new mode 100644 index b2f5d63..ebef7f3 --- a/softfloat/s_roundPackToI64.c +++ b/softfloat/s_roundPackToI64.c @@ -1,52 +1,89 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" int_fast64_t softfloat_roundPackToI64( bool sign, - uint_fast64_t sig64, - uint_fast64_t sig0, - int_fast8_t roundingMode, + uint_fast64_t sig, + uint_fast64_t sigExtra, + uint_fast8_t roundingMode, bool exact ) { - bool roundNearestEven, increment; + bool roundNearEven, doIncrement; union { uint64_t ui; int64_t i; } uZ; int_fast64_t z; - roundNearestEven = ( roundingMode == softfloat_round_nearest_even ); - increment = ( UINT64_C( 0x8000000000000000 ) <= sig0 ); - if ( - ! roundNearestEven - && ( roundingMode != softfloat_round_nearest_maxMag ) - ) { - increment = - ( roundingMode != softfloat_round_minMag ) - && ( roundingMode - == ( sign ? softfloat_round_min : softfloat_round_max ) ) - && sig0; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); + doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + doIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + && sigExtra; } - if ( increment ) { - ++sig64; - if ( ! sig64 ) goto invalid; - sig64 &= - ~ ( ! ( sig0 & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) - & roundNearestEven ); + if ( doIncrement ) { + ++sig; + if ( ! sig ) goto invalid; + sig &= + ~(uint_fast64_t) + (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + & roundNearEven); } - uZ.ui = sign ? - sig64 : sig64; + uZ.ui = sign ? -sig : sig; z = uZ.i; - if ( z && ( ( z < 0 ) ^ sign ) ) goto invalid; - if ( exact && sig0 ) softfloat_exceptionFlags |= softfloat_flag_inexact; + if ( z && ((z < 0) ^ sign) ) goto invalid; + if ( exact && sigExtra ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; + } return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return - sign ? - INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1 - : INT64_C( 0x7FFFFFFFFFFFFFFF ); + return sign ? i64_fromNegOverflow : i64_fromPosOverflow; } diff --git a/softfloat/s_roundPackToUI32.c b/softfloat/s_roundPackToUI32.c old mode 100755 new mode 100644 index ab44ec7..f0021fe --- a/softfloat/s_roundPackToUI32.c +++ b/softfloat/s_roundPackToUI32.c @@ -1,44 +1,80 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast32_t softfloat_roundPackToUI32( - bool sign, uint_fast64_t sig, int_fast8_t roundingMode, bool exact ) + bool sign, uint_fast64_t sig, uint_fast8_t roundingMode, bool exact ) { - bool roundNearestEven; - int roundIncrement, roundBits; + bool roundNearEven; + uint_fast8_t roundIncrement, roundBits; uint_fast32_t z; - roundNearestEven = ( roundingMode == softfloat_round_nearest_even ); + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); roundIncrement = 0x40; - if ( - ! roundNearestEven - && ( roundingMode != softfloat_round_nearest_maxMag ) - ) { + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { roundIncrement = - ( roundingMode == softfloat_round_minMag ) - || ( roundingMode - == ( sign ? softfloat_round_max : softfloat_round_min ) ) - ? 0 - : 0x7F; + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + ? 0x7F + : 0; } roundBits = sig & 0x7F; sig += roundIncrement; if ( sig & UINT64_C( 0xFFFFFF8000000000 ) ) goto invalid; z = sig>>7; - z &= ~ ( ! ( roundBits ^ 0x40 ) & roundNearestEven ); + z &= ~(uint_fast32_t) (! (roundBits ^ 0x40) & roundNearEven); if ( sign && z ) goto invalid; if ( exact && roundBits ) { softfloat_exceptionFlags |= softfloat_flag_inexact; } return z; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return 0xFFFFFFFF; + return sign ? ui32_fromNegOverflow : ui32_fromPosOverflow; } diff --git a/softfloat/s_roundPackToUI64.c b/softfloat/s_roundPackToUI64.c old mode 100755 new mode 100644 index d42266f..fada184 --- a/softfloat/s_roundPackToUI64.c +++ b/softfloat/s_roundPackToUI64.c @@ -1,46 +1,85 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" #include "internals.h" +#include "specialize.h" #include "softfloat.h" uint_fast64_t softfloat_roundPackToUI64( bool sign, - uint_fast64_t sig64, - uint_fast64_t sig0, - int_fast8_t roundingMode, + uint_fast64_t sig, + uint_fast64_t sigExtra, + uint_fast8_t roundingMode, bool exact ) { - bool roundNearestEven, increment; - - roundNearestEven = ( roundingMode == softfloat_round_nearest_even ); - increment = ( UINT64_C( 0x8000000000000000 ) <= sig0 ); - if ( - ! roundNearestEven - && ( roundingMode != softfloat_round_nearest_maxMag ) - ) { - increment = - ( roundingMode != softfloat_round_minMag ) - && ( roundingMode - == ( sign ? softfloat_round_min : softfloat_round_max ) ) - && sig0; + bool roundNearEven, doIncrement; + + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ + roundNearEven = (roundingMode == softfloat_round_near_even); + doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra); + if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) { + doIncrement = + (roundingMode + == (sign ? softfloat_round_min : softfloat_round_max)) + && sigExtra; + } + if ( doIncrement ) { + ++sig; + if ( ! sig ) goto invalid; + sig &= + ~(uint_fast64_t) + (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF )) + & roundNearEven); } - if ( increment ) { - ++sig64; - if ( ! sig64 ) goto invalid; - sig64 &= - ~ ( ! ( sig0 & UINT64_C( 0x7FFFFFFFFFFFFFFF ) ) - & roundNearestEven ); + if ( sign && sig ) goto invalid; + if ( exact && sigExtra ) { + softfloat_exceptionFlags |= softfloat_flag_inexact; } - if ( sign && sig64 ) goto invalid; - if ( exact && sig0 ) softfloat_exceptionFlags |= softfloat_flag_inexact; - return sig64; + return sig; + /*------------------------------------------------------------------------ + *------------------------------------------------------------------------*/ invalid: softfloat_raiseFlags( softfloat_flag_invalid ); - return UINT64_C( 0xFFFFFFFFFFFFFFFF ); + return sign ? ui64_fromNegOverflow : ui64_fromPosOverflow; } diff --git a/softfloat/s_shift128ExtraRightJam.c b/softfloat/s_shift128ExtraRightJam.c deleted file mode 100755 index 6c57974..0000000 --- a/softfloat/s_shift128ExtraRightJam.c +++ /dev/null @@ -1,38 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint128_extra - softfloat_shift128ExtraRightJam( - uint64_t a64, uint64_t a0, uint64_t extra, unsigned int count ) -{ - unsigned int negCount; - struct uint128_extra z; - - negCount = - count; - if ( count < 64 ) { - z.v64 = a64>>count; - z.v0 = a64<<( negCount & 63 ) | a0>>count; - z.extra = a0<<( negCount & 63 ); - } else { - z.v64 = 0; - if ( count == 64 ) { - z.v0 = a64; - z.extra = a0; - } else { - extra |= a0; - if ( count < 128 ) { - z.v0 = a64>>( count & 63 ); - z.extra = a64<<( negCount & 63 ); - } else { - z.v0 = 0; - z.extra = ( count == 128 ) ? a64 : ( a64 != 0 ); - } - } - } - z.extra |= ( extra != 0 ); - return z; - -} - diff --git a/softfloat/s_shift128RightJam.c b/softfloat/s_shift128RightJam.c deleted file mode 100755 index 5a4e188..0000000 --- a/softfloat/s_shift128RightJam.c +++ /dev/null @@ -1,31 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint128 - softfloat_shift128RightJam( uint64_t a64, uint64_t a0, unsigned int count ) -{ - unsigned int negCount; - struct uint128 z; - - if ( count < 64 ) { - negCount = - count; - z.v64 = a64>>( count & 63 ); - z.v0 = - a64<<( negCount & 63 ) | a0>>count - | ( (uint64_t) ( a0<<( negCount & 63 ) ) != 0 ); - } else { - z.v64 = 0; - z.v0 = - ( count < 128 ) - ? a64>>( count & 63 ) - | ( ( ( a64 & ( ( (uint64_t) 1<<( count & 63 ) ) - 1 ) ) - | a0 ) - != 0 ) - : ( ( a64 | a0 ) != 0 ); - } - return z; - -} - diff --git a/softfloat/s_shift32RightJam.c b/softfloat/s_shift32RightJam.c deleted file mode 100755 index b697a34..0000000 --- a/softfloat/s_shift32RightJam.c +++ /dev/null @@ -1,15 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -uint32_t softfloat_shift32RightJam( uint32_t a, unsigned int count ) -{ - - return - ( count < 32 ) - ? a>>count | ( (uint32_t) ( a<<( ( - count ) & 31 ) ) != 0 ) - : ( a != 0 ); - -} - diff --git a/softfloat/s_shift64ExtraRightJam.c b/softfloat/s_shift64ExtraRightJam.c deleted file mode 100755 index 167ea54..0000000 --- a/softfloat/s_shift64ExtraRightJam.c +++ /dev/null @@ -1,23 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint64_extra - softfloat_shift64ExtraRightJam( - uint64_t a, uint64_t extra, unsigned int count ) -{ - struct uint64_extra z; - - if ( count < 64 ) { - z.v = a>>count; - z.extra = a<<( ( - count ) & 63 ); - } else { - z.v = 0; - z.extra = ( count == 64 ) ? a : ( a != 0 ); - } - z.extra |= ( extra != 0 ); - return z; - -} - diff --git a/softfloat/s_shift64RightJam.c b/softfloat/s_shift64RightJam.c deleted file mode 100755 index ebebb61..0000000 --- a/softfloat/s_shift64RightJam.c +++ /dev/null @@ -1,15 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -uint64_t softfloat_shift64RightJam( uint64_t a, unsigned int count ) -{ - - return - ( count < 64 ) - ? a>>count | ( (uint64_t) ( a<<( ( - count ) & 63 ) ) != 0 ) - : ( a != 0 ); - -} - diff --git a/softfloat/s_shiftRightJam128.c b/softfloat/s_shiftRightJam128.c new file mode 100644 index 0000000..4e8a88f --- /dev/null +++ b/softfloat/s_shiftRightJam128.c @@ -0,0 +1,69 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shiftRightJam128 + +struct uint128 + softfloat_shiftRightJam128( uint64_t a64, uint64_t a0, uint_fast32_t count ) +{ + int_fast32_t negCount; + struct uint128 z; + + if ( count < 64 ) { + negCount = -count; + z.v64 = a64>>count; + z.v0 = + a64<<(negCount & 63) | a0>>count + | ((uint64_t) (a0<<(negCount & 63)) != 0); + } else { + z.v64 = 0; + z.v0 = + (count < 127) + ? a64>>(count & 63) + | (((a64 & (((uint_fast64_t) 1<<(count & 63)) - 1)) | a0) + != 0) + : ((a64 | a0) != 0); + } + return z; + +} + +#endif + diff --git a/softfloat/s_shiftRightJam32.c b/softfloat/s_shiftRightJam32.c new file mode 100644 index 0000000..e1df875 --- /dev/null +++ b/softfloat/s_shiftRightJam32.c @@ -0,0 +1,52 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" + +#ifndef softfloat_shiftRightJam32 + +uint32_t softfloat_shiftRightJam32( uint32_t a, uint_fast16_t count ) +{ + + return + (count < 31) ? a>>count | ((uint32_t) (a<<(-count & 31)) != 0) + : (a != 0); + +} + +#endif + diff --git a/softfloat/s_shiftRightJam64.c b/softfloat/s_shiftRightJam64.c new file mode 100644 index 0000000..876640d --- /dev/null +++ b/softfloat/s_shiftRightJam64.c @@ -0,0 +1,52 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" + +#ifndef softfloat_shiftRightJam64 + +uint64_t softfloat_shiftRightJam64( uint64_t a, uint_fast32_t count ) +{ + + return + (count < 63) ? a>>count | ((uint64_t) (a<<(-count & 63)) != 0) + : (a != 0); + +} + +#endif + diff --git a/softfloat/s_shiftRightJam64Extra.c b/softfloat/s_shiftRightJam64Extra.c new file mode 100644 index 0000000..df31362 --- /dev/null +++ b/softfloat/s_shiftRightJam64Extra.c @@ -0,0 +1,62 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shiftRightJam64Extra + +struct uint64_extra + softfloat_shiftRightJam64Extra( + uint64_t a, uint64_t extra, uint_fast32_t count ) +{ + struct uint64_extra z; + + if ( count < 64 ) { + z.v = a>>count; + z.extra = a<<(-count & 63); + } else { + z.v = 0; + z.extra = (count == 64) ? a : (a != 0); + } + z.extra |= (extra != 0); + return z; + +} + +#endif + diff --git a/softfloat/s_shortShift128ExtraRightJam.c b/softfloat/s_shortShift128ExtraRightJam.c deleted file mode 100755 index c772740..0000000 --- a/softfloat/s_shortShift128ExtraRightJam.c +++ /dev/null @@ -1,20 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint128_extra - softfloat_shortShift128ExtraRightJam( - uint64_t a64, uint64_t a0, uint64_t extra, unsigned int count ) -{ - unsigned int negCount; - struct uint128_extra z; - - negCount = - count; - z.v64 = a64>>count; - z.v0 = a64<<( negCount & 63 ) | a0>>count; - z.extra = a0<<( negCount & 63 ) | ( extra != 0 ); - return z; - -} - diff --git a/softfloat/s_shortShift128Left.c b/softfloat/s_shortShift128Left.c deleted file mode 100755 index 9c29988..0000000 --- a/softfloat/s_shortShift128Left.c +++ /dev/null @@ -1,16 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint128 - softfloat_shortShift128Left( uint64_t a64, uint64_t a0, unsigned int count ) -{ - struct uint128 z; - - z.v64 = a64<>( ( - count ) & 63 ); - z.v0 = a0< -#include "platform.h" -#include "primitives.h" - -struct uint128 - softfloat_shortShift128Right( uint64_t a64, uint64_t a0, unsigned int count ) -{ - struct uint128 z; - - z.v64 = a64>>count; - z.v0 = a64<<( ( - count ) & 63 ) | a0>>count; - return z; - -} - diff --git a/softfloat/s_shortShift192Left.c b/softfloat/s_shortShift192Left.c deleted file mode 100755 index cf1e55d..0000000 --- a/softfloat/s_shortShift192Left.c +++ /dev/null @@ -1,20 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint192 - softfloat_shortShift192Left( - uint64_t a128, uint64_t a64, uint64_t a0, unsigned int count ) -{ - unsigned int negCount; - struct uint192 z; - - negCount = - count; - z.v128 = a128<>( negCount & 63 ); - z.v64 = a64<>( negCount & 63 ); - z.v0 = a0< -#include "platform.h" -#include "primitives.h" - -uint32_t softfloat_shortShift32Right1Jam( uint32_t a ) -{ - - return a>>1 | ( a & 1 ); - -} - diff --git a/softfloat/s_shortShift64ExtraRightJam.c b/softfloat/s_shortShift64ExtraRightJam.c deleted file mode 100755 index b861c67..0000000 --- a/softfloat/s_shortShift64ExtraRightJam.c +++ /dev/null @@ -1,17 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint64_extra - softfloat_shortShift64ExtraRightJam( - uint64_t a, uint64_t extra, unsigned int count ) -{ - struct uint64_extra z; - - z.v = a>>count; - z.extra = a<<( ( - count ) & 63 ) | ( extra != 0 ); - return z; - -} - diff --git a/softfloat/s_shortShift64RightJam.c b/softfloat/s_shortShift64RightJam.c deleted file mode 100755 index 0da6c93..0000000 --- a/softfloat/s_shortShift64RightJam.c +++ /dev/null @@ -1,12 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -uint64_t softfloat_shortShift64RightJam( uint64_t a, unsigned int count ) -{ - - return a>>count | ( ( a & ( ( (uint64_t) 1< +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shortShiftLeft64To96M + +void + softfloat_shortShiftLeft64To96M( + uint64_t a, uint_fast8_t count, uint32_t *zPtr ) +{ + + zPtr[indexWord( 3, 0 )] = (uint32_t) a<>= 32 - count; + zPtr[indexWord( 3, 2 )] = a>>32; + zPtr[indexWord( 3, 1 )] = a; + +} + +#endif + diff --git a/softfloat/s_shortShiftLeftM.c b/softfloat/s_shortShiftLeftM.c new file mode 100644 index 0000000..acb3e29 --- /dev/null +++ b/softfloat/s_shortShiftLeftM.c @@ -0,0 +1,70 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shortShiftLeftM + +void + softfloat_shortShiftLeftM( + uint_fast8_t size_words, + const uint32_t *aPtr, + uint_fast8_t count, + uint32_t *zPtr + ) +{ + uint_fast8_t negCount; + unsigned int index, lastIndex; + uint32_t partWordZ, wordA; + + negCount = -count; + index = indexWordHi( size_words ); + lastIndex = indexWordLo( size_words ); + partWordZ = aPtr[index]<>(negCount & 31); + index -= wordIncr; + partWordZ = wordA< +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shortShiftRightExtendM + +void + softfloat_shortShiftRightExtendM( + uint_fast8_t size_words, + const uint32_t *aPtr, + uint_fast8_t count, + uint32_t *zPtr + ) +{ + uint_fast8_t negCount; + unsigned int indexA, lastIndexA; + uint32_t partWordZ, wordA; + + negCount = -count; + indexA = indexWordLo( size_words ); + lastIndexA = indexWordHi( size_words ); + zPtr += indexWordLo( size_words + 1 ); + partWordZ = 0; + for (;;) { + wordA = aPtr[indexA]; + *zPtr = wordA<<(negCount & 31) | partWordZ; + zPtr += wordIncr; + partWordZ = wordA>>count; + if ( indexA == lastIndexA ) break; + indexA += wordIncr; + } + *zPtr = partWordZ; + +} + +#endif + diff --git a/softfloat/s_shortShiftRightJam64.c b/softfloat/s_shortShiftRightJam64.c new file mode 100644 index 0000000..93c6f0a --- /dev/null +++ b/softfloat/s_shortShiftRightJam64.c @@ -0,0 +1,50 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" + +#ifndef softfloat_shortShiftRightJam64 + +uint64_t softfloat_shortShiftRightJam64( uint64_t a, uint_fast8_t count ) +{ + + return a>>count | ((a & (((uint_fast64_t) 1< +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shortShiftRightJam64Extra + +struct uint64_extra + softfloat_shortShiftRightJam64Extra( + uint64_t a, uint64_t extra, uint_fast8_t count ) +{ + struct uint64_extra z; + + z.v = a>>count; + z.extra = a<<(-count & 63) | (extra != 0); + return z; + +} + +#endif + diff --git a/softfloat/s_shortShiftRightJamM.c b/softfloat/s_shortShiftRightJamM.c new file mode 100644 index 0000000..9aeba80 --- /dev/null +++ b/softfloat/s_shortShiftRightJamM.c @@ -0,0 +1,72 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shortShiftRightJamM + +void + softfloat_shortShiftRightJamM( + uint_fast8_t size_words, + const uint32_t *aPtr, + uint_fast8_t count, + uint32_t *zPtr + ) +{ + uint_fast8_t negCount; + unsigned int index, lastIndex; + uint32_t partWordZ, wordA; + + negCount = -count; + index = indexWordLo( size_words ); + lastIndex = indexWordHi( size_words ); + wordA = aPtr[index]; + partWordZ = wordA>>count; + if ( partWordZ<>count; + } + zPtr[index] = partWordZ; + +} + +#endif + diff --git a/softfloat/s_shortShiftRightM.c b/softfloat/s_shortShiftRightM.c new file mode 100644 index 0000000..ec61c25 --- /dev/null +++ b/softfloat/s_shortShiftRightM.c @@ -0,0 +1,70 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_shortShiftRightM + +void + softfloat_shortShiftRightM( + uint_fast8_t size_words, + const uint32_t *aPtr, + uint_fast8_t count, + uint32_t *zPtr + ) +{ + uint_fast8_t negCount; + unsigned int index, lastIndex; + uint32_t partWordZ, wordA; + + negCount = -count; + index = indexWordLo( size_words ); + lastIndex = indexWordHi( size_words ); + partWordZ = aPtr[index]>>count; + while ( index != lastIndex ) { + wordA = aPtr[index + wordIncr]; + zPtr[index] = wordA<<(negCount & 31) | partWordZ; + index += wordIncr; + partWordZ = wordA>>count; + } + zPtr[index] = partWordZ; + +} + +#endif + diff --git a/softfloat/s_sub128.c b/softfloat/s_sub128.c old mode 100755 new mode 100644 index 0c4f181..7659b40 --- a/softfloat/s_sub128.c +++ b/softfloat/s_sub128.c @@ -1,17 +1,55 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint128 - softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) -{ - struct uint128 z; - - z.v0 = a0 - b0; - z.v64 = a64 - b64; - z.v64 -= ( a0 < b0 ); - return z; - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_sub128 + +struct uint128 + softfloat_sub128( uint64_t a64, uint64_t a0, uint64_t b64, uint64_t b0 ) +{ + struct uint128 z; + + z.v0 = a0 - b0; + z.v64 = a64 - b64 - (a0 < b0); + return z; + +} + +#endif + diff --git a/softfloat/s_sub192.c b/softfloat/s_sub192.c deleted file mode 100755 index 96f21c9..0000000 --- a/softfloat/s_sub192.c +++ /dev/null @@ -1,30 +0,0 @@ - -#include -#include "platform.h" -#include "primitives.h" - -struct uint192 - softfloat_sub192( - uint64_t a128, - uint64_t a64, - uint64_t a0, - uint64_t b128, - uint64_t b64, - uint64_t b0 - ) -{ - struct uint192 z; - unsigned int borrow64, borrow128; - - z.v0 = a0 - b0; - borrow64 = ( a0 < b0 ); - z.v64 = a64 - b64; - borrow128 = ( a64 < b64 ); - z.v128 = a128 - b128; - borrow128 += ( z.v64 < borrow64 ); - z.v64 -= borrow64; - z.v128 -= borrow128; - return z; - -} - diff --git a/softfloat/s_subM.c b/softfloat/s_subM.c new file mode 100644 index 0000000..df984d0 --- /dev/null +++ b/softfloat/s_subM.c @@ -0,0 +1,70 @@ + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "primitiveTypes.h" + +#ifndef softfloat_subM + +void + softfloat_subM( + uint_fast8_t size_words, + const uint32_t *aPtr, + const uint32_t *bPtr, + uint32_t *zPtr + ) +{ + unsigned int index, lastIndex; + uint_fast8_t borrow; + uint32_t wordA, wordB; + + index = indexWordLo( size_words ); + lastIndex = indexWordHi( size_words ); + borrow = 0; + for (;;) { + wordA = aPtr[index]; + wordB = bPtr[index]; + zPtr[index] = wordA - wordB - borrow; + if ( index == lastIndex ) break; + borrow = borrow ? (wordA <= wordB) : (wordA < wordB); + index += wordIncr; + } + +} + +#endif + diff --git a/softfloat/s_subMagsF32.c b/softfloat/s_subMagsF32.c old mode 100755 new mode 100644 index 0c83b02..ba5ac9a --- a/softfloat/s_subMagsF32.c +++ b/softfloat/s_subMagsF32.c @@ -1,8 +1,42 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" -#include "primitives.h" #include "internals.h" #include "specialize.h" #include "softfloat.h" @@ -50,7 +84,7 @@ float32_t goto uiZ; } sigA += expA ? 0x40000000 : sigA; - sigA = softfloat_shift32RightJam( sigA, - expDiff ); + sigA = softfloat_shiftRightJam32( sigA, -expDiff ); sigB |= 0x40000000; bBigger: signZ ^= 1; @@ -64,7 +98,7 @@ float32_t goto uiZ; } sigB += expB ? 0x40000000 : sigB; - sigB = softfloat_shift32RightJam( sigB, expDiff ); + sigB = softfloat_shiftRightJam32( sigB, expDiff ); sigA |= 0x40000000; aBigger: expZ = expA; diff --git a/softfloat/s_subMagsF64.c b/softfloat/s_subMagsF64.c old mode 100755 new mode 100644 index 45b81ba..e499d98 --- a/softfloat/s_subMagsF64.c +++ b/softfloat/s_subMagsF64.c @@ -1,8 +1,42 @@ +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + #include #include #include "platform.h" -#include "primitives.h" #include "internals.h" #include "specialize.h" #include "softfloat.h" @@ -50,7 +84,7 @@ float64_t goto uiZ; } sigA += expA ? UINT64_C( 0x4000000000000000 ) : sigA; - sigA = softfloat_shift64RightJam( sigA, - expDiff ); + sigA = softfloat_shiftRightJam64( sigA, -expDiff ); sigB |= UINT64_C( 0x4000000000000000 ); bBigger: signZ ^= 1; @@ -64,7 +98,7 @@ float64_t goto uiZ; } sigB += expB ? UINT64_C( 0x4000000000000000 ) : sigB; - sigB = softfloat_shift64RightJam( sigB, expDiff ); + sigB = softfloat_shiftRightJam64( sigB, expDiff ); sigA |= UINT64_C( 0x4000000000000000 ); aBigger: expZ = expA; diff --git a/softfloat/softfloat.ac b/softfloat/softfloat.ac deleted file mode 100644 index e69de29..0000000 diff --git a/softfloat/softfloat.h b/softfloat/softfloat.h old mode 100755 new mode 100644 index bacaf1e..45ff0cf --- a/softfloat/softfloat.h +++ b/softfloat/softfloat.h @@ -1,235 +1,332 @@ - -#ifndef softfloat_h -#define softfloat_h - -#ifdef __cplusplus -extern "C" { -#endif - -/*** UPDATE COMMENTS. ***/ - -/*============================================================================ - -This C header file is part of the SoftFloat IEEE Floating-point Arithmetic -Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -#include "softfloat_types.h" - -/*---------------------------------------------------------------------------- -| Software floating-point underflow tininess-detection mode. -*----------------------------------------------------------------------------*/ -extern int_fast8_t softfloat_detectTininess; -enum { - softfloat_tininess_beforeRounding = 0, - softfloat_tininess_afterRounding = 1 -}; - -/*---------------------------------------------------------------------------- -| Software floating-point rounding mode. -*----------------------------------------------------------------------------*/ -extern int_fast8_t softfloat_roundingMode; -enum { - softfloat_round_nearest_even = 0, - softfloat_round_minMag = 1, - softfloat_round_min = 2, - softfloat_round_max = 3, - softfloat_round_nearest_maxMag = 4 -}; - -/*---------------------------------------------------------------------------- -| Software floating-point exception flags. -*----------------------------------------------------------------------------*/ -extern int_fast8_t softfloat_exceptionFlags; -enum { - softfloat_flag_inexact = 1, - softfloat_flag_underflow = 2, - softfloat_flag_overflow = 4, - softfloat_flag_infinity = 8, - softfloat_flag_invalid = 16 -}; - -/*---------------------------------------------------------------------------- -| Routine to raise any or all of the software floating-point exception flags. -*----------------------------------------------------------------------------*/ -void softfloat_raiseFlags( int_fast8_t ); - -/*---------------------------------------------------------------------------- -| Integer-to-floating-point conversion routines. -*----------------------------------------------------------------------------*/ -float32_t ui32_to_f32( uint_fast32_t ); -float64_t ui32_to_f64( uint_fast32_t ); -floatx80_t ui32_to_fx80( uint_fast32_t ); -float128_t ui32_to_f128( uint_fast32_t ); -float32_t ui64_to_f32( uint_fast64_t ); -float64_t ui64_to_f64( uint_fast64_t ); -floatx80_t ui64_to_fx80( uint_fast64_t ); -float128_t ui64_to_f128( uint_fast64_t ); -float32_t i32_to_f32( int_fast32_t ); -float64_t i32_to_f64( int_fast32_t ); -floatx80_t i32_to_fx80( int_fast32_t ); -float128_t i32_to_f128( int_fast32_t ); -float32_t i64_to_f32( int_fast64_t ); -float64_t i64_to_f64( int_fast64_t ); -floatx80_t i64_to_fx80( int_fast64_t ); -float128_t i64_to_f128( int_fast64_t ); - -/*---------------------------------------------------------------------------- -| 32-bit (single-precision) floating-point operations. -*----------------------------------------------------------------------------*/ -uint_fast32_t f32_to_ui32( float32_t, int_fast8_t, bool ); -uint_fast64_t f32_to_ui64( float32_t, int_fast8_t, bool ); -int_fast32_t f32_to_i32( float32_t, int_fast8_t, bool ); -int_fast64_t f32_to_i64( float32_t, int_fast8_t, bool ); -uint_fast32_t f32_to_ui32_r_minMag( float32_t, bool ); -uint_fast64_t f32_to_ui64_r_minMag( float32_t, bool ); -int_fast32_t f32_to_i32_r_minMag( float32_t, bool ); -int_fast64_t f32_to_i64_r_minMag( float32_t, bool ); -float64_t f32_to_f64( float32_t ); -floatx80_t f32_to_fx80( float32_t ); -float128_t f32_to_f128( float32_t ); -float32_t f32_roundToInt( float32_t, int_fast8_t, bool ); -float32_t f32_add( float32_t, float32_t ); -float32_t f32_sub( float32_t, float32_t ); -float32_t f32_mul( float32_t, float32_t ); -float32_t f32_mulAdd( float32_t, float32_t, float32_t ); -float32_t f32_div( float32_t, float32_t ); -float32_t f32_rem( float32_t, float32_t ); -float32_t f32_sqrt( float32_t ); -bool f32_eq( float32_t, float32_t ); -bool f32_le( float32_t, float32_t ); -bool f32_lt( float32_t, float32_t ); -bool f32_eq_signaling( float32_t, float32_t ); -bool f32_le_quiet( float32_t, float32_t ); -bool f32_lt_quiet( float32_t, float32_t ); -bool f32_isSignalingNaN( float32_t ); -uint_fast16_t f32_classify( float32_t ); - -/*---------------------------------------------------------------------------- -| 64-bit (double-precision) floating-point operations. -*----------------------------------------------------------------------------*/ -uint_fast32_t f64_to_ui32( float64_t, int_fast8_t, bool ); -uint_fast64_t f64_to_ui64( float64_t, int_fast8_t, bool ); -int_fast32_t f64_to_i32( float64_t, int_fast8_t, bool ); -int_fast64_t f64_to_i64( float64_t, int_fast8_t, bool ); -uint_fast32_t f64_to_ui32_r_minMag( float64_t, bool ); -uint_fast64_t f64_to_ui64_r_minMag( float64_t, bool ); -int_fast32_t f64_to_i32_r_minMag( float64_t, bool ); -int_fast64_t f64_to_i64_r_minMag( float64_t, bool ); -float32_t f64_to_f32( float64_t ); -floatx80_t f64_to_fx80( float64_t ); -float128_t f64_to_f128( float64_t ); -float64_t f64_roundToInt( float64_t, int_fast8_t, bool ); -float64_t f64_add( float64_t, float64_t ); -float64_t f64_sub( float64_t, float64_t ); -float64_t f64_mul( float64_t, float64_t ); -float64_t f64_mulAdd( float64_t, float64_t, float64_t ); -float64_t f64_div( float64_t, float64_t ); -float64_t f64_rem( float64_t, float64_t ); -float64_t f64_sqrt( float64_t ); -bool f64_eq( float64_t, float64_t ); -bool f64_le( float64_t, float64_t ); -bool f64_lt( float64_t, float64_t ); -bool f64_eq_signaling( float64_t, float64_t ); -bool f64_le_quiet( float64_t, float64_t ); -bool f64_lt_quiet( float64_t, float64_t ); -bool f64_isSignalingNaN( float64_t ); -uint_fast16_t f64_classify( float64_t ); - -/*---------------------------------------------------------------------------- -| Extended double-precision rounding precision. Valid values are 32, 64, and -| 80. -*----------------------------------------------------------------------------*/ -extern int_fast8_t floatx80_roundingPrecision; - -/*---------------------------------------------------------------------------- -| Extended double-precision floating-point operations. -*----------------------------------------------------------------------------*/ -uint_fast32_t fx80_to_ui32( floatx80_t, int_fast8_t, bool ); -uint_fast64_t fx80_to_ui64( floatx80_t, int_fast8_t, bool ); -int_fast32_t fx80_to_i32( floatx80_t, int_fast8_t, bool ); -int_fast64_t fx80_to_i64( floatx80_t, int_fast8_t, bool ); -uint_fast32_t fx80_to_ui32_r_minMag( floatx80_t, bool ); -uint_fast64_t fx80_to_ui64_r_minMag( floatx80_t, bool ); -int_fast32_t fx80_to_i32_r_minMag( floatx80_t, bool ); -int_fast64_t fx80_to_i64_r_minMag( floatx80_t, bool ); -float32_t fx80_to_f32( floatx80_t ); -float64_t fx80_to_f64( floatx80_t ); -float128_t fx80_to_f128( floatx80_t ); -floatx80_t fx80_roundToInt( floatx80_t, int_fast8_t, bool ); -floatx80_t fx80_add( floatx80_t, floatx80_t ); -floatx80_t fx80_sub( floatx80_t, floatx80_t ); -floatx80_t fx80_mul( floatx80_t, floatx80_t ); -floatx80_t fx80_mulAdd( floatx80_t, floatx80_t, floatx80_t ); -floatx80_t fx80_div( floatx80_t, floatx80_t ); -floatx80_t fx80_rem( floatx80_t, floatx80_t ); -floatx80_t fx80_sqrt( floatx80_t ); -bool fx80_eq( floatx80_t, floatx80_t ); -bool fx80_le( floatx80_t, floatx80_t ); -bool fx80_lt( floatx80_t, floatx80_t ); -bool fx80_eq_signaling( floatx80_t, floatx80_t ); -bool fx80_le_quiet( floatx80_t, floatx80_t ); -bool fx80_lt_quiet( floatx80_t, floatx80_t ); -bool fx80_isSignalingNaN( floatx80_t ); - -/*---------------------------------------------------------------------------- -| 128-bit (quadruple-precision) floating-point operations. -*----------------------------------------------------------------------------*/ -uint_fast32_t f128_to_ui32( float128_t, int_fast8_t, bool ); -uint_fast64_t f128_to_ui64( float128_t, int_fast8_t, bool ); -int_fast32_t f128_to_i32( float128_t, int_fast8_t, bool ); -int_fast64_t f128_to_i64( float128_t, int_fast8_t, bool ); -uint_fast32_t f128_to_ui32_r_minMag( float128_t, bool ); -uint_fast64_t f128_to_ui64_r_minMag( float128_t, bool ); -int_fast32_t f128_to_i32_r_minMag( float128_t, bool ); -int_fast64_t f128_to_i64_r_minMag( float128_t, bool ); -float32_t f128_to_f32( float128_t ); -float64_t f128_to_f64( float128_t ); -floatx80_t f128_to_fx80( float128_t ); -float128_t f128_roundToInt( float128_t, int_fast8_t, bool ); -float128_t f128_add( float128_t, float128_t ); -float128_t f128_sub( float128_t, float128_t ); -float128_t f128_mul( float128_t, float128_t ); -float128_t f128_mulAdd( float128_t, float128_t, float128_t ); -float128_t f128_div( float128_t, float128_t ); -float128_t f128_rem( float128_t, float128_t ); -float128_t f128_sqrt( float128_t ); -bool f128_eq( float128_t, float128_t ); -bool f128_le( float128_t, float128_t ); -bool f128_lt( float128_t, float128_t ); -bool f128_eq_signaling( float128_t, float128_t ); -bool f128_le_quiet( float128_t, float128_t ); -bool f128_lt_quiet( float128_t, float128_t ); -bool f128_isSignalingNaN( float128_t ); - -#ifdef __cplusplus -} -#endif - -#endif - + +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + + +/*============================================================================ +| Note: If SoftFloat is made available as a general library for programs to +| use, it is strongly recommended that a platform-specific version of this +| header, "softfloat.h", be created that folds in "softfloat_types.h" and that +| eliminates all dependencies on compile-time macros. +*============================================================================*/ + + +#ifndef softfloat_h +#define softfloat_h 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "softfloat_types.h" + +/*---------------------------------------------------------------------------- +| Software floating-point underflow tininess-detection mode. +*----------------------------------------------------------------------------*/ +extern uint_fast8_t softfloat_detectTininess; +enum { + softfloat_tininess_beforeRounding = 0, + softfloat_tininess_afterRounding = 1 +}; + +/*---------------------------------------------------------------------------- +| Software floating-point rounding mode. +*----------------------------------------------------------------------------*/ +extern uint_fast8_t softfloat_roundingMode; +enum { + softfloat_round_near_even = 0, + softfloat_round_minMag = 1, + softfloat_round_min = 2, + softfloat_round_max = 3, + softfloat_round_near_maxMag = 4 +}; + +/*---------------------------------------------------------------------------- +| Software floating-point exception flags. +*----------------------------------------------------------------------------*/ +extern uint_fast8_t softfloat_exceptionFlags; +enum { + softfloat_flag_inexact = 1, + softfloat_flag_underflow = 2, + softfloat_flag_overflow = 4, + softfloat_flag_infinite = 8, + softfloat_flag_invalid = 16 +}; + +/*---------------------------------------------------------------------------- +| Routine to raise any or all of the software floating-point exception flags. +*----------------------------------------------------------------------------*/ +void softfloat_raiseFlags( uint_fast8_t ); + +/*---------------------------------------------------------------------------- +| Integer-to-floating-point conversion routines. +*----------------------------------------------------------------------------*/ +float32_t ui32_to_f32( uint32_t ); +float64_t ui32_to_f64( uint32_t ); +#ifdef SOFTFLOAT_FAST_INT64 +extFloat80_t ui32_to_extF80( uint32_t ); +float128_t ui32_to_f128( uint32_t ); +#endif +void ui32_to_extF80M( uint32_t, extFloat80_t * ); +void ui32_to_f128M( uint32_t, float128_t * ); +float32_t ui64_to_f32( uint64_t ); +float64_t ui64_to_f64( uint64_t ); +#ifdef SOFTFLOAT_FAST_INT64 +extFloat80_t ui64_to_extF80( uint64_t ); +float128_t ui64_to_f128( uint64_t ); +#endif +void ui64_to_extF80M( uint64_t, extFloat80_t * ); +void ui64_to_f128M( uint64_t, float128_t * ); +float32_t i32_to_f32( int32_t ); +float64_t i32_to_f64( int32_t ); +#ifdef SOFTFLOAT_FAST_INT64 +extFloat80_t i32_to_extF80( int32_t ); +float128_t i32_to_f128( int32_t ); +#endif +void i32_to_extF80M( int32_t, extFloat80_t * ); +void i32_to_f128M( int32_t, float128_t * ); +float32_t i64_to_f32( int64_t ); +float64_t i64_to_f64( int64_t ); +#ifdef SOFTFLOAT_FAST_INT64 +extFloat80_t i64_to_extF80( int64_t ); +float128_t i64_to_f128( int64_t ); +#endif +void i64_to_extF80M( int64_t, extFloat80_t * ); +void i64_to_f128M( int64_t, float128_t * ); + +/*---------------------------------------------------------------------------- +| 32-bit (single-precision) floating-point operations. +*----------------------------------------------------------------------------*/ +uint_fast32_t f32_to_ui32( float32_t, uint_fast8_t, bool ); +uint_fast64_t f32_to_ui64( float32_t, uint_fast8_t, bool ); +int_fast32_t f32_to_i32( float32_t, uint_fast8_t, bool ); +int_fast64_t f32_to_i64( float32_t, uint_fast8_t, bool ); +uint_fast32_t f32_to_ui32_r_minMag( float32_t, bool ); +uint_fast64_t f32_to_ui64_r_minMag( float32_t, bool ); +int_fast32_t f32_to_i32_r_minMag( float32_t, bool ); +int_fast64_t f32_to_i64_r_minMag( float32_t, bool ); +float64_t f32_to_f64( float32_t ); +#ifdef SOFTFLOAT_FAST_INT64 +extFloat80_t f32_to_extF80( float32_t ); +float128_t f32_to_f128( float32_t ); +#endif +void f32_to_extF80M( float32_t, extFloat80_t * ); +void f32_to_f128M( float32_t, float128_t * ); +float32_t f32_roundToInt( float32_t, uint_fast8_t, bool ); +float32_t f32_add( float32_t, float32_t ); +float32_t f32_sub( float32_t, float32_t ); +float32_t f32_mul( float32_t, float32_t ); +float32_t f32_mulAdd( float32_t, float32_t, float32_t ); +float32_t f32_div( float32_t, float32_t ); +float32_t f32_rem( float32_t, float32_t ); +float32_t f32_sqrt( float32_t ); +bool f32_eq( float32_t, float32_t ); +bool f32_le( float32_t, float32_t ); +bool f32_lt( float32_t, float32_t ); +bool f32_eq_signaling( float32_t, float32_t ); +bool f32_le_quiet( float32_t, float32_t ); +bool f32_lt_quiet( float32_t, float32_t ); +bool f32_isSignalingNaN( float32_t ); +uint_fast16_t f32_classify( float32_t ); + +/*---------------------------------------------------------------------------- +| 64-bit (double-precision) floating-point operations. +*----------------------------------------------------------------------------*/ +uint_fast32_t f64_to_ui32( float64_t, uint_fast8_t, bool ); +uint_fast64_t f64_to_ui64( float64_t, uint_fast8_t, bool ); +int_fast32_t f64_to_i32( float64_t, uint_fast8_t, bool ); +int_fast64_t f64_to_i64( float64_t, uint_fast8_t, bool ); +uint_fast32_t f64_to_ui32_r_minMag( float64_t, bool ); +uint_fast64_t f64_to_ui64_r_minMag( float64_t, bool ); +int_fast32_t f64_to_i32_r_minMag( float64_t, bool ); +int_fast64_t f64_to_i64_r_minMag( float64_t, bool ); +float32_t f64_to_f32( float64_t ); +#ifdef SOFTFLOAT_FAST_INT64 +extFloat80_t f64_to_extF80( float64_t ); +float128_t f64_to_f128( float64_t ); +#endif +void f64_to_extF80M( float64_t, extFloat80_t * ); +void f64_to_f128M( float64_t, float128_t * ); +float64_t f64_roundToInt( float64_t, uint_fast8_t, bool ); +float64_t f64_add( float64_t, float64_t ); +float64_t f64_sub( float64_t, float64_t ); +float64_t f64_mul( float64_t, float64_t ); +float64_t f64_mulAdd( float64_t, float64_t, float64_t ); +float64_t f64_div( float64_t, float64_t ); +float64_t f64_rem( float64_t, float64_t ); +float64_t f64_sqrt( float64_t ); +bool f64_eq( float64_t, float64_t ); +bool f64_le( float64_t, float64_t ); +bool f64_lt( float64_t, float64_t ); +bool f64_eq_signaling( float64_t, float64_t ); +bool f64_le_quiet( float64_t, float64_t ); +bool f64_lt_quiet( float64_t, float64_t ); +bool f64_isSignalingNaN( float64_t ); +uint_fast16_t f64_classify( float64_t ); + +/*---------------------------------------------------------------------------- +| Rounding precision for 80-bit extended double-precision floating-point. +| Valid values are 32, 64, and 80. +*----------------------------------------------------------------------------*/ +extern uint_fast8_t extF80_roundingPrecision; + +/*---------------------------------------------------------------------------- +| 80-bit extended double-precision floating-point operations. +*----------------------------------------------------------------------------*/ +#ifdef SOFTFLOAT_FAST_INT64 +uint_fast32_t extF80_to_ui32( extFloat80_t, uint_fast8_t, bool ); +uint_fast64_t extF80_to_ui64( extFloat80_t, uint_fast8_t, bool ); +int_fast32_t extF80_to_i32( extFloat80_t, uint_fast8_t, bool ); +int_fast64_t extF80_to_i64( extFloat80_t, uint_fast8_t, bool ); +uint_fast32_t extF80_to_ui32_r_minMag( extFloat80_t, bool ); +uint_fast64_t extF80_to_ui64_r_minMag( extFloat80_t, bool ); +int_fast32_t extF80_to_i32_r_minMag( extFloat80_t, bool ); +int_fast64_t extF80_to_i64_r_minMag( extFloat80_t, bool ); +float32_t extF80_to_f32( extFloat80_t ); +float64_t extF80_to_f64( extFloat80_t ); +float128_t extF80_to_f128( extFloat80_t ); +extFloat80_t extF80_roundToInt( extFloat80_t, uint_fast8_t, bool ); +extFloat80_t extF80_add( extFloat80_t, extFloat80_t ); +extFloat80_t extF80_sub( extFloat80_t, extFloat80_t ); +extFloat80_t extF80_mul( extFloat80_t, extFloat80_t ); +extFloat80_t extF80_div( extFloat80_t, extFloat80_t ); +extFloat80_t extF80_rem( extFloat80_t, extFloat80_t ); +extFloat80_t extF80_sqrt( extFloat80_t ); +bool extF80_eq( extFloat80_t, extFloat80_t ); +bool extF80_le( extFloat80_t, extFloat80_t ); +bool extF80_lt( extFloat80_t, extFloat80_t ); +bool extF80_eq_signaling( extFloat80_t, extFloat80_t ); +bool extF80_le_quiet( extFloat80_t, extFloat80_t ); +bool extF80_lt_quiet( extFloat80_t, extFloat80_t ); +bool extF80_isSignalingNaN( extFloat80_t ); +#endif +uint_fast32_t extF80M_to_ui32( const extFloat80_t *, uint_fast8_t, bool ); +uint_fast64_t extF80M_to_ui64( const extFloat80_t *, uint_fast8_t, bool ); +int_fast32_t extF80M_to_i32( const extFloat80_t *, uint_fast8_t, bool ); +int_fast64_t extF80M_to_i64( const extFloat80_t *, uint_fast8_t, bool ); +uint_fast32_t extF80M_to_ui32_r_minMag( const extFloat80_t *, bool ); +uint_fast64_t extF80M_to_ui64_r_minMag( const extFloat80_t *, bool ); +int_fast32_t extF80M_to_i32_r_minMag( const extFloat80_t *, bool ); +int_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *, bool ); +float32_t extF80M_to_f32( const extFloat80_t * ); +float64_t extF80M_to_f64( const extFloat80_t * ); +void extF80M_to_f128M( const extFloat80_t *, float128_t * ); +void + extF80M_roundToInt( + const extFloat80_t *, uint_fast8_t, bool, extFloat80_t * ); +void extF80M_add( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); +void extF80M_sub( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); +void extF80M_mul( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); +void extF80M_div( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); +void extF80M_rem( const extFloat80_t *, const extFloat80_t *, extFloat80_t * ); +void extF80M_sqrt( const extFloat80_t *, extFloat80_t * ); +bool extF80M_eq( const extFloat80_t *, const extFloat80_t * ); +bool extF80M_le( const extFloat80_t *, const extFloat80_t * ); +bool extF80M_lt( const extFloat80_t *, const extFloat80_t * ); +bool extF80M_eq_signaling( const extFloat80_t *, const extFloat80_t * ); +bool extF80M_le_quiet( const extFloat80_t *, const extFloat80_t * ); +bool extF80M_lt_quiet( const extFloat80_t *, const extFloat80_t * ); +bool extF80M_isSignalingNaN( const extFloat80_t * ); + +/*---------------------------------------------------------------------------- +| 128-bit (quadruple-precision) floating-point operations. +*----------------------------------------------------------------------------*/ +#ifdef SOFTFLOAT_FAST_INT64 +uint_fast32_t f128_to_ui32( float128_t, uint_fast8_t, bool ); +uint_fast64_t f128_to_ui64( float128_t, uint_fast8_t, bool ); +int_fast32_t f128_to_i32( float128_t, uint_fast8_t, bool ); +int_fast64_t f128_to_i64( float128_t, uint_fast8_t, bool ); +uint_fast32_t f128_to_ui32_r_minMag( float128_t, bool ); +uint_fast64_t f128_to_ui64_r_minMag( float128_t, bool ); +int_fast32_t f128_to_i32_r_minMag( float128_t, bool ); +int_fast64_t f128_to_i64_r_minMag( float128_t, bool ); +float32_t f128_to_f32( float128_t ); +float64_t f128_to_f64( float128_t ); +extFloat80_t f128_to_extF80( float128_t ); +float128_t f128_roundToInt( float128_t, uint_fast8_t, bool ); +float128_t f128_add( float128_t, float128_t ); +float128_t f128_sub( float128_t, float128_t ); +float128_t f128_mul( float128_t, float128_t ); +float128_t f128_mulAdd( float128_t, float128_t, float128_t ); +float128_t f128_div( float128_t, float128_t ); +float128_t f128_rem( float128_t, float128_t ); +float128_t f128_sqrt( float128_t ); +bool f128_eq( float128_t, float128_t ); +bool f128_le( float128_t, float128_t ); +bool f128_lt( float128_t, float128_t ); +bool f128_eq_signaling( float128_t, float128_t ); +bool f128_le_quiet( float128_t, float128_t ); +bool f128_lt_quiet( float128_t, float128_t ); +bool f128_isSignalingNaN( float128_t ); +#endif +uint_fast32_t f128M_to_ui32( const float128_t *, uint_fast8_t, bool ); +uint_fast64_t f128M_to_ui64( const float128_t *, uint_fast8_t, bool ); +int_fast32_t f128M_to_i32( const float128_t *, uint_fast8_t, bool ); +int_fast64_t f128M_to_i64( const float128_t *, uint_fast8_t, bool ); +uint_fast32_t f128M_to_ui32_r_minMag( const float128_t *, bool ); +uint_fast64_t f128M_to_ui64_r_minMag( const float128_t *, bool ); +int_fast32_t f128M_to_i32_r_minMag( const float128_t *, bool ); +int_fast64_t f128M_to_i64_r_minMag( const float128_t *, bool ); +float32_t f128M_to_f32( const float128_t * ); +float64_t f128M_to_f64( const float128_t * ); +void f128M_to_extF80M( const float128_t *, extFloat80_t * ); +void f128M_roundToInt( const float128_t *, uint_fast8_t, bool, float128_t * ); +void f128M_add( const float128_t *, const float128_t *, float128_t * ); +void f128M_sub( const float128_t *, const float128_t *, float128_t * ); +void f128M_mul( const float128_t *, const float128_t *, float128_t * ); +void + f128M_mulAdd( + const float128_t *, const float128_t *, const float128_t *, float128_t * + ); +void f128M_div( const float128_t *, const float128_t *, float128_t * ); +void f128M_rem( const float128_t *, const float128_t *, float128_t * ); +void f128M_sqrt( const float128_t *, float128_t * ); +bool f128M_eq( const float128_t *, const float128_t * ); +bool f128M_le( const float128_t *, const float128_t * ); +bool f128M_lt( const float128_t *, const float128_t * ); +bool f128M_eq_signaling( const float128_t *, const float128_t * ); +bool f128M_le_quiet( const float128_t *, const float128_t * ); +bool f128M_lt_quiet( const float128_t *, const float128_t * ); +bool f128M_isSignalingNaN( const float128_t * ); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/softfloat/softfloat.mk.in b/softfloat/softfloat.mk.in index 7f70053..e373df1 100644 --- a/softfloat/softfloat.mk.in +++ b/softfloat/softfloat.mk.in @@ -1,125 +1,124 @@ -softfloat_subproject_deps = \ +softfloat_subproject_deps = softfloat_hdrs = \ - internals.h \ - primitives.h \ - softfloat.h \ - softfloat_types.h \ - platform.h \ - specialize.h \ + internals.h \ + primitives.h \ + primitiveTypes.h \ + softfloat.h \ + softfloat_types.h \ + specialize.h \ softfloat_c_srcs = \ - f32_add.c \ - f32_div.c \ - f32_eq.c \ - f32_eq_signaling.c \ - f32_isSignalingNaN.c \ - f32_le.c \ - f32_le_quiet.c \ - f32_lt.c \ - f32_lt_quiet.c \ - f32_mulAdd.c \ - f32_mul.c \ - f32_rem.c \ - f32_roundToInt.c \ - f32_sqrt.c \ - f32_sub.c \ - f32_to_f64.c \ - f32_to_i32.c \ - f32_to_i32_r_minMag.c \ - f32_to_i64.c \ - f32_to_i64_r_minMag.c \ - f32_to_ui32.c \ - f32_to_ui32_r_minMag.c \ - f32_to_ui64.c \ - f32_to_ui64_r_minMag.c \ - f32_classify.c \ - f64_add.c \ - f64_div.c \ - f64_eq.c \ - f64_eq_signaling.c \ - f64_isSignalingNaN.c \ - f64_le.c \ - f64_le_quiet.c \ - f64_lt.c \ - f64_lt_quiet.c \ - f64_mulAdd.c \ - f64_mul.c \ - f64_rem.c \ - f64_roundToInt.c \ - f64_sqrt.c \ - f64_sub.c \ - f64_to_f32.c \ - f64_to_i32.c \ - f64_to_i32_r_minMag.c \ - f64_to_i64.c \ - f64_to_i64_r_minMag.c \ - f64_to_ui32.c \ - f64_to_ui32_r_minMag.c \ - f64_to_ui64.c \ - f64_to_ui64_r_minMag.c \ - f64_classify.c \ - i32_to_f32.c \ - i32_to_f64.c \ - i64_to_f32.c \ - i64_to_f64.c \ - s_add128.c \ - s_add192.c \ - s_addMagsF32.c \ - s_addMagsF64.c \ - s_countLeadingZeros32.c \ - s_countLeadingZeros64.c \ - s_countLeadingZeros8.c \ - s_eq128.c \ - s_estimateDiv128To64.c \ - s_estimateSqrt32.c \ - s_le128.c \ - s_lt128.c \ - s_mul128By64To192.c \ - s_mul128To256.c \ - s_mul64To128.c \ - s_mulAddF32.c \ - s_mulAddF64.c \ - s_normRoundPackToF32.c \ - s_normRoundPackToF64.c \ - s_normSubnormalF32Sig.c \ - s_normSubnormalF64Sig.c \ - softfloat_state.c \ - s_roundPackToF32.c \ - s_roundPackToF64.c \ - s_roundPackToI32.c \ - s_roundPackToI64.c \ - s_roundPackToUI32.c \ - s_roundPackToUI64.c \ - s_shift128ExtraRightJam.c \ - s_shift128RightJam.c \ - s_shift32RightJam.c \ - s_shift64ExtraRightJam.c \ - s_shift64RightJam.c \ - s_shortShift128ExtraRightJam.c \ - s_shortShift128Left.c \ - s_shortShift128Right.c \ - s_shortShift192Left.c \ - s_shortShift32Right1Jam.c \ - s_shortShift64ExtraRightJam.c \ - s_shortShift64RightJam.c \ - s_sub128.c \ - s_sub192.c \ - s_subMagsF32.c \ - s_subMagsF64.c \ - ui32_to_f32.c \ - ui32_to_f64.c \ - ui64_to_f32.c \ - ui64_to_f64.c \ - softfloat_raiseFlags.c \ - s_commonNaNToF32UI.c \ - s_commonNaNToF64UI.c \ - s_f32UIToCommonNaN.c \ - s_f64UIToCommonNaN.c \ - s_isSigNaNF32UI.c \ - s_isSigNaNF64UI.c \ - s_propagateNaNF32UI.c \ - s_propagateNaNF64UI.c \ + f32_add.c \ + f32_classify.c \ + f32_div.c \ + f32_eq.c \ + f32_eq_signaling.c \ + f32_isSignalingNaN.c \ + f32_le.c \ + f32_le_quiet.c \ + f32_lt.c \ + f32_lt_quiet.c \ + f32_mulAdd.c \ + f32_mul.c \ + f32_rem.c \ + f32_roundToInt.c \ + f32_sqrt.c \ + f32_sub.c \ + f32_to_f64.c \ + f32_to_i32.c \ + f32_to_i32_r_minMag.c \ + f32_to_i64.c \ + f32_to_i64_r_minMag.c \ + f32_to_ui32.c \ + f32_to_ui32_r_minMag.c \ + f32_to_ui64.c \ + f32_to_ui64_r_minMag.c \ + f64_add.c \ + f64_classify.c \ + f64_div.c \ + f64_eq.c \ + f64_eq_signaling.c \ + f64_isSignalingNaN.c \ + f64_le.c \ + f64_le_quiet.c \ + f64_lt.c \ + f64_lt_quiet.c \ + f64_mulAdd.c \ + f64_mul.c \ + f64_rem.c \ + f64_roundToInt.c \ + f64_sqrt.c \ + f64_sub.c \ + f64_to_f32.c \ + f64_to_i32.c \ + f64_to_i32_r_minMag.c \ + f64_to_i64.c \ + f64_to_i64_r_minMag.c \ + f64_to_ui32.c \ + f64_to_ui32_r_minMag.c \ + f64_to_ui64.c \ + f64_to_ui64_r_minMag.c \ + i32_to_f32.c \ + i32_to_f64.c \ + i64_to_f32.c \ + i64_to_f64.c \ + s_add128.c \ + s_addCarryM.c \ + s_addComplCarryM.c \ + s_addMagsF32.c \ + s_addMagsF64.c \ + s_addM.c \ + s_approxRecip32_1.c \ + s_approxRecipSqrt32_1.c \ + s_commonNaNToF32UI.c \ + s_commonNaNToF64UI.c \ + s_compare96M.c \ + s_countLeadingZeros32.c \ + s_countLeadingZeros64.c \ + s_countLeadingZeros8.c \ + s_f32UIToCommonNaN.c \ + s_f64UIToCommonNaN.c \ + s_mul64To128.c \ + s_mulAddF32.c \ + s_mulAddF64.c \ + s_negXM.c \ + s_normRoundPackToF32.c \ + s_normRoundPackToF64.c \ + s_normSubnormalF32Sig.c \ + s_normSubnormalF64Sig.c \ + softfloat_raiseFlags.c \ + softfloat_state.c \ + s_propagateNaNF32UI.c \ + s_propagateNaNF64UI.c \ + s_remStepMBy32.c \ + s_roundPackMToI64.c \ + s_roundPackMToUI64.c \ + s_roundPackToF32.c \ + s_roundPackToF64.c \ + s_roundPackToI32.c \ + s_roundPackToI64.c \ + s_roundPackToUI32.c \ + s_roundPackToUI64.c \ + s_shiftRightJam128.c \ + s_shiftRightJam32.c \ + s_shiftRightJam64.c \ + s_shiftRightJam64Extra.c \ + s_shortShiftLeft64To96M.c \ + s_shortShiftLeftM.c \ + s_shortShiftRightExtendM.c \ + s_shortShiftRightJam64.c \ + s_shortShiftRightJam64Extra.c \ + s_shortShiftRightJamM.c \ + s_shortShiftRightM.c \ + s_sub128.c \ + s_subMagsF32.c \ + s_subMagsF64.c \ + s_subM.c \ + ui32_to_f32.c \ + ui32_to_f64.c \ + ui64_to_f32.c \ + ui64_to_f64.c \ softfloat_test_srcs = diff --git a/softfloat/softfloat_raiseFlags.c b/softfloat/softfloat_raiseFlags.c old mode 100755 new mode 100644 index c0c0dc8..7b5ba25 --- a/softfloat/softfloat_raiseFlags.c +++ b/softfloat/softfloat_raiseFlags.c @@ -1,34 +1,36 @@ /*============================================================================ -*** FIX. - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================*/ @@ -39,10 +41,9 @@ these four paragraphs for those parts of this code that are retained. | Raises the exceptions specified by `flags'. Floating-point traps can be | defined here if desired. It is currently not possible for such a trap | to substitute a result value. If traps are not implemented, this routine -| should be simply `float_exception_flags |= flags;'. +| should be simply `softfloat_exceptionFlags |= flags;'. *----------------------------------------------------------------------------*/ - -void softfloat_raiseFlags( int_fast8_t flags ) +void softfloat_raiseFlags( uint_fast8_t flags ) { softfloat_exceptionFlags |= flags; diff --git a/softfloat/softfloat_state.c b/softfloat/softfloat_state.c old mode 100755 new mode 100644 index 8859089..d93087d --- a/softfloat/softfloat_state.c +++ b/softfloat/softfloat_state.c @@ -1,19 +1,48 @@ - -/*** COMMENTS. ***/ - -#include -#include "platform.h" -#include "internals.h" -#include "specialize.h" -#include "softfloat.h" - -/*---------------------------------------------------------------------------- -| Floating-point rounding mode, extended double-precision rounding precision, -| and exception flags. -*----------------------------------------------------------------------------*/ -int_fast8_t softfloat_roundingMode = softfloat_round_nearest_even; -int_fast8_t softfloat_detectTininess = init_detectTininess; -int_fast8_t softfloat_exceptionFlags = 0; - -int_fast8_t floatx80_roundingPrecision = 80; - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "internals.h" +#include "specialize.h" +#include "softfloat.h" + +uint_fast8_t softfloat_roundingMode = softfloat_round_near_even; +uint_fast8_t softfloat_detectTininess = init_detectTininess; +uint_fast8_t softfloat_exceptionFlags = 0; + +uint_fast8_t extF80_roundingPrecision = 80; + diff --git a/softfloat/softfloat_types.h b/softfloat/softfloat_types.h old mode 100755 new mode 100644 index 9fada89..c7b67ae --- a/softfloat/softfloat_types.h +++ b/softfloat/softfloat_types.h @@ -1,16 +1,80 @@ -#ifndef softfloat_types_h -#define softfloat_types_h +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. -/*** COMMENTS. ***/ +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#ifndef softfloat_types_h +#define softfloat_types_h 1 -#include #include -typedef uint32_t float32_t; -typedef uint64_t float64_t; -typedef struct { uint64_t v; uint16_t x; } floatx80_t; -typedef struct { uint64_t v[ 2 ]; } float128_t; +/*---------------------------------------------------------------------------- +| Types used to pass 32-bit, 64-bit, and 128-bit floating-point arguments and +| results to/from functions. These types must be exactly 32 bits, 64 bits, +| and 128 bits in size, respectively. Where a platform has "native" support +| for IEEE-Standard floating-point formats, the types below may, if desired, +| be defined as aliases for the native types (typically `float' and `double', +| and possibly `long double'). +*----------------------------------------------------------------------------*/ +typedef struct { uint32_t v; } float32_t; +typedef struct { uint64_t v; } float64_t; +typedef struct { uint64_t v[2]; } float128_t; + +/*---------------------------------------------------------------------------- +| The format of an 80-bit extended floating-point number in memory. This +| structure must contain a 16-bit field named `signExp' and a 64-bit field +| named `signif'. +*----------------------------------------------------------------------------*/ +#ifdef LITTLEENDIAN +struct extFloat80M { uint64_t signif; uint16_t signExp; }; +#else +struct extFloat80M { uint16_t signExp; uint64_t signif; }; +#endif + +/*---------------------------------------------------------------------------- +| The type used to pass 80-bit extended floating-point arguments and +| results to/from functions. This type must have size identical to +| `struct extFloat80M'. Type `extFloat80_t' can be defined as an alias for +| `struct extFloat80M'. Alternatively, if a platform has "native" support +| for IEEE-Standard 80-bit extended floating-point, it may be possible, +| if desired, to define `extFloat80_t' as an alias for the native type +| (presumably either `long double' or a nonstandard compiler-intrinsic type). +| In that case, the `signif' and `signExp' fields of `struct extFloat80M' +| must align exactly with the locations in memory of the sign, exponent, and +| significand of the native type. +*----------------------------------------------------------------------------*/ +typedef struct extFloat80M extFloat80_t; #endif diff --git a/softfloat/specialize.h b/softfloat/specialize.h old mode 100755 new mode 100644 index 4b0138a..6975f39 --- a/softfloat/specialize.h +++ b/softfloat/specialize.h @@ -1,113 +1,372 @@ - -/*============================================================================ - -*** FIX. - -This C source fragment is part of the SoftFloat IEC/IEEE Floating-point -Arithmetic Package, Release 2b. - -Written by John R. Hauser. This work was made possible in part by the -International Computer Science Institute, located at Suite 600, 1947 Center -Street, Berkeley, California 94704. Funding was partially provided by the -National Science Foundation under grant MIP-9311980. The original version -of this code was written as part of a project to build a fixed-point vector -processor in collaboration with the University of California at Berkeley, -overseen by Profs. Nelson Morgan and John Wawrzynek. More information -is available through the Web page `http://www.cs.berkeley.edu/~jhauser/ -arithmetic/SoftFloat.html'. - -THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has -been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES -RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS -AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES, -COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE -EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE -INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR -OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - -Derivative works are acceptable, even for commercial purposes, so long as -(1) the source code for the derivative work includes prominent notice that -the work is derivative, and (2) the source code includes prominent notice with -these four paragraphs for those parts of this code that are retained. - -=============================================================================*/ - -#include -#include - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#define init_detectTininess softfloat_tininess_beforeRounding; - -/*---------------------------------------------------------------------------- -| Structure used to transfer NaN representations from one format to another. -*----------------------------------------------------------------------------*/ -struct commonNaN { - bool sign; - uint64_t v64, v0; -}; - -/*---------------------------------------------------------------------------- -| The pattern for a default generated single-precision NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF32UI 0x7FC00000 - -/*---------------------------------------------------------------------------- -| Returns 1 if the single-precision floating-point value `a' is a signaling -| NaN; otherwise, returns 0. -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 1 <= INLINE_LEVEL ) -INLINE bool softfloat_isSigNaNF32UI( uint_fast32_t ui ) - { return ( ( ui>>22 & 0x1FF ) == 0x1FE ) && ( ui & 0x003FFFFF ); } -#else -bool softfloat_isSigNaNF32UI( uint_fast32_t ); -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -struct commonNaN softfloat_f32UIToCommonNaN( uint_fast32_t ); -#if defined INLINE_LEVEL && ( 1 <= INLINE_LEVEL ) -INLINE uint_fast32_t softfloat_commonNaNToF32UI( struct commonNaN a ) - { return defaultNaNF32UI; } -#else -uint_fast32_t softfloat_commonNaNToF32UI( struct commonNaN ); -#endif - -/*---------------------------------------------------------------------------- -| Takes two single-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast32_t softfloat_propagateNaNF32UI( uint_fast32_t, uint_fast32_t ); - -/*---------------------------------------------------------------------------- -| The pattern for a default generated double-precision NaN. -*----------------------------------------------------------------------------*/ -#define defaultNaNF64UI UINT64_C(0x7FF8000000000000) - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -#if defined INLINE_LEVEL && ( 1 <= INLINE_LEVEL ) -INLINE bool softfloat_isSigNaNF64UI( uint_fast64_t ui ) -{ - return - ( ( ui>>51 & 0xFFF ) == 0xFFE ) - && ( ui & UINT64_C( 0x0007FFFFFFFFFFFF ) ); -} -#else -bool softfloat_isSigNaNF64UI( uint_fast64_t ); -#endif - -/*---------------------------------------------------------------------------- -*----------------------------------------------------------------------------*/ -/*** MIGHT BE INLINE'D. ***/ -struct commonNaN softfloat_f64UIToCommonNaN( uint_fast64_t ); -uint_fast64_t softfloat_commonNaNToF64UI( struct commonNaN ); - -/*---------------------------------------------------------------------------- -| Takes two double-precision floating-point values `a' and `b', one of which -| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a -| signaling NaN, the invalid exception is raised. -*----------------------------------------------------------------------------*/ -uint_fast64_t softfloat_propagateNaNF64UI( uint_fast64_t, uint_fast64_t ); - + +/*============================================================================ + +This C header file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a+, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the University of +California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#ifndef specialize_h +#define specialize_h 1 + +#include +#include +#include "primitiveTypes.h" +#include "softfloat.h" + +/*---------------------------------------------------------------------------- +| Default value for `softfloat_detectTininess'. +*----------------------------------------------------------------------------*/ +#define init_detectTininess softfloat_tininess_afterRounding + +/*---------------------------------------------------------------------------- +| The values to return on conversions to 32-bit integer format that raise an +| invalid exception. +*----------------------------------------------------------------------------*/ +#define ui32_fromPosOverflow 0xFFFFFFFF +#define ui32_fromNegOverflow 0 +#define ui32_fromNaN 0xFFFFFFFF +#define i32_fromPosOverflow 0x7FFFFFFF +#define i32_fromNegOverflow (-0x7FFFFFFF - 1) +#define i32_fromNaN 0x7FFFFFFF + +/*---------------------------------------------------------------------------- +| The values to return on conversions to 64-bit integer format that raise an +| invalid exception. +*----------------------------------------------------------------------------*/ +#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF ) +#define ui64_fromNegOverflow 0 +#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF ) +#define i64_fromPosOverflow UINT64_C( 0x7FFFFFFFFFFFFFFF ) +#define i64_fromNegOverflow (-UINT64_C( 0x7FFFFFFFFFFFFFFF ) - 1) +#define i64_fromNaN UINT64_C( 0x7FFFFFFFFFFFFFFF ) + +/*---------------------------------------------------------------------------- +| "Common NaN" structure, used to transfer NaN representations from one format +| to another. +*----------------------------------------------------------------------------*/ +struct commonNaN { char _unused; }; + +/*---------------------------------------------------------------------------- +| The bit pattern for a default generated 32-bit floating-point NaN. +*----------------------------------------------------------------------------*/ +#define defaultNaNF32UI 0x7FC00000 + +/*---------------------------------------------------------------------------- +| Returns true when 32-bit unsigned integer `uiA' has the bit pattern of a +| 32-bit floating-point signaling NaN. +| Note: This macro evaluates its argument more than once. +*----------------------------------------------------------------------------*/ +#define softfloat_isSigNaNF32UI( uiA ) ((((uiA) & 0x7FC00000) == 0x7F800000) && ((uiA) & 0x003FFFFF)) + +/*---------------------------------------------------------------------------- +| Assuming `uiA' has the bit pattern of a 32-bit floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +#define softfloat_f32UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & 0x00400000) ) softfloat_raiseFlags( softfloat_flag_invalid ) + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into a 32-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +#define softfloat_commonNaNToF32UI( aPtr ) ((uint_fast32_t) defaultNaNF32UI) + +/*---------------------------------------------------------------------------- +| Interpreting `uiA' and `uiB' as the bit patterns of two 32-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either `uiA' or `uiB' has the pattern of a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +uint_fast32_t + softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB ); + +/*---------------------------------------------------------------------------- +| The bit pattern for a default generated 64-bit floating-point NaN. +*----------------------------------------------------------------------------*/ +#define defaultNaNF64UI UINT64_C( 0x7FF8000000000000 ) + +/*---------------------------------------------------------------------------- +| Returns true when 64-bit unsigned integer `uiA' has the bit pattern of a +| 64-bit floating-point signaling NaN. +| Note: This macro evaluates its argument more than once. +*----------------------------------------------------------------------------*/ +#define softfloat_isSigNaNF64UI( uiA ) ((((uiA) & UINT64_C( 0x7FF8000000000000 )) == UINT64_C( 0x7FF0000000000000 )) && ((uiA) & UINT64_C( 0x0007FFFFFFFFFFFF ))) + +/*---------------------------------------------------------------------------- +| Assuming `uiA' has the bit pattern of a 64-bit floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +#define softfloat_f64UIToCommonNaN( uiA, zPtr ) if ( ! ((uiA) & UINT64_C( 0x0008000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into a 64-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +#define softfloat_commonNaNToF64UI( aPtr ) ((uint_fast64_t) defaultNaNF64UI) + +/*---------------------------------------------------------------------------- +| Interpreting `uiA' and `uiB' as the bit patterns of two 64-bit floating- +| point values, at least one of which is a NaN, returns the bit pattern of +| the combined NaN result. If either `uiA' or `uiB' has the pattern of a +| signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +uint_fast64_t + softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB ); + +/*---------------------------------------------------------------------------- +| The bit pattern for a default generated 80-bit extended floating-point NaN. +*----------------------------------------------------------------------------*/ +#define defaultNaNExtF80UI64 0x7FFF +#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 ) + +/*---------------------------------------------------------------------------- +| Returns true when the 80-bit unsigned integer formed from concatenating +| 16-bit `uiA64' and 64-bit `uiA0' has the bit pattern of an 80-bit extended +| floating-point signaling NaN. +| Note: This macro evaluates its arguments more than once. +*----------------------------------------------------------------------------*/ +#define softfloat_isSigNaNExtF80UI( uiA64, uiA0 ) ((((uiA64) & 0x7FFF) == 0x7FFF) && ! ((uiA0) & UINT64_C( 0x4000000000000000 )) && ((uiA0) & UINT64_C( 0x3FFFFFFFFFFFFFFF ))) + +#ifdef SOFTFLOAT_FAST_INT64 + +/*---------------------------------------------------------------------------- +| The following functions are needed only when `SOFTFLOAT_FAST_INT64' is +| defined. +*----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0' +| has the bit pattern of an 80-bit extended floating-point NaN, converts +| this NaN to the common NaN form, and stores the resulting common NaN at the +| location pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +#define softfloat_extF80UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA0) & UINT64_C( 0x4000000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into an 80-bit extended +| floating-point NaN, and returns the bit pattern of this value as an unsigned +| integer. +*----------------------------------------------------------------------------*/ +#if defined INLINE && ! defined softfloat_commonNaNToExtF80UI +INLINE + struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ) +{ + struct uint128 uiZ; + uiZ.v64 = defaultNaNExtF80UI64; + uiZ.v0 = defaultNaNExtF80UI0; + return uiZ; +} +#else +struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr ); +#endif + +/*---------------------------------------------------------------------------- +| Interpreting the unsigned integer formed from concatenating `uiA64' and +| `uiA0' as an 80-bit extended floating-point value, and likewise interpreting +| the unsigned integer formed from concatenating `uiB64' and `uiB0' as another +| 80-bit extended floating-point value, and assuming at least on of these +| floating-point values is a NaN, returns the bit pattern of the combined NaN +| result. If either original floating-point value is a signaling NaN, the +| invalid exception is raised. +*----------------------------------------------------------------------------*/ +struct uint128 + softfloat_propagateNaNExtF80UI( + uint_fast16_t uiA64, + uint_fast64_t uiA0, + uint_fast16_t uiB64, + uint_fast64_t uiB0 + ); + +/*---------------------------------------------------------------------------- +| The bit pattern for a default generated 128-bit floating-point NaN. +*----------------------------------------------------------------------------*/ +#define defaultNaNF128UI64 UINT64_C( 0x7FFF800000000000 ) +#define defaultNaNF128UI0 UINT64_C( 0 ) + +/*---------------------------------------------------------------------------- +| Returns true when the 128-bit unsigned integer formed from concatenating +| 64-bit `uiA64' and 64-bit `uiA0' has the bit pattern of a 128-bit floating- +| point signaling NaN. +| Note: This macro evaluates its arguments more than once. +*----------------------------------------------------------------------------*/ +#define softfloat_isSigNaNF128UI( uiA64, uiA0 ) ((((uiA64) & UINT64_C( 0x7FFF800000000000 )) == UINT64_C( 0x7FFF000000000000 )) && ((uiA0) || ((uiA64) & UINT64_C( 0x00007FFFFFFFFFFF )))) + +/*---------------------------------------------------------------------------- +| Assuming the unsigned integer formed from concatenating `uiA64' and `uiA0' +| has the bit pattern of a 128-bit floating-point NaN, converts this NaN to +| the common NaN form, and stores the resulting common NaN at the location +| pointed to by `zPtr'. If the NaN is a signaling NaN, the invalid exception +| is raised. +*----------------------------------------------------------------------------*/ +#define softfloat_f128UIToCommonNaN( uiA64, uiA0, zPtr ) if ( ! ((uiA64) & UINT64_C( 0x0000800000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point +| NaN, and returns the bit pattern of this value as an unsigned integer. +*----------------------------------------------------------------------------*/ +#if defined INLINE && ! defined softfloat_commonNaNToF128UI +INLINE + struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr ) +{ + struct uint128 uiZ; + uiZ.v64 = defaultNaNF128UI64; + uiZ.v0 = defaultNaNF128UI0; + return uiZ; +} +#else +struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * ); +#endif + +/*---------------------------------------------------------------------------- +| Interpreting the unsigned integer formed from concatenating `uiA64' and +| `uiA0' as a 128-bit floating-point value, and likewise interpreting the +| unsigned integer formed from concatenating `uiB64' and `uiB0' as another +| 128-bit floating-point value, and assuming at least on of these floating- +| point values is a NaN, returns the bit pattern of the combined NaN result. +| If either original floating-point value is a signaling NaN, the invalid +| exception is raised. +*----------------------------------------------------------------------------*/ +struct uint128 + softfloat_propagateNaNF128UI( + uint_fast64_t uiA64, + uint_fast64_t uiA0, + uint_fast64_t uiB64, + uint_fast64_t uiB0 + ); + +#else + +/*---------------------------------------------------------------------------- +| The following functions are needed only when `SOFTFLOAT_FAST_INT64' is not +| defined. +*----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- +| Assuming the 80-bit extended floating-point value pointed to by `aSPtr' is +| a NaN, converts this NaN to the common NaN form, and stores the resulting +| common NaN at the location pointed to by `zPtr'. If the NaN is a signaling +| NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +#define softfloat_extF80MToCommonNaN( aSPtr, zPtr ) if ( ! ((aSPtr)->signif & UINT64_C( 0x4000000000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into an 80-bit extended +| floating-point NaN, and stores this NaN at the location pointed to by +| `zSPtr'. +*----------------------------------------------------------------------------*/ +#if defined INLINE && ! defined softfloat_commonNaNToExtF80M +INLINE + void + softfloat_commonNaNToExtF80M( + const struct commonNaN *aPtr, struct extFloat80M *zSPtr ) +{ + zSPtr->signExp = defaultNaNExtF80UI64; + zSPtr->signif = defaultNaNExtF80UI0; +} +#else +void + softfloat_commonNaNToExtF80M( + const struct commonNaN *aPtr, struct extFloat80M *zSPtr ); +#endif + +/*---------------------------------------------------------------------------- +| Assuming at least one of the two 80-bit extended floating-point values +| pointed to by `aSPtr' and `bSPtr' is a NaN, stores the combined NaN result +| at the location pointed to by `zSPtr'. If either original floating-point +| value is a signaling NaN, the invalid exception is raised. +*----------------------------------------------------------------------------*/ +void + softfloat_propagateNaNExtF80M( + const struct extFloat80M *aSPtr, + const struct extFloat80M *bSPtr, + struct extFloat80M *zSPtr + ); + +/*---------------------------------------------------------------------------- +| The bit pattern for a default generated 128-bit floating-point NaN. +*----------------------------------------------------------------------------*/ +#define defaultNaNF128UI96 0xFFFFFFFF +#define defaultNaNF128UI64 0xFFFFFFFF +#define defaultNaNF128UI32 0xFFFFFFFF +#define defaultNaNF128UI0 0xFFFFFFFF + +/*---------------------------------------------------------------------------- +| Assuming the 128-bit floating-point value pointed to by `aWPtr' is a NaN, +| converts this NaN to the common NaN form, and stores the resulting common +| NaN at the location pointed to by `zPtr'. If the NaN is a signaling NaN, +| the invalid exception is raised. Argument `aWPtr' points to an array of +| four 32-bit elements that concatenate in the platform's normal endian order +| to form a 128-bit floating-point value. +*----------------------------------------------------------------------------*/ +#define softfloat_f128MToCommonNaN( aWPtr, zPtr ) if ( ! ((aWPtr)[indexWordHi( 4 )] & UINT64_C( 0x0000800000000000 )) ) softfloat_raiseFlags( softfloat_flag_invalid ) + +/*---------------------------------------------------------------------------- +| Converts the common NaN pointed to by `aPtr' into a 128-bit floating-point +| NaN, and stores this NaN at the location pointed to by `zWPtr'. Argument +| `zWPtr' points to an array of four 32-bit elements that concatenate in the +| platform's normal endian order to form a 128-bit floating-point value. +*----------------------------------------------------------------------------*/ +#if defined INLINE && ! defined softfloat_commonNaNToF128M +INLINE + void + softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ) +{ + zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96; + zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64; + zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32; + zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0; +} +#else +void + softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr ); +#endif + +/*---------------------------------------------------------------------------- +| Assuming at least one of the two 128-bit floating-point values pointed to by +| `aWPtr' and `bWPtr' is a NaN, stores the combined NaN result at the location +| pointed to by `zWPtr'. If either original floating-point value is a +| signaling NaN, the invalid exception is raised. Each of `aWPtr', `bWPtr', +| and `zWPtr' points to an array of four 32-bit elements that concatenate in +| the platform's normal endian order to form a 128-bit floating-point value. +*----------------------------------------------------------------------------*/ +void + softfloat_propagateNaNF128M( + const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr ); + +#endif + +#endif + diff --git a/softfloat/ui32_to_f32.c b/softfloat/ui32_to_f32.c old mode 100755 new mode 100644 index ba0fc1a..ae98fb7 --- a/softfloat/ui32_to_f32.c +++ b/softfloat/ui32_to_f32.c @@ -1,25 +1,57 @@ - -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -float32_t ui32_to_f32( uint_fast32_t a ) -{ - union ui32_f32 uZ; - - if ( ! a ) { - uZ.ui = 0; - return uZ.f; - } - if ( a & 0x80000000 ) { - return - softfloat_roundPackToF32( - 0, 0x9D, softfloat_shortShift32Right1Jam( a ) ); - } else { - return softfloat_normRoundPackToF32( 0, 0x9C, a ); - } - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float32_t ui32_to_f32( uint32_t a ) +{ + union ui32_f32 uZ; + + if ( ! a ) { + uZ.ui = 0; + return uZ.f; + } + if ( a & 0x80000000 ) { + return softfloat_roundPackToF32( 0, 0x9D, a>>1 | (a & 1) ); + } else { + return softfloat_normRoundPackToF32( 0, 0x9C, a ); + } + +} + diff --git a/softfloat/ui32_to_f64.c b/softfloat/ui32_to_f64.c old mode 100755 new mode 100644 index d0bd177..6b72fa5 --- a/softfloat/ui32_to_f64.c +++ b/softfloat/ui32_to_f64.c @@ -1,26 +1,60 @@ - -#include -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -float64_t ui32_to_f64( uint_fast32_t a ) -{ - uint_fast64_t uiZ; - int shiftCount; - union ui64_f64 uZ; - - if ( ! a ) { - uiZ = 0; - } else { - shiftCount = softfloat_countLeadingZeros32( a ) + 21; - uiZ = - packToF64UI( - 0, 0x432 - shiftCount, (uint_fast64_t) a< +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float64_t ui32_to_f64( uint32_t a ) +{ + uint_fast64_t uiZ; + int_fast8_t shiftCount; + union ui64_f64 uZ; + + if ( ! a ) { + uiZ = 0; + } else { + shiftCount = softfloat_countLeadingZeros32( a ) + 21; + uiZ = + packToF64UI( + 0, 0x432 - shiftCount, (uint_fast64_t) a< -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -float32_t ui64_to_f32( uint_fast64_t a ) -{ - int shiftCount; - union ui32_f32 u; - uint_fast32_t sig; - - shiftCount = softfloat_countLeadingZeros64( a ) - 40; - if ( 0 <= shiftCount ) { - u.ui = - a ? packToF32UI( - 0, 0x95 - shiftCount, (uint_fast32_t) a< +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float32_t ui64_to_f32( uint64_t a ) +{ + int_fast8_t shiftCount; + union ui32_f32 u; + uint_fast32_t sig; + + shiftCount = softfloat_countLeadingZeros64( a ) - 40; + if ( 0 <= shiftCount ) { + u.ui = + a ? packToF32UI( + 0, 0x95 - shiftCount, (uint_fast32_t) a< -#include "platform.h" -#include "primitives.h" -#include "internals.h" -#include "softfloat.h" - -float64_t ui64_to_f64( uint_fast64_t a ) -{ - union ui64_f64 uZ; - - if ( ! a ) { - uZ.ui = 0; - return uZ.f; - } - if ( a & UINT64_C( 0x8000000000000000 ) ) { - return - softfloat_roundPackToF64( - 0, 0x43D, softfloat_shortShift64RightJam( a, 1 ) ); - } else { - return softfloat_normRoundPackToF64( 0, 0x43C, a ); - } - -} - + +/*============================================================================ + +This C source file is part of the SoftFloat IEEE Floating-Point Arithmetic +Package, Release 3a, by John R. Hauser. + +Copyright 2011, 2012, 2013, 2014 The Regents of the University of California. +All Rights Reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions, and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions, and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + 3. Neither the name of the University nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=============================================================================*/ + +#include +#include "platform.h" +#include "internals.h" +#include "softfloat.h" + +float64_t ui64_to_f64( uint64_t a ) +{ + union ui64_f64 uZ; + + if ( ! a ) { + uZ.ui = 0; + return uZ.f; + } + if ( a & UINT64_C( 0x8000000000000000 ) ) { + return + softfloat_roundPackToF64( + 0, 0x43D, softfloat_shortShiftRightJam64( a, 1 ) ); + } else { + return softfloat_normRoundPackToF64( 0, 0x43C, a ); + } + +} +