From dc2b6e2e3714b59e4780a12741b339900ea04ea0 Mon Sep 17 00:00:00 2001 From: michaelh Date: Sun, 28 Oct 2001 00:35:47 +0000 Subject: [PATCH] * src/z80/gen.c (genArrayInit): Made it work for on stack arrays. * src/z80/main.c (gbz80_port =): Added rle support to the gbz80 port. * src/z80/gen.c (genMinus): Fixed for where the result is one byte. (movLeft2ResultLong): Created. * src/z80/ralloc.c (packRegsForHLUse): Added a couple of simple cases for the GB. (joinPushes): Added. Joins two char pushes into a word push. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1457 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 12 ++++ device/lib/gbz80/Makefile | 2 +- device/lib/gbz80/crt0_rle.s | 45 ++++++++++++ device/lib/z80/Makefile | 2 +- device/lib/z80/crt0.s | 51 -------------- device/lib/z80/crt0_rle.s | 45 ++++++++++++ src/z80/gen.c | 87 +++++++++++++++++------ src/z80/gen.h | 4 +- src/z80/main.c | 2 +- src/z80/ralloc.c | 118 ++++++++++++++++++++++++++++---- src/z80/z80.h | 2 +- support/regression/tests/args.c | 1 + 12 files changed, 279 insertions(+), 92 deletions(-) create mode 100644 device/lib/gbz80/crt0_rle.s create mode 100644 device/lib/z80/crt0_rle.s diff --git a/ChangeLog b/ChangeLog index 5d3c148a..24dbd279 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2001-10-28 Michael Hope + + * src/z80/gen.c (genArrayInit): Made it work for on stack arrays. + + * src/z80/main.c (gbz80_port =): Added rle support to the gbz80 port. + + * src/z80/gen.c (genMinus): Fixed for where the result is one byte. + (movLeft2ResultLong): Created. + + * src/z80/ralloc.c (packRegsForHLUse): Added a couple of simple cases for the GB. + (joinPushes): Added. Joins two char pushes into a word push. + 2001-10-27 Michael Hope * support/cpp2/Makefile.in (install): Added creation of dest dir. diff --git a/device/lib/gbz80/Makefile b/device/lib/gbz80/Makefile index e0bddf0d..91098a1b 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 +OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o LIB = gbz80.lib CC = $(SCC) diff --git a/device/lib/gbz80/crt0_rle.s b/device/lib/gbz80/crt0_rle.s new file mode 100644 index 00000000..d5778142 --- /dev/null +++ b/device/lib/gbz80/crt0_rle.s @@ -0,0 +1,45 @@ + .area _CODE + + ;; Special RLE decoder used for initing global data +__initrleblock:: + ;; Pull the destination address out + ld c,l + ld b,h + + ;; Pop the return address + pop hl +1$: + ;; Fetch the run + ld e,(hl) + inc hl + ;; Negative means a run + bit 7,e + jp z,2$ + ;; Code for expanding a run + ld a,(hl) + inc hl +3$: + ld (bc),a + inc bc + inc e + jp nz,3$ + jp 1$ +2$: + ;; Zero means end of a block + xor a + or e + jp z,4$ + ;; Code for expanding a block +5$: + ld a,(hl) + inc hl + ld (bc),a + inc bc + dec e + jp nz,5$ + jp 1$ +4$: + ;; Push the return address back onto the stack + push hl + ret + diff --git a/device/lib/z80/Makefile b/device/lib/z80/Makefile index 8d40d867..fac4986d 100644 --- a/device/lib/z80/Makefile +++ b/device/lib/z80/Makefile @@ -5,7 +5,7 @@ TOPDIR = ../../.. SCC = $(TOPDIR)/bin/sdcc -mz80 SAS = $(TOPDIR)/bin/as-z80 -OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o +OBJ = div.o mul.o putchar.o printf.o shift.o stubs.o crt0_rle.o LIB = z80.lib CC = $(SCC) diff --git a/device/lib/z80/crt0.s b/device/lib/z80/crt0.s index 5aa3991d..9f21f26b 100644 --- a/device/lib/z80/crt0.s +++ b/device/lib/z80/crt0.s @@ -54,57 +54,6 @@ _exit:: halt jr 1$ - ;; Special RLE decoder used for initing global data -__initrleblock:: - ;; Pop the return address - pop hl - ;; Save registers - push bc - push de - - ;; Pull the destination address out - ld c,(hl) - inc hl - ld b,(hl) - inc hl -1$: - ;; Fetch the run - ld e,(hl) - inc hl - ;; Negative means a run - bit 7,e - jp z,2$ - ;; Code for expanding a run - ld a,(hl) - inc hl -3$: - ld (bc),a - inc bc - inc e - jp nz,3$ - jp 1$ -2$: - ;; Zero means end of a block - xor a - or e - jp z,4$ - ;; Code for expanding a block -5$: - ld a,(hl) - inc hl - ld (bc),a - inc bc - dec e - jp nz,5$ - jp 1$ -4$: - pop de - pop bc - - ;; Push the return address back onto the stack - push hl - ret - .area _GSINIT gsinit:: diff --git a/device/lib/z80/crt0_rle.s b/device/lib/z80/crt0_rle.s new file mode 100644 index 00000000..d5778142 --- /dev/null +++ b/device/lib/z80/crt0_rle.s @@ -0,0 +1,45 @@ + .area _CODE + + ;; Special RLE decoder used for initing global data +__initrleblock:: + ;; Pull the destination address out + ld c,l + ld b,h + + ;; Pop the return address + pop hl +1$: + ;; Fetch the run + ld e,(hl) + inc hl + ;; Negative means a run + bit 7,e + jp z,2$ + ;; Code for expanding a run + ld a,(hl) + inc hl +3$: + ld (bc),a + inc bc + inc e + jp nz,3$ + jp 1$ +2$: + ;; Zero means end of a block + xor a + or e + jp z,4$ + ;; Code for expanding a block +5$: + ld a,(hl) + inc hl + ld (bc),a + inc bc + dec e + jp nz,5$ + jp 1$ +4$: + ;; Push the return address back onto the stack + push hl + ret + diff --git a/src/z80/gen.c b/src/z80/gen.c index 00b01920..d0c7f3a8 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -406,7 +406,7 @@ getPairName (asmop * aop) break; } } - else if (aop->type == AOP_STR) + else if (aop->type == AOP_STR || aop->type == AOP_HLREG) { switch (*aop->aopu.aop_str[0]) { @@ -445,7 +445,7 @@ getPairId (asmop * aop) return PAIR_HL; } } - if (aop->type == AOP_STR) + if (aop->type == AOP_STR || aop->type == AOP_HLREG) { if (!strcmp (aop->aopu.aop_str[0], "c") && !strcmp (aop->aopu.aop_str[1], "b")) { @@ -840,9 +840,8 @@ aopOp (operand * op, iCode * ic, bool result, bool requires_a) aop->aopu.aop_str[0] = _pairs[PAIR_AF].h; } - else if (sym->accuse == ACCUSE_HL) + else if (sym->accuse == ACCUSE_SCRATCH) { - wassert (!IS_GB); aop = op->aop = sym->aop = newAsmop (AOP_HLREG); aop->size = getSize (sym->type); wassertl(aop->size <= 2, "Internal error: Caching in HL, but too big to fit in HL"); @@ -1062,6 +1061,7 @@ requiresHL (asmop * aop) case AOP_HL: case AOP_STK: case AOP_EXSTK: + case AOP_HLREG: return TRUE; default: return FALSE; @@ -1656,6 +1656,7 @@ movLeft2Result (operand * left, int offl, operand * result, int offr, int sign) { const char *l; + if (!sameRegs (AOP (left), AOP (result)) || (offl != offr)) { l = aopGet (AOP (left), offl, FALSE); @@ -1675,6 +1676,33 @@ movLeft2Result (operand * left, int offl, } } +static void +movLeft2ResultLong (operand * left, int offl, + operand * result, int offr, int sign, + int size) +{ + if (size == 1) + { + movLeft2Result (left, offl, result, offr, sign); + } + else + { + wassertl (offl == 0 && offr == 0, "Only implemented for zero offset"); + wassertl (size == 2, "Only implemented for two bytes or one"); + + if ( IS_GB && requiresHL ( AOP (left)) && getPairId ( AOP (result)) == PAIR_HL) + { + emit2 ("ld a,%s", aopGet (AOP (left), LSB, FALSE)); + emit2 ("ld h,%s", aopGet (AOP (left), MSB16, FALSE)); + emit2 ("ld l,a"); + } + else + { + movLeft2Result (left, offl, result, offr, sign); + movLeft2Result (left, offl+1, result, offr+1, sign); + } + } +} /** Put Acc into a register set */ @@ -1976,6 +2004,25 @@ assignResultValue (operand * oper) } } +/** Simple restore that doesn't take into account what is used in the + return. +*/ +static void +_restoreRegsAfterCall(void) +{ + if (_G.stack.pushedDE) + { + _pop ( PAIR_DE); + _G.stack.pushedDE = FALSE; + } + if (_G.stack.pushedBC) + { + _pop ( PAIR_BC); + _G.stack.pushedBC = FALSE; + } + _G.saves.saved = FALSE; +} + static void _saveRegsForCall(iCode *ic, int sendSetSize) { @@ -2784,7 +2831,7 @@ genPlusIncr (iCode * ic) { if (isLitWord (AOP (IC_LEFT (ic)))) { - fetchLitPair (getPairId (AOP (IC_RESULT (ic))), AOP (IC_LEFT (ic)), icount); + fetchLitPair (getPairId (AOP (IC_RESULT (ic))), AOP (IC_LEFT (ic)), icount); return TRUE; } if (isPair (AOP (IC_LEFT (ic))) && resultId == PAIR_HL && icount > 2) @@ -2800,8 +2847,7 @@ genPlusIncr (iCode * ic) { if (icount > 2) return FALSE; - movLeft2Result (IC_LEFT (ic), 0, IC_RESULT (ic), 0, 0); - movLeft2Result (IC_LEFT (ic), 1, IC_RESULT (ic), 1, 0); + movLeft2ResultLong (IC_LEFT (ic), 0, IC_RESULT (ic), 0, 0, 2); } while (icount--) { @@ -3187,8 +3233,7 @@ genMinusDec (iCode * ic) /* If result is a pair */ if (isPair (AOP (IC_RESULT (ic)))) { - movLeft2Result (IC_LEFT (ic), 0, IC_RESULT (ic), 0, 0); - movLeft2Result (IC_LEFT (ic), 1, IC_RESULT (ic), 1, 0); + movLeft2ResultLong (IC_LEFT (ic), 0, IC_RESULT (ic), 0, 0, 2); while (icount--) emit2 ("dec %s", getPairName (AOP (IC_RESULT (ic)))); return TRUE; @@ -3300,7 +3345,10 @@ genMinus (iCode * ic) emit2 ("ld a,%s", _pairs[left].h); emit2 ("sbc a,%s", _pairs[right].h); - aopPut (AOP (IC_RESULT (ic)), "a", 1); + if ( AOP_SIZE (IC_RESULT (ic)) > 1) + { + aopPut (AOP (IC_RESULT (ic)), "a", 1); + } aopPut (AOP (IC_RESULT (ic)), "e", 0); goto release; } @@ -6189,16 +6237,10 @@ genArrayInit (iCode * ic) aopOp (IC_LEFT(ic), ic, FALSE, FALSE); - if (AOP_TYPE(IC_LEFT(ic)) == AOP_IMMD) - { - /* Emit the support function call and the destination address. */ - emit2("call __initrleblock"); - emit2(".dw %s", aopGetWord (AOP(IC_LEFT(ic)), 0)); - } - else - { - wassertl (0, "Unexpected operand to genArrayInit.\n"); - } + _saveRegsForCall(ic, 0); + + fetchPair (PAIR_HL, AOP (IC_LEFT (ic))); + emit2 ("call __initrleblock"); type = operandType(IC_LEFT(ic)); @@ -6242,6 +6284,10 @@ genArrayInit (iCode * ic) /* Mark the end of the run. */ emit2(".db 0"); + _restoreRegsAfterCall(); + + spillCached (); + freeAsmop (IC_LEFT(ic), NULL, ic); } @@ -6517,6 +6563,7 @@ genZ80Code (iCode * lic) break; case ARRAYINIT: + emitDebug ("; genArrayInit"); genArrayInit(ic); break; diff --git a/src/z80/gen.h b/src/z80/gen.h index 20b57877..becc53ad 100644 --- a/src/z80/gen.h +++ b/src/z80/gen.h @@ -22,8 +22,8 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ -#ifndef SDCCGEN51_H -#define SDCCGEN51_H +#ifndef Z80GEN_H +#define Z80GEN_H typedef enum { diff --git a/src/z80/main.c b/src/z80/main.c index a3d70ca9..d2b2639c 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -592,6 +592,6 @@ PORT gbz80_port = 1, /* transform >= to ! < */ 1, /* transform != to !(a == b) */ 0, /* leave == */ - FALSE, /* No array initializer support. */ + TRUE, /* Array initializer support. */ PORT_MAGIC }; diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index bc1c337e..95682c0f 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -63,7 +63,8 @@ enum D_ALLOC = 0, D_ALLOC2 = 0, D_ACCUSE2 = 0, - D_ACCUSE2_VERBOSE = 0 + D_ACCUSE2_VERBOSE = 0, + D_HLUSE = 0 }; #if 1 @@ -2017,34 +2018,63 @@ packRegsForHLUse (iCode * ic) { iCode *uic; - if (IS_GB) - return; - /* has only one definition */ if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1) - return; + { + D (D_HLUSE, (" + Dropping as has more than one def\n")); + return; + } /* has only one use */ if (bitVectnBitsOn (OP_USES (IC_RESULT (ic))) > 1) - return; + { + D (D_HLUSE, (" + Dropping as has more than one use\n")); + return; + } /* and the usage immediately follows this iCode */ if (!(uic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_USES (IC_RESULT (ic)))))) - return; + { + D (D_HLUSE, (" + Dropping as usage isn't in this block\n")); + return; + } if (ic->next != uic) - return; + { + D (D_HLUSE, (" + Dropping as usage doesn't follow this\n")); + return; + } - if (ic->op == CAST && uic->op == IPUSH) - goto hluse; - if (ic->op == ADDRESS_OF && uic->op == IPUSH) - goto hluse; - if (ic->op == CALL && ic->parmBytes == 0 && (uic->op == '-' || uic->op == '+')) - goto hluse; + if (IS_Z80) + { + if (ic->op == CAST && uic->op == IPUSH) + goto hluse; + if (ic->op == ADDRESS_OF && uic->op == IPUSH) + goto hluse; + if (ic->op == CALL && ic->parmBytes == 0 && (uic->op == '-' || uic->op == '+')) + goto hluse; + } + else if (IS_GB) + { + /* Case of assign a constant to offset in a static array. */ + if (ic->op == '+' && IS_VALOP (IC_RIGHT (ic))) + { + if (uic->op == '=' && POINTER_SET (uic)) + { + goto hluse; + } + else if (uic->op == IPUSH) + { + goto hluse; + } + } + } + + D (D_HLUSE, (" + Dropping as it's a bad op\n")); return; hluse: - OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HL; + OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_SCRATCH; } static bool @@ -2533,6 +2563,62 @@ packRegisters (eBBlock * ebp) } } +/** Joins together two byte constant pushes into one word push. + */ +static iCode * +joinPushes (iCode *lic) +{ + iCode *ic, *uic; + + for (ic = lic; ic; ic = ic->next) + { + int first, second; + value *val; + + uic = ic->next; + + /* Anything past this? */ + if (uic == NULL) + { + continue; + } + /* This and the next pushes? */ + if (ic->op != IPUSH || uic->op != IPUSH) + { + continue; + } + /* Both literals? */ + if ( !IS_OP_LITERAL (IC_LEFT (ic)) || !IS_OP_LITERAL (IC_LEFT (uic))) + { + continue; + } + /* Both characters? */ + if ( getSize (operandType (IC_LEFT (ic))) != 1 || getSize (operandType (IC_LEFT (uic))) != 1) + { + continue; + } + /* Pull out the values, make a new type, and create the new iCode for it. + */ + first = (int)operandLitValue ( IC_LEFT (ic)); + second = (int)operandLitValue ( IC_LEFT (uic)); + + sprintf (buffer, "%u", ((first << 8) | (second & 0xFF)) & 0xFFFFU); + val = constVal (buffer); + SPEC_NOUN (val->type) = V_INT; + IC_LEFT (ic)->operand.valOperand = val; + + /* Now remove the second one from the list. */ + ic->next = uic->next; + if (uic->next) + { + /* Patch up the reverse link */ + uic->next->prev = ic; + } + } + + return lic; +} + /*-----------------------------------------------------------------*/ /* assignRegisters - assigns registers to each live range as need */ /*-----------------------------------------------------------------*/ @@ -2601,6 +2687,8 @@ z80_assignRegisters (eBBlock ** ebbs, int count) /* now get back the chain */ ic = iCodeLabelOptimize (iCodeFromeBBlock (ebbs, count)); + ic = joinPushes (ic); + /* redo that offsets for stacked automatic variables */ redoStackOffsets (); diff --git a/src/z80/z80.h b/src/z80/z80.h index 9b112ded..66c55676 100644 --- a/src/z80/z80.h +++ b/src/z80/z80.h @@ -26,5 +26,5 @@ extern Z80_OPTS z80_opts; enum { ACCUSE_A = 1, - ACCUSE_HL + ACCUSE_SCRATCH }; diff --git a/support/regression/tests/args.c b/support/regression/tests/args.c index 4c73c619..9754344a 100644 --- a/support/regression/tests/args.c +++ b/support/regression/tests/args.c @@ -42,4 +42,5 @@ testArgs(void) ASSERT(returnThirdArg(-33, -34, -35) == -35); ASSERT(returnThirdArg(-33, -34, 35) == 35); + } -- 2.47.2