From 16214d455711e8fb60f327b55dd1f3f42a6f13db Mon Sep 17 00:00:00 2001 From: igor-m Date: Fri, 11 Apr 2014 13:36:20 +0200 Subject: [PATCH 01/24] Double Precision Floating Math implementation --- cross.mk | 10 +-- include/math.h | 5 +- include/stdarg.h | 4 +- lib/Makefile | 10 +-- src/libc/compat/Makefile | 2 +- src/libc/gen/Makefile | 6 +- src/libc/gen/isinff.c | 12 +--- src/libc/gen/isnanf.c | 11 +-- src/libc/gen/ldexp.c | 80 ++++++++++----------- src/libc/gen/modf.c | 138 +++++++++++++++++++++---------------- src/libc/gen/modff.c | 38 ++++------ src/libc/gen/ndbm.c | 2 +- src/libc/mips/sys/Makefile | 1 - src/libc/stdio/Makefile | 2 +- src/libc/stdio/doprnt.c | 28 ++++++-- src/libc/stdio/doscan.c | 4 ++ src/libc/stdlib/Makefile | 2 +- src/libc/string/Makefile | 2 +- src/libm/asin.c | 22 +++--- src/libm/atan.c | 2 +- src/libm/ieee.h | 56 ++++++++++----- sys/kernel/kern_exec.c | 4 ++ sys/pic32/Makefile | 3 +- sys/pic32/float.h | 28 +++++--- sys/pic32/gcc-config.mk | 8 --- sys/pic32/kernel-post.mk | 2 +- target.mk | 13 +--- 27 files changed, 260 insertions(+), 235 deletions(-) diff --git a/cross.mk b/cross.mk index 8dec173..f0eb9a2 100644 --- a/cross.mk +++ b/cross.mk @@ -18,14 +18,6 @@ TAGSFILE = tags MANROFF = nroff -man -h ELF2AOUT = cp -CFLAGS = -O -DCROSS +CFLAGS = -O -DCROSS -I/usr/include -I$(TOPSRC)/include LDFLAGS = LIBS = - -# Add system include path -ifeq (,$(wildcard /usr/include/i386-linux-gnu)) - CFLAGS += -I/usr/include -else - CFLAGS += -I/usr/include/i386-linux-gnu -endif -CFLAGS += -I$(TOPSRC)/include diff --git a/include/math.h b/include/math.h index 666123d..626f0e4 100644 --- a/include/math.h +++ b/include/math.h @@ -12,8 +12,9 @@ extern double sinh(), cosh(), tanh(); extern double gamma(); extern double j0(), j1(), jn(), y0(), y1(), yn(); -#define HUGE 1.701411733192644270e38 -#define LOGHUGE 39 +// ###PITO #define HUGE 1.701411733192644270e38 +#define HUGE 1.79769313486231570000e+308 +#define LOGHUGE 307 int isnanf(float x); int isnan(double x); diff --git a/include/stdarg.h b/include/stdarg.h index 27ffdda..b66ebb7 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -22,8 +22,8 @@ #define va_copy(dest, src) __builtin_va_copy((dest), (src)) -#ifndef _VA_LIST_T -#define _VA_LIST_T +#ifndef _VA_LIST +#define _VA_LIST #ifdef __GNUC__ typedef __builtin_va_list va_list; #endif diff --git a/lib/Makefile b/lib/Makefile index e821099..ddf9cc2 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -5,15 +5,9 @@ PROG = ar as aout ld nm ranlib size strip # Build a list of the host include directories. CPP = $(shell gcc -print-prog-name=cc1) HOSTINC = $(addprefix -I,$(shell echo | $(CPP) -v 2>&1 | grep '^ /.*include')) +HOSTINC += -I/usr/include/i386-linux-gnu -# Add system include path -ifeq (,$(wildcard /usr/include/i386-linux-gnu)) - HOSTINC += -I/usr/include -else - HOSTINC += -I/usr/include/i386-linux-gnu -endif - -CFLAGS += -nostdinc -fno-builtin -g -Werror -Wall -DCROSS -I. $(HOSTINC) \ +CFLAGS += -nostdinc -g -Werror -Wall -DCROSS -I. $(HOSTINC) \ -I$(TOPSRC)/include -I$(TOPSRC)/src/cmd/ar \ -I$(TOPSRC)/src/cmd/as LDFLAGS += -g diff --git a/src/libc/compat/Makefile b/src/libc/compat/Makefile index 917649e..548f084 100644 --- a/src/libc/compat/Makefile +++ b/src/libc/compat/Makefile @@ -6,7 +6,7 @@ TOPSRC = $(shell cd ../../..; pwd) include $(TOPSRC)/target.mk -CFLAGS += ${DEFS} -Os +CFLAGS += ${DEFS} SRCS = creat.c ftime.c gethostid.c gtty.c memccpy.c memchr.c memcmp.c \ memcpy.c memset.c nice.c pause.c rand.c sethostid.c \ diff --git a/src/libc/gen/Makefile b/src/libc/gen/Makefile index f6ceacd..0dd687b 100644 --- a/src/libc/gen/Makefile +++ b/src/libc/gen/Makefile @@ -6,7 +6,7 @@ TOPSRC = $(shell cd ../../..; pwd) include $(TOPSRC)/target.mk -CFLAGS += ${DEFS} -Os -Wall -Werror +CFLAGS += ${DEFS} SRCS = ${STDSRC} OBJS = ${STDOBJ} @@ -19,7 +19,7 @@ STDSRC = abort.c alarm.c atof.c atoi.c atol.c calloc.c closedir.c crypt.c \ getpass.c getpwent.c getloadavg.c getmntinfo.c \ getttyent.c getttynam.c getusershell.c getwd.c \ initgroups.c isatty.c isinff.c isnanf.c ldexp.c malloc.c mktemp.c \ - modff.c ndbm.c nlist.c knlist.c opendir.c perror.c popen.c \ + modff.c modf.c ndbm.c nlist.c knlist.c opendir.c perror.c popen.c \ psignal.c qsort.c random.c readdir.c regex.c scandir.c \ seekdir.c setmode.c sethostname.c setenv.c siglist.c \ signal.c siginterrupt.c sigsetops.c \ @@ -36,7 +36,7 @@ STDOBJ = abort.o alarm.o atof.o atoi.o atol.o calloc.o closedir.o crypt.o \ getpass.o getpwent.o getloadavg.o getmntinfo.o \ getttyent.o getttynam.o getusershell.o getwd.o \ initgroups.o isatty.o isinff.o isnanf.o ldexp.o malloc.o mktemp.o \ - modff.o ndbm.o nlist.o knlist.o opendir.o perror.o popen.o \ + modff.o modf.o ndbm.o nlist.o knlist.o opendir.o perror.o popen.o \ psignal.o qsort.o random.o readdir.o regex.o scandir.o \ seekdir.o setmode.o sethostname.o setenv.o siglist.o \ signal.o siginterrupt.o sigsetops.o \ diff --git a/src/libc/gen/isinff.c b/src/libc/gen/isinff.c index 1755a65..0286a25 100644 --- a/src/libc/gen/isinff.c +++ b/src/libc/gen/isinff.c @@ -13,15 +13,9 @@ */ int isinff (float x) { - union { - long s32; - float f32; - } u; - long v; - - u.f32 = x; - v = (u.s32 & 0x7fffffff) ^ 0x7f800000; - return ~((v | -v) >> 31) & (u.s32 >> 30); + long lx = *(long*) &x; + long v = (lx & 0x7fffffff) ^ 0x7f800000; + return ~((v | -v) >> 31) & (lx >> 30); } /* diff --git a/src/libc/gen/isnanf.c b/src/libc/gen/isnanf.c index dda3938..a3eaa52 100644 --- a/src/libc/gen/isnanf.c +++ b/src/libc/gen/isnanf.c @@ -13,15 +13,10 @@ */ int isnanf (float x) { - union { - long s32; - float f32; - } u; - unsigned long ul; + long lx = *(long*) &x; - u.f32 = x; - ul = 0x7f800000 - (u.s32 & 0x7fffffff); - return ul >> 31; + lx = 0x7f800000 - (lx & 0x7fffffff); + return (int) (((unsigned long) lx) >> 31); } /* diff --git a/src/libc/gen/ldexp.c b/src/libc/gen/ldexp.c index 46c1807..858d570 100644 --- a/src/libc/gen/ldexp.c +++ b/src/libc/gen/ldexp.c @@ -1,46 +1,46 @@ #include +#include + +static const double +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ +huge = 1.0e+308, +tiny = 1.0e-307; + +static double +_copysign(double x, double y) +{ + unsigned long hx,hy; + GET_HIGH_WORD(hx,x); + GET_HIGH_WORD(hy,y); + SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000)); + return x; +} double -ldexp(fr, exp) - double fr; - int exp; +ldexp(double x, int n) { - double huge = 1.701411834604692293e38; - int neg; - int i; - - neg = 0; - if (fr < 0) { - fr = -fr; - neg = 1; + unsigned long k,hx,lx; + EXTRACT_WORDS(hx,lx,x); + k = (hx&0x7ff00000)>>20; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ + x *= two54; + GET_HIGH_WORD(hx,x); + k = ((hx&0x7ff00000)>>20) - 54; + if (n< -50000) return tiny*x; /*underflow*/ + } + if (k==0x7ff) return x+x; /* NaN or Inf */ + k = k+n; + if (k > 0x7fe) return huge*_copysign(huge,x); /* overflow */ + if (k > 0) /* normal result */ + {SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;} + if (k <= -54) { + if (n > 50000) /* in case integer overflow in n+k */ + return huge*_copysign(huge,x); /*overflow*/ + else return tiny*_copysign(tiny,x); /*underflow*/ } - fr = frexp(fr, &i); - while (fr < 0.5) { - fr = 2*fr; - i = i-1; - } - exp = exp+i; - if (exp > 127) { - if (neg) - return(-huge); - else - return(huge); - } - if (exp < -127) - return(0); - while (exp > 30) { - fr = fr*(1L<<30); - exp = exp-30; - } - while (exp < -30) { - fr = fr/(1L<<30); - exp = exp+30; - } - if (exp > 0) - fr = fr*(1L< +// *** modified by Pito 11/2013 for RetroBSD *** + +typedef union // LITTLE ENDIAN +{ + double value; + struct + { + unsigned long lsw; + unsigned long msw; + } parts; +} ieee_double_shape_type; /* Get two 32 bit ints from a double. */ -#define EXTRACT_WORDS(high,low,d) \ - high = *(unsigned long long*) &d; \ - low = (*(unsigned long long*) &d) >> 32 +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) /* Set a double from two 32 bit ints. */ -#define INSERT_WORDS(d,high,low) \ - *(unsigned long long*) &(x) = (unsigned long long) (high) << 32 | (low) +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) -/* - * modf(double x, double *iptr) - * return fraction part of x, and return x's integral part in *iptr. - * Method: - * Bit twiddling. - * - * Exception: - * No exception. - */ -static const double one = 1.0; - -double modf (double x, double *iptr) +double modf(double x, double *iptr) { - long i0, i1, j0; - unsigned long i; - - EXTRACT_WORDS (i0, i1, x); - j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */ - if (j0 < 20) { /* integer part in high x */ - if (j0 < 0) { /* |x|<1 */ - INSERT_WORDS (*iptr, i0 & 0x80000000, 0); - /* *iptr = +-0 */ - return x; - } else { - i = (0x000fffff) >> j0; - if (((i0 & i) | i1) == 0) { /* x is integral */ - *iptr = x; - INSERT_WORDS (x, i0 & 0x80000000, 0); - /* return +-0 */ - return x; - } else { - INSERT_WORDS (*iptr, i0 & (~i), 0); - return x - *iptr; - } - } - } else if (j0 > 51) { /* no fraction part */ - *iptr = x * one; - /* We must handle NaNs separately. */ - if (j0 == 0x400 && ((i0 & 0xfffff) | i1)) - return x * one; - - INSERT_WORDS (x, i0 & 0x80000000, 0); - /* return +-0 */ - return x; - } else { /* fraction part in low x */ - i = ((unsigned long) (0xffffffff)) >> (j0 - 20); - if ((i1 & i) == 0) { /* x is integral */ - *iptr = x; - INSERT_WORDS (x, i0 & 0x80000000, 0); - /* return +-0 */ - return x; - } else { - INSERT_WORDS (*iptr, i0, i1 & (~i)); - return x - *iptr; - } - } + long int i0,i1,j0; + unsigned long i; + double one = 1.0; + EXTRACT_WORDS(i0,i1,x); + j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ + if(j0<20) { /* integer part in high x */ + if(j0<0) { /* |x|<1 */ + INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ + return x; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) { /* x is integral */ + unsigned long high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0&(~i),0); + return x - *iptr; + } + } + } else if (j0>51) { /* no fraction part */ + unsigned long high; + *iptr = x*one; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((unsigned long)(0xffffffff))>>(j0-20); + if((i1&i)==0) { /* x is integral */ + unsigned long high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0,i1&(~i)); + return x - *iptr; + } + } } diff --git a/src/libc/gen/modff.c b/src/libc/gen/modff.c index 7eeac60..4e099da 100644 --- a/src/libc/gen/modff.c +++ b/src/libc/gen/modff.c @@ -13,43 +13,35 @@ */ static const float one = 1.0; -float modff (float fx, float *iptr) +float modff (float x, float *iptr) { - union { - unsigned u32; - float f32; - } x; - unsigned hx, s; + unsigned hx = *(unsigned*) &x & ~0x80000000; + unsigned s; - x.f32 = fx; - hx = x.u32 & ~0x80000000; if (hx >= 0x4b000000) { /* x is NaN, infinite, or integral */ - *iptr = x.f32; + *iptr = x; if (hx <= 0x7f800000) - x.u32 &= 0x80000000; - return x.f32; + *(unsigned*) &x &= 0x80000000; + return x; } if (hx < 0x3f800000) { /* |x| < 1 */ - float ret = x.f32; - x.u32 &= 0x80000000; - *iptr = x.f32; - return ret; + *iptr = x; + *(unsigned*) iptr &= 0x80000000; + return x; } /* split x at the binary point */ - s = x.u32 & 0x80000000; - fx = x.f32; - x.u32 &= ~((1 << (0x96 - (hx >> 23))) - 1); - *iptr = x.f32; - x.f32 = fx - *iptr; + s = *(unsigned*) &x & 0x80000000; + *(unsigned*) iptr = *(unsigned*) &x & ~((1 << (0x96 - (hx >> 23))) - 1); + x -= *iptr; /* restore sign in case difference is 0 */ - x.u32 = (x.u32 & ~0x80000000) | s; - return x.f32; + *(unsigned*) &x = (*(unsigned*) &x & ~0x80000000) | s; + return x; } /* * For PIC32, double is the same as float. */ -double modf (double x, double *iptr) __attribute__((alias ("modff"))); +//double modf (double x, double *iptr) __attribute__((alias ("modff"))); diff --git a/src/libc/gen/ndbm.c b/src/libc/gen/ndbm.c index 70447df..071bcd3 100644 --- a/src/libc/gen/ndbm.c +++ b/src/libc/gen/ndbm.c @@ -465,7 +465,7 @@ dbm_nextkey(db) db->dbm_flags |= _DBM_IOERR; #endif } - if (db->dbm_pagbuf[0] != 0 && db->dbm_pagbuf[1] != 0) { + if (((short *)db->dbm_pagbuf)[0] != 0) { item = makdatum(db->dbm_pagbuf, db->dbm_keyptr); if (item.dptr != NULL) { db->dbm_keyptr += 2; diff --git a/src/libc/mips/sys/Makefile b/src/libc/mips/sys/Makefile index a513cdb..dcf8622 100644 --- a/src/libc/mips/sys/Makefile +++ b/src/libc/mips/sys/Makefile @@ -2,7 +2,6 @@ TOPSRC = $(shell cd ../../../..; pwd) include $(TOPSRC)/target.mk ASFLAGS += ${DEFS} -CFLAGS += -Os # modules which can not use SYSCALL and must be assembled from sources. The # rest of the system calls are generated with printf(1) and do not have diff --git a/src/libc/stdio/Makefile b/src/libc/stdio/Makefile index 4238c6d..796d33b 100644 --- a/src/libc/stdio/Makefile +++ b/src/libc/stdio/Makefile @@ -6,7 +6,7 @@ TOPSRC = $(shell cd ../../..; pwd) include $(TOPSRC)/target.mk -CFLAGS += ${DEFS} -Os +CFLAGS += ${DEFS} SRCS = ${STDSRC} fgetc.c fgets.c fputc.c fputs.c gets.c puts.c \ feof.c ferror.c fileno.c diff --git a/src/libc/stdio/doprnt.c b/src/libc/stdio/doprnt.c index eea7f09..9d3c7c3 100644 --- a/src/libc/stdio/doprnt.c +++ b/src/libc/stdio/doprnt.c @@ -42,7 +42,9 @@ #include /* Max number conversion buffer length: a long in base 2, plus NUL byte. */ -#define MAXNBUF (sizeof(long) * 8 + 1) +//#define MAXNBUF (sizeof(long) * 8 + 1) +/* Max number conversion buffer length: MAXEXP(308) + MAXFRACTION(15) + 2 */ +#define MAXNBUF 308+15+2 static unsigned char *ksprintn (unsigned char *buf, unsigned long v, unsigned char base, int width, unsigned char *lp); @@ -361,7 +363,20 @@ number: if (sign && ((long) ul != 0L)) { case 'F': case 'g': case 'G': { - double d = va_arg (ap, double); + + double d; + unsigned long *l = (unsigned long *) &d; + + if (*(unsigned long*)&ap & 4) { + l[0]= va_arg(ap, unsigned long); + l[1]= va_arg(ap, unsigned long); + } + else { + l[0]= va_arg(ap, unsigned long); + l[0]= va_arg(ap, unsigned long); + l[1]= va_arg(ap, unsigned long); + } + /* * don't do unrealistic precision; just pad it with * zeroes later, so buffer size stays rational. @@ -583,10 +598,11 @@ cvt (double number, int prec, int sharpflag, unsigned char *negp, unsigned char * get integer portion of number; put into the end of the buffer; the * .01 is added for modf (356.0 / 10, &integer) returning .59999999... */ - for (p = endp - 1; integer; ++expcnt) { - tmp = modf (integer / 10, &integer); - *p-- = (int) ((tmp + .01) * 10) + '0'; - } + p = endp - 1; + for (; integer && p >= startp; ++expcnt) { + tmp = modf(integer * 0.1L , &integer); + *p-- = (int)((tmp + .01L) * 10) + '0'; + } switch (fmtch) { case 'f': /* reverse integer into beginning of buffer */ diff --git a/src/libc/stdio/doscan.c b/src/libc/stdio/doscan.c index c596612..ee73363 100644 --- a/src/libc/stdio/doscan.c +++ b/src/libc/stdio/doscan.c @@ -1,6 +1,10 @@ #include #include #include +#include +#include + +#define HAVE_FLOAT 1 #define SPC 01 #define STP 02 diff --git a/src/libc/stdlib/Makefile b/src/libc/stdlib/Makefile index 952f211..2a6e09d 100644 --- a/src/libc/stdlib/Makefile +++ b/src/libc/stdlib/Makefile @@ -7,7 +7,7 @@ TOPSRC = $(shell cd ../../..; pwd) include $(TOPSRC)/target.mk DEFS = -CFLAGS += ${DEFS} -Os +CFLAGS += ${DEFS} SRCS = getopt.c getsubopt.c strtol.c strtoul.c strtod.c OBJS = getopt.o getsubopt.o strtol.o strtoul.o strtod.o diff --git a/src/libc/string/Makefile b/src/libc/string/Makefile index d1fc06b..40daeec 100644 --- a/src/libc/string/Makefile +++ b/src/libc/string/Makefile @@ -7,7 +7,7 @@ TOPSRC = $(shell cd ../../..; pwd) include $(TOPSRC)/target.mk DEFS = -CFLAGS += ${DEFS} -Os +CFLAGS += ${DEFS} SRCS = strcspn.c strpbrk.c strerror.c strsep.c strspn.c strstr.c strtok.c strtok_r.c OBJS = strcspn.o strpbrk.o strerror.o strsep.o strspn.o strstr.o strtok.o strtok_r.o diff --git a/src/libm/asin.c b/src/libm/asin.c index 8373f93..23da206 100644 --- a/src/libm/asin.c +++ b/src/libm/asin.c @@ -39,15 +39,17 @@ asin(arg) double acos(arg) - double arg; +double arg; { - if(arg < 0) - arg = -arg; + double sign = 1.0; + if(arg < 0.0){ + arg = -arg; + sign = -1.0; + } + if(arg > 1.0){ + errno = EDOM; + return(0.0); + } - if(arg > 1.){ - errno = EDOM; - return(0.); - } - - return(pio2 - asin(arg)); -} + return(pio2 - sign*asin(arg)); +} diff --git a/src/libm/atan.c b/src/libm/atan.c index a249167..8ecbea9 100644 --- a/src/libm/atan.c +++ b/src/libm/atan.c @@ -13,7 +13,7 @@ */ #include -double static sq2p1 =2.414213562373095048802e0; +static double sq2p1 =2.414213562373095048802e0; static double sq2m1 = .414213562373095048802e0; static double pio2 =1.570796326794896619231e0; static double pio4 = .785398163397448309615e0; diff --git a/src/libm/ieee.h b/src/libm/ieee.h index 20a8eee..56ea4ec 100644 --- a/src/libm/ieee.h +++ b/src/libm/ieee.h @@ -1,23 +1,47 @@ -/* Get two 32 bit ints from a double. */ - -#define EXTRACT_WORDS(high,low,d) \ - high = *(unsigned long long*) &d; \ - low = (*(unsigned long long*) &d) >> 32 - - -/* Set a double from two 32 bit ints. */ - -#define INSERT_WORDS(d,high,low) \ - *(unsigned long long*) &(x) = (unsigned long long) (high) << 32 | (low) - - -typedef union +typedef union // LITTLE ENDIAN { double value; struct { - uint32_t lsw; - uint32_t msw; + unsigned long lsw; + unsigned long msw; } parts; } ieee_double_shape_type; +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +#define SET_HIGH_WORD(d,v) \ +do { \ + ieee_double_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + diff --git a/sys/kernel/kern_exec.c b/sys/kernel/kern_exec.c index 18cfbbf..f7f6e13 100644 --- a/sys/kernel/kern_exec.c +++ b/sys/kernel/kern_exec.c @@ -405,8 +405,12 @@ again: bdwrite (bp); } bp = 0; + // ###PITO nc = (nc + NBPW-1) & ~(NBPW-1); getxfile (ip, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid); + //nc = (nc + (NBPW*2)-1) & ~((NBPW*2)-1); + //getxfile (ip, &exdata.ex_exec, nc + (na+4)*(NBPW*2), uid, gid); + // ###PITO if (u.u_error) { //printf ("execve: getxfile error = %d\n", u.u_error); badarg: diff --git a/sys/pic32/Makefile b/sys/pic32/Makefile index d06a76f..f5322cf 100644 --- a/sys/pic32/Makefile +++ b/sys/pic32/Makefile @@ -5,8 +5,7 @@ SUBDIR = baremetal dip duinomite duinomite-uart duinomite-e \ duinomite-e-uart explorer16 max32 max32-eth maximite \ meb pinguino-micro starter-kit ubw32 ubw32-uart \ ubw32-uart-sdram baremetal fubarino fubarino-uart \ - fubarino-uart-sramc mmb-mx7 maximite-color \ - 32mxsdram-uart + fubarino-uart-sramc mmb-mx7 maximite-color 32mxsdram-uart default: diff --git a/sys/pic32/float.h b/sys/pic32/float.h index 3888d80..c5d7980 100644 --- a/sys/pic32/float.h +++ b/sys/pic32/float.h @@ -24,19 +24,29 @@ * The values are dependant upon the presence of the -fno-short-double * compiler option. */ -#define DBL_EPSILON FLT_EPSILON -#define DBL_MAX FLT_MAX -#define DBL_MIN FLT_MIN -#define DBL_DIG FLT_DIG -#define DBL_MANT_DIG FLT_MANT_DIG -#define DBL_MAX_10_EXP FLT_MAX_10_EXP -#define DBL_MAX_EXP FLT_MAX_EXP -#define DBL_MIN_10_EXP FLT_MIN_10_EXP -#define DBL_MIN_EXP FLT_MIN_EXP +//#define DBL_EPSILON FLT_EPSILON +//#define DBL_MAX FLT_MAX +//#define DBL_MIN FLT_MIN +//#define DBL_DIG FLT_DIG +//#define DBL_MANT_DIG FLT_MANT_DIG +//#define DBL_MAX_10_EXP FLT_MAX_10_EXP +//#define DBL_MAX_EXP FLT_MAX_EXP +//#define DBL_MIN_10_EXP FLT_MIN_10_EXP +//#define DBL_MIN_EXP FLT_MIN_EXP /* * These values provide information pertaining to the long double type. */ +#define DBL_EPSILON 2.2204460492503131E-16 +#define DBL_MAX 1.7976931348623157E+308 +#define DBL_MIN 2.2250738585072014E-308 +#define DBL_DIG 15 +#define DBL_MANT_DIG 53 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define DBL_MIN_10_EXP (-307) +#define DBL_MIN_EXP (-1021) + #define LDBL_EPSILON 2.2204460492503131E-16 #define LDBL_MAX 1.7976931348623157E+308 #define LDBL_MIN 2.2250738585072014E-308 diff --git a/sys/pic32/gcc-config.mk b/sys/pic32/gcc-config.mk index d026bc4..aae0bcb 100644 --- a/sys/pic32/gcc-config.mk +++ b/sys/pic32/gcc-config.mk @@ -1,11 +1,3 @@ -# chipKIT PIC32 compiler from UECIDE -ifdef UECIDE -ifndef GCCPREFIX - GCCPREFIX = ${HOME}/.uecide/compilers/pic32-tools/bin/pic32- - LDFLAGS = -Wl,--oformat=elf32-tradlittlemips -endif -endif - # chipKIT PIC32 compiler on Linux # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Download from https://github.com/jasonkajita/chipKIT-cxx/downloads diff --git a/sys/pic32/kernel-post.mk b/sys/pic32/kernel-post.mk index b73fd0e..acbae77 100644 --- a/sys/pic32/kernel-post.mk +++ b/sys/pic32/kernel-post.mk @@ -73,7 +73,7 @@ vers.o: $(BUILDPATH)/newvers.sh $(H)/*.h $(M)/*.[ch] $(S)/*.c $(CC) -c vers.c reconfig: - ../../../tools/configsys/config $(CONFIG) + $(CONFIGPATH)/config $(CONFIG) .SUFFIXES: .i .srec .hex .dis .cpp .cxx .bin .elf diff --git a/target.mk b/target.mk index 00e3c49..987d679 100644 --- a/target.mk +++ b/target.mk @@ -1,15 +1,6 @@ MACHINE = mips DESTDIR ?= $(TOPSRC) -# chipKIT PIC32 compiler from UECIDE -ifdef UECIDE -ifndef GCCPREFIX - GCCPREFIX = ${HOME}/.uecide/compilers/pic32-tools/bin/pic32- - LDFLAGS = -Wl,--oformat=elf32-tradlittlemips - INCLUDES = -I${HOME}/.uecide/compilers/pic32-tools/lib/gcc/pic32mx/4.5.1/include -endif -endif - # chipKIT PIC32 compiler on Linux # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Download from https://github.com/jasonkajita/chipKIT-cxx/downloads @@ -34,8 +25,8 @@ ifndef GCCPREFIX INCLUDES = endif -CC = $(GCCPREFIX)gcc -mips32r2 -EL -msoft-float -nostdinc -fshort-double -I$(TOPSRC)/include $(INCLUDES) -CXX = $(GCCPREFIX)g++ -mips32r2 -EL -msoft-float -nostdinc -fshort-double -I$(TOPSRC)/include $(INCLUDES) +CC = $(GCCPREFIX)gcc -mips32r2 -EL -msoft-float -nostdinc -fno-short-double -I$(TOPSRC)/include $(INCLUDES) +CXX = $(GCCPREFIX)g++ -mips32r2 -EL -msoft-float -nostdinc -fno-short-double -I$(TOPSRC)/include $(INCLUDES) LD = $(GCCPREFIX)ld AR = $(GCCPREFIX)ar RANLIB = $(GCCPREFIX)ranlib From 16e7b63b483f8627fbc92d3b1bd80052cacca582 Mon Sep 17 00:00:00 2001 From: igor-m Date: Fri, 11 Apr 2014 19:35:55 +0200 Subject: [PATCH 02/24] Fix the Double Precision changes --- cross.mk | 10 +++++++++- lib/Makefile | 10 ++++++++-- src/libc/compat/Makefile | 2 +- src/libc/gen/Makefile | 4 ++-- src/libc/gen/ndbm.c | 2 +- src/libc/mips/sys/Makefile | 1 + src/libc/stdio/Makefile | 2 +- src/libc/stdlib/Makefile | 2 +- sys/kernel/kern_exec.c | 4 ---- sys/pic32/gcc-config.mk | 8 ++++++++ sys/pic32/kernel-post.mk | 2 +- target.mk | 11 ++++++++++- 12 files changed, 43 insertions(+), 15 deletions(-) mode change 100644 => 100755 cross.mk mode change 100644 => 100755 lib/Makefile mode change 100644 => 100755 src/libc/compat/Makefile mode change 100644 => 100755 src/libc/gen/Makefile mode change 100644 => 100755 src/libc/gen/ndbm.c mode change 100644 => 100755 src/libc/mips/sys/Makefile mode change 100644 => 100755 src/libc/stdio/Makefile mode change 100644 => 100755 src/libc/stdlib/Makefile mode change 100644 => 100755 sys/kernel/kern_exec.c mode change 100644 => 100755 sys/pic32/gcc-config.mk mode change 100644 => 100755 sys/pic32/kernel-post.mk mode change 100644 => 100755 target.mk diff --git a/cross.mk b/cross.mk old mode 100644 new mode 100755 index f0eb9a2..8dec173 --- a/cross.mk +++ b/cross.mk @@ -18,6 +18,14 @@ TAGSFILE = tags MANROFF = nroff -man -h ELF2AOUT = cp -CFLAGS = -O -DCROSS -I/usr/include -I$(TOPSRC)/include +CFLAGS = -O -DCROSS LDFLAGS = LIBS = + +# Add system include path +ifeq (,$(wildcard /usr/include/i386-linux-gnu)) + CFLAGS += -I/usr/include +else + CFLAGS += -I/usr/include/i386-linux-gnu +endif +CFLAGS += -I$(TOPSRC)/include diff --git a/lib/Makefile b/lib/Makefile old mode 100644 new mode 100755 index ddf9cc2..e821099 --- a/lib/Makefile +++ b/lib/Makefile @@ -5,9 +5,15 @@ PROG = ar as aout ld nm ranlib size strip # Build a list of the host include directories. CPP = $(shell gcc -print-prog-name=cc1) HOSTINC = $(addprefix -I,$(shell echo | $(CPP) -v 2>&1 | grep '^ /.*include')) -HOSTINC += -I/usr/include/i386-linux-gnu -CFLAGS += -nostdinc -g -Werror -Wall -DCROSS -I. $(HOSTINC) \ +# Add system include path +ifeq (,$(wildcard /usr/include/i386-linux-gnu)) + HOSTINC += -I/usr/include +else + HOSTINC += -I/usr/include/i386-linux-gnu +endif + +CFLAGS += -nostdinc -fno-builtin -g -Werror -Wall -DCROSS -I. $(HOSTINC) \ -I$(TOPSRC)/include -I$(TOPSRC)/src/cmd/ar \ -I$(TOPSRC)/src/cmd/as LDFLAGS += -g diff --git a/src/libc/compat/Makefile b/src/libc/compat/Makefile old mode 100644 new mode 100755 index 548f084..917649e --- a/src/libc/compat/Makefile +++ b/src/libc/compat/Makefile @@ -6,7 +6,7 @@ TOPSRC = $(shell cd ../../..; pwd) include $(TOPSRC)/target.mk -CFLAGS += ${DEFS} +CFLAGS += ${DEFS} -Os SRCS = creat.c ftime.c gethostid.c gtty.c memccpy.c memchr.c memcmp.c \ memcpy.c memset.c nice.c pause.c rand.c sethostid.c \ diff --git a/src/libc/gen/Makefile b/src/libc/gen/Makefile old mode 100644 new mode 100755 index 0dd687b..933e2af --- a/src/libc/gen/Makefile +++ b/src/libc/gen/Makefile @@ -6,7 +6,7 @@ TOPSRC = $(shell cd ../../..; pwd) include $(TOPSRC)/target.mk -CFLAGS += ${DEFS} +CFLAGS += ${DEFS} -Os -Wall -Werror SRCS = ${STDSRC} OBJS = ${STDOBJ} @@ -36,7 +36,7 @@ STDOBJ = abort.o alarm.o atof.o atoi.o atol.o calloc.o closedir.o crypt.o \ getpass.o getpwent.o getloadavg.o getmntinfo.o \ getttyent.o getttynam.o getusershell.o getwd.o \ initgroups.o isatty.o isinff.o isnanf.o ldexp.o malloc.o mktemp.o \ - modff.o modf.o ndbm.o nlist.o knlist.o opendir.o perror.o popen.o \ + modff.o modf.c ndbm.o nlist.o knlist.o opendir.o perror.o popen.o \ psignal.o qsort.o random.o readdir.o regex.o scandir.o \ seekdir.o setmode.o sethostname.o setenv.o siglist.o \ signal.o siginterrupt.o sigsetops.o \ diff --git a/src/libc/gen/ndbm.c b/src/libc/gen/ndbm.c old mode 100644 new mode 100755 index 071bcd3..70447df --- a/src/libc/gen/ndbm.c +++ b/src/libc/gen/ndbm.c @@ -465,7 +465,7 @@ dbm_nextkey(db) db->dbm_flags |= _DBM_IOERR; #endif } - if (((short *)db->dbm_pagbuf)[0] != 0) { + if (db->dbm_pagbuf[0] != 0 && db->dbm_pagbuf[1] != 0) { item = makdatum(db->dbm_pagbuf, db->dbm_keyptr); if (item.dptr != NULL) { db->dbm_keyptr += 2; diff --git a/src/libc/mips/sys/Makefile b/src/libc/mips/sys/Makefile old mode 100644 new mode 100755 index dcf8622..a513cdb --- a/src/libc/mips/sys/Makefile +++ b/src/libc/mips/sys/Makefile @@ -2,6 +2,7 @@ TOPSRC = $(shell cd ../../../..; pwd) include $(TOPSRC)/target.mk ASFLAGS += ${DEFS} +CFLAGS += -Os # modules which can not use SYSCALL and must be assembled from sources. The # rest of the system calls are generated with printf(1) and do not have diff --git a/src/libc/stdio/Makefile b/src/libc/stdio/Makefile old mode 100644 new mode 100755 index 796d33b..4238c6d --- a/src/libc/stdio/Makefile +++ b/src/libc/stdio/Makefile @@ -6,7 +6,7 @@ TOPSRC = $(shell cd ../../..; pwd) include $(TOPSRC)/target.mk -CFLAGS += ${DEFS} +CFLAGS += ${DEFS} -Os SRCS = ${STDSRC} fgetc.c fgets.c fputc.c fputs.c gets.c puts.c \ feof.c ferror.c fileno.c diff --git a/src/libc/stdlib/Makefile b/src/libc/stdlib/Makefile old mode 100644 new mode 100755 index 2a6e09d..952f211 --- a/src/libc/stdlib/Makefile +++ b/src/libc/stdlib/Makefile @@ -7,7 +7,7 @@ TOPSRC = $(shell cd ../../..; pwd) include $(TOPSRC)/target.mk DEFS = -CFLAGS += ${DEFS} +CFLAGS += ${DEFS} -Os SRCS = getopt.c getsubopt.c strtol.c strtoul.c strtod.c OBJS = getopt.o getsubopt.o strtol.o strtoul.o strtod.o diff --git a/sys/kernel/kern_exec.c b/sys/kernel/kern_exec.c old mode 100644 new mode 100755 index f7f6e13..18cfbbf --- a/sys/kernel/kern_exec.c +++ b/sys/kernel/kern_exec.c @@ -405,12 +405,8 @@ again: bdwrite (bp); } bp = 0; - // ###PITO nc = (nc + NBPW-1) & ~(NBPW-1); getxfile (ip, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid); - //nc = (nc + (NBPW*2)-1) & ~((NBPW*2)-1); - //getxfile (ip, &exdata.ex_exec, nc + (na+4)*(NBPW*2), uid, gid); - // ###PITO if (u.u_error) { //printf ("execve: getxfile error = %d\n", u.u_error); badarg: diff --git a/sys/pic32/gcc-config.mk b/sys/pic32/gcc-config.mk old mode 100644 new mode 100755 index aae0bcb..d026bc4 --- a/sys/pic32/gcc-config.mk +++ b/sys/pic32/gcc-config.mk @@ -1,3 +1,11 @@ +# chipKIT PIC32 compiler from UECIDE +ifdef UECIDE +ifndef GCCPREFIX + GCCPREFIX = ${HOME}/.uecide/compilers/pic32-tools/bin/pic32- + LDFLAGS = -Wl,--oformat=elf32-tradlittlemips +endif +endif + # chipKIT PIC32 compiler on Linux # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Download from https://github.com/jasonkajita/chipKIT-cxx/downloads diff --git a/sys/pic32/kernel-post.mk b/sys/pic32/kernel-post.mk old mode 100644 new mode 100755 index acbae77..b73fd0e --- a/sys/pic32/kernel-post.mk +++ b/sys/pic32/kernel-post.mk @@ -73,7 +73,7 @@ vers.o: $(BUILDPATH)/newvers.sh $(H)/*.h $(M)/*.[ch] $(S)/*.c $(CC) -c vers.c reconfig: - $(CONFIGPATH)/config $(CONFIG) + ../../../tools/configsys/config $(CONFIG) .SUFFIXES: .i .srec .hex .dis .cpp .cxx .bin .elf diff --git a/target.mk b/target.mk old mode 100644 new mode 100755 index 987d679..816b10f --- a/target.mk +++ b/target.mk @@ -1,6 +1,15 @@ MACHINE = mips DESTDIR ?= $(TOPSRC) +# chipKIT PIC32 compiler from UECIDE +ifdef UECIDE +ifndef GCCPREFIX + GCCPREFIX = ${HOME}/.uecide/compilers/pic32-tools/bin/pic32- + LDFLAGS = -Wl,--oformat=elf32-tradlittlemips + INCLUDES = -I${HOME}/.uecide/compilers/pic32-tools/lib/gcc/pic32mx/4.5.1/include +endif +endif + # chipKIT PIC32 compiler on Linux # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Download from https://github.com/jasonkajita/chipKIT-cxx/downloads @@ -26,7 +35,7 @@ ifndef GCCPREFIX endif CC = $(GCCPREFIX)gcc -mips32r2 -EL -msoft-float -nostdinc -fno-short-double -I$(TOPSRC)/include $(INCLUDES) -CXX = $(GCCPREFIX)g++ -mips32r2 -EL -msoft-float -nostdinc -fno-short-double -I$(TOPSRC)/include $(INCLUDES) +CXX = $(GCCPREFIX)g++ -mips32r2 -EL -msoft-float -nostdinc -fno-short-double -I$(TOPSRC)/include $(INCLUDES) LD = $(GCCPREFIX)ld AR = $(GCCPREFIX)ar RANLIB = $(GCCPREFIX)ranlib From c31e4fa1e8dcf0648165f1d95c1cd122f585d216 Mon Sep 17 00:00:00 2001 From: igor-m Date: Fri, 11 Apr 2014 20:13:51 +0200 Subject: [PATCH 03/24] Was within untracked files ?? --- include/ieee.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 include/ieee.h diff --git a/include/ieee.h b/include/ieee.h new file mode 100644 index 0000000..56ea4ec --- /dev/null +++ b/include/ieee.h @@ -0,0 +1,47 @@ +typedef union // LITTLE ENDIAN +{ + double value; + struct + { + unsigned long lsw; + unsigned long msw; + } parts; +} ieee_double_shape_type; + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + +#define SET_HIGH_WORD(d,v) \ +do { \ + ieee_double_shape_type sh_u; \ + sh_u.value = (d); \ + sh_u.parts.msw = (v); \ + (d) = sh_u.value; \ +} while (0) + From b73ccfb9dce367c80e1edb49b7dde5962ac5abdb Mon Sep 17 00:00:00 2001 From: igor-m Date: Fri, 11 Apr 2014 21:23:23 +0200 Subject: [PATCH 04/24] Attempt to fix isinff.c --- src/libc/gen/isinff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libc/gen/isinff.c b/src/libc/gen/isinff.c index 0286a25..8292355 100644 --- a/src/libc/gen/isinff.c +++ b/src/libc/gen/isinff.c @@ -11,7 +11,7 @@ * isinff(x) returns 1 is x is inf, -1 if x is -inf, else 0; * no branching! */ -int isinff (float x) +int isinff (double x) { long lx = *(long*) &x; long v = (lx & 0x7fffffff) ^ 0x7f800000; From af3db0bcd215312174f35ebf7fff27874018bad1 Mon Sep 17 00:00:00 2001 From: igor-m Date: Fri, 11 Apr 2014 21:51:23 +0200 Subject: [PATCH 05/24] Another attempt to fix isinff.c, grrh --- src/libc/gen/isinff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libc/gen/isinff.c b/src/libc/gen/isinff.c index 8292355..c0edc8f 100644 --- a/src/libc/gen/isinff.c +++ b/src/libc/gen/isinff.c @@ -11,7 +11,7 @@ * isinff(x) returns 1 is x is inf, -1 if x is -inf, else 0; * no branching! */ -int isinff (double x) +int isinff (float x) { long lx = *(long*) &x; long v = (lx & 0x7fffffff) ^ 0x7f800000; @@ -21,4 +21,4 @@ int isinff (double x) /* * For PIC32, double is the same as float. */ -int isinf (double x) __attribute__((alias ("isinff"))); +//int isinf (double x) __attribute__((alias ("isinff"))); From 0f6e23c2fe9e4cc74708efdaaf94a4395123f963 Mon Sep 17 00:00:00 2001 From: igor-m Date: Fri, 11 Apr 2014 21:55:53 +0200 Subject: [PATCH 06/24] Fix 3 --- src/libc/gen/isinff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libc/gen/isinff.c b/src/libc/gen/isinff.c index c0edc8f..3d17f7f 100644 --- a/src/libc/gen/isinff.c +++ b/src/libc/gen/isinff.c @@ -13,7 +13,7 @@ */ int isinff (float x) { - long lx = *(long*) &x; + long lx = *(unsigned long*) &x; long v = (lx & 0x7fffffff) ^ 0x7f800000; return ~((v | -v) >> 31) & (lx >> 30); } From 98d034efe12fbe00ac8a25d5bceb87e80809ed53 Mon Sep 17 00:00:00 2001 From: igor-m Date: Fri, 11 Apr 2014 22:24:56 +0200 Subject: [PATCH 07/24] Fix4 --- src/libc/gen/isinff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libc/gen/isinff.c b/src/libc/gen/isinff.c index 3d17f7f..6ffac7d 100644 --- a/src/libc/gen/isinff.c +++ b/src/libc/gen/isinff.c @@ -13,7 +13,7 @@ */ int isinff (float x) { - long lx = *(unsigned long*) &x; + unsigned long lx = *(unsigned long*) &x; long v = (lx & 0x7fffffff) ^ 0x7f800000; return ~((v | -v) >> 31) & (lx >> 30); } From bcff791a3cafab987804a990d163d42a5ddbeb2e Mon Sep 17 00:00:00 2001 From: igor-m Date: Fri, 11 Apr 2014 22:45:22 +0200 Subject: [PATCH 08/24] Fix5 --- src/libc/gen/isinff.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/libc/gen/isinff.c b/src/libc/gen/isinff.c index 6ffac7d..0ad88eb 100644 --- a/src/libc/gen/isinff.c +++ b/src/libc/gen/isinff.c @@ -11,9 +11,25 @@ * isinff(x) returns 1 is x is inf, -1 if x is -inf, else 0; * no branching! */ -int isinff (float x) +typedef union { + float x; + struct { + long lxx; + }; +} ival; + +//int isinff (float x) +//{ +// long lx = *(long*) &x; +// long v = (lx & 0x7fffffff) ^ 0x7f800000; +// return ~((v | -v) >> 31) & (lx >> 30); +//} + +int isinff (float xx) { - unsigned long lx = *(unsigned long*) &x; + ival temp; + temp.x = xx; + long lx = temp.lxx; long v = (lx & 0x7fffffff) ^ 0x7f800000; return ~((v | -v) >> 31) & (lx >> 30); } From 5b1496e5c38dddf20f70fe8e187f3788cb7449d5 Mon Sep 17 00:00:00 2001 From: igor-m Date: Fri, 11 Apr 2014 22:55:29 +0200 Subject: [PATCH 09/24] Fix6 --- src/libc/gen/isnanf.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/libc/gen/isnanf.c b/src/libc/gen/isnanf.c index a3eaa52..2b298fe 100644 --- a/src/libc/gen/isnanf.c +++ b/src/libc/gen/isnanf.c @@ -11,15 +11,31 @@ * isnan(x) returns 1 is x is nan, else 0; * no branching! */ -int isnanf (float x) -{ - long lx = *(long*) &x; +typedef union { + float x; + struct { + long lxx; + }; +} ival; + +//int isnanf (float x) +//{ +// long lx = *(long*) &x; +// lx = 0x7f800000 - (lx & 0x7fffffff); +// return (int) (((unsigned long) lx) >> 31); +//} +int isnanf (float xx) { + ival temp; + temp.x = xx; + long lx = temp.lxx; lx = 0x7f800000 - (lx & 0x7fffffff); return (int) (((unsigned long) lx) >> 31); } + + /* * For PIC32, double is the same as float. */ -int isnan (double x) __attribute__((alias ("isnanf"))); +//int isnan (double x) __attribute__((alias ("isnanf"))); From 2afff6f8aa5275c9f96ee8177bcfada763ea62ed Mon Sep 17 00:00:00 2001 From: igor-m Date: Sat, 12 Apr 2014 01:14:47 +0200 Subject: [PATCH 10/24] Fix to doprnt.c and moded modff, modf etc --- src/libc/gen/isinff.c | 32 ++++------ src/libc/gen/isnanf.c | 33 ++++------ src/libc/gen/modf.c | 138 ++++++++++++++++++---------------------- src/libc/gen/modff.c | 38 ++++++----- src/libc/stdio/doprnt.c | 2 +- 5 files changed, 107 insertions(+), 136 deletions(-) diff --git a/src/libc/gen/isinff.c b/src/libc/gen/isinff.c index 0ad88eb..1755a65 100644 --- a/src/libc/gen/isinff.c +++ b/src/libc/gen/isinff.c @@ -11,30 +11,20 @@ * isinff(x) returns 1 is x is inf, -1 if x is -inf, else 0; * no branching! */ -typedef union { - float x; - struct { - long lxx; - }; -} ival; - -//int isinff (float x) -//{ -// long lx = *(long*) &x; -// long v = (lx & 0x7fffffff) ^ 0x7f800000; -// return ~((v | -v) >> 31) & (lx >> 30); -//} - -int isinff (float xx) +int isinff (float x) { - ival temp; - temp.x = xx; - long lx = temp.lxx; - long v = (lx & 0x7fffffff) ^ 0x7f800000; - return ~((v | -v) >> 31) & (lx >> 30); + union { + long s32; + float f32; + } u; + long v; + + u.f32 = x; + v = (u.s32 & 0x7fffffff) ^ 0x7f800000; + return ~((v | -v) >> 31) & (u.s32 >> 30); } /* * For PIC32, double is the same as float. */ -//int isinf (double x) __attribute__((alias ("isinff"))); +int isinf (double x) __attribute__((alias ("isinff"))); diff --git a/src/libc/gen/isnanf.c b/src/libc/gen/isnanf.c index 2b298fe..dda3938 100644 --- a/src/libc/gen/isnanf.c +++ b/src/libc/gen/isnanf.c @@ -11,31 +11,20 @@ * isnan(x) returns 1 is x is nan, else 0; * no branching! */ +int isnanf (float x) +{ + union { + long s32; + float f32; + } u; + unsigned long ul; -typedef union { - float x; - struct { - long lxx; - }; -} ival; - -//int isnanf (float x) -//{ -// long lx = *(long*) &x; -// lx = 0x7f800000 - (lx & 0x7fffffff); -// return (int) (((unsigned long) lx) >> 31); -//} -int isnanf (float xx) { - ival temp; - temp.x = xx; - long lx = temp.lxx; - lx = 0x7f800000 - (lx & 0x7fffffff); - return (int) (((unsigned long) lx) >> 31); + u.f32 = x; + ul = 0x7f800000 - (u.s32 & 0x7fffffff); + return ul >> 31; } - - /* * For PIC32, double is the same as float. */ -//int isnan (double x) __attribute__((alias ("isnanf"))); +int isnan (double x) __attribute__((alias ("isnanf"))); diff --git a/src/libc/gen/modf.c b/src/libc/gen/modf.c index f226091..a331a26 100644 --- a/src/libc/gen/modf.c +++ b/src/libc/gen/modf.c @@ -1,95 +1,79 @@ /* - * ==================================================== * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. * * Developed at SunPro, a Sun Microsystems, Inc. business. * Permission to use, copy, modify, and distribute this * software is freely granted, provided that this notice * is preserved. - * ==================================================== */ -// *** modified by Pito 11/2013 for RetroBSD *** - -typedef union // LITTLE ENDIAN -{ - double value; - struct - { - unsigned long lsw; - unsigned long msw; - } parts; -} ieee_double_shape_type; +#include /* Get two 32 bit ints from a double. */ -#define EXTRACT_WORDS(ix0,ix1,d) \ -do { \ - ieee_double_shape_type ew_u; \ - ew_u.value = (d); \ - (ix0) = ew_u.parts.msw; \ - (ix1) = ew_u.parts.lsw; \ -} while (0) +#define EXTRACT_WORDS(high,low,d) \ + high = *(unsigned long long*) &d; \ + low = (*(unsigned long long*) &d) >> 32 -/* Get the more significant 32 bit int from a double. */ - -#define GET_HIGH_WORD(i,d) \ -do { \ - ieee_double_shape_type gh_u; \ - gh_u.value = (d); \ - (i) = gh_u.parts.msw; \ -} while (0) /* Set a double from two 32 bit ints. */ -#define INSERT_WORDS(d,ix0,ix1) \ -do { \ - ieee_double_shape_type iw_u; \ - iw_u.parts.msw = (ix0); \ - iw_u.parts.lsw = (ix1); \ - (d) = iw_u.value; \ -} while (0) +#define INSERT_WORDS(d,high,low) \ + *(unsigned long long*) &(x) = (unsigned long long) (high) << 32 | (low) -double modf(double x, double *iptr) +/* + * modf(double x, double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ +static const double one = 1.0; + +double modf (double x, double *iptr) { - long int i0,i1,j0; - unsigned long i; - double one = 1.0; - EXTRACT_WORDS(i0,i1,x); - j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ - if(j0<20) { /* integer part in high x */ - if(j0<0) { /* |x|<1 */ - INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ - return x; - } else { - i = (0x000fffff)>>j0; - if(((i0&i)|i1)==0) { /* x is integral */ - unsigned long high; - *iptr = x; - GET_HIGH_WORD(high,x); - INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ - return x; - } else { - INSERT_WORDS(*iptr,i0&(~i),0); - return x - *iptr; - } - } - } else if (j0>51) { /* no fraction part */ - unsigned long high; - *iptr = x*one; - GET_HIGH_WORD(high,x); - INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ - return x; - } else { /* fraction part in low x */ - i = ((unsigned long)(0xffffffff))>>(j0-20); - if((i1&i)==0) { /* x is integral */ - unsigned long high; - *iptr = x; - GET_HIGH_WORD(high,x); - INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ - return x; - } else { - INSERT_WORDS(*iptr,i0,i1&(~i)); - return x - *iptr; - } - } + long i0, i1, j0; + unsigned long i; + + EXTRACT_WORDS (i0, i1, x); + j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */ + if (j0 < 20) { /* integer part in high x */ + if (j0 < 0) { /* |x|<1 */ + INSERT_WORDS (*iptr, i0 & 0x80000000, 0); + /* *iptr = +-0 */ + return x; + } else { + i = (0x000fffff) >> j0; + if (((i0 & i) | i1) == 0) { /* x is integral */ + *iptr = x; + INSERT_WORDS (x, i0 & 0x80000000, 0); + /* return +-0 */ + return x; + } else { + INSERT_WORDS (*iptr, i0 & (~i), 0); + return x - *iptr; + } + } + } else if (j0 > 51) { /* no fraction part */ + *iptr = x * one; + /* We must handle NaNs separately. */ + if (j0 == 0x400 && ((i0 & 0xfffff) | i1)) + return x * one; + + INSERT_WORDS (x, i0 & 0x80000000, 0); + /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((unsigned long) (0xffffffff)) >> (j0 - 20); + if ((i1 & i) == 0) { /* x is integral */ + *iptr = x; + INSERT_WORDS (x, i0 & 0x80000000, 0); + /* return +-0 */ + return x; + } else { + INSERT_WORDS (*iptr, i0, i1 & (~i)); + return x - *iptr; + } + } } diff --git a/src/libc/gen/modff.c b/src/libc/gen/modff.c index 4e099da..7eeac60 100644 --- a/src/libc/gen/modff.c +++ b/src/libc/gen/modff.c @@ -13,35 +13,43 @@ */ static const float one = 1.0; -float modff (float x, float *iptr) +float modff (float fx, float *iptr) { - unsigned hx = *(unsigned*) &x & ~0x80000000; - unsigned s; + union { + unsigned u32; + float f32; + } x; + unsigned hx, s; + x.f32 = fx; + hx = x.u32 & ~0x80000000; if (hx >= 0x4b000000) { /* x is NaN, infinite, or integral */ - *iptr = x; + *iptr = x.f32; if (hx <= 0x7f800000) - *(unsigned*) &x &= 0x80000000; - return x; + x.u32 &= 0x80000000; + return x.f32; } if (hx < 0x3f800000) { /* |x| < 1 */ - *iptr = x; - *(unsigned*) iptr &= 0x80000000; - return x; + float ret = x.f32; + x.u32 &= 0x80000000; + *iptr = x.f32; + return ret; } /* split x at the binary point */ - s = *(unsigned*) &x & 0x80000000; - *(unsigned*) iptr = *(unsigned*) &x & ~((1 << (0x96 - (hx >> 23))) - 1); - x -= *iptr; + s = x.u32 & 0x80000000; + fx = x.f32; + x.u32 &= ~((1 << (0x96 - (hx >> 23))) - 1); + *iptr = x.f32; + x.f32 = fx - *iptr; /* restore sign in case difference is 0 */ - *(unsigned*) &x = (*(unsigned*) &x & ~0x80000000) | s; - return x; + x.u32 = (x.u32 & ~0x80000000) | s; + return x.f32; } /* * For PIC32, double is the same as float. */ -//double modf (double x, double *iptr) __attribute__((alias ("modff"))); +double modf (double x, double *iptr) __attribute__((alias ("modff"))); diff --git a/src/libc/stdio/doprnt.c b/src/libc/stdio/doprnt.c index 9d3c7c3..78b7751 100644 --- a/src/libc/stdio/doprnt.c +++ b/src/libc/stdio/doprnt.c @@ -367,7 +367,7 @@ number: if (sign && ((long) ul != 0L)) { double d; unsigned long *l = (unsigned long *) &d; - if (*(unsigned long*)&ap & 4) { + if (*(unsigned long*)&ap & 4L) { l[0]= va_arg(ap, unsigned long); l[1]= va_arg(ap, unsigned long); } From 0220852a66676f4cefaab1d09e5a594990d87d15 Mon Sep 17 00:00:00 2001 From: igor-m Date: Sat, 12 Apr 2014 01:25:31 +0200 Subject: [PATCH 11/24] Fix of va_arg aliasing in doprnt.c --- src/libc/stdio/doprnt.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/libc/stdio/doprnt.c b/src/libc/stdio/doprnt.c index 78b7751..40a8998 100644 --- a/src/libc/stdio/doprnt.c +++ b/src/libc/stdio/doprnt.c @@ -53,6 +53,11 @@ static unsigned char mkhex (unsigned char ch); static int cvt (double number, int prec, int sharpflag, unsigned char *negp, unsigned char fmtch, unsigned char *startp, unsigned char *endp); + union { + unsigned long u32; + va_list ap32; + } x; + int _doprnt (char const *fmt, va_list ap, FILE *stream) { @@ -367,7 +372,9 @@ number: if (sign && ((long) ul != 0L)) { double d; unsigned long *l = (unsigned long *) &d; - if (*(unsigned long*)&ap & 4L) { + x.ap32 = ap; + + if ( x.u32 & 4) { l[0]= va_arg(ap, unsigned long); l[1]= va_arg(ap, unsigned long); } From 190aa1e633ac03c38b11227f38612a04bba4d597 Mon Sep 17 00:00:00 2001 From: igor-m Date: Sat, 12 Apr 2014 12:51:40 +0200 Subject: [PATCH 12/24] Fixes with aliasing --- src/libc/gen/Makefile | 2 +- src/libc/gen/isinff.c | 2 +- src/libc/gen/isnanf.c | 2 +- src/libc/gen/modf.c | 44 ++++++++++++++++++++++++++++++++----------- src/libc/gen/modff.c | 2 +- 5 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/libc/gen/Makefile b/src/libc/gen/Makefile index 933e2af..254fd60 100755 --- a/src/libc/gen/Makefile +++ b/src/libc/gen/Makefile @@ -36,7 +36,7 @@ STDOBJ = abort.o alarm.o atof.o atoi.o atol.o calloc.o closedir.o crypt.o \ getpass.o getpwent.o getloadavg.o getmntinfo.o \ getttyent.o getttynam.o getusershell.o getwd.o \ initgroups.o isatty.o isinff.o isnanf.o ldexp.o malloc.o mktemp.o \ - modff.o modf.c ndbm.o nlist.o knlist.o opendir.o perror.o popen.o \ + modff.o modf.o ndbm.o nlist.o knlist.o opendir.o perror.o popen.o \ psignal.o qsort.o random.o readdir.o regex.o scandir.o \ seekdir.o setmode.o sethostname.o setenv.o siglist.o \ signal.o siginterrupt.o sigsetops.o \ diff --git a/src/libc/gen/isinff.c b/src/libc/gen/isinff.c index 1755a65..8bba21f 100644 --- a/src/libc/gen/isinff.c +++ b/src/libc/gen/isinff.c @@ -27,4 +27,4 @@ int isinff (float x) /* * For PIC32, double is the same as float. */ -int isinf (double x) __attribute__((alias ("isinff"))); +//int isinf (double x) __attribute__((alias ("isinff"))); diff --git a/src/libc/gen/isnanf.c b/src/libc/gen/isnanf.c index dda3938..c54ba7c 100644 --- a/src/libc/gen/isnanf.c +++ b/src/libc/gen/isnanf.c @@ -27,4 +27,4 @@ int isnanf (float x) /* * For PIC32, double is the same as float. */ -int isnan (double x) __attribute__((alias ("isnanf"))); +//int isnan (double x) __attribute__((alias ("isnanf"))); diff --git a/src/libc/gen/modf.c b/src/libc/gen/modf.c index a331a26..a9ee6f3 100644 --- a/src/libc/gen/modf.c +++ b/src/libc/gen/modf.c @@ -8,12 +8,20 @@ */ #include +// IM: dereferencing type-punned pointer will break strict-aliasing rules +// TODO check Endiannes + union { + double d64; + struct { long i32h; + long i32l; + }; + } ew; + /* Get two 32 bit ints from a double. */ -#define EXTRACT_WORDS(high,low,d) \ - high = *(unsigned long long*) &d; \ - low = (*(unsigned long long*) &d) >> 32 - +//#define EXTRACT_WORDS(high,low,d) +// high = *(unsigned long long*) &d; +// low = (*(unsigned long long*) &d) >> 32 /* Set a double from two 32 bit ints. */ @@ -36,22 +44,30 @@ double modf (double x, double *iptr) long i0, i1, j0; unsigned long i; - EXTRACT_WORDS (i0, i1, x); + //EXTRACT_WORDS (i0, i1, x); + ew.d64 = x; i0 = ew.i32h; i1 = ew.i32l; + // j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */ if (j0 < 20) { /* integer part in high x */ if (j0 < 0) { /* |x|<1 */ - INSERT_WORDS (*iptr, i0 & 0x80000000, 0); + //INSERT_WORDS (*iptr, i0 & 0x80000000, 0); + ew.i32h = i0 & 0x80000000; ew.i32l = 0; *iptr = ew.d64; + // /* *iptr = +-0 */ return x; } else { i = (0x000fffff) >> j0; if (((i0 & i) | i1) == 0) { /* x is integral */ *iptr = x; - INSERT_WORDS (x, i0 & 0x80000000, 0); + //INSERT_WORDS (x, i0 & 0x80000000, 0); + ew.i32h = i0 & 0x80000000; ew.i32l = 0; x = ew.d64; + // /* return +-0 */ return x; } else { - INSERT_WORDS (*iptr, i0 & (~i), 0); + //INSERT_WORDS (*iptr, i0 & (~i), 0); + ew.i32h = i0 & (~i); ew.i32l = 0; *iptr = ew.d64; + // return x - *iptr; } } @@ -61,18 +77,24 @@ double modf (double x, double *iptr) if (j0 == 0x400 && ((i0 & 0xfffff) | i1)) return x * one; - INSERT_WORDS (x, i0 & 0x80000000, 0); + //INSERT_WORDS (x, i0 & 0x80000000, 0); + ew.i32h = i0 & 0x80000000; ew.i32l = 0; x = ew.d64; + // /* return +-0 */ return x; } else { /* fraction part in low x */ i = ((unsigned long) (0xffffffff)) >> (j0 - 20); if ((i1 & i) == 0) { /* x is integral */ *iptr = x; - INSERT_WORDS (x, i0 & 0x80000000, 0); + //INSERT_WORDS (x, i0 & 0x80000000, 0); + ew.i32h = i0 & 0x80000000; ew.i32l = 0; x = ew.d64; + // /* return +-0 */ return x; } else { - INSERT_WORDS (*iptr, i0, i1 & (~i)); + //INSERT_WORDS (*iptr, i0, i1 & (~i)); + ew.i32h = i0; ew.i32l = i1 & (~i); *iptr = ew.d64; + // return x - *iptr; } } diff --git a/src/libc/gen/modff.c b/src/libc/gen/modff.c index 7eeac60..41a5d94 100644 --- a/src/libc/gen/modff.c +++ b/src/libc/gen/modff.c @@ -52,4 +52,4 @@ float modff (float fx, float *iptr) /* * For PIC32, double is the same as float. */ -double modf (double x, double *iptr) __attribute__((alias ("modff"))); +//double modf (double x, double *iptr) __attribute__((alias ("modff"))); From 297b14aa0ca397956b6db47686f7c56919f0bea5 Mon Sep 17 00:00:00 2001 From: igor-m Date: Sat, 12 Apr 2014 13:39:05 +0200 Subject: [PATCH 13/24] Fixes with aliasing - using ieee.h --- src/libc/gen/modf.c | 42 ++++++++---------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) diff --git a/src/libc/gen/modf.c b/src/libc/gen/modf.c index a9ee6f3..33529c7 100644 --- a/src/libc/gen/modf.c +++ b/src/libc/gen/modf.c @@ -7,26 +7,7 @@ * is preserved. */ #include - -// IM: dereferencing type-punned pointer will break strict-aliasing rules -// TODO check Endiannes - union { - double d64; - struct { long i32h; - long i32l; - }; - } ew; - -/* Get two 32 bit ints from a double. */ - -//#define EXTRACT_WORDS(high,low,d) -// high = *(unsigned long long*) &d; -// low = (*(unsigned long long*) &d) >> 32 - -/* Set a double from two 32 bit ints. */ - -#define INSERT_WORDS(d,high,low) \ - *(unsigned long long*) &(x) = (unsigned long long) (high) << 32 | (low) +#include /* * modf(double x, double *iptr) @@ -44,14 +25,12 @@ double modf (double x, double *iptr) long i0, i1, j0; unsigned long i; - //EXTRACT_WORDS (i0, i1, x); - ew.d64 = x; i0 = ew.i32h; i1 = ew.i32l; + EXTRACT_WORDS (i0, i1, x); // j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */ if (j0 < 20) { /* integer part in high x */ if (j0 < 0) { /* |x|<1 */ - //INSERT_WORDS (*iptr, i0 & 0x80000000, 0); - ew.i32h = i0 & 0x80000000; ew.i32l = 0; *iptr = ew.d64; + INSERT_WORDS (*iptr, i0 & 0x80000000, 0); // /* *iptr = +-0 */ return x; @@ -59,14 +38,12 @@ double modf (double x, double *iptr) i = (0x000fffff) >> j0; if (((i0 & i) | i1) == 0) { /* x is integral */ *iptr = x; - //INSERT_WORDS (x, i0 & 0x80000000, 0); - ew.i32h = i0 & 0x80000000; ew.i32l = 0; x = ew.d64; + INSERT_WORDS (x, i0 & 0x80000000, 0); // /* return +-0 */ return x; } else { - //INSERT_WORDS (*iptr, i0 & (~i), 0); - ew.i32h = i0 & (~i); ew.i32l = 0; *iptr = ew.d64; + INSERT_WORDS (*iptr, i0 & (~i), 0); // return x - *iptr; } @@ -77,8 +54,7 @@ double modf (double x, double *iptr) if (j0 == 0x400 && ((i0 & 0xfffff) | i1)) return x * one; - //INSERT_WORDS (x, i0 & 0x80000000, 0); - ew.i32h = i0 & 0x80000000; ew.i32l = 0; x = ew.d64; + INSERT_WORDS (x, i0 & 0x80000000, 0); // /* return +-0 */ return x; @@ -86,14 +62,12 @@ double modf (double x, double *iptr) i = ((unsigned long) (0xffffffff)) >> (j0 - 20); if ((i1 & i) == 0) { /* x is integral */ *iptr = x; - //INSERT_WORDS (x, i0 & 0x80000000, 0); - ew.i32h = i0 & 0x80000000; ew.i32l = 0; x = ew.d64; + INSERT_WORDS (x, i0 & 0x80000000, 0); // /* return +-0 */ return x; } else { - //INSERT_WORDS (*iptr, i0, i1 & (~i)); - ew.i32h = i0; ew.i32l = i1 & (~i); *iptr = ew.d64; + INSERT_WORDS (*iptr, i0, i1 & (~i)); // return x - *iptr; } From c04495837f9bb1b27ced94b0d91fdcb070336173 Mon Sep 17 00:00:00 2001 From: igor-m Date: Sun, 13 Apr 2014 09:34:13 +0200 Subject: [PATCH 14/24] Fix of the vaarg fix --- src/libc/stdio/doprnt.c | 21 ++++++++++++++------- target.mk | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/libc/stdio/doprnt.c b/src/libc/stdio/doprnt.c index 40a8998..2a5bae4 100644 --- a/src/libc/stdio/doprnt.c +++ b/src/libc/stdio/doprnt.c @@ -53,10 +53,10 @@ static unsigned char mkhex (unsigned char ch); static int cvt (double number, int prec, int sharpflag, unsigned char *negp, unsigned char fmtch, unsigned char *startp, unsigned char *endp); - union { - unsigned long u32; - va_list ap32; - } x; +// union { +// unsigned long u32; +// va_list ap32; +// } x; int _doprnt (char const *fmt, va_list ap, FILE *stream) @@ -368,13 +368,18 @@ number: if (sign && ((long) ul != 0L)) { case 'F': case 'g': case 'G': { + + // --- IM - vaarg alignment issue fix: double d; + + unsigned long *da; + + da = (unsigned long *) ≈ + unsigned long *l = (unsigned long *) &d; - x.ap32 = ap; - - if ( x.u32 & 4) { + if ( (*da) & 4) { // maj l[0]= va_arg(ap, unsigned long); l[1]= va_arg(ap, unsigned long); } @@ -384,6 +389,8 @@ number: if (sign && ((long) ul != 0L)) { l[1]= va_arg(ap, unsigned long); } + // --- + /* * don't do unrealistic precision; just pad it with * zeroes later, so buffer size stays rational. diff --git a/target.mk b/target.mk index 816b10f..1aaebdb 100755 --- a/target.mk +++ b/target.mk @@ -50,7 +50,7 @@ TAGSFILE = tags MANROFF = nroff -man -h -Tascii ELF2AOUT = $(TOPSRC)/tools/elf2aout/elf2aout -CFLAGS = -O +CFLAGS = -O -fno-short-double LDFLAGS += -N -nostartfiles -fno-dwarf2-cfi-asm -T$(TOPSRC)/src/elf32-mips.ld \ $(TOPSRC)/src/crt0.o -L$(TOPSRC)/src From bad98ad2391cf271e2fa40450342e747d406fdd1 Mon Sep 17 00:00:00 2001 From: igor-m Date: Mon, 14 Apr 2014 13:30:22 +0200 Subject: [PATCH 15/24] Single -fno-short-double in target.mk --- target.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/target.mk b/target.mk index 1aaebdb..8a28658 100755 --- a/target.mk +++ b/target.mk @@ -34,8 +34,8 @@ ifndef GCCPREFIX INCLUDES = endif -CC = $(GCCPREFIX)gcc -mips32r2 -EL -msoft-float -nostdinc -fno-short-double -I$(TOPSRC)/include $(INCLUDES) -CXX = $(GCCPREFIX)g++ -mips32r2 -EL -msoft-float -nostdinc -fno-short-double -I$(TOPSRC)/include $(INCLUDES) +CC = $(GCCPREFIX)gcc -mips32r2 -EL -msoft-float -nostdinc -I$(TOPSRC)/include $(INCLUDES) +CXX = $(GCCPREFIX)g++ -mips32r2 -EL -msoft-float -nostdinc -I$(TOPSRC)/include $(INCLUDES) LD = $(GCCPREFIX)ld AR = $(GCCPREFIX)ar RANLIB = $(GCCPREFIX)ranlib From 6d689c335c8bdbb14b797d02c1f694049d862c01 Mon Sep 17 00:00:00 2001 From: igor-m Date: Wed, 16 Apr 2014 15:03:35 +0200 Subject: [PATCH 16/24] Added SPI modes R,W,RB,WB,RWB --- sys/include/spi.h | 13 +++++++ sys/pic32/spi.c | 90 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/sys/include/spi.h b/sys/include/spi.h index ef8f114..1b670b1 100644 --- a/sys/include/spi.h +++ b/sys/include/spi.h @@ -15,10 +15,23 @@ #define SPICTL_SETMODE _IO ('p', 0) /* set SPI mode */ #define SPICTL_SETRATE _IO ('p', 1) /* set clock rate, kHz */ #define SPICTL_SETSELPIN _IO ('p', 2) /* set select pin */ + #define SPICTL_IO8(n) _ION('p', 3, n) /* transfer n*8 bits */ #define SPICTL_IO16(n) _ION('p', 4, n) /* transfer n*16 bits */ #define SPICTL_IO32(n) _ION('p', 5, n) /* transfer n*32 bits */ +#define SPICTL_IO8R(n) _ION('p', 6, n) /* transfer R n*8 bits */ +#define SPICTL_IO16R(n) _ION('p', 7, n) /* transfer R n*16 bits */ +#define SPICTL_IO32R(n) _ION('p', 8, n) /* transfer R n*32 bits */ + +#define SPICTL_IO8W(n) _ION('p', 9, n) /* transfer W n*8 bits */ +#define SPICTL_IO16W(n) _ION('p', 10, n) /* transfer W n*16 bits */ +#define SPICTL_IO32W(n) _ION('p', 11, n) /* transfer W n*32 bits */ + +#define SPICTL_IO32B(n) _ION('p', 12, n) /* transfer BE n*32 bits */ +#define SPICTL_IO32RB(n) _ION('p', 13, n) /* transfer RBE n*32 bits */ +#define SPICTL_IO32WB(n) _ION('p', 14, n) /* transfer WBE n*32 bits */ + #ifdef KERNEL #include "conf.h" diff --git a/sys/pic32/spi.c b/sys/pic32/spi.c index caf60c3..e2e0595 100644 --- a/sys/pic32/spi.c +++ b/sys/pic32/spi.c @@ -101,9 +101,18 @@ int spidev_write (dev_t dev, struct uio *uio, int flag) * - SPICTL_SETMODE - set clock polarity and phase * - SPICTL_SETRATE - set data rate in kHz * - SPICTL_SETSELPIN - set select pin - * - SPICTL_IO8(n) - n*8 bit transaction - * - SPICTL_IO16(n) - n*16 bit transaction - * - SPICTL_IO32(n) - n*32 bit transaction + * - SPICTL_IO8(n) - n*8 bit RW transaction + * - SPICTL_IO16(n) - n*16 bit RW transaction + * - SPICTL_IO32(n) - n*32 bit RW transaction + * - SPICTL_IO8R(n) - n*8 bit R transaction + * - SPICTL_IO16R(n) - n*16 bit R transaction + * - SPICTL_IO32R(n) - n*32 bit R transaction + * - SPICTL_IO8W(n) - n*8 bit W transaction + * - SPICTL_IO16W(n) - n*16 bit W transaction + * - SPICTL_IO32W(n) - n*32 bit W transaction + * - SPICTL_IO32RB(n) - n*32 bit RB transaction + * - SPICTL_IO32WB(n) - n*32 bit WB transaction + * - SPICTL_IO32B(n) - n*32 bit B transaction */ int spidev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag) { @@ -173,6 +182,81 @@ int spidev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag) return EFAULT; spi_bulk_rw_32(spi_fd[channel], nelem<<2, (char *)addr); break; +// IM: added R and W and BE modes + case SPICTL_IO8R(0): /* transfer n*8 bits */ + spi_select(spi_fd[channel]); + nelem = (cmd >> 16) & IOCPARM_MASK; + if (baduaddr (addr) || baduaddr (addr + nelem - 1)) + return EFAULT; + spi_bulk_read(spi_fd[channel], nelem, cval); + spi_deselect(spi_fd[channel]); + break; + + case SPICTL_IO16R(0): /* transfer n*16 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 1) || + baduaddr (addr) || baduaddr (addr + nelem*2 - 1)) + return EFAULT; + spi_bulk_read_16(spi_fd[channel], nelem<<1, (char *)addr); + break; + + case SPICTL_IO32R(0): /* transfer n*32 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 3) || + baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) + return EFAULT; + spi_bulk_read_32(spi_fd[channel], nelem<<2, (char *)addr); + break; + + case SPICTL_IO8W(0): /* transfer n*8 bits */ + spi_select(spi_fd[channel]); + nelem = (cmd >> 16) & IOCPARM_MASK; + if (baduaddr (addr) || baduaddr (addr + nelem - 1)) + return EFAULT; + spi_bulk_write(spi_fd[channel], nelem, cval); + spi_deselect(spi_fd[channel]); + break; + + case SPICTL_IO16W(0): /* transfer n*16 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 1) || + baduaddr (addr) || baduaddr (addr + nelem*2 - 1)) + return EFAULT; + spi_bulk_write_16(spi_fd[channel], nelem<<1, (char *)addr); + break; + + case SPICTL_IO32W(0): /* transfer n*32 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 3) || + baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) + return EFAULT; + spi_bulk_write_32(spi_fd[channel], nelem<<2, (char *)addr); + break; + + case SPICTL_IO32RB(0): /* transfer n*32 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 3) || + baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) + return EFAULT; + spi_bulk_read_32_be(spi_fd[channel], nelem<<2, (char *)addr); + break; + + case SPICTL_IO32WB(0): /* transfer n*32 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 3) || + baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) + return EFAULT; + spi_bulk_write_32_be(spi_fd[channel], nelem<<2, (char *)addr); + break; + + case SPICTL_IO32B(0): /* transfer n*32 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 3) || + baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) + return EFAULT; + spi_bulk_write_32_be(spi_fd[channel], nelem<<2, (char *)addr); + break; +// } return 0; } From 28aae2c42776e9c2719669167a6ddb67d5dd8e52 Mon Sep 17 00:00:00 2001 From: igor-m Date: Wed, 16 Apr 2014 15:24:09 +0200 Subject: [PATCH 17/24] Added comment to spi.c --- sys/pic32/spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/pic32/spi.c b/sys/pic32/spi.c index e2e0595..3e42abe 100644 --- a/sys/pic32/spi.c +++ b/sys/pic32/spi.c @@ -110,9 +110,9 @@ int spidev_write (dev_t dev, struct uio *uio, int flag) * - SPICTL_IO8W(n) - n*8 bit W transaction * - SPICTL_IO16W(n) - n*16 bit W transaction * - SPICTL_IO32W(n) - n*32 bit W transaction - * - SPICTL_IO32RB(n) - n*32 bit RB transaction + * - SPICTL_IO32RB(n) - n*32 bit RB transaction (B - swap bytes order) * - SPICTL_IO32WB(n) - n*32 bit WB transaction - * - SPICTL_IO32B(n) - n*32 bit B transaction + * - SPICTL_IO32B(n) - n*32 bit RWB transaction */ int spidev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag) { From d9033fbf2d6427f64b2bd931cde5181c85da4ea8 Mon Sep 17 00:00:00 2001 From: igor-m Date: Thu, 17 Apr 2014 00:07:00 +0200 Subject: [PATCH 18/24] target.mk back with -fno-short-double --- target.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/target.mk b/target.mk index 8a28658..effea0a 100755 --- a/target.mk +++ b/target.mk @@ -34,8 +34,8 @@ ifndef GCCPREFIX INCLUDES = endif -CC = $(GCCPREFIX)gcc -mips32r2 -EL -msoft-float -nostdinc -I$(TOPSRC)/include $(INCLUDES) -CXX = $(GCCPREFIX)g++ -mips32r2 -EL -msoft-float -nostdinc -I$(TOPSRC)/include $(INCLUDES) +CC = $(GCCPREFIX)gcc -mips32r2 -EL -msoft-float -fno-short-double -nostdinc -I$(TOPSRC)/include $(INCLUDES) +CXX = $(GCCPREFIX)g++ -mips32r2 -EL -msoft-float -fno-short-double -nostdinc -I$(TOPSRC)/include $(INCLUDES) LD = $(GCCPREFIX)ld AR = $(GCCPREFIX)ar RANLIB = $(GCCPREFIX)ranlib @@ -50,7 +50,7 @@ TAGSFILE = tags MANROFF = nroff -man -h -Tascii ELF2AOUT = $(TOPSRC)/tools/elf2aout/elf2aout -CFLAGS = -O -fno-short-double +CFLAGS = -O LDFLAGS += -N -nostartfiles -fno-dwarf2-cfi-asm -T$(TOPSRC)/src/elf32-mips.ld \ $(TOPSRC)/src/crt0.o -L$(TOPSRC)/src From eddfd51e51cbede189fb1944e610e7edcef2437d Mon Sep 17 00:00:00 2001 From: igor-m Date: Thu, 17 Apr 2014 00:14:41 +0200 Subject: [PATCH 19/24] Fix of vaarg alignment addr calc --- src/libc/stdio/doprnt.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/libc/stdio/doprnt.c b/src/libc/stdio/doprnt.c index 2a5bae4..b5137b4 100644 --- a/src/libc/stdio/doprnt.c +++ b/src/libc/stdio/doprnt.c @@ -68,6 +68,9 @@ _doprnt (char const *fmt, va_list ap, FILE *stream) int n, width, dwidth, retval, uppercase, extrazeros, sign; unsigned long ul; + double d; + unsigned long *da; + if (! stream) return 0; if (! fmt) @@ -371,15 +374,11 @@ number: if (sign && ((long) ul != 0L)) { // --- IM - vaarg alignment issue fix: - double d; - - unsigned long *da; - da = (unsigned long *) ≈ unsigned long *l = (unsigned long *) &d; - if ( (*da) & 4) { // maj + if ( ((unsigned long)da) & 4) { // maj_II l[0]= va_arg(ap, unsigned long); l[1]= va_arg(ap, unsigned long); } From 54a771c6f00e50901b01043df3392de7c10128ad Mon Sep 17 00:00:00 2001 From: igor-m Date: Thu, 17 Apr 2014 00:53:24 +0200 Subject: [PATCH 20/24] Revert "Added comment to spi.c" This reverts commit 28aae2c42776e9c2719669167a6ddb67d5dd8e52. --- sys/pic32/spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/pic32/spi.c b/sys/pic32/spi.c index 3e42abe..e2e0595 100644 --- a/sys/pic32/spi.c +++ b/sys/pic32/spi.c @@ -110,9 +110,9 @@ int spidev_write (dev_t dev, struct uio *uio, int flag) * - SPICTL_IO8W(n) - n*8 bit W transaction * - SPICTL_IO16W(n) - n*16 bit W transaction * - SPICTL_IO32W(n) - n*32 bit W transaction - * - SPICTL_IO32RB(n) - n*32 bit RB transaction (B - swap bytes order) + * - SPICTL_IO32RB(n) - n*32 bit RB transaction * - SPICTL_IO32WB(n) - n*32 bit WB transaction - * - SPICTL_IO32B(n) - n*32 bit RWB transaction + * - SPICTL_IO32B(n) - n*32 bit B transaction */ int spidev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag) { From 1d1151403b3de2b615a120d4e0e4daab0004853e Mon Sep 17 00:00:00 2001 From: igor-m Date: Thu, 17 Apr 2014 01:06:49 +0200 Subject: [PATCH 21/24] Revert "Added comment to spi.c" This reverts commit 28aae2c42776e9c2719669167a6ddb67d5dd8e52. --- sys/include/spi.h | 47 --------- sys/pic32/spi.c | 262 ---------------------------------------------- 2 files changed, 309 deletions(-) delete mode 100644 sys/include/spi.h delete mode 100644 sys/pic32/spi.c diff --git a/sys/include/spi.h b/sys/include/spi.h deleted file mode 100644 index 1b670b1..0000000 --- a/sys/include/spi.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 1986 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. - */ - -/* - * Ioctl definitions for SPI driver. - */ -#ifndef _SPI_H -#define _SPI_H - -#include - -#define SPICTL_SETMODE _IO ('p', 0) /* set SPI mode */ -#define SPICTL_SETRATE _IO ('p', 1) /* set clock rate, kHz */ -#define SPICTL_SETSELPIN _IO ('p', 2) /* set select pin */ - -#define SPICTL_IO8(n) _ION('p', 3, n) /* transfer n*8 bits */ -#define SPICTL_IO16(n) _ION('p', 4, n) /* transfer n*16 bits */ -#define SPICTL_IO32(n) _ION('p', 5, n) /* transfer n*32 bits */ - -#define SPICTL_IO8R(n) _ION('p', 6, n) /* transfer R n*8 bits */ -#define SPICTL_IO16R(n) _ION('p', 7, n) /* transfer R n*16 bits */ -#define SPICTL_IO32R(n) _ION('p', 8, n) /* transfer R n*32 bits */ - -#define SPICTL_IO8W(n) _ION('p', 9, n) /* transfer W n*8 bits */ -#define SPICTL_IO16W(n) _ION('p', 10, n) /* transfer W n*16 bits */ -#define SPICTL_IO32W(n) _ION('p', 11, n) /* transfer W n*32 bits */ - -#define SPICTL_IO32B(n) _ION('p', 12, n) /* transfer BE n*32 bits */ -#define SPICTL_IO32RB(n) _ION('p', 13, n) /* transfer RBE n*32 bits */ -#define SPICTL_IO32WB(n) _ION('p', 14, n) /* transfer WBE n*32 bits */ - -#ifdef KERNEL -#include "conf.h" - -extern const struct devspec spidevs[]; - -int spidev_open (dev_t dev, int flag, int mode); -int spidev_close (dev_t dev, int flag, int mode); -int spidev_read (dev_t dev, struct uio *uio, int flag); -int spidev_write (dev_t dev, struct uio *uio, int flag); -int spidev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag); -#endif - -#endif diff --git a/sys/pic32/spi.c b/sys/pic32/spi.c deleted file mode 100644 index e2e0595..0000000 --- a/sys/pic32/spi.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Generic SPI driver for PIC32. - * - * Copyright (C) 2012 Serge Vakulenko, - * - * Permission to use, copy, modify, and distribute this software - * and its documentation for any purpose and without fee is hereby - * granted, provided that the above copyright notice appear in all - * copies and that both that the copyright notice and this - * permission notice and warranty disclaimer appear in supporting - * documentation, and that the name of the author not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * - * The author disclaim all warranties with regard to this - * software, including all implied warranties of merchantability - * and fitness. In no event shall the author be liable for any - * special, indirect or consequential damages or any damages - * whatsoever resulting from loss of use, data or profits, whether - * in an action of contract, negligence or other tortious action, - * arising out of or in connection with the use or performance of - * this software. - */ -#include "param.h" -#include "conf.h" -#include "user.h" -#include "ioctl.h" -#include "systm.h" -#include "uio.h" -#include "spi.h" -#include "spi_bus.h" - -const struct devspec spidevs[] = { - { 0, "spi1" }, - { 1, "spi2" }, - { 2, "spi3" }, - { 3, "spi4" }, - { 0, 0 } -}; - -#define NSPI 4 /* Ports SPI1...SPI4 */ - -/* - * To enable debug output, uncomment the first line. - */ -//#define PRINTDBG printf -#ifndef PRINTDBG -# define PRINTDBG(...) /*empty*/ -#endif - -int spi_fd[NSPI]; - -/* - * Open /dev/spi# device. - * Use default SPI parameters: - * - rate 250 kHz; - * - no sleect pin. - */ -int spidev_open (dev_t dev, int flag, int mode) -{ - int channel = minor (dev); - - if (channel >= NSPI) - return ENXIO; - - if (u.u_uid != 0) - return EPERM; - - spi_fd[channel] = spi_open(channel+1,NULL,NULL); - if(spi_fd[channel]==-1) - return ENODEV; - return 0; -} - -int spidev_close (dev_t dev, int flag, int mode) -{ - int channel = minor (dev); - - if (channel >= NSPI) - return ENXIO; - - if (u.u_uid != 0) - return EPERM; - - spi_close(spi_fd[channel]); - return 0; -} - -int spidev_read (dev_t dev, struct uio *uio, int flag) -{ - return 0; -} - -int spidev_write (dev_t dev, struct uio *uio, int flag) -{ - return 0; -} - -/* - * SPI control operations: - * - SPICTL_SETMODE - set clock polarity and phase - * - SPICTL_SETRATE - set data rate in kHz - * - SPICTL_SETSELPIN - set select pin - * - SPICTL_IO8(n) - n*8 bit RW transaction - * - SPICTL_IO16(n) - n*16 bit RW transaction - * - SPICTL_IO32(n) - n*32 bit RW transaction - * - SPICTL_IO8R(n) - n*8 bit R transaction - * - SPICTL_IO16R(n) - n*16 bit R transaction - * - SPICTL_IO32R(n) - n*32 bit R transaction - * - SPICTL_IO8W(n) - n*8 bit W transaction - * - SPICTL_IO16W(n) - n*16 bit W transaction - * - SPICTL_IO32W(n) - n*32 bit W transaction - * - SPICTL_IO32RB(n) - n*32 bit RB transaction - * - SPICTL_IO32WB(n) - n*32 bit WB transaction - * - SPICTL_IO32B(n) - n*32 bit B transaction - */ -int spidev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag) -{ - int channel = minor (dev); - unsigned char *cval = (unsigned char *)addr; - int nelem; - static unsigned volatile *const tris[8] = { - 0, &TRISA,&TRISB,&TRISC,&TRISD,&TRISE,&TRISF,&TRISG, - }; - int mask, portnum; - - //PRINTDBG ("spi%d: ioctl (cmd=%08x, addr=%08x)\n", channel+1, cmd, addr); - if (channel >= NSPI) - return ENXIO; - - switch (cmd & ~(IOCPARM_MASK << 16)) { - default: - return ENODEV; - - case SPICTL_SETMODE: /* set SPI mode */ - /* --- Clock ---- - * Mode Polarity Phase - * 0 0 0 - * 1 0 1 - * 2 1 0 - * 3 1 1 - */ - if((unsigned int) addr & 0x01) - spi_set(spi_fd[channel], PIC32_SPICON_CKE); - if((unsigned int) addr & 0x02) - spi_set(spi_fd[channel], PIC32_SPICON_CKP); - return 0; - - case SPICTL_SETRATE: /* set clock rate, kHz */ - spi_brg(spi_fd[channel], (unsigned int) addr); - return 0; - - case SPICTL_SETSELPIN: /* set select pin */ - mask = 1 << ((unsigned int) addr & 15); - portnum = ((unsigned int) addr >> 8) & 7; - if (! portnum) - return 0; - spi_set_cspin(spi_fd[channel], (unsigned int *)tris[((unsigned int) addr >> 8) & 7], (unsigned int) addr & 15); - return 0; - - case SPICTL_IO8(0): /* transfer n*8 bits */ - spi_select(spi_fd[channel]); - nelem = (cmd >> 16) & IOCPARM_MASK; - if (baduaddr (addr) || baduaddr (addr + nelem - 1)) - return EFAULT; - spi_bulk_rw(spi_fd[channel], nelem, cval); - spi_deselect(spi_fd[channel]); - break; - - case SPICTL_IO16(0): /* transfer n*16 bits */ - nelem = (cmd >> 16) & IOCPARM_MASK; - if (((unsigned) addr & 1) || - baduaddr (addr) || baduaddr (addr + nelem*2 - 1)) - return EFAULT; - spi_bulk_rw_16(spi_fd[channel], nelem<<1, (char *)addr); - break; - - case SPICTL_IO32(0): /* transfer n*32 bits */ - nelem = (cmd >> 16) & IOCPARM_MASK; - if (((unsigned) addr & 3) || - baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) - return EFAULT; - spi_bulk_rw_32(spi_fd[channel], nelem<<2, (char *)addr); - break; -// IM: added R and W and BE modes - case SPICTL_IO8R(0): /* transfer n*8 bits */ - spi_select(spi_fd[channel]); - nelem = (cmd >> 16) & IOCPARM_MASK; - if (baduaddr (addr) || baduaddr (addr + nelem - 1)) - return EFAULT; - spi_bulk_read(spi_fd[channel], nelem, cval); - spi_deselect(spi_fd[channel]); - break; - - case SPICTL_IO16R(0): /* transfer n*16 bits */ - nelem = (cmd >> 16) & IOCPARM_MASK; - if (((unsigned) addr & 1) || - baduaddr (addr) || baduaddr (addr + nelem*2 - 1)) - return EFAULT; - spi_bulk_read_16(spi_fd[channel], nelem<<1, (char *)addr); - break; - - case SPICTL_IO32R(0): /* transfer n*32 bits */ - nelem = (cmd >> 16) & IOCPARM_MASK; - if (((unsigned) addr & 3) || - baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) - return EFAULT; - spi_bulk_read_32(spi_fd[channel], nelem<<2, (char *)addr); - break; - - case SPICTL_IO8W(0): /* transfer n*8 bits */ - spi_select(spi_fd[channel]); - nelem = (cmd >> 16) & IOCPARM_MASK; - if (baduaddr (addr) || baduaddr (addr + nelem - 1)) - return EFAULT; - spi_bulk_write(spi_fd[channel], nelem, cval); - spi_deselect(spi_fd[channel]); - break; - - case SPICTL_IO16W(0): /* transfer n*16 bits */ - nelem = (cmd >> 16) & IOCPARM_MASK; - if (((unsigned) addr & 1) || - baduaddr (addr) || baduaddr (addr + nelem*2 - 1)) - return EFAULT; - spi_bulk_write_16(spi_fd[channel], nelem<<1, (char *)addr); - break; - - case SPICTL_IO32W(0): /* transfer n*32 bits */ - nelem = (cmd >> 16) & IOCPARM_MASK; - if (((unsigned) addr & 3) || - baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) - return EFAULT; - spi_bulk_write_32(spi_fd[channel], nelem<<2, (char *)addr); - break; - - case SPICTL_IO32RB(0): /* transfer n*32 bits */ - nelem = (cmd >> 16) & IOCPARM_MASK; - if (((unsigned) addr & 3) || - baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) - return EFAULT; - spi_bulk_read_32_be(spi_fd[channel], nelem<<2, (char *)addr); - break; - - case SPICTL_IO32WB(0): /* transfer n*32 bits */ - nelem = (cmd >> 16) & IOCPARM_MASK; - if (((unsigned) addr & 3) || - baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) - return EFAULT; - spi_bulk_write_32_be(spi_fd[channel], nelem<<2, (char *)addr); - break; - - case SPICTL_IO32B(0): /* transfer n*32 bits */ - nelem = (cmd >> 16) & IOCPARM_MASK; - if (((unsigned) addr & 3) || - baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) - return EFAULT; - spi_bulk_write_32_be(spi_fd[channel], nelem<<2, (char *)addr); - break; -// - } - return 0; -} From 249b5716bb8da960e8d4dd25c9bf6fe32f8572f9 Mon Sep 17 00:00:00 2001 From: igor-m Date: Thu, 17 Apr 2014 01:17:06 +0200 Subject: [PATCH 22/24] Original spi.c and spi.h --- sys/include/spi.h | 34 +++++++++ sys/pic32/spi.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 sys/include/spi.h create mode 100644 sys/pic32/spi.c diff --git a/sys/include/spi.h b/sys/include/spi.h new file mode 100644 index 0000000..ef8f114 --- /dev/null +++ b/sys/include/spi.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1986 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +/* + * Ioctl definitions for SPI driver. + */ +#ifndef _SPI_H +#define _SPI_H + +#include + +#define SPICTL_SETMODE _IO ('p', 0) /* set SPI mode */ +#define SPICTL_SETRATE _IO ('p', 1) /* set clock rate, kHz */ +#define SPICTL_SETSELPIN _IO ('p', 2) /* set select pin */ +#define SPICTL_IO8(n) _ION('p', 3, n) /* transfer n*8 bits */ +#define SPICTL_IO16(n) _ION('p', 4, n) /* transfer n*16 bits */ +#define SPICTL_IO32(n) _ION('p', 5, n) /* transfer n*32 bits */ + +#ifdef KERNEL +#include "conf.h" + +extern const struct devspec spidevs[]; + +int spidev_open (dev_t dev, int flag, int mode); +int spidev_close (dev_t dev, int flag, int mode); +int spidev_read (dev_t dev, struct uio *uio, int flag); +int spidev_write (dev_t dev, struct uio *uio, int flag); +int spidev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag); +#endif + +#endif diff --git a/sys/pic32/spi.c b/sys/pic32/spi.c new file mode 100644 index 0000000..caf60c3 --- /dev/null +++ b/sys/pic32/spi.c @@ -0,0 +1,178 @@ +/* + * Generic SPI driver for PIC32. + * + * Copyright (C) 2012 Serge Vakulenko, + * + * Permission to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that the copyright notice and this + * permission notice and warranty disclaimer appear in supporting + * documentation, and that the name of the author not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * The author disclaim all warranties with regard to this + * software, including all implied warranties of merchantability + * and fitness. In no event shall the author be liable for any + * special, indirect or consequential damages or any damages + * whatsoever resulting from loss of use, data or profits, whether + * in an action of contract, negligence or other tortious action, + * arising out of or in connection with the use or performance of + * this software. + */ +#include "param.h" +#include "conf.h" +#include "user.h" +#include "ioctl.h" +#include "systm.h" +#include "uio.h" +#include "spi.h" +#include "spi_bus.h" + +const struct devspec spidevs[] = { + { 0, "spi1" }, + { 1, "spi2" }, + { 2, "spi3" }, + { 3, "spi4" }, + { 0, 0 } +}; + +#define NSPI 4 /* Ports SPI1...SPI4 */ + +/* + * To enable debug output, uncomment the first line. + */ +//#define PRINTDBG printf +#ifndef PRINTDBG +# define PRINTDBG(...) /*empty*/ +#endif + +int spi_fd[NSPI]; + +/* + * Open /dev/spi# device. + * Use default SPI parameters: + * - rate 250 kHz; + * - no sleect pin. + */ +int spidev_open (dev_t dev, int flag, int mode) +{ + int channel = minor (dev); + + if (channel >= NSPI) + return ENXIO; + + if (u.u_uid != 0) + return EPERM; + + spi_fd[channel] = spi_open(channel+1,NULL,NULL); + if(spi_fd[channel]==-1) + return ENODEV; + return 0; +} + +int spidev_close (dev_t dev, int flag, int mode) +{ + int channel = minor (dev); + + if (channel >= NSPI) + return ENXIO; + + if (u.u_uid != 0) + return EPERM; + + spi_close(spi_fd[channel]); + return 0; +} + +int spidev_read (dev_t dev, struct uio *uio, int flag) +{ + return 0; +} + +int spidev_write (dev_t dev, struct uio *uio, int flag) +{ + return 0; +} + +/* + * SPI control operations: + * - SPICTL_SETMODE - set clock polarity and phase + * - SPICTL_SETRATE - set data rate in kHz + * - SPICTL_SETSELPIN - set select pin + * - SPICTL_IO8(n) - n*8 bit transaction + * - SPICTL_IO16(n) - n*16 bit transaction + * - SPICTL_IO32(n) - n*32 bit transaction + */ +int spidev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag) +{ + int channel = minor (dev); + unsigned char *cval = (unsigned char *)addr; + int nelem; + static unsigned volatile *const tris[8] = { + 0, &TRISA,&TRISB,&TRISC,&TRISD,&TRISE,&TRISF,&TRISG, + }; + int mask, portnum; + + //PRINTDBG ("spi%d: ioctl (cmd=%08x, addr=%08x)\n", channel+1, cmd, addr); + if (channel >= NSPI) + return ENXIO; + + switch (cmd & ~(IOCPARM_MASK << 16)) { + default: + return ENODEV; + + case SPICTL_SETMODE: /* set SPI mode */ + /* --- Clock ---- + * Mode Polarity Phase + * 0 0 0 + * 1 0 1 + * 2 1 0 + * 3 1 1 + */ + if((unsigned int) addr & 0x01) + spi_set(spi_fd[channel], PIC32_SPICON_CKE); + if((unsigned int) addr & 0x02) + spi_set(spi_fd[channel], PIC32_SPICON_CKP); + return 0; + + case SPICTL_SETRATE: /* set clock rate, kHz */ + spi_brg(spi_fd[channel], (unsigned int) addr); + return 0; + + case SPICTL_SETSELPIN: /* set select pin */ + mask = 1 << ((unsigned int) addr & 15); + portnum = ((unsigned int) addr >> 8) & 7; + if (! portnum) + return 0; + spi_set_cspin(spi_fd[channel], (unsigned int *)tris[((unsigned int) addr >> 8) & 7], (unsigned int) addr & 15); + return 0; + + case SPICTL_IO8(0): /* transfer n*8 bits */ + spi_select(spi_fd[channel]); + nelem = (cmd >> 16) & IOCPARM_MASK; + if (baduaddr (addr) || baduaddr (addr + nelem - 1)) + return EFAULT; + spi_bulk_rw(spi_fd[channel], nelem, cval); + spi_deselect(spi_fd[channel]); + break; + + case SPICTL_IO16(0): /* transfer n*16 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 1) || + baduaddr (addr) || baduaddr (addr + nelem*2 - 1)) + return EFAULT; + spi_bulk_rw_16(spi_fd[channel], nelem<<1, (char *)addr); + break; + + case SPICTL_IO32(0): /* transfer n*32 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 3) || + baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) + return EFAULT; + spi_bulk_rw_32(spi_fd[channel], nelem<<2, (char *)addr); + break; + } + return 0; +} From 4783836659ba26fea9fc8d3fbcfeaf5889a0cba0 Mon Sep 17 00:00:00 2001 From: igor-m Date: Thu, 17 Apr 2014 19:49:40 +0200 Subject: [PATCH 23/24] New SPI IOCTL modi - R,W,RB,WB,RWB --- sys/include/spi.h | 13 +++++++ sys/pic32/spi.c | 90 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 100 insertions(+), 3 deletions(-) diff --git a/sys/include/spi.h b/sys/include/spi.h index ef8f114..1b670b1 100644 --- a/sys/include/spi.h +++ b/sys/include/spi.h @@ -15,10 +15,23 @@ #define SPICTL_SETMODE _IO ('p', 0) /* set SPI mode */ #define SPICTL_SETRATE _IO ('p', 1) /* set clock rate, kHz */ #define SPICTL_SETSELPIN _IO ('p', 2) /* set select pin */ + #define SPICTL_IO8(n) _ION('p', 3, n) /* transfer n*8 bits */ #define SPICTL_IO16(n) _ION('p', 4, n) /* transfer n*16 bits */ #define SPICTL_IO32(n) _ION('p', 5, n) /* transfer n*32 bits */ +#define SPICTL_IO8R(n) _ION('p', 6, n) /* transfer R n*8 bits */ +#define SPICTL_IO16R(n) _ION('p', 7, n) /* transfer R n*16 bits */ +#define SPICTL_IO32R(n) _ION('p', 8, n) /* transfer R n*32 bits */ + +#define SPICTL_IO8W(n) _ION('p', 9, n) /* transfer W n*8 bits */ +#define SPICTL_IO16W(n) _ION('p', 10, n) /* transfer W n*16 bits */ +#define SPICTL_IO32W(n) _ION('p', 11, n) /* transfer W n*32 bits */ + +#define SPICTL_IO32B(n) _ION('p', 12, n) /* transfer BE n*32 bits */ +#define SPICTL_IO32RB(n) _ION('p', 13, n) /* transfer RBE n*32 bits */ +#define SPICTL_IO32WB(n) _ION('p', 14, n) /* transfer WBE n*32 bits */ + #ifdef KERNEL #include "conf.h" diff --git a/sys/pic32/spi.c b/sys/pic32/spi.c index caf60c3..3f7fb94 100644 --- a/sys/pic32/spi.c +++ b/sys/pic32/spi.c @@ -101,9 +101,18 @@ int spidev_write (dev_t dev, struct uio *uio, int flag) * - SPICTL_SETMODE - set clock polarity and phase * - SPICTL_SETRATE - set data rate in kHz * - SPICTL_SETSELPIN - set select pin - * - SPICTL_IO8(n) - n*8 bit transaction - * - SPICTL_IO16(n) - n*16 bit transaction - * - SPICTL_IO32(n) - n*32 bit transaction + * - SPICTL_IO8(n) - n*8 bit RW transaction + * - SPICTL_IO16(n) - n*16 bit RW transaction + * - SPICTL_IO32(n) - n*32 bit RW transaction + * - SPICTL_IO8R(n) - n*8 bit R transaction + * - SPICTL_IO16R(n) - n*16 bit R transaction + * - SPICTL_IO32R(n) - n*32 bit R transaction + * - SPICTL_IO8W(n) - n*8 bit W transaction + * - SPICTL_IO16W(n) - n*16 bit W transaction + * - SPICTL_IO32W(n) - n*32 bit W transaction + * - SPICTL_IO32RB(n) - n*32 bit RB transaction (B - swaps byte's order) + * - SPICTL_IO32WB(n) - n*32 bit WB transaction + * - SPICTL_IO32B(n) - n*32 bit B transaction */ int spidev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag) { @@ -173,6 +182,81 @@ int spidev_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag) return EFAULT; spi_bulk_rw_32(spi_fd[channel], nelem<<2, (char *)addr); break; +// IM: added R and W and BE modes + case SPICTL_IO8R(0): /* transfer n*8 bits */ + spi_select(spi_fd[channel]); + nelem = (cmd >> 16) & IOCPARM_MASK; + if (baduaddr (addr) || baduaddr (addr + nelem - 1)) + return EFAULT; + spi_bulk_read(spi_fd[channel], nelem, cval); + spi_deselect(spi_fd[channel]); + break; + + case SPICTL_IO16R(0): /* transfer n*16 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 1) || + baduaddr (addr) || baduaddr (addr + nelem*2 - 1)) + return EFAULT; + spi_bulk_read_16(spi_fd[channel], nelem<<1, (char *)addr); + break; + + case SPICTL_IO32R(0): /* transfer n*32 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 3) || + baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) + return EFAULT; + spi_bulk_read_32(spi_fd[channel], nelem<<2, (char *)addr); + break; + + case SPICTL_IO8W(0): /* transfer n*8 bits */ + spi_select(spi_fd[channel]); + nelem = (cmd >> 16) & IOCPARM_MASK; + if (baduaddr (addr) || baduaddr (addr + nelem - 1)) + return EFAULT; + spi_bulk_write(spi_fd[channel], nelem, cval); + spi_deselect(spi_fd[channel]); + break; + + case SPICTL_IO16W(0): /* transfer n*16 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 1) || + baduaddr (addr) || baduaddr (addr + nelem*2 - 1)) + return EFAULT; + spi_bulk_write_16(spi_fd[channel], nelem<<1, (char *)addr); + break; + + case SPICTL_IO32W(0): /* transfer n*32 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 3) || + baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) + return EFAULT; + spi_bulk_write_32(spi_fd[channel], nelem<<2, (char *)addr); + break; + + case SPICTL_IO32RB(0): /* transfer n*32 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 3) || + baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) + return EFAULT; + spi_bulk_read_32_be(spi_fd[channel], nelem<<2, (char *)addr); + break; + + case SPICTL_IO32WB(0): /* transfer n*32 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 3) || + baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) + return EFAULT; + spi_bulk_write_32_be(spi_fd[channel], nelem<<2, (char *)addr); + break; + + case SPICTL_IO32B(0): /* transfer n*32 bits */ + nelem = (cmd >> 16) & IOCPARM_MASK; + if (((unsigned) addr & 3) || + baduaddr (addr) || baduaddr (addr + nelem*4 - 1)) + return EFAULT; + spi_bulk_write_32_be(spi_fd[channel], nelem<<2, (char *)addr); + break; +// } return 0; } From 6ce8e28a85a52e461d48134b24b55961f38f2048 Mon Sep 17 00:00:00 2001 From: igor-m Date: Sat, 19 Apr 2014 09:50:04 +0200 Subject: [PATCH 24/24] Fix of 16byte stack alignment, doprnt.c does not require va_arg fix now --- src/libc/stdio/doprnt.c | 24 ++---------------------- sys/include/signal.h | 1 + sys/kernel/kern_exec.c | 2 +- 3 files changed, 4 insertions(+), 23 deletions(-) diff --git a/src/libc/stdio/doprnt.c b/src/libc/stdio/doprnt.c index b5137b4..7cc4bf6 100644 --- a/src/libc/stdio/doprnt.c +++ b/src/libc/stdio/doprnt.c @@ -53,11 +53,6 @@ static unsigned char mkhex (unsigned char ch); static int cvt (double number, int prec, int sharpflag, unsigned char *negp, unsigned char fmtch, unsigned char *startp, unsigned char *endp); -// union { -// unsigned long u32; -// va_list ap32; -// } x; - int _doprnt (char const *fmt, va_list ap, FILE *stream) { @@ -69,7 +64,6 @@ _doprnt (char const *fmt, va_list ap, FILE *stream) unsigned long ul; double d; - unsigned long *da; if (! stream) return 0; @@ -372,22 +366,8 @@ number: if (sign && ((long) ul != 0L)) { case 'g': case 'G': { - // --- IM - vaarg alignment issue fix: - - da = (unsigned long *) ≈ - - unsigned long *l = (unsigned long *) &d; - - if ( ((unsigned long)da) & 4) { // maj_II - l[0]= va_arg(ap, unsigned long); - l[1]= va_arg(ap, unsigned long); - } - else { - l[0]= va_arg(ap, unsigned long); - l[0]= va_arg(ap, unsigned long); - l[1]= va_arg(ap, unsigned long); - } - + // ---va_arg alignment fix + d = va_arg(ap, double); // --- /* diff --git a/sys/include/signal.h b/sys/include/signal.h index 475dd43..119608d 100644 --- a/sys/include/signal.h +++ b/sys/include/signal.h @@ -113,6 +113,7 @@ struct sigstack { struct sigcontext { int sc_onstack; /* sigstack state to restore */ long sc_mask; /* signal mask to restore */ + int sc_align[2]; /* align to 16 bytes */ int sc_r1; /* r1 to restore */ int sc_r2; /* and other registers */ int sc_r3; diff --git a/sys/kernel/kern_exec.c b/sys/kernel/kern_exec.c index 18cfbbf..ee9d404 100755 --- a/sys/kernel/kern_exec.c +++ b/sys/kernel/kern_exec.c @@ -432,7 +432,7 @@ badarg: */ ucp = USER_DATA_END - nc - NBPW; ap = ucp - na*NBPW - 2*NBPW; - u.u_frame [FRAME_SP] = ap - 16; + u.u_frame [FRAME_SP] = (ap - 16) & ~0xf; /* align to 16 bytes */ u.u_frame [FRAME_R4] = na - ne; /* $a0 := argc */ u.u_frame [FRAME_R5] = ap; /* $a1 := argv */ u.u_frame [FRAME_R6] = ap + (na-ne+1)*NBPW; /* $a2 := env */