+2001-11-07 Michael Hope <michaelh@juju.net.nz>
+
+ * 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 <bernhard@bernhardheld.de>
* sdcc/sim/ucsim/s51.src/glob.cc: Minor fix.
_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)
#include <limits.h>
+signed long __fs2slong (float f);
+
/* convert float to signed char */
signed char __fs2schar (float f) {
signed long sl=__fs2slong(f);
#include <limits.h>
+signed long __fs2slong (float f);
+
/* convert float to signed int */
signed int __fs2sint (float f) {
signed long sl=__fs2slong(f);
#include <limits.h>
+unsigned long __fs2ulong (float a1);
+
/* convert float to signed long */
signed long __fs2slong (float f) {
#include <limits.h>
+unsigned long __fs2ulong (float a1);
+
/* convert float to unsigned char */
unsigned char __fs2uchar (float f) {
unsigned long ul=__fs2ulong(f);
#include <limits.h>
+unsigned long __fs2ulong (float a1);
+
/* convert float to unsigned int */
unsigned int __fs2uint (float f) {
unsigned long ul=__fs2ulong(f);
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;
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;
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++;
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);
+float __slong2fs (long a );
+
/* convert signed char to float */
float __schar2fs (signed char sc) {
signed long sl=sc;
+float __slong2fs (signed long sl);
+
/* convert signed int to float */
float __sint2fs (signed int si) {
signed long sl=si;
+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
+float __ulong2fs (unsigned long a );
+
/* convert unsigned char to float */
float __uchar2fs (unsigned char uc) {
unsigned long ul=uc;
+float __ulong2fs (unsigned long a );
+
/* convert unsigned int to float */
float __uint2fs (unsigned int ui) {
unsigned long ul=ui;
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)
--- /dev/null
+ ;; Stubs to match between function names
+ .area _CODE
+
+___slong2fs_rrx_s::
+ jp ___slong2fs
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)
--- /dev/null
+ ;; Stubs to match between function names
+ .area _CODE
+
+___slong2fs_rrx_s::
+ jp ___slong2fs
aopGetLitWordLong (asmop * aop, int offset, bool with_hash)
{
char *s = buffer;
- char *rs;
/* depending on type */
switch (aop->type)
}
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:
}
}
+/*-----------------------------------------------------------------*/
+/* 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 */
/*-----------------------------------------------------------------*/
/* 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));
emit2 ("sub a,!one");
outBitC (IC_RESULT (ic));
+ release:
/* release the aops */
freeAsmop (IC_LEFT (ic), NULL, ic);
freeAsmop (IC_RESULT (ic), NULL, ic);
_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 */
/*-----------------------------------------------------------------*/
/* 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;
}
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))));
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;
} 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
%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
+}
{
iCode *uic;
+ /* PENDING: Could do IFX */
+ if (ic->op == IFX)
+ {
+ return;
+ }
+
/* has only one definition */
if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1)
{
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)
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;
}
ic->op != '=' &&
ic->op != EQ_OP &&
ic->op != CAST &&
+ ic->op != GETHBIT &&
1)
{
D (D_ACCUSE2, (" + Dropping as not a 'good' source command\n"));
#include <testfwk.h>
/* Set to one to show the bug */
-#if 0
+#if 1
#define NAME(_a) _a
#else
#define NAME(_a)
};
int
-initProxy(void)
+initProxy(devsw_t *pdrv)
{
- return (*_sillyDriver.dev_init)(5);
+ return (*pdrv->dev_init)(5);
}
--- /dev/null
+/* Simple floating pt tests.
+ */
+#include <testfwk.h>
+
+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));
+}