From 07df12abd9fe9f3ff2fa7edb177ff5e38a78324c Mon Sep 17 00:00:00 2001 From: michaelh Date: Wed, 7 Nov 2001 21:17:05 +0000 Subject: [PATCH] * src/z80/ralloc.c (packRegsForHLUse): Banned IFXs from being packed into HL. (packRegsForHLUse): Added rule to pack address of/pointer get for itemps into HL for the Z80. (packRegsForAccUse2): Added rule to pack hbit IFXs into A. * src/z80/main.c (_setDefaultOptions): Made float code re-entrant by default. * src/z80/gen.c (aopGetLitWordLong): Added word support for floats. (genNotFloat): Added. (genUminusFloat): Added. * device/lib/z80/Makefile: Added floating pt stubs. * device/lib/Makefile.in (Z80SOURCES): Added floating pt support. * src/z80/gen.c (genIpush): Fixed up a push of one byte when left is in a pair. * device/lib/_fsadd.c (__fsadd): Fixed up return where the numbers are hugely different. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1524 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 20 +++++ device/lib/Makefile.in | 9 ++- device/lib/_fs2schar.c | 2 + device/lib/_fs2sint.c | 2 + device/lib/_fs2slong.c | 2 + device/lib/_fs2uchar.c | 2 + device/lib/_fs2uint.c | 2 + device/lib/_fsadd.c | 12 +-- device/lib/_schar2fs.c | 2 + device/lib/_sint2fs.c | 2 + device/lib/_slong2fs.c | 6 +- device/lib/_uchar2fs.c | 2 + device/lib/_uint2fs.c | 2 + device/lib/gbz80/Makefile | 2 +- device/lib/gbz80/fstubs.s | 5 ++ device/lib/z80/Makefile | 3 +- device/lib/z80/fstubs.s | 5 ++ src/z80/gen.c | 99 ++++++++++++++++++++++--- src/z80/main.c | 1 + src/z80/peeph.def | 25 ++++++- src/z80/ralloc.c | 19 ++++- support/regression/tests/driverstruct.c | 6 +- support/regression/tests/float.c | 25 +++++++ 23 files changed, 229 insertions(+), 26 deletions(-) create mode 100644 device/lib/gbz80/fstubs.s create mode 100644 device/lib/z80/fstubs.s create mode 100644 support/regression/tests/float.c diff --git a/ChangeLog b/ChangeLog index a5c420c2..11b1f65a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2001-11-07 Michael Hope + + * src/z80/ralloc.c (packRegsForHLUse): Banned IFXs from being packed into HL. + (packRegsForHLUse): Added rule to pack address of/pointer get for itemps into HL for the Z80. + (packRegsForAccUse2): Added rule to pack hbit IFXs into A. + + * src/z80/main.c (_setDefaultOptions): Made float code re-entrant by default. + + * src/z80/gen.c (aopGetLitWordLong): Added word support for floats. + (genNotFloat): Added. + (genUminusFloat): Added. + + * device/lib/z80/Makefile: Added floating pt stubs. + + * device/lib/Makefile.in (Z80SOURCES): Added floating pt support. + + * src/z80/gen.c (genIpush): Fixed up a push of one byte when left is in a pair. + + * device/lib/_fsadd.c (__fsadd): Fixed up return where the numbers are hugely different. + 2001-11-07 Bernhard Held * sdcc/sim/ucsim/s51.src/glob.cc: Minor fix. diff --git a/device/lib/Makefile.in b/device/lib/Makefile.in index 102f62ab..4f282582 100644 --- a/device/lib/Makefile.in +++ b/device/lib/Makefile.in @@ -75,7 +75,14 @@ Z80SOURCES = _atoi.c \ _modslong.c _modulong.c \ _mullong.c \ _divslong.c _divulong.c \ - malloc.c + malloc.c \ + _fs2schar.c _fs2sint.c _fs2slong.c \ + _fs2uchar.c _fs2uint.c _fs2ulong.c _fsadd.c \ + _fsdiv.c _fseq.c _fsgt.c _fslt.c _fsmul.c \ + _fsneq.c _fssub.c \ + _uchar2fs.c _uint2fs.c \ + _ulong2fs.c \ + _slong2fs.c _sint2fs.c _schar2fs.c Z80OBJECTS = $(Z80SOURCES:%.c=$(PORTDIR)/%.o) diff --git a/device/lib/_fs2schar.c b/device/lib/_fs2schar.c index c804e710..b783ea59 100644 --- a/device/lib/_fs2schar.c +++ b/device/lib/_fs2schar.c @@ -1,5 +1,7 @@ #include +signed long __fs2slong (float f); + /* convert float to signed char */ signed char __fs2schar (float f) { signed long sl=__fs2slong(f); diff --git a/device/lib/_fs2sint.c b/device/lib/_fs2sint.c index bb578292..dd49c4e7 100644 --- a/device/lib/_fs2sint.c +++ b/device/lib/_fs2sint.c @@ -1,5 +1,7 @@ #include +signed long __fs2slong (float f); + /* convert float to signed int */ signed int __fs2sint (float f) { signed long sl=__fs2slong(f); diff --git a/device/lib/_fs2slong.c b/device/lib/_fs2slong.c index 82f9255f..1c3aec8c 100644 --- a/device/lib/_fs2slong.c +++ b/device/lib/_fs2slong.c @@ -1,5 +1,7 @@ #include +unsigned long __fs2ulong (float a1); + /* convert float to signed long */ signed long __fs2slong (float f) { diff --git a/device/lib/_fs2uchar.c b/device/lib/_fs2uchar.c index 3bfa951e..68e4c679 100644 --- a/device/lib/_fs2uchar.c +++ b/device/lib/_fs2uchar.c @@ -1,5 +1,7 @@ #include +unsigned long __fs2ulong (float a1); + /* convert float to unsigned char */ unsigned char __fs2uchar (float f) { unsigned long ul=__fs2ulong(f); diff --git a/device/lib/_fs2uint.c b/device/lib/_fs2uint.c index 0eaa2edf..464a729e 100644 --- a/device/lib/_fs2uint.c +++ b/device/lib/_fs2uint.c @@ -1,5 +1,7 @@ #include +unsigned long __fs2ulong (float a1); + /* convert float to unsigned int */ unsigned int __fs2uint (float f) { unsigned long ul=__fs2ulong(f); diff --git a/device/lib/_fsadd.c b/device/lib/_fsadd.c index be0b44fc..a4273d9a 100644 --- a/device/lib/_fsadd.c +++ b/device/lib/_fsadd.c @@ -19,7 +19,7 @@ __fsadd (float a1, float a2) volatile long mant1, mant2; volatile union float_long fl1, fl2; volatile int exp1, exp2; - volatile long sign = 0; + volatile unsigned long sign = 0; fl1.f = a1; fl2.f = a2; @@ -34,9 +34,9 @@ __fsadd (float a1, float a2) exp2 = EXP (fl2.l); if (exp1 > exp2 + 25) - return (fl1.l); + return (fl1.f); if (exp2 > exp1 + 25) - return (fl2.l); + return (fl2.f); /* do everything in excess precision so's we can round later */ mant1 = MANT (fl1.l) << 6; @@ -67,14 +67,14 @@ __fsadd (float a1, float a2) return (0); /* normalize up */ - while (!(mant1 & (unsigned long) 0xE0000000)) + while (!((unsigned long)mant1 & (unsigned long) 0xE0000000)) { mant1 <<= 1; exp1--; } /* normalize down? */ - if (mant1 & (unsigned long)(1 << 30)) + if ((unsigned long)mant1 & (unsigned long)(1 << 30)) { mant1 >>= 1 ; exp1++; @@ -94,7 +94,7 @@ __fsadd (float a1, float a2) mant1 >>= 6; /* turn off hidden bit */ - mant1 &= ~HIDDEN; + mant1 = (unsigned long)mant1 & ~HIDDEN; /* pack up and go home */ fl1.l = PACK (sign, (unsigned long) exp1, mant1); diff --git a/device/lib/_schar2fs.c b/device/lib/_schar2fs.c index d3227fff..f7c90f33 100644 --- a/device/lib/_schar2fs.c +++ b/device/lib/_schar2fs.c @@ -1,3 +1,5 @@ +float __slong2fs (long a ); + /* convert signed char to float */ float __schar2fs (signed char sc) { signed long sl=sc; diff --git a/device/lib/_sint2fs.c b/device/lib/_sint2fs.c index 679eaf7d..4ee9c800 100644 --- a/device/lib/_sint2fs.c +++ b/device/lib/_sint2fs.c @@ -1,3 +1,5 @@ +float __slong2fs (signed long sl); + /* convert signed int to float */ float __sint2fs (signed int si) { signed long sl=si; diff --git a/device/lib/_slong2fs.c b/device/lib/_slong2fs.c index 0b1e2259..11516e4f 100644 --- a/device/lib/_slong2fs.c +++ b/device/lib/_slong2fs.c @@ -1,5 +1,9 @@ +float +__ulong2fs (unsigned long a ); + /* convert signed long to float */ -float __slong2fs (signed long sl) { +float __slong2fs (signed long sl) +{ if (sl<0) return -__ulong2fs(-sl); else diff --git a/device/lib/_uchar2fs.c b/device/lib/_uchar2fs.c index 3c9633e8..47525301 100644 --- a/device/lib/_uchar2fs.c +++ b/device/lib/_uchar2fs.c @@ -1,3 +1,5 @@ +float __ulong2fs (unsigned long a ); + /* convert unsigned char to float */ float __uchar2fs (unsigned char uc) { unsigned long ul=uc; diff --git a/device/lib/_uint2fs.c b/device/lib/_uint2fs.c index 9a78b4c9..514c0211 100644 --- a/device/lib/_uint2fs.c +++ b/device/lib/_uint2fs.c @@ -1,3 +1,5 @@ +float __ulong2fs (unsigned long a ); + /* convert unsigned int to float */ float __uint2fs (unsigned int ui) { unsigned long ul=ui; diff --git a/device/lib/gbz80/Makefile b/device/lib/gbz80/Makefile index 40480d66..e41c61f2 100644 --- a/device/lib/gbz80/Makefile +++ b/device/lib/gbz80/Makefile @@ -5,7 +5,7 @@ TOPDIR = ../../.. SCC = $(TOPDIR)/bin/sdcc -mgbz80 SAS = $(TOPDIR)/bin/as-gbz80 -OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o heap.o +OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o heap.o fstubs.o LIB = gbz80.lib CC = $(SCC) diff --git a/device/lib/gbz80/fstubs.s b/device/lib/gbz80/fstubs.s new file mode 100644 index 00000000..3d5f6107 --- /dev/null +++ b/device/lib/gbz80/fstubs.s @@ -0,0 +1,5 @@ + ;; Stubs to match between function names + .area _CODE + +___slong2fs_rrx_s:: + jp ___slong2fs diff --git a/device/lib/z80/Makefile b/device/lib/z80/Makefile index cda0855e..ae0e16f4 100644 --- a/device/lib/z80/Makefile +++ b/device/lib/z80/Makefile @@ -5,7 +5,8 @@ TOPDIR = ../../.. SCC = $(TOPDIR)/bin/sdcc -mz80 SAS = $(TOPDIR)/bin/as-z80 -OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o heap.o +OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o heap.o \ + fstubs.o LIB = z80.lib CC = $(SCC) diff --git a/device/lib/z80/fstubs.s b/device/lib/z80/fstubs.s new file mode 100644 index 00000000..3d5f6107 --- /dev/null +++ b/device/lib/z80/fstubs.s @@ -0,0 +1,5 @@ + ;; Stubs to match between function names + .area _CODE + +___slong2fs_rrx_s:: + jp ___slong2fs diff --git a/src/z80/gen.c b/src/z80/gen.c index b9e9569a..7515252e 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -940,7 +940,6 @@ char * aopGetLitWordLong (asmop * aop, int offset, bool with_hash) { char *s = buffer; - char *rs; /* depending on type */ switch (aop->type) @@ -994,15 +993,27 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash) } else { - /* A float */ - Z80_FLOAT f; - convertFloat (&f, floatFromVal (val)); + union { + float f; + unsigned char c[4]; + } + fl; + unsigned int i; + + /* it is type float */ + fl.f = (float) floatFromVal (val); + +#ifdef _BIG_ENDIAN + i = fl.c[3-offset] | (fl.c[3-offset-1]<<8); +#else + i = fl.c[offset] | (fl.c[offset+1]<<8); +#endif if (with_hash) - tsprintf (buffer, "!immedword", f.w[offset / 2]); + tsprintf (buffer, "!immedword", i); else - tsprintf (buffer, "!constword", f.w[offset / 2]); - rs = Safe_calloc (1, strlen (buffer) + 1); - return strcpy (rs, buffer); + tsprintf (buffer, "!constword", i); + + return traceAlloc(&_G.trace.aops, Safe_strdup(buffer)); } } default: @@ -1787,6 +1798,44 @@ _toBoolean (operand * oper) } } +/*-----------------------------------------------------------------*/ +/* genNotFloat - generates not for float operations */ +/*-----------------------------------------------------------------*/ +static void +genNotFloat (operand * op, operand * res) +{ + int size, offset; + symbol *tlbl; + + emitDebug ("; genNotFloat"); + + /* we will put 127 in the first byte of + the result */ + aopPut (AOP (res), "!immedbyte", 0x7F); + size = AOP_SIZE (op) - 1; + offset = 1; + + _moveA (aopGet (op->aop, offset++, FALSE)); + + while (size--) + { + emit2 ("or a,%s", aopGet (op->aop, offset++, FALSE)); + } + + tlbl = newiTempLabel (NULL); + aopPut (res->aop, "!one", 1); + emit2 ("!shortjp z !tlabel", tlbl->key + 100); + aopPut (res->aop, "!zero", 1); + + emitLabel(tlbl->key + 100); + + size = res->aop->size - 2; + offset = 2; + /* put zeros in the rest */ + while (size--) + aopPut (res->aop, "!zero", offset++); +} + /*-----------------------------------------------------------------*/ /* genNot - generate code for ! operation */ /*-----------------------------------------------------------------*/ @@ -1808,7 +1857,8 @@ genNot (iCode * ic) /* if type float then do float */ if (IS_FLOAT (optype)) { - wassertl (0, "Tried to negate a float"); + genNotFloat (IC_LEFT (ic), IC_RESULT (ic)); + goto release; } _toBoolean (IC_LEFT (ic)); @@ -1820,6 +1870,7 @@ genNot (iCode * ic) emit2 ("sub a,!one"); outBitC (IC_RESULT (ic)); + release: /* release the aops */ freeAsmop (IC_LEFT (ic), NULL, ic); freeAsmop (IC_RESULT (ic), NULL, ic); @@ -1914,6 +1965,32 @@ _gbz80_emitAddSubLong (iCode *ic, bool isAdd) _gbz80_emitAddSubLongLong (ic, AOP (IC_LEFT (ic)), AOP (IC_RIGHT (ic)), isAdd); } +/*-----------------------------------------------------------------*/ +/* genUminusFloat - unary minus for floating points */ +/*-----------------------------------------------------------------*/ +static void +genUminusFloat (operand * op, operand * result) +{ + int size, offset = 0; + + emitDebug("; genUminusFloat"); + + /* for this we just need to flip the + first it then copy the rest in place */ + size = AOP_SIZE (op) - 1; + + _moveA(aopGet (AOP (op), MSB32, FALSE)); + + emit2("xor a,!immedbyte", 0x80); + aopPut (AOP (result), "a", MSB32); + + while (size--) + { + aopPut (AOP (result), aopGet (AOP (op), offset, FALSE), offset); + offset++; + } +} + /*-----------------------------------------------------------------*/ /* genUminus - unary minus code generation */ /*-----------------------------------------------------------------*/ @@ -1942,7 +2019,7 @@ genUminus (iCode * ic) /* if float then do float stuff */ if (IS_FLOAT (optype)) { - wassertl (0, "Tried to do a unary minus on a float"); + genUminusFloat (IC_LEFT (ic), IC_RESULT (ic)); goto release; } @@ -2140,7 +2217,7 @@ genIpush (iCode * ic) size = AOP_SIZE (IC_LEFT (ic)); - if (isPair (AOP (IC_LEFT (ic)))) + if (isPair (AOP (IC_LEFT (ic))) && size == 2) { _G.stack.pushed += 2; emit2 ("push %s", getPairName (AOP (IC_LEFT (ic)))); diff --git a/src/z80/main.c b/src/z80/main.c index d2b2639c..7727275f 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -320,6 +320,7 @@ _setDefaultOptions (void) options.mainreturn = 1; /* first the options part */ options.intlong_rent = 1; + options.float_rent = 1; options.noRegParams = 1; /* Default code and data locations. */ options.code_loc = 0x200; diff --git a/src/z80/peeph.def b/src/z80/peeph.def index e29001de..a00fd659 100644 --- a/src/z80/peeph.def +++ b/src/z80/peeph.def @@ -96,12 +96,18 @@ replace restart { } by { xor a,a } -replace restart { +replace { ld e,#0x00 ld d,#0x00 } by { ld de,#0x0000 } +replace { + ld l,#0x00 + ld h,#0x00 +} by { + ld hl,#0x0000 +} replace restart { ld %1,a ld a,%1 @@ -119,3 +125,20 @@ replace restart { %2: jp %4 } +replace { + ld l,e + ld h,d + push hl + ld l,c + ld h,b + push hl +} by { + push de + push bc +} +replace { + and a,#%1 + or a,a +} by { + and a,#%1 +} diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index dd248b71..59ee73c6 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -2018,6 +2018,12 @@ packRegsForHLUse (iCode * ic) { iCode *uic; + /* PENDING: Could do IFX */ + if (ic->op == IFX) + { + return; + } + /* has only one definition */ if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1) { @@ -2046,9 +2052,17 @@ packRegsForHLUse (iCode * ic) return; } - if (getSize (operandType (IC_RESULT (ic))) != 2) + if (uic->op ==IFX) + { + return; + } + + if (getSize (operandType (IC_RESULT (ic))) != 2 || + (IC_LEFT(uic) && getSize (operandType (IC_LEFT (uic))) != 2) || + (IC_RIGHT(uic) && getSize (operandType (IC_RIGHT (uic))) != 2)) { D (D_HLUSE, (" + Dropping as the result size is not 2\n")); + return; } if (IS_Z80) @@ -2057,6 +2071,8 @@ packRegsForHLUse (iCode * ic) goto hluse; if (ic->op == ADDRESS_OF && uic->op == IPUSH) goto hluse; + if (ic->op == ADDRESS_OF && POINTER_GET (uic) && IS_ITEMP( IC_RESULT (uic))) + goto hluse; if (ic->op == CALL && ic->parmBytes == 0 && (uic->op == '-' || uic->op == '+')) goto hluse; } @@ -2223,6 +2239,7 @@ packRegsForAccUse2 (iCode * ic) ic->op != '=' && ic->op != EQ_OP && ic->op != CAST && + ic->op != GETHBIT && 1) { D (D_ACCUSE2, (" + Dropping as not a 'good' source command\n")); diff --git a/support/regression/tests/driverstruct.c b/support/regression/tests/driverstruct.c index 542c2db3..0a9c4aa6 100644 --- a/support/regression/tests/driverstruct.c +++ b/support/regression/tests/driverstruct.c @@ -4,7 +4,7 @@ #include /* Set to one to show the bug */ -#if 0 +#if 1 #define NAME(_a) _a #else #define NAME(_a) @@ -38,8 +38,8 @@ static devsw_t _sillyDriver = { }; int -initProxy(void) +initProxy(devsw_t *pdrv) { - return (*_sillyDriver.dev_init)(5); + return (*pdrv->dev_init)(5); } diff --git a/support/regression/tests/float.c b/support/regression/tests/float.c new file mode 100644 index 00000000..2a421144 --- /dev/null +++ b/support/regression/tests/float.c @@ -0,0 +1,25 @@ +/* Simple floating pt tests. + */ +#include + +void +testFloatAdd(void) +{ + volatile float result, left, right; + + left = 4; + right = 5; + ASSERT(left+right == 9); + + left = 7; + right = -3; + ASSERT(left+right == 4); + + left = -1234; + right = 409; + ASSERT(left+right == (-1234+409)); + + left = -34567; + right = -123456; + ASSERT(left+right == (-34567-123456)); +} -- 2.30.2