diff --git a/mach/.distr b/mach/.distr index d63cff37d..19010d2c1 100644 --- a/mach/.distr +++ b/mach/.distr @@ -4,6 +4,7 @@ 6809 i80 compare +con_float i86 install em22 diff --git a/mach/con_float b/mach/con_float new file mode 100644 index 000000000..26cf7fb6e --- /dev/null +++ b/mach/con_float @@ -0,0 +1,603 @@ +/* + (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands. + See the copyright notice in the ACK home directory, in the file "Copyright". +*/ + +/* $Header$ */ + +/* #define NOFLOAT for machines without floating point + #define ACKFLOAT for machines using the ACK floating point software + #define IEEEFLOAT for machines using IEEE floating point format + #define OWNFLOAT to use floating point format of machine on which + the code generator runs + If none of these are defined, PDP-11 format is generated. +*/ + +#ifndef NOFLOAT +#ifndef OWNFLOAT + +#include + +struct mantissa { + unsigned long h_32; + unsigned long l_32; +}; + +struct EXTEND { + short sign; + short exp; + struct mantissa mantissa; +#define m1 mantissa.h_32 +#define m2 mantissa.l_32 +}; + +static int b64_add(); +static int b64_sft(); + +static +mul_ext(e1,e2,e3) +struct EXTEND *e1,*e2,*e3; +{ + /* Multiply the extended numbers e1 and e2, and put the + result in e3. + */ + register int i,j; /* loop control */ + unsigned short mp[4]; + unsigned short mc[4]; + unsigned short result[8]; /* result */ + + register unsigned short *pres; + + /* first save the sign (XOR) */ + e3->sign = e1->sign ^ e2->sign; + + /* compute new exponent */ + e3->exp = e1->exp + e2->exp + 1; + + /* check for overflow/underflow ??? */ + + /* 128 bit multiply of mantissas */ + + /* assign unknown long formats */ + /* to known unsigned word formats */ + mp[0] = e1->m1 >> 16; + mp[1] = (unsigned short) e1->m1; + mp[2] = e1->m2 >> 16; + mp[3] = (unsigned short) e1->m2; + mc[0] = e2->m1 >> 16; + mc[1] = (unsigned short) e2->m1; + mc[2] = e2->m2 >> 16; + mc[3] = (unsigned short) e2->m2; + for (i = 8; i--;) { + result[i] = 0; + } + /* + * fill registers with their components + */ + for(i=4, pres = &result[4];i--;pres--) if (mp[i]) { + unsigned short k = 0; + unsigned long mpi = mp[i]; + for(j=4;j--;) { + unsigned long tmp = (unsigned long)pres[j] + k; + if (mc[j]) tmp += mpi * mc[j]; + pres[j] = tmp; + k = tmp >> 16; + } + pres[-1] = k; + } + + if (! (result[0] & 0x8000)) { + e3->exp--; + for (i = 0; i <= 3; i++) { + result[i] <<= 1; + if (result[i+1]&0x8000) result[i] |= 1; + } + result[4] <<= 1; + } + /* + * combine the registers to a total + */ + e3->m1 = ((unsigned long)(result[0]) << 16) + result[1]; + e3->m2 = ((unsigned long)(result[2]) << 16) + result[3]; + if (result[4] & 0x8000) { + if (++e3->m2 == 0) { + if (++e3->m1 == 0) { + e3->m1 = 0x80000000; + e3->exp++; + } + } + } +} + +static +b64_sft(e1,n) + struct mantissa *e1; + int n; +{ + if (n > 0) { + if (n > 63) { + e1->l_32 = 0; + e1->h_32 = 0; + return; + } + if (n >= 32) { + e1->l_32 = e1->h_32; + e1->h_32 = 0; + n -= 32; + } + if (n > 0) { + e1->l_32 >>= n; + if (e1->h_32 != 0) { + e1->l_32 |= (e1->h_32 << (32 - n)); + e1->h_32 >>= n; + } + } + return; + } + n = -n; + if (n > 0) { + if (n > 63) { + e1->l_32 = 0; + e1->h_32 = 0; + return; + } + if (n >= 32) { + e1->h_32 = e1->l_32; + e1->l_32 = 0; + n -= 32; + } + if (n > 0) { + e1->h_32 <<= n; + if (e1->l_32 != 0) { + e1->h_32 |= (e1->l_32 >> (32 - n)); + e1->l_32 <<= n; + } + } + } +} + +static int +b64_add(e1,e2) + /* + * pointers to 64 bit 'registers' + */ + struct mantissa *e1,*e2; +{ + register int overflow; + int carry; + + /* add higher pair of 32 bits */ + overflow = ((unsigned long) 0xFFFFFFFF - e1->h_32 < e2->h_32); + e1->h_32 += e2->h_32; + + /* add lower pair of 32 bits */ + carry = ((unsigned long) 0xFFFFFFFF - e1->l_32 < e2->l_32); + e1->l_32 += e2->l_32; + if ((carry) && (++e1->h_32 == 0)) + return(1); /* had a 64 bit overflow */ + else + return(overflow); /* return status from higher add */ +} + +/* The following tables can be computed with the following bc(1) + program: + +obase=16 +scale=0 +define t(x){ + auto a, b, c + a=2;b=1;c=2^32;n=1 + while(asign = 0; + e->exp = 0; + e->m1 = e->m2 = 0; + + c = *s; + switch(c) { + case '-': + e->sign = 1; + case '+': + s++; + } + while (c = *s++, isdigit(c) || (c == '.' && ! dotseen++)) { + if (c == '.') continue; + digitseen = 1; + if (e->m1 <= (unsigned long)(0xFFFFFFFF)/10) { + struct mantissa a1; + + a1 = e->mantissa; + b64_sft(&(e->mantissa), -3); + b64_sft(&a1, -1); + b64_add(&(e->mantissa), &a1); + a1.h_32 = 0; + a1.l_32 = c - '0'; + b64_add(&(e->mantissa), &a1); + } + else exp++; + if (dotseen) exp--; + } + if (! digitseen) return; + + if (ss) *ss = s - 1; + + if (c == 'E' || c == 'e') { + int exp1 = 0; + int sign = 1; + + switch(*s) { + case '-': + sign = -1; + case '+': + s++; + } + if (c = *s, isdigit(c)) { + do { + exp1 = 10 * exp1 + (c - '0'); + } while (c = *++s, isdigit(c)); + if (ss) *ss = s; + } + exp += sign * exp1; + } + if (e->m1 == 0 && e->m2 == 0) return; + e->exp = 63; + while (! (e->m1 & 0x80000000)) { + b64_sft(&(e->mantissa),-1); + e->exp--; + } + add_exponent(e, exp); +} + +#endif +#endif + +#ifdef NOFLOAT +con_float() { + +static int been_here; + if (argval != 4 && argval != 8) + fatal("bad fcon size"); + fputs(".data4\t", codefile); + if (argval == 8) + fputs("0,", codefile); + fputs("0 !dummy float\n", codefile); + if ( !been_here++) { + fputs("Warning : dummy float-constant(s)\n", stderr); + } +} +#else +#define ACKFLOAT 1 + +con_float() { + int i, j; + char *p; +#ifdef OWNFLOAT + float fl; + double f; + double atof(); +#else + int overflow = 0; + struct EXTEND e; + char buf[8]; +#endif + + if (argval!= 4 && argval!= 8) { + fprintf(stderr,"float constant size = %d\n",argval); + fatal("bad fcon size"); + } + fprintf(codefile,"!float %s sz %d\n", str, argval); +#ifdef OWNFLOAT + f = atof(str); + if (argval == 4) { + fl = f; + p = (char *) &fl; + } + else { + p = (char *) &f; + } + fprintf(codefile, ".data1 0%o", *p++ & 0377); + for (i = argval-1; i; i--) { + fprintf(codefile,",0%o", *p++ & 0377); + } +#else + _str_ext_cvt(str, (char **) 0, &e); +#if IEEEFLOAT+ACKFLOAT + if (argval == 4) { +#endif + e.exp += 127; +#ifndef IEEEFLOAT + e.exp += 2; +#endif + if (e.m1 == 0) e.exp = 0; +#if IEEEFLOAT+ACKFLOAT + if (e.exp >= 255) { + overflow = 1; + e.exp = 255; + e.m1 = e.m2 = 0; + } + if (e.exp <= 0) { +#if IEEEFLOAT + b64_sft(&(e.mantissa), 1); + if (e.exp < 0) { + b64_sft(&(e.mantissa), -e.exp); + e.exp = 0; + } +#else + e.exp = 0; + e.m1 = e.m2 = 0; +#endif + } +#endif + buf[0] = (e.sign << 7) | (e.exp >> 1); + buf[1] = ((e.exp&1) << 7) | ((e.m1 & 0x7fffffff) >> 24); + buf[2] = e.m1 >> 16; + buf[3] = e.m1 >> 8; + if (argval == 8) { + buf[4] = e.m1; + buf[5] = e.m2 >> 24; + buf[6] = e.m2 >> 16; + buf[7] = e.m2 >> 8; + b64_sft(&(e.mantissa), -56); + } + else b64_sft(&(e.mantissa), -24); +#if IEEEFLOAT+ACKFLOAT + } + else { + e.exp += 1023; +#ifndef IEEEFLOAT + e.exp += 2; +#endif + if (e.m1 == 0) e.exp = 0; + if (e.exp >= 2047) { + overflow = 1; + e.exp = 2047; + e.m1 = e.m2 = 0; + } + if (e.exp <= 0) { +#if IEEEFLOAT + b64_sft(&(e.mantissa), 1); + if (e.exp < 0) { + b64_sft(&(e.mantissa), -e.exp); + e.exp = 0; + } +#else + e.exp = 0; + e.m1 = e.m2 = 0; +#endif + } + buf[0] = (e.sign << 7) | (e.exp >> 4); + buf[1] = ((e.exp & 017)<< 4) | ((e.m1&0x7fffffff) >> 27); + buf[2] = e.m1 >> 19; + buf[3] = e.m1 >> 11; + buf[4] = e.m1 >> 3; + buf[5] = (e.m1 << 5) | (e.m2 >> 27); + buf[6] = e.m2 >> 19; + buf[7] = e.m2 >> 11; + b64_sft(&(e.mantissa), -53); + } +#endif + if (! overflow && (e.m1 & 0x80000000)) for (i = argval-1; i>=0; i--) { + if ((buf[i] &0377) != 0377) { + buf[i]++; + break; + } + else buf[i] = 0; + } + if (overflow || i < 0) { + fprintf(stderr, "Warning: overflow in floating point constant %s\n", str); + } + for (i = 0; i < argval; i++) { + fprintf(codefile, + i != 0 ? ",0%o" : ".data1 0%o", + buf[i]&0377); + } +#endif + putc('\n', codefile); +} +#endif