From 5c62ec2d8f281901a1ee0ffdcac6d8bf7ce4617c Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sat, 5 Nov 2016 16:24:18 -0400 Subject: [PATCH 1/7] Assume ANSI C in modules/src/flt_arith Remove the #include "ansi.h" and always use the prototypes. --- modules/src/flt_arith/flt_arith.h | 26 ++++++++++++-------------- modules/src/flt_arith/flt_misc.h | 10 +++++----- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/modules/src/flt_arith/flt_arith.h b/modules/src/flt_arith/flt_arith.h index bd6ecb157..964c19580 100644 --- a/modules/src/flt_arith/flt_arith.h +++ b/modules/src/flt_arith/flt_arith.h @@ -7,8 +7,6 @@ #ifndef __FLT_INCLUDED__ #define __FLT_INCLUDED__ -#include "ansi.h" - #ifndef arith #define arith long #endif @@ -33,17 +31,17 @@ extern int flt_status; #define FLT_STRLEN 32 /* max length of result of flt_flt2str() */ -_PROTOTYPE(void flt_add, (flt_arith *, flt_arith *, flt_arith *)); -_PROTOTYPE(void flt_sub, (flt_arith *, flt_arith *, flt_arith *)); -_PROTOTYPE(void flt_mul, (flt_arith *, flt_arith *, flt_arith *)); -_PROTOTYPE(void flt_div, (flt_arith *, flt_arith *, flt_arith *)); -_PROTOTYPE(void flt_modf, (flt_arith *, flt_arith *, flt_arith *)); -_PROTOTYPE(int flt_cmp, (flt_arith *, flt_arith *)); -_PROTOTYPE(void flt_str2flt, (char *, flt_arith *)); -_PROTOTYPE(void flt_flt2str, (flt_arith *, char *, int)); -_PROTOTYPE(void flt_arith2flt, (arith, flt_arith *, int)); -_PROTOTYPE(arith flt_flt2arith, (flt_arith *, int)); -_PROTOTYPE(void flt_b64_sft, (struct flt_mantissa *, int)); -_PROTOTYPE(void flt_umin, (flt_arith *)); +void flt_add(flt_arith *, flt_arith *, flt_arith *); +void flt_sub(flt_arith *, flt_arith *, flt_arith *); +void flt_mul(flt_arith *, flt_arith *, flt_arith *); +void flt_div(flt_arith *, flt_arith *, flt_arith *); +void flt_modf(flt_arith *, flt_arith *, flt_arith *); +int flt_cmp(flt_arith *, flt_arith *); +void flt_str2flt(char *, flt_arith *); +void flt_flt2str(flt_arith *, char *, int); +void flt_arith2flt(arith, flt_arith *, int); +arith flt_flt2arith(flt_arith *, int); +void flt_b64_sft(struct flt_mantissa *, int); +void flt_umin(flt_arith *); #endif /* __FLT_INCLUDED__ */ diff --git a/modules/src/flt_arith/flt_misc.h b/modules/src/flt_arith/flt_misc.h index ec850697f..c5cf5a7cf 100644 --- a/modules/src/flt_arith/flt_misc.h +++ b/modules/src/flt_arith/flt_misc.h @@ -21,8 +21,8 @@ #define flt_b64_add _flt_64add #define flt_split _flt_split -_PROTOTYPE(int ucmp, (long, long)); -_PROTOTYPE(void flt_nrm, (flt_arith *)); -_PROTOTYPE(void flt_chk, (flt_arith *)); -_PROTOTYPE(int flt_b64_add, (struct flt_mantissa *, struct flt_mantissa *)); -_PROTOTYPE(void flt_split, (flt_arith *, unsigned short *)); +int ucmp(long, long); +void flt_nrm(flt_arith *); +void flt_chk(flt_arith *); +int flt_b64_add(struct flt_mantissa *, struct flt_mantissa *); +void flt_split(flt_arith *, unsigned short *); From 3bb41d391038f56b74bd5e34a820d31a4dbd658f Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sat, 5 Nov 2016 17:00:24 -0400 Subject: [PATCH 2/7] Switch flt_mantissa fields from long to uint32_t. This seems to fix an error when flt_arith converts a literal double-precision float to IEEE format. For example, 0.5 and 0.75 got converted to slightly below their correct values. My host gcc for amd64 has 64-bit long, but flt_arith needs only 32 bits. The code (at least flt_add.c) can make 32-bit overflows. Such overflows would set the higher bits of a 64-bit long, which might cause problems later. I need to use uint32_t and not int32_t because the code still uses long, and the sign extension from int32_t to long would cause problems. The mantissa represents a value in [0, 2) that can't be negative, so unsigned type is better. Also, signed overflow is undefined behavior in C, so flt_add.c better make overflows with uint32_t and not int32_t. This commit doesn't touch lang/cem/libcc.ansi/stdlib/ext_fmt.h which continues to use unsigned long for its mantissa fields. --- modules/src/flt_arith/flt_arith.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/src/flt_arith/flt_arith.h b/modules/src/flt_arith/flt_arith.h index 964c19580..9a21e5135 100644 --- a/modules/src/flt_arith/flt_arith.h +++ b/modules/src/flt_arith/flt_arith.h @@ -7,13 +7,15 @@ #ifndef __FLT_INCLUDED__ #define __FLT_INCLUDED__ +#include + #ifndef arith #define arith long #endif struct flt_mantissa { - long flt_h_32; /* high order 32 bits of mantissa */ - long flt_l_32; /* low order 32 bits of mantissa */ + uint32_t flt_h_32; /* high order 32 bits of mantissa */ + uint32_t flt_l_32; /* low order 32 bits of mantissa */ }; typedef struct flt_arith { From daeeb5aca3a18ff8e240a534bad1f0941523cf9c Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sat, 5 Nov 2016 21:29:03 -0400 Subject: [PATCH 3/7] Simplify flt_arith now that mantissa uses uint32_t. It seems that someone wanted to build flt_arith with a compiler that had long but not unsigned long. This required extra code to accomplish unsigned right shift, unsigned division, and unsigned comparison using the signed operations. Now that we use uint32_t, we can simply use the unsigned operations and remove the ucmp() function. We have similar code in mach/proto/fp/ and in lang/cem/libcc.ansi/stdlib/ext_comp.c where we use the unsigned operations. Some long variables become uint32_t, and some masks with 0xFFFFFFFF disappear because uint32_t has only 32 bits. Update flt_arith.3 to show that mantissa uses uint32_t. Provide a target to install modules/src/flt_arith/test.c as flt_test so I can run the tests. --- modules/src/flt_arith/b64_add.c | 10 +++---- modules/src/flt_arith/b64_sft.c | 15 ++++------ modules/src/flt_arith/build.lua | 15 +++++++++- modules/src/flt_arith/flt_add.c | 9 +++--- modules/src/flt_arith/flt_arith.3 | 4 +-- modules/src/flt_arith/flt_div.c | 47 +++++++++++++------------------ modules/src/flt_arith/flt_misc.h | 2 -- modules/src/flt_arith/flt_mul.c | 13 +++++---- modules/src/flt_arith/flt_nrm.c | 5 ++-- modules/src/flt_arith/test.c | 5 +++- modules/src/flt_arith/ucmp.c | 21 -------------- 11 files changed, 64 insertions(+), 82 deletions(-) delete mode 100644 modules/src/flt_arith/ucmp.c diff --git a/modules/src/flt_arith/b64_add.c b/modules/src/flt_arith/b64_add.c index ca03e84a0..71bd66607 100644 --- a/modules/src/flt_arith/b64_add.c +++ b/modules/src/flt_arith/b64_add.c @@ -5,6 +5,7 @@ /* $Id$ */ +#include #include "flt_misc.h" int @@ -15,16 +16,15 @@ flt_b64_add(e1,e2) int carry; /* add higher pair of 32 bits */ - overflow = ucmp((long)0xFFFFFFFF - e1->flt_h_32, e2->flt_h_32) < 0; + overflow = (0xFFFFFFFFUL - e1->flt_h_32 < e2->flt_h_32); e1->flt_h_32 += e2->flt_h_32; /* add lower pair of 32 bits */ - carry = ucmp((long)0xFFFFFFFF - e1->flt_l_32, e2->flt_l_32) < 0; + carry = (0xFFFFFFFFUL - e1->flt_l_32 < e2->flt_l_32); e1->flt_l_32 += e2->flt_l_32; - if ((carry) && ((++e1->flt_h_32 &~0xFFFFFFFF) || e1->flt_h_32 == 0)) { - e1->flt_h_32 = 0; + if ((carry) && (++e1->flt_h_32 == 0)) return(1); /* had a 64 bit overflow */ - } + return(overflow); /* return status from higher add */ } diff --git a/modules/src/flt_arith/b64_sft.c b/modules/src/flt_arith/b64_sft.c index f891c6936..ef6d74a9e 100644 --- a/modules/src/flt_arith/b64_sft.c +++ b/modules/src/flt_arith/b64_sft.c @@ -23,12 +23,10 @@ flt_b64_sft(e,n) n -= 32; } if (n > 0) { - e->flt_l_32 = (e->flt_l_32 >> 1) & 0x7FFFFFFF; - e->flt_l_32 >>= (n - 1); + e->flt_l_32 >>= n; if (e->flt_h_32 != 0) { - e->flt_l_32 |= (e->flt_h_32 << (32 - n)) & 0xFFFFFFFF; - e->flt_h_32 = (e->flt_h_32 >> 1) & 0x7FFFFFFF; - e->flt_h_32 >>= (n - 1); + e->flt_l_32 |= (e->flt_h_32 << (32 - n)); + e->flt_h_32 >>= n; } } n = -n; @@ -38,11 +36,10 @@ flt_b64_sft(e,n) n -= 32; } if (n > 0) { - e->flt_h_32 = (e->flt_h_32 << n) & 0xFFFFFFFF; + e->flt_h_32 <<= n; if (e->flt_l_32 != 0) { - long l = (e->flt_l_32 >> 1) & 0x7FFFFFFF; - e->flt_h_32 |= (l >> (31 - n)); - e->flt_l_32 = (e->flt_l_32 << n) & 0xFFFFFFFF; + e->flt_h_32 |= (e->flt_l_32 >> (32 - n)); + e->flt_l_32 <<= n; } } } diff --git a/modules/src/flt_arith/build.lua b/modules/src/flt_arith/build.lua index e6ac2dd40..54aa3b097 100644 --- a/modules/src/flt_arith/build.lua +++ b/modules/src/flt_arith/build.lua @@ -15,7 +15,6 @@ clibrary { "./flt_umin.c", "./flt_chk.c", "./split.c", - "./ucmp.c", }, hdrs = { "./flt_arith.h" }, deps = { @@ -24,4 +23,18 @@ clibrary { } } +-- The test program isn't built by default. Here is a target +-- modules/src/flt_arith+pkg to install it as flt_test +cprogram { + name = "test", + srcs = { "./test.c" }, + deps = { "+lib" }, +} + +installable { + name = "pkg", + map = { + ["$(INSDIR)/bin/flt_test"] = "+test", + }, +} diff --git a/modules/src/flt_arith/flt_add.c b/modules/src/flt_arith/flt_add.c index d9d4d57c5..ca9830ec3 100644 --- a/modules/src/flt_arith/flt_add.c +++ b/modules/src/flt_arith/flt_add.c @@ -44,11 +44,10 @@ flt_add(e1,e2,e3) } if (e1->flt_sign != e2->flt_sign) { /* e2 + e1 = e2 - (-e1) */ - int tmp = ucmp(e1->m1, e2->m1); - int tmp2 = ucmp(e1->m2, e2->m2); - if (tmp > 0 || (tmp == 0 && tmp2 > 0)) { + if (e1->m1 > e2->m1 || + (e1->m1 == e2->m1 && e1->m2 > e2->m2)) { /* abs(e1) > abs(e2) */ - if (tmp2 < 0) { + if (e1->m2 < e2->m2) { e1->m1 -= 1; /* carry in */ } e1->m1 -= e2->m1; @@ -56,7 +55,7 @@ flt_add(e1,e2,e3) *e3 = *e1; } else { - if (tmp2 > 0) + if (e1->m2 > e2->m2) e2->m1 -= 1; /* carry in */ e2->m1 -= e1->m1; e2->m2 -= e1->m2; diff --git a/modules/src/flt_arith/flt_arith.3 b/modules/src/flt_arith/flt_arith.3 index 2e6a5feb1..91bce44ea 100644 --- a/modules/src/flt_arith/flt_arith.3 +++ b/modules/src/flt_arith/flt_arith.3 @@ -9,8 +9,8 @@ flt_arith \- high precision floating point arithmetic .if t .ta 3m 13m 22m .if n .ta 5m 25m 40m struct flt_mantissa { - long flt_h_32; /* high order 32 bits of mantissa */ - long flt_l_32; /* low order 32 bits of mantissa */ + uint32_t flt_h_32; /* high order 32 bits of mantissa */ + uint32_t flt_l_32; /* low order 32 bits of mantissa */ }; typedef struct { diff --git a/modules/src/flt_arith/flt_div.c b/modules/src/flt_arith/flt_div.c index 11b74c0e1..3295fe63b 100644 --- a/modules/src/flt_arith/flt_div.c +++ b/modules/src/flt_arith/flt_div.c @@ -5,14 +5,15 @@ /* $Id$ */ +#include #include "flt_misc.h" void flt_div(e1,e2,e3) register flt_arith *e1,*e2,*e3; { - long result[2]; - register long *lp; + uint32_t result[2]; + register uint32_t *rp; unsigned short u[9], v[5]; register int j; register unsigned short *u_p = u; @@ -44,7 +45,7 @@ flt_div(e1,e2,e3) while (! v[maxv]) maxv--; result[0] = 0; result[1] = 0; - lp = result; + rp = result; /* * Use an algorithm of Knuth (The art of programming, Seminumerical @@ -52,35 +53,25 @@ flt_div(e1,e2,e3) * with base 65536. */ for (j = 0; j <= 3; j++, u_p++) { - long q_est, temp; - long v1 = v[1]; + uint32_t q_est, temp; - if (j == 2) lp++; + if (j == 2) rp++; if (u_p[0] == 0 && u_p[1] < v[1]) continue; - temp = ((long)u_p[0] << 16) + u_p[1]; + temp = ((uint32_t)u_p[0] << 16) + u_p[1]; if (u_p[0] >= v[1]) { - q_est = 0x0000FFFFL; + q_est = 0x0000FFFFUL; } else if (v[1] == 1) { q_est = temp; } - else if (temp >= 0) { - q_est = temp / v1; - } else { - long rem; - q_est = (0x7FFFFFFF/v1)+((temp&0x7FFFFFFF)/v1); - rem = (0x7FFFFFFF%v1)+((temp&0x7FFFFFFF)%v1)+1; - while (rem >= v1) { - q_est++; - rem -= v1; - } + q_est = temp / v[1]; } - temp -= q_est * v1; + temp -= q_est * v[1]; while (!(temp&0xFFFF0000) && - ucmp((long)v[2]*q_est,(temp<<16)+(long)u_p[2]) > 0) { + v[2]*q_est > (temp<<16)+u_p[2]) { q_est--; - temp += v1; + temp += v[1]; } /* Now, according to Knuth, we have an estimate of the quotient, that is either correct or one too big, but @@ -88,11 +79,11 @@ flt_div(e1,e2,e3) */ if (q_est != 0) { int i; - long k = 0; + uint32_t k = 0; int borrow = 0; for (i = maxv; i > 0; i--) { - long tmp = q_est * (long)v[i] + k + borrow; + uint32_t tmp = q_est * v[i] + k + borrow; unsigned short md = tmp & 0xFFFF; borrow = (md > u_p[i]); @@ -100,7 +91,7 @@ flt_div(e1,e2,e3) k = (tmp >> 16) & 0xFFFF; } k += borrow; - borrow = (long)u_p[0] < k; + borrow = u_p[0] < k; u_p[0] -= k; if (borrow) { @@ -110,15 +101,15 @@ flt_div(e1,e2,e3) q_est--; borrow = 0; for (i = maxv; i > 0; i--) { - long tmp - = v[i]+(long)u_p[i]+borrow; - + uint32_t tmp + = v[i]+(uint32_t)u_p[i]+borrow; + u_p[i] = tmp & 0xFFFF; borrow = (tmp >> 16) & 0xFFFF; } u_p[0] += borrow; } - *lp |= (j & 1) ? q_est : (q_est<<16); + *rp |= (j & 1) ? q_est : (q_est<<16); } } e3->m1 = result[0]; diff --git a/modules/src/flt_arith/flt_misc.h b/modules/src/flt_arith/flt_misc.h index c5cf5a7cf..64b6865aa 100644 --- a/modules/src/flt_arith/flt_misc.h +++ b/modules/src/flt_arith/flt_misc.h @@ -15,13 +15,11 @@ #define EXT_MIN (-16384) /* min exponent */ /* hiding of names: */ -#define ucmp _flt_ucmp #define flt_nrm _flt_nrm #define flt_chk _flt_chk #define flt_b64_add _flt_64add #define flt_split _flt_split -int ucmp(long, long); void flt_nrm(flt_arith *); void flt_chk(flt_arith *); int flt_b64_add(struct flt_mantissa *, struct flt_mantissa *); diff --git a/modules/src/flt_arith/flt_mul.c b/modules/src/flt_arith/flt_mul.c index e6972ab54..4d989382b 100644 --- a/modules/src/flt_arith/flt_mul.c +++ b/modules/src/flt_arith/flt_mul.c @@ -5,6 +5,7 @@ /* $Id$ */ +#include #include "flt_misc.h" void @@ -43,9 +44,9 @@ flt_mul(e1,e2,e3) */ for(i=4, pres = &result[4];i--;pres--) if (mp[i]) { unsigned short k = 0; - long mpi = mp[i]; + uint32_t mpi = mp[i]; for(j=4;j--;) { - long tmp = (long)pres[j] + k; + long tmp = (uint32_t)pres[j] + k; if (mc[j]) tmp += mpi * mc[j]; pres[j] = tmp & 0xFFFF; k = (tmp >> 16) & 0xFFFF; @@ -64,12 +65,12 @@ flt_mul(e1,e2,e3) /* * combine the registers to a total */ - e3->m1 = ((long)result[0] << 16) + result[1]; - e3->m2 = ((long)result[2] << 16) + result[3]; + e3->m1 = ((uint32_t)result[0] << 16) + result[1]; + e3->m2 = ((uint32_t)result[2] << 16) + result[3]; if (result[4] & 0x8000) { - if (++e3->m2 == 0 || (e3->m2 & ~ 0xFFFFFFFF)) { + if (++e3->m2 == 0) { e3->m2 = 0; - if (++e3->m1 == 0 || (e3->m1 & ~ 0xFFFFFFFF)) { + if (++e3->m1 == 0) { e3->m1 = 0x80000000; e3->flt_exp++; } diff --git a/modules/src/flt_arith/flt_nrm.c b/modules/src/flt_arith/flt_nrm.c index 14762b616..3520ee5b4 100644 --- a/modules/src/flt_arith/flt_nrm.c +++ b/modules/src/flt_arith/flt_nrm.c @@ -5,6 +5,7 @@ /* $Id$ */ +#include #include "flt_misc.h" void @@ -24,8 +25,8 @@ flt_nrm(e) e->m2 = 0L; e->flt_exp -= 32; } - if ((e->m1 & 0x80000000) == 0) { - long l = 0x40000000; + if ((e->m1 & 0x80000000UL) == 0) { + uint32_t l = 0x40000000UL; int cnt = -1; while (! (l & e->m1)) { diff --git a/modules/src/flt_arith/test.c b/modules/src/flt_arith/test.c index bf9c43c69..dfc4a694a 100644 --- a/modules/src/flt_arith/test.c +++ b/modules/src/flt_arith/test.c @@ -1,3 +1,5 @@ +#include +#include #include "flt_arith.h" struct tests { @@ -22,6 +24,7 @@ struct tests { { 0, 0, 0, 0} }; +int main() { register struct tests *p = tests; @@ -31,7 +34,7 @@ main() if (! dotest(p)) exit_status = 1; p++; } - exit(exit_status); + return exit_status; } int diff --git a/modules/src/flt_arith/ucmp.c b/modules/src/flt_arith/ucmp.c deleted file mode 100644 index c4b7bc0a4..000000000 --- a/modules/src/flt_arith/ucmp.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands. - See the copyright notice in the ACK home directory, in the file "Copyright". -*/ - -/* $Id$ */ - -#include "flt_misc.h" - -int -ucmp(l1,l2) - long l1,l2; -{ - if (l1 == l2) return 0; - if (l2 >= 0) { - if (l1 > l2 || l1 < 0) return 1; - return -1; - } - if (l1 >= 0 || l1 < l2) return -1; - return 1; -} From 19ca28e22f6de12cbff8f0be250a0a30b74b3c92 Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sun, 6 Nov 2016 15:01:25 -0500 Subject: [PATCH 4/7] Undo commit bfeb736 for lang/cem/libcc.ansi/headers/float.h This restores the correct values of DBL_MAX, DBL_MIN_EXP, and related constants. This fixes some range checks within libc, causing atof("-36e90") and atof("1.44e-288") to return the correct values. --- lang/cem/libcc.ansi/headers/float.h | 108 ++++++++++++++++++---------- 1 file changed, 72 insertions(+), 36 deletions(-) diff --git a/lang/cem/libcc.ansi/headers/float.h b/lang/cem/libcc.ansi/headers/float.h index 43656651b..8cdb34c4f 100644 --- a/lang/cem/libcc.ansi/headers/float.h +++ b/lang/cem/libcc.ansi/headers/float.h @@ -1,43 +1,79 @@ /* - -- simple version used by "gimplify" + * float.h - implementation limits + */ +/* $Id$ */ - last edit: 2007-02-12 D A Gwyn -*/ +#if !defined(_FLOAT_H) +#define _FLOAT_H -/* Does not exactly fit any model, and is minimal for "universality". */ +#if defined(__vax) || defined(__pdp) +#define FLT_DIG 6 +#define FLT_EPSILON 5.96046448e-08F +#define FLT_MANT_DIG 8 +#define FLT_MAX 1.70141173e+38F +#define FLT_MAX_10_EXP 38 +#define FLT_MAX_EXP 127 +#define FLT_MIN 2.93873588e-39F +#define FLT_MIN_10_EXP (-38) +#define FLT_MIN_EXP (-127) -#define FLT_ROUNDS (-1) -#define FLT_EVAL_METHOD (-1) -#define FLT_RADIX 2 -#define DECIMAL_DIG 10 +#define DBL_DIG 16 +#define DBL_EPSILON 1.38777878078144568e-17 +#define DBL_MANT_DIG 8 +#define DBL_MAX 1.70141183460469229e+38 +#define DBL_MAX_10_EXP 38 +#define DBL_MAX_EXP 127 +#define DBL_MIN 2.93873587705571877e-39 +#define DBL_MIN_10_EXP (-38) +#define DBL_MIN_EXP (-127) -/* assumes that "gimplify" specifies "-Dfloat=double" */ -#define FLT_MANT_DIG 10 -#define FLT_EPSILON (1E-9F) -#define FLT_DIG 10 -#define FLT_MIN_EXP (-31) -#define FLT_MIN (1E-37F) -#define FLT_MIN_10_EXP (-37) -#define FLT_MAX_EXP 37 -#define FLT_MAX (1E+37F) -#define FLT_MAX_10_EXP 37 +#define LDBL_DIG 16 +#define LDBL_EPSILON 1.38777878078144568e-17L +#define LDBL_MANT_DIG 8 +#define LDBL_MAX 1.70141183460469229e+38L +#define LDBL_MAX_10_EXP 38 +#define LDBL_MAX_EXP 127 +#define LDBL_MIN 2.93873587705571877e-39L +#define LDBL_MIN_10_EXP (-38) +#define LDBL_MIN_EXP (-127) -#define DBL_MANT_DIG 10 -#define DBL_EPSILON (1E-9) -#define DBL_DIG 10 -#define DBL_MIN_EXP (-31) -#define DBL_MIN (1E-37) -#define DBL_MIN_10_EXP (-37) -#define DBL_MAX_EXP 37 -#define DBL_MAX (1E+37) -#define DBL_MAX_10_EXP 37 +#define FLT_ROUNDS 1 +#define FLT_RADIX 2 -#define LDBL_MANT_DIG 10 -#define LDBL_EPSILON (1E-9L) -#define LDBL_DIG 10 -#define LDBL_MIN_EXP (-31) -#define LDBL_MIN (1E-37L) -#define LDBL_MIN_10_EXP (-37) -#define LDBL_MAX_EXP 37 -#define LDBL_MAX (1E+37L) -#define LDBL_MAX_10_EXP 37 +#else /* IEEE format */ +#define FLT_DIG 6 +#define FLT_EPSILON 1.19209290e-07F +#define FLT_MANT_DIG 24 +#define FLT_MAX 3.40282347e+38F +#define FLT_MAX_10_EXP 38 +#define FLT_MAX_EXP 128 +#define FLT_MIN 1.17549435e-38F +#define FLT_MIN_10_EXP (-37) +#define FLT_MIN_EXP (-125) + +#define DBL_DIG 15 +#define DBL_EPSILON 2.2204460492503131e-16 +#define DBL_MANT_DIG 53 +#define DBL_MAX 1.7976931348623157e+308 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define DBL_MIN 2.2250738585072014e-308 +#define DBL_MIN_10_EXP (-307) +#define DBL_MIN_EXP (-1021) + +#define LDBL_DIG 15 +#define LDBL_EPSILON 2.2204460492503131e-16L +#define LDBL_MANT_DIG 53 +#define LDBL_MAX 1.7976931348623157e+308L +#define LDBL_MAX_10_EXP 308 +#define LDBL_MAX_EXP 1024 +#define LDBL_MIN 2.2250738585072014e-308L +#define LDBL_MIN_10_EXP (-307) +#define LDBL_MIN_EXP (-1021) + +#define FLT_ROUNDS 1 +#define FLT_RADIX 2 + +#endif /* vax, pdp or ieee */ + +#endif /* _FLOAT_H */ From 08f9869a63d85a4634ec87c826212b01f935af8e Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sun, 6 Nov 2016 15:49:47 -0500 Subject: [PATCH 5/7] Remove unused defines from lang/cem/libcc.ansi/math/localmath.h This undoes part of bfeb736, and returns to using DBL_MAX_EXP and DBL_MIN_EXP from float.h. Add a dependency on math/localmath.h and other local header files so libc is rebuilt when those headers change. --- lang/cem/libcc.ansi/build.lua | 20 ++++++++++++-------- lang/cem/libcc.ansi/math/localmath.h | 17 ++--------------- 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/lang/cem/libcc.ansi/build.lua b/lang/cem/libcc.ansi/build.lua index 3ca95b629..601a50de4 100644 --- a/lang/cem/libcc.ansi/build.lua +++ b/lang/cem/libcc.ansi/build.lua @@ -28,9 +28,9 @@ normalrule { } for _, plat in ipairs(vars.plats) do - acklibrary { - name = "lib_"..plat, - srcs = { + acklibrary { + name = "lib_"..plat, + srcs = { "+ctype_files", "+ctype_tab", "./ctype/*.c", @@ -43,20 +43,24 @@ for _, plat in ipairs(vars.plats) do "./setjmp/*.c", "./setjmp/*.e", "./signal/*.c", - "./assert/*.c", + "./assert/*.c", "./stdio/*.c", "./stdlib/*.c", "./string/*.c", "./time/*.c", - - }, + }, hdrs = {}, -- must be empty deps = { "lang/cem/libcc.ansi/headers+headers", "plat/"..plat.."/include+headers", + "./malloc/malloc.h", + "./math/localmath.h", + "./stdio/loc_incl.h", + "./stdlib/ext_fmt.h", + "./time/loc_time.h", }, - vars = { plat = plat } - } + vars = { plat = plat } + } ackfile { name = "crt_"..plat, diff --git a/lang/cem/libcc.ansi/math/localmath.h b/lang/cem/libcc.ansi/math/localmath.h index 7c9a67465..e85c81c0a 100644 --- a/lang/cem/libcc.ansi/math/localmath.h +++ b/lang/cem/libcc.ansi/math/localmath.h @@ -18,18 +18,5 @@ #define POLYNOM12(x, a) (POLYNOM11((x),(a)+1)*(x)+(a)[0]) #define POLYNOM13(x, a) (POLYNOM12((x),(a)+1)*(x)+(a)[0]) -/* These are set up for 64-bit doubles. */ - -#ifndef M_MAX_D -#define M_MAX_D 1.7976931348623157e+308 -#define M_MIN_D 2.2250738585072014e-308 -#define M_DEXPLEN 11 -#endif -#define M_DMAXEXP ((1 << (M_DEXPLEN - 1)) - 1) -#define M_DMINEXP (-M_DMAXEXP) -#define M_LN_MAX_D (M_LN2 * M_DMAXEXP) -#define M_LN_MIN_D (M_LN2 * (M_DMINEXP - 1)) - -#define HUGE M_MAX_D -#define MAXDOUBLE M_MAX_D - +#define M_LN_MAX_D (M_LN2 * DBL_MAX_EXP) +#define M_LN_MIN_D (M_LN2 * (DBL_MIN_EXP - 1)) From e5e96d5226c27e4f31d199bc8530885c78c2058d Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sun, 6 Nov 2016 19:34:51 -0500 Subject: [PATCH 6/7] Convert 1 to 1.0, not 0.0, for machines with 64-bit long. This fixes flt_arith2flt() when sizeof(arith) != 4, where arith is long. When cemcom.ansi sees an expression like d + 1 (where d is some double), it calls flt_arith2flt() to convert 1 to floating-point. On machines where sizeof(arith) != 4, the code did n >>= 1 when n should not have been changed. If n was 1, then n == 0 became true. This caused the code to convert 1 or -1 to 0.0. My fix assumes sizeof(arith) >= 8, so I can use n >> 32. Machines with sizeof(arith) of 5 to 7 would need to do (uarith)n >> 32, where uarith must be an unsigned integer type of same size as arith. In startrek.c, the Enterprise can now dock with a starbase. The compiler no longer translates s1 - 1 to s1 - 0.0 and s1 + 1 to s1 + 0.0, so the game now looks for starbases next to the Enterprise. --- modules/src/flt_arith/flt_ar2flt.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/src/flt_arith/flt_ar2flt.c b/modules/src/flt_arith/flt_ar2flt.c index f1d159a67..6dac35883 100644 --- a/modules/src/flt_arith/flt_ar2flt.c +++ b/modules/src/flt_arith/flt_ar2flt.c @@ -25,10 +25,9 @@ flt_arith2flt(n, e, uns) e->m1 = 0; e->m2 = n; } else { - e->m2 = n & 0xffffffffL; - n >>= 1; - n &= ~((arith) 1 << (8*sizeof(arith)-1)); - e->m1 = (n >> 31); + /* assuming sizeof(arith) >= 8 */ + e->m1 = n >> 32; + e->m2 = n; } if (n == 0) { e->flt_exp = 0; From 82c2d184822c739f4761bee2e26c5974b9e16d1e Mon Sep 17 00:00:00 2001 From: George Koehler Date: Sun, 6 Nov 2016 20:21:48 -0500 Subject: [PATCH 7/7] Edit startrek.c so I can compile it with gcc and OpenBSD libc. Rename our getline() to get_line() to prevent a conflict with POSIX getline() declared in stdio.h. Remove dangerous call to gets(). OpenBSD does not have gets(), C99 deprecated it and C11 removed it. Also change spelling "sheild" to "shield". --- examples/startrek.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/startrek.c b/examples/startrek.c index f4f35a8bd..572c53597 100644 --- a/examples/startrek.c +++ b/examples/startrek.c @@ -107,7 +107,7 @@ void phaser_control(void); void photon_torpedoes(void); void torpedo_hit(void); void damage_control(void); -void sheild_control(void); +void shield_control(void); void library_computer(void); void galactic_record(void); void status_report(void); @@ -137,7 +137,7 @@ void sub2(void); void showfile(char *filename); int openfile(char * sFilename, char * sMode); void closefile(void); -int getline(char *s); +int get_line(char *s); void randomize(void); int get_rand(int iSpread); double rnd(void); @@ -203,7 +203,7 @@ void reads(char* buffer) { fflush(stdout); - gets(buffer); + fgets(buffer, sizeof(string), stdin); } /* Main Program */ @@ -292,7 +292,7 @@ new_game(void) else if (! strncmp(sTemp, "tor", 3)) photon_torpedoes(); else if (! strncmp(sTemp, "she", 3)) - sheild_control(); + shield_control(); else if (! strncmp(sTemp, "dam", 3)) damage_control(); else if (! strncmp(sTemp, "com", 3)) @@ -307,7 +307,7 @@ new_game(void) printf(" lrs - Long Range Sensors\n"); printf(" pha - Phasers\n"); printf(" tor - Photon Torpedoes\n"); - printf(" she - Sheild Control\n"); + printf(" she - Shield Control\n"); printf(" dam - Damage Control\n"); printf(" com - Library Computer\n"); printf(" xxx - Resign Command\n"); @@ -1206,14 +1206,14 @@ damage_control(void) } void -sheild_control(void) +shield_control(void) { int i; string sTemp; if (d[7] < 0.0) { - printf("Sheild Control inoperable\n"); + printf("Shield Control inoperable\n"); return; } @@ -1229,15 +1229,15 @@ sheild_control(void) if (i < 0 || s == i) { - printf("\n\n"); + printf("\n\n"); return; } if (i >= e + s) { - printf("Sheild Control Reports:\n"); + printf("Shield Control Reports:\n"); printf(" 'This is not the Federation Treasury.'\n"); - printf("\n\n"); + printf("\n\n"); return; } @@ -1776,7 +1776,7 @@ get_device_name(void) { static char * device_name[] = { "", "Warp Engines","Short Range Sensors","Long Range Sensors", - "Phaser Control","Photon Tubes","Damage Control","Sheild Control", + "Phaser Control","Photon Tubes","Damage Control","Shield Control", "Library-Computer"}; if (r1 < 0 || r1 > 8) @@ -1888,7 +1888,7 @@ showfile(char *filename) if (openfile(filename, "r") != 0) return; - while (getline(lBuffer) != 0) + while (get_line(lBuffer) != 0) { printf(lBuffer); @@ -1926,7 +1926,7 @@ closefile(void) } int -getline(char *s) +get_line(char *s) { fflush(stdout); if (fgets(s, MAXCOL, stream) == NULL)