From ef30f07b8418a1ea0d8e16a4ecda4b61d66830ff Mon Sep 17 00:00:00 2001 From: michaelh Date: Sun, 20 Feb 2000 05:28:38 +0000 Subject: [PATCH] Nice. Up to 85.55 C / 157.52 asm. Is now definatly better code than gbdk. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@113 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- device/lib/gbz80/Makefile | 2 +- device/lib/gbz80/asm_strings.s | 78 ++++++++++---------- device/lib/gbz80/string.c | 17 +++-- src/z80/Makefile | 4 ++ src/z80/gbz80.c | 2 +- src/z80/gen.c | 120 ++++++++++++++++++++++--------- src/z80/ralloc.c | 20 +++--- support/tests/dhrystone/Makefile | 11 +-- support/tests/dhrystone/dhry.c | 5 +- 9 files changed, 152 insertions(+), 107 deletions(-) diff --git a/device/lib/gbz80/Makefile b/device/lib/gbz80/Makefile index 01a1cc31..96a7d67a 100644 --- a/device/lib/gbz80/Makefile +++ b/device/lib/gbz80/Makefile @@ -5,7 +5,7 @@ TOPDIR = ../../.. SCC = $(TOPDIR)/bin/sdcc -mgbz80 -v SAS = as-gb -OBJ = putchar.o string.o printf.o div.o mul.o # asm_strings.o +OBJ = putchar.o string.o printf.o div.o mul.o asm_strings.o LIB = z80.lib CC = $(SCC) AS = $(SAS) diff --git a/device/lib/gbz80/asm_strings.s b/device/lib/gbz80/asm_strings.s index fd263927..1d9f3241 100644 --- a/device/lib/gbz80/asm_strings.s +++ b/device/lib/gbz80/asm_strings.s @@ -5,42 +5,41 @@ ; char *strcpy(char *dest, const char *source) _strcpy:: - push de - push ix - ld ix,#0 - add ix,sp - ld l,6(ix) - ld h,7(ix) - ld e,8(ix) - ld d,9(ix) + lda hl,2(sp) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld a,(hl+) + ld h,(hl) + ld l,a - push hl + push de 1$: - ld a,(de) - ld (hl),a - inc hl + ld a,(hl+) + ld (de),a inc de or a,a jr nz,1$ - pop hl - pop ix pop de ret ; void *memcpy(void *dest, const void *source, int count) _memcpy:: - push de push bc - push ix - ld ix,#0 - add ix,sp - ld l,8(ix) - ld h,9(ix) - ld e,10(ix) - ld d,11(ix) - ld c,12(ix) - ld b,13(ix) + lda hl,6(sp) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld c,(hl) + inc hl + ld b,(hl) + lda hl,4(sp) + ld a,(hl+) + ld h,(hl) + ld l,a inc b inc c @@ -49,31 +48,28 @@ _memcpy:: jr 2$ 1$: ld a,(de) - ld (hl),a + ld (hl+),a inc de - inc hl 2$: dec c jr nz,1$ dec b jr nz,1$ - pop hl - pop ix - pop bc pop de + pop bc ret ; int strcmp(const char *s1, const char *s2) _strcmp:: - push de - push ix - ld ix,#0 - add ix,sp - ld e,6(ix) - ld d,7(ix) - ld l,8(ix) - ld h,9(ix) + lda hl,2(sp) + ld e,(hl) + inc hl + ld d,(hl) + inc hl + ld a,(hl+) + ld h,(hl) + ld l,a jr 1$ 2$: @@ -89,14 +85,12 @@ _strcmp:: jr 2$ 3$: - ld hl,#0 + ld de,#0 jr 5$ 4$: - ld hl,#1 + ld de,#1 jr nc,5$ - ld hl,#-1 + ld de,#-1 5$: - pop ix - pop de ret \ No newline at end of file diff --git a/device/lib/gbz80/string.c b/device/lib/gbz80/string.c index 53ee9b2c..e20cb2b6 100644 --- a/device/lib/gbz80/string.c +++ b/device/lib/gbz80/string.c @@ -1,25 +1,30 @@ /* Dumb strings stub. Wanted a quick hack for now - will use the libc version later. */ -char *strcpy(char *dest, const char *source) +char *_strcpy(char *dest, const char *source) { char *d = dest; const char *s = source; - while (*d++ = *s++); + while (*d = *s) + d++, s++; + return dest; } -void *memcpy(void *dest, const void *source, int count) +void *_memcpy(void *dest, const void *source, int count) { char *d = dest; const char *s = source; - while (count--) - *d++ = *s++; + while (count--) { + *d = *s; + d++; + s++; + } return dest; } -int strcmp(const char *s1, const char *s2) +int _strcmp(const char *s1, const char *s2) { char ret = 0; diff --git a/src/z80/Makefile b/src/z80/Makefile index 18b79f2f..f3b71b32 100644 --- a/src/z80/Makefile +++ b/src/z80/Makefile @@ -18,6 +18,10 @@ $(LIB): peeph.rul $(OBJ) peeph.rul: peeph.def $(AWK) -f ../SDCCpeeph.awk peeph.def > peeph.rul +peeph-gbz80.rul: peeph-gbz80.def + $(AWK) -f ../SDCCpeeph.awk peeph-gbz80.def > peeph-gbz80.rul + main.o: main.c peeph.rul +gbz80.o: gbz80.o peeph-gbz80.rul include clean.mk diff --git a/src/z80/gbz80.c b/src/z80/gbz80.c index dea697a3..d0b2f88a 100644 --- a/src/z80/gbz80.c +++ b/src/z80/gbz80.c @@ -9,7 +9,7 @@ static char _defaultRules[] = { - "" +#include "peeph-gbz80.rul" }; static char *_gbz80_keywords[] = { NULL }; diff --git a/src/z80/gen.c b/src/z80/gen.c index 4ac569f5..029cbfad 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -77,6 +77,8 @@ extern int ptrRegReq ; extern int nRegs; extern FILE *codeOutFile; set *sendSet = NULL; +const char *_shortJP = "jp"; + #define RESULTONSTACK(x) \ (IC_RESULT(x) && IC_RESULT(x)->aop && \ IC_RESULT(x)->aop->type == AOP_STK ) @@ -97,6 +99,8 @@ unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F, static int _lastStack = 0; static int _pushed = 0; static int _spoffset; +static int _lastHLOff = 0; +static asmop *_lastHL; #define LSB 0 #define MSB16 1 @@ -235,7 +239,7 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) if (sym->onStack || sym->iaccess) { sym->aop = aop = newAsmop(AOP_STK); aop->size = getSize(sym->type); - + _lastHL = NULL; aop->aopu.aop_stk = sym->stack; return aop; } @@ -264,8 +268,10 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) /* only remaining is far space */ /* in which case DPTR gets the address */ - if (IS_GB) + if (IS_GB) { sym->aop = aop = newAsmop(AOP_HL); + _lastHL = NULL; + } else { sym->aop = aop = newAsmop(AOP_IY); emitcode ("ld","iy,#%s ; a", sym->rname); @@ -588,6 +594,35 @@ char *aopGetWord(asmop *aop, int offset) return aopGetWordLong(aop, offset, TRUE); } +static void setupHL(asmop *aop, int offset) +{ + if (_lastHL != aop) { + switch (aop->type) { + case AOP_HL: + emitcode("ld", "hl,#%s+%d", aop->aopu.aop_dir, offset); + break; + case AOP_STK: + /* In some cases we can still inc or dec hl */ + emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset); + break; + default: + assert(0); + } + _lastHL = aop; + _lastHLOff = offset; + } + else { + while (offset < _lastHLOff) { + emitcode("dec", "hl"); + _lastHLOff--; + } + while (offset > _lastHLOff) { + emitcode("inc", "hl"); + _lastHLOff++; + } + } +} + /*-----------------------------------------------------------------*/ /* aopGet - for fetching value of the aop */ /*-----------------------------------------------------------------*/ @@ -631,7 +666,8 @@ static char *aopGet (asmop *aop, int offset, bool bit16) return aop->aopu.aop_reg[offset]->name; case AOP_HL: - emitcode("ld", "hl,#%s+%d", aop->aopu.aop_dir, offset); + assert(IS_GB); + setupHL(aop, offset); sprintf(s, "(hl)"); ALLOC_ATOMIC(rs, strlen(s)+1); strcpy(rs,s); @@ -645,10 +681,7 @@ static char *aopGet (asmop *aop, int offset, bool bit16) case AOP_STK: if (IS_GB) { - /* We cant really optimise this as we cant afford to - change the flags. - */ - emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset); + setupHL(aop, offset); sprintf(s, "(hl)"); } else { @@ -754,7 +787,7 @@ static void aopPut (asmop *aop, char *s, int offset) emitcode("ld", "a,(hl)"); s = "a"; } - emitcode("ld", "hl,#%s+%d", aop->aopu.aop_dir, offset); + setupHL(aop, offset); emitcode("ld", "(hl),%s", s); break; @@ -764,7 +797,7 @@ static void aopPut (asmop *aop, char *s, int offset) emitcode("ld", "a,(hl)"); s = "a"; } - emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset); + setupHL(aop, offset); if (!canAssignToPtr(s)) { emitcode("ld", "a,%s", s); emitcode("ld", "(hl),a"); @@ -1040,7 +1073,6 @@ release: static bool requiresHL(asmop *aop) { switch (aop->type) { - case AOP_DIR: case AOP_HL: case AOP_STK: return TRUE; @@ -1259,18 +1291,23 @@ static void emitCall (iCode *ic, bool ispcall) if (IC_LEFT(ic)->parmBytes) { int i = IC_LEFT(ic)->parmBytes; _pushed -= i; - if (i>6) { - emitcode("ld", "hl,#%d", i); - emitcode("add", "hl,sp"); - emitcode("ld", "sp,hl"); + if (IS_GB) { + emitcode("lda", "sp,%d(sp)", i); } else { - while (i>1) { - emitcode("pop", "hl"); - i-=2; + if (i>6) { + emitcode("ld", "hl,#%d", i); + emitcode("add", "hl,sp"); + emitcode("ld", "sp,hl"); + } + else { + while (i>1) { + emitcode("pop", "hl"); + i-=2; + } + if (i) + emitcode("inc", "sp"); } - if (i) - emitcode("inc", "sp"); } } @@ -1352,9 +1389,14 @@ static void genFunction (iCode *ic) _lastStack = sym->stack; if (sym->stack) { - emitcode("ld", "hl,#-%d", sym->stack); - emitcode("add", "hl,sp"); - emitcode("ld", "sp,hl"); + if (IS_GB) { + emitcode("lda", "sp,-%d(sp)", sym->stack); + } + else { + emitcode("ld", "hl,#-%d", sym->stack); + emitcode("add", "hl,sp"); + emitcode("ld", "sp,hl"); + } } _spoffset = sym->stack; } @@ -1520,7 +1562,7 @@ static bool genPlusIncr (iCode *ic) (icount == 1)) { symbol *tlbl = newiTempLabel(NULL); emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE)); - emitcode("jp", "nz," LABEL_STR ,tlbl->key+100); + emitcode(_shortJP, "nz," LABEL_STR ,tlbl->key+100); emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB16,FALSE)); if(size == 4) { @@ -1568,7 +1610,7 @@ void outBitAcc(operand *result) assert(0); } else { - emitcode("jp","z," LABEL_STR ,tlbl->key+100); + emitcode(_shortJP,"z," LABEL_STR ,tlbl->key+100); emitcode("ld","a,%s",one); emitcode("", LABEL_STR ":",tlbl->key+100); outAcc(result); @@ -2144,7 +2186,7 @@ static void gencjne(operand *left, operand *right, symbol *lbl) /* PENDING: ?? */ emitcode("ld","a,%s",one); - emitcode("jp", LABEL_STR ,tlbl->key+100); + emitcode(_shortJP, LABEL_STR ,tlbl->key+100); emitcode("", LABEL_STR ":",lbl->key+100); emitcode("xor","a,a"); emitcode("", LABEL_STR ":",tlbl->key+100); @@ -2185,7 +2227,7 @@ static void genCmpEq (iCode *ic, iCode *ifx) } else { /* PENDING: do this better */ symbol *lbl = newiTempLabel(NULL); - emitcode("jp", LABEL_STR ,lbl->key+100); + emitcode(_shortJP, LABEL_STR ,lbl->key+100); emitcode("", LABEL_STR ":",tlbl->key+100); emitcode("jp", LABEL_STR ,IC_FALSE(ifx)->key+100); emitcode("", LABEL_STR ":",lbl->key+100); @@ -2266,7 +2308,7 @@ static void genAndOp (iCode *ic) } else { tlbl = newiTempLabel(NULL); toBoolean(left); - emitcode("jp","z," LABEL_STR ,tlbl->key+100); + emitcode(_shortJP, "z," LABEL_STR ,tlbl->key+100); toBoolean(right); emitcode("", LABEL_STR ":",tlbl->key+100); outBitAcc(result); @@ -2299,7 +2341,7 @@ static void genOrOp (iCode *ic) } else { tlbl = newiTempLabel(NULL); toBoolean(left); - emitcode("jp","nz," LABEL_STR,tlbl->key+100); + emitcode(_shortJP, "nz," LABEL_STR,tlbl->key+100); toBoolean(right); emitcode("", LABEL_STR,tlbl->key+100); outBitAcc(result); @@ -2833,7 +2875,7 @@ static void shiftR2Left2Result (operand *left, int offl, emitcode("ld","a,#%u+1", shCount); tlbl = newiTempLabel(NULL); tlbl1 = newiTempLabel(NULL); - emitcode("jp", LABEL_STR ,tlbl1->key+100); + emitcode(_shortJP, LABEL_STR ,tlbl1->key+100); emitcode("", LABEL_STR ":",tlbl->key+100); } @@ -2846,7 +2888,7 @@ static void shiftR2Left2Result (operand *left, int offl, if (shCount>1) { emitcode("", LABEL_STR ":",tlbl1->key+100); emitcode("dec", "a"); - emitcode("jp","nz," LABEL_STR ,tlbl->key+100); + emitcode(_shortJP,"nz," LABEL_STR ,tlbl->key+100); } } } @@ -2878,7 +2920,7 @@ static void shiftL2Left2Result (operand *left, int offl, emitcode("ld","a,#%u+1", shCount); tlbl = newiTempLabel(NULL); tlbl1 = newiTempLabel(NULL); - emitcode("jp", LABEL_STR ,tlbl1->key+100); + emitcode(_shortJP, LABEL_STR ,tlbl1->key+100); emitcode("", LABEL_STR ":",tlbl->key+100); } @@ -2890,7 +2932,7 @@ static void shiftL2Left2Result (operand *left, int offl, if (shCount>1) { emitcode("", LABEL_STR ":",tlbl1->key+100); emitcode("dec", "a"); - emitcode("jp","nz," LABEL_STR ,tlbl->key+100); + emitcode(_shortJP,"nz," LABEL_STR ,tlbl->key+100); } } } @@ -3130,7 +3172,7 @@ static void genLeftShift (iCode *ic) offset = 0 ; tlbl1 = newiTempLabel(NULL); - emitcode("jp", LABEL_STR ,tlbl1->key+100); + emitcode(_shortJP, LABEL_STR ,tlbl1->key+100); emitcode("", LABEL_STR ":",tlbl->key+100); l = aopGet(AOP(result),offset,FALSE); emitcode("or", "a,a"); @@ -3140,7 +3182,7 @@ static void genLeftShift (iCode *ic) } emitcode("", LABEL_STR ":",tlbl1->key+100); emitcode("dec", "a"); - emitcode("jp","nz," LABEL_STR ,tlbl->key+100); + emitcode(_shortJP,"nz," LABEL_STR ,tlbl->key+100); freeAsmop(left,NULL,ic); freeAsmop(result,NULL,ic); @@ -3636,6 +3678,13 @@ static void genAssign (iCode *ic) offset); offset++; } + } + else if (size == 2 && requiresHL(AOP(right)) && requiresHL(AOP(result))) { + /* Special case. Load into a and d, then load out. */ + MOVA(aopGet(AOP(right), 0, FALSE)); + emitcode("ld", "e,%s", aopGet(AOP(right), 1, FALSE)); + aopPut(AOP(result), "a", 0); + aopPut(AOP(result), "e", 1); } else { while (size--) { aopPut(AOP(result), @@ -3670,6 +3719,7 @@ static void genJumpTab (iCode *ic) emitcode("ld", "hl,#" LABEL_STR, jtab->key+100); emitcode("add", "hl,de"); emitcode("add", "hl,de"); + emitcode("add", "hl,de"); freeAsmop(IC_JTCOND(ic),NULL,ic); if (!IS_GB) emitcode("pop", "de"); @@ -3796,10 +3846,12 @@ void genZ80Code (iCode *lic) if (IS_GB) { _fReturn = _gbz80_return; _fTmp = _gbz80_return; + _shortJP = "jr"; } else { _fReturn = _z80_return; _fTmp = _z80_return; + _shortJP = "jp"; } lineHead = lineCurr = NULL; diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index 330de6b4..2a758fde 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -2076,17 +2076,15 @@ static void packRegisters (eBBlock *ebp) getSize(operandType(IC_RESULT(ic))) <= 2) packRegsForAccUse (ic); #else - if (!IS_GB) { - if ((POINTER_GET(ic) || - 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))) == 1) - packRegsForAccUse2(ic); - } + if ((POINTER_GET(ic) || + 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))) == 1) + packRegsForAccUse2(ic); #endif } } diff --git a/support/tests/dhrystone/Makefile b/support/tests/dhrystone/Makefile index da2343ef..b0b93904 100644 --- a/support/tests/dhrystone/Makefile +++ b/support/tests/dhrystone/Makefile @@ -1,10 +1,8 @@ # Simple Makefile for dhrystone and sdcc -#CC = /home/michaelh/projects/sdcc/bin/sdcc +CC = /home/michaelh/projects/sdcc/bin/sdcc # -DNOENUM is here to make the results more predictable -#CFLAGS = -mgbz80 -v --dumpall -CC = lcc-gb -CFLAGS = -int16 -DSDCC=1 -v +CFLAGS = -mgbz80 -v --dumpall CFLAGS += -DREG= -DNOSTRUCTASSIGN -DNOENUM -DBROKEN_SDCC=0 -DHZ=100 LIBDIR = /home/michaelh/projects/sdcc/device/lib/gbz80/ LD = link-gb @@ -29,8 +27,3 @@ dhry.c: clean: rm -r *~ dhry - -dhry.o: dhry.c - /usr/lib/SDK/gbz80-gb/2.1.0/bin/cpp -DINT_16_BITS -D__STDC__=1 -DZ80 -DGB -DGAMEBOY -D__LCC__ -DSDCC=1 -DREG= -DNOSTRUCTASSIGN -DNOENUM -DBROKEN_SDCC=0 -DHZ=100 -I/usr/lib/sdcc/include dhry.c dhry.i - /usr/lib/SDK/gbz80-gb/2.1.0/bin/rcc -target=gbz80/int16 -optimize -v dhry.i dhry.asm - $(AS) -plosff dhry.o dhry.asm \ No newline at end of file diff --git a/support/tests/dhrystone/dhry.c b/support/tests/dhrystone/dhry.c index 02da21bb..a893a202 100644 --- a/support/tests/dhrystone/dhry.c +++ b/support/tests/dhrystone/dhry.c @@ -72,7 +72,6 @@ char Ch_1_Glob, Ch_2_Glob; int Arr_1_Glob [50]; int Arr_2_Glob [50] [50]; -char silly; /* Used instead of malloc() */ static Rec_Type _r[2]; @@ -107,11 +106,12 @@ int main(void) REG int Number_Of_Runs; unsigned runTime; - printf("[dhry]\n"); + // printf("[dhry]\n"); Next_Ptr_Glob = &_r[0]; Ptr_Glob = &_r[1]; + Ptr_Glob->Ptr_Comp = Next_Ptr_Glob; Ptr_Glob->Discr = Ident_1; Ptr_Glob->variant.var_1.Enum_Comp = Ident_3; @@ -294,7 +294,6 @@ void Proc_1 (REG Rec_Pointer Ptr_Val_Par) } else /* not executed */ structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp); - silly = 1; } /* Proc_1 */ -- 2.47.2