+2001-10-21 Michael Hope <michaelh@juju.net.nz>
+
+ * src/z80/ralloc.c: Turned off faulty pack for one use.
+
+ * src/z80/peeph-gbz80.def: Removed redundent restart options.
+
+ * src/z80/gen.c (genMult): Added native mul for constants on the z80 and gbz80.
+
2001-10-21 Bernhard Held <bernhard@bernhardheld.de>
* support/regression/Makefile: Improved clean
* support/regression/ports/mcs51/timeout.c: little improvements
+2001-10-17 Michael Hope <michaelh@juju.net.nz>
+
+ * device/lib/malloc.c (MEMHEADER): Fixed against new pedantic pointers.
+
+ * support/regression/fwk/include/testfwk.h: Fixed up to use function pts correctly.
+
+ * support/regression/generate-cases.py: Fixed up to use function pts correctly.
2001-10-16 Bernhard Held <bernhard@bernhardheld.de>
* support/regression/port/mcs51/timeout.c: add timeout for uCsim
2001-10-13 Michael Hope <michaelh@juju.net.nz>
+ * src/z80/gen.c (emitCall): Fixed up missing spill of HL when used to assign the result value.
+
+ * src/z80/ralloc.c: Turned off pack for one use as it's quite broken.
* src/SDCCmain.c (linkEdit): Added support for passing a legacy command line through the processor.
/* if long / int mult or divide or mod */
if (ic->op == '*' || ic->op == '/' || ic->op == '%')
{
- sym_link *type = operandType (IC_LEFT (ic));
- if (IS_INTEGRAL (type) && getSize (type) > port->support.muldiv)
+ sym_link *leftType = operandType (IC_LEFT (ic));
+
+ if (IS_INTEGRAL (leftType) && getSize (leftType) > port->support.muldiv)
{
- convilong (ic, ebbs[i], type, ic->op);
+ sym_link *rightType = operandType (IC_RIGHT (ic));
+
+ if (port->hasNativeMulFor != NULL &&
+ port->hasNativeMulFor (ic, leftType, rightType))
+ {
+ /* Leave as native */
+ }
+ else
+ {
+ convilong (ic, ebbs[i], leftType, ic->op);
+ }
}
}
lbp = lb;
l = pl->line;
+
while (*l)
{
/* if the line contains a variable */
/* for all rules */
for (pr = rootRules; pr; pr = pr->next)
{
- fflush(stdout);
-
for (spl = *pls; spl; spl = spl->next)
{
/* if inline assembler then no peep hole */
continue;
mtail = NULL;
-
+
/* Tidy up any data stored in the hTab */
/* if it matches */
_avr_regparm,
NULL,
NULL,
+ NULL,
FALSE,
0, /* leave lt */
1, /* transform gt ==> not le */
_ds390_regparm,
NULL,
NULL,
+ NULL,
FALSE,
0, /* leave lt */
0, /* leave gt */
_i186_regparm,
NULL,
NULL,
+ NULL,
FALSE,
0, /* leave lt */
0, /* leave gt */
_tlcs900h_regparm,
NULL,
NULL,
+ NULL,
FALSE,
0, /* leave lt */
0, /* leave gt */
_mcs51_regparm,
NULL,
NULL,
+ NULL,
FALSE,
0, /* leave lt */
0, /* leave gt */
_pic14_regparm,
NULL,
NULL,
+ NULL,
FALSE,
0, /* leave lt */
0, /* leave gt */
#ifndef PORT_INCLUDE
#define PORT_INCLUDE
+#include "SDCCicode.h"
+
#define TARGET_ID_MCS51 1
#define TARGET_ID_GBZ80 2
#define TARGET_ID_Z80 3
*/
char *(*getMangledFunctionName) (char *szOrginial);
+ /** Returns true if the port can multiply the two types nativly
+ without using support functions.
+ */
+ bool (*hasNativeMulFor) (iCode *ic, sym_link *left, sym_link *right);
+
/** If TRUE, then tprintf and !dw will be used for some initalisers
*/
bool use_dw_for_init;
return FALSE;
}
}
+
+static void
+spillPair (PAIR_ID pairId)
+{
+ _G.pairs[pairId].last_type = AOP_INVALID;
+ _G.pairs[pairId].base = NULL;
+}
+
/** Push a register pair onto the stack */
void
genPairPush (asmop * aop)
{
emit2 ("pop %s", _pairs[pairId].name);
_G.stack.pushed -= 2;
+ spillPair (pairId);
}
/*-----------------------------------------------------------------*/
}
}
-static void
-spillPair (PAIR_ID pairId)
-{
- _G.pairs[pairId].last_type = AOP_INVALID;
- _G.pairs[pairId].base = NULL;
-}
-
static void
spillCached (void)
{
if (i)
emit2 ("inc sp");
}
- spillCached ();
}
}
+ spillCached ();
+
if (_G.stack.pushedDE)
{
bool dInUse = bitVectBitValue(rInUse, D_IDX);
goto release;
}
+ if (isPair (AOP (IC_RIGHT (ic))) && AOP_TYPE (IC_LEFT (ic)) == AOP_IMMD)
+ {
+ fetchPair (PAIR_HL, AOP (IC_LEFT (ic)));
+ emit2 ("add hl,%s", getPairName (AOP (IC_RIGHT (ic))));
+ spillCached();
+ commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
+ goto release;
+ }
+
/* Special case:
ld hl,sp+n trashes C so we cant afford to do it during an
add with stack based varibles. Worst case is:
static void
genMult (iCode * ic)
{
+ int val;
+ int count, i;
+ /* If true then the final operation should be a subtract */
+ bool active = FALSE;
+
/* Shouldn't occur - all done through function calls */
- wassertl (0, "Multiplication is handled through support function calls");
+ aopOp (IC_LEFT (ic), ic, FALSE, FALSE);
+ aopOp (IC_RIGHT (ic), ic, FALSE, FALSE);
+ aopOp (IC_RESULT (ic), ic, TRUE, FALSE);
+
+ if (AOP_SIZE (IC_LEFT (ic)) > 2 ||
+ AOP_SIZE (IC_RIGHT (ic)) > 2 ||
+ AOP_SIZE (IC_RESULT (ic)) > 2)
+ {
+ wassertl (0, "Multiplication is handled through support function calls");
+ }
+
+ /* Swap left and right such that right is a literal */
+ if ((AOP_TYPE (IC_LEFT (ic)) == AOP_LIT))
+ {
+ operand *t = IC_RIGHT (ic);
+ IC_RIGHT (ic) = IC_LEFT (ic);
+ IC_LEFT (ic) = t;
+ }
+
+ wassertl (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT, "Right must be a literal");
+
+ val = (int)floatFromVal ( AOP (IC_RIGHT (ic))->aopu.aop_lit);
+ // wassertl (val > 0, "Multiply must be positive");
+ wassertl (val != 1, "Can't multiply by 1");
+
+ if (IS_Z80) {
+ _push (PAIR_DE);
+ }
+
+ if ( AOP_SIZE (IC_LEFT (ic)) == 1 && !SPEC_USIGN (getSpec (operandType ( IC_LEFT (ic)))))
+ {
+ emit2 ("ld e,%s", aopGet (AOP (IC_LEFT (ic)), LSB, FALSE));
+ emit2 ("ld a,e");
+ emit2 ("rlc a");
+ emit2 ("sbc a,a");
+ emit2 ("ld d,a");
+ }
+ else
+ {
+ fetchPair (PAIR_DE, AOP (IC_LEFT (ic)));
+ }
+
+ i = val;
+
+ /* Fully unroled version of mul.s. Not the most efficient.
+ */
+ for (count = 0; count < 16; count++)
+ {
+ if (count != 0 && active)
+ {
+ emit2 ("add hl,hl");
+ }
+ if (i & 0x8000U)
+ {
+ if (active == FALSE)
+ {
+ emit2 ("ld l,e");
+ emit2 ("ld h,d");
+ }
+ else
+ {
+ emit2 ("add hl,de");
+ }
+ active = TRUE;
+ }
+ i <<= 1;
+ }
+
+ spillCached();
+
+ if (IS_Z80)
+ {
+ _pop (PAIR_DE);
+ }
+
+ commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
+
+ freeAsmop (IC_LEFT (ic), NULL, ic);
+ freeAsmop (IC_RIGHT (ic), NULL, ic);
+ freeAsmop (IC_RESULT (ic), NULL, ic);
}
/*-----------------------------------------------------------------*/
return "err";
}
+static bool
+_hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
+{
+ sym_link *test = NULL;
+ value *val;
+
+ if ( ic->op != '*')
+ {
+ return FALSE;
+ }
+
+ if ( IS_LITERAL (left))
+ {
+ test = left;
+ val = OP_VALUE (IC_LEFT (ic));
+ }
+ else if ( IS_LITERAL (right))
+ {
+ test = left;
+ val = OP_VALUE (IC_RIGHT (ic));
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ if ( getSize (test) <= 2)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
#define LINKCMD \
"{bindir}{sep}link-{port} -n -c -- {z80bases} -m -j" \
" {z80libspec}" \
_reg_parm,
_process_pragma,
_mangleSupportFunctionName,
+ _hasNativeMulFor,
TRUE,
0, /* leave lt */
0, /* leave gt */
_reg_parm,
_process_pragma,
_mangleSupportFunctionName,
+ _hasNativeMulFor,
TRUE,
0, /* leave lt */
0, /* leave gt */
-replace restart {
+replace {
+ ld (hl),a
+ dec hl
+} by {
+ ld (hl-),a
+}
+replace {
ld (hl),a
inc hl
} by {
ld (hl+),a
}
-replace restart {
+replace {
ld a,(hl)
inc hl
} by {
ld a,(hl+)
}
-replace restart {
- ld (hl),a
- dec hl
-} by {
- ld (hl-),a
-}
-replace restart {
+replace {
ld a,[hl]
inc hl
} by {
ld a,[hl+]
}
-replace restart {
+replace {
ld a,[hl]
inc hl
} by {
ld a,[hl+]
}
-replace restart {
+replace {
ld [hl],a
inc hl
} by {
ld [hl+],a
}
-replace restart {
+replace {
ld [hl],a
dec hl
} by {
-replace restart {
+replace {
ld (hl),(hl)
} by {
ERROR - peephole - caught (hl),(hl)
}
-replace restart {
+replace {
ld %1,%1
} by {
; Removed redundent load
{
DISABLE_PACK_ACC = 0,
DISABLE_PACK_ASSIGN = 0,
- DISABLE_PACK_ONE_USE = 0,
+ /* Pack for one use is quite broken. */
+ DISABLE_PACK_ONE_USE = 1,
DISABLE_PACK_HL = 0,
};
packRegsForSupport (ic, ebp);
#endif
-#if 0
- /* some cases the redundant moves can
- can be eliminated for return statements */
- if ((ic->op == RETURN || ic->op == SEND) &&
- !isOperandInFarSpace (IC_LEFT (ic)) &&
- !options.model)
- packRegsForOneuse (ic, IC_LEFT (ic), ebp);
-#endif
/* if pointer set & left has a size more than
one and right is not in far space */
if (!DISABLE_PACK_ONE_USE &&
packRegsForOneuse (ic, IC_LEFT (ic), ebp);
}
+
/* pack registers for accumulator use, when the result of an
arithmetic or bit wise operation has only one use, that use is
immediately following the defintion and the using iCode has
{
packRegsForHLUse (ic);
}
-#if 0
- if ((IS_ARITHMETIC_OP (ic)
- || IS_BITWISE_OP (ic)
- || ic->op == LEFT_OP || ic->op == RIGHT_OP
- ) &&
- IS_ITEMP (IC_RESULT (ic)) &&
- getSize (operandType (IC_RESULT (ic))) <= 2)
- packRegsForAccUse (ic);
-#else
+
if (!DISABLE_PACK_ACC && IS_ITEMP (IC_RESULT (ic)) &&
getSize (operandType (IC_RESULT (ic))) == 1)
{
packRegsForAccUse2 (ic);
}
-#endif
}
}
dhry.c: dhry.h
dhry.bin: dhry.ihx
- cat $< | ../../makebin/makebin > $@
+ cat $< | $(TOPDIR)/bin/makebin > $@
native:
gcc -g -O2 -DREG= -DNOSTRUCTASSIGN -DNOENUM -o dhry dhry.c
printf (" should be: %d\n", (int)7);
printf ("Enum_Loc: %d\n", Enum_Loc);
printf (" should be: %d\n", (int)1);
- printf ("Str_1_Loc: %s\n", (char _generic *)Str_1_Loc);
+ printf ("Str_1_Loc: %s\n", (char *)Str_1_Loc);
printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
- printf ("Str_2_Loc: %s\n", (char _generic *)Str_2_Loc);
+ printf ("Str_2_Loc: %s\n", (char *)Str_2_Loc);
printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
printf ("\n");
#endif