From: michaelh Date: Wed, 8 Aug 2001 03:22:14 +0000 (+0000) Subject: * Optimised many of the library functions X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=f239a9f256f022ade8216daba928e817f2d5f528;p=fw%2Fsdcc * Optimised many of the library functions * Added profiling support into the gb port * Improved the peephole. * Improved acc packing. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1131 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/device/include/asm/z80/features.h b/device/include/asm/z80/features.h index e3f3b68a..616eb02a 100644 --- a/device/include/asm/z80/features.h +++ b/device/include/asm/z80/features.h @@ -7,5 +7,6 @@ #define _CODE #define _SDCC_MANGLES_SUPPORT_FUNS 1 +#define _SDCC_Z80_STYLE_LIB_OPT 1 #endif diff --git a/device/lib/Makefile.in b/device/lib/Makefile.in index d85e1ee5..1c64fa11 100644 --- a/device/lib/Makefile.in +++ b/device/lib/Makefile.in @@ -32,7 +32,7 @@ infodir = @infodir@ srcdir = @srcdir@ CPPFLAGS = -I$(INCDIR) -CFLAGS = $(MODELFLAGS) +CFLAGS = $(MODELFLAGS) --nostdinc --nostdlib BUILDDIR = build # Default @@ -71,7 +71,10 @@ Z80SOURCES = _atoi.c \ _strncpy.c _strpbrk.c _strrchr.c _strspn.c \ _strstr.c _strtok.c \ puts.c gets.c \ - assert.c _strcat.c + assert.c _strcat.c \ + _modslong.c _modulong.c \ + _mulslong.c _mululong.c \ + _divslong.c _divulong.c Z80OBJECTS = $(Z80SOURCES:%.c=$(PORTDIR)/%.o) diff --git a/device/lib/_memcpy.c b/device/lib/_memcpy.c index b59c27fb..2bb6d29f 100644 --- a/device/lib/_memcpy.c +++ b/device/lib/_memcpy.c @@ -22,14 +22,40 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ #include "string.h" +#include + #define NULL (void *)0 void _generic * memcpy ( void _generic * dst, void _generic * src, - int count + int acount ) { +#if _SDCC_Z80_STYLE_LIB_OPT + char _generic * d = dst; + char _generic * s = src; + int count = -acount; + + count /= 4; + + while (count) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + count++; + } + + if (acount & 2) { + *d++ = *s++; + *d++ = *s++; + } + if (acount & 1) { + *d++ = *s++; + } + return dst; +#else void _generic * ret = dst; char _generic * d = dst; char _generic * s = src; @@ -37,9 +63,10 @@ void _generic * memcpy ( /* * copy from lower addresses to higher addresses */ - while (count--) { + while (acount--) { *d++ = *s++; } return(ret); +#endif } diff --git a/device/lib/_strcmp.c b/device/lib/_strcmp.c index ea1cc68f..1e6121fd 100644 --- a/device/lib/_strcmp.c +++ b/device/lib/_strcmp.c @@ -22,22 +22,35 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ #include "string.h" +#include + #define NULL (void *)0 int strcmp ( - char _generic *src, - char _generic *dst + char _generic *asrc, + char _generic *adst ) { - register int ret = 0 ; +#if _SDCC_Z80_STYLE_LIB_OPT + char ret = 0 ; + char _generic *src = asrc; + char _generic *dst = adst; - while( ! (ret = *src - *dst) && *dst) + while( ! (*src - *dst) && *dst) ++src, ++dst; + return *src - *dst; +#else + register int ret = 0 ; + + while( ! (ret = *asrc - *adst) && *adst) + ++asrc, ++adst; + if ( ret < 0 ) ret = -1 ; else if ( ret > 0 ) ret = 1 ; return( ret ); +#endif } diff --git a/device/lib/_strcpy.c b/device/lib/_strcpy.c index 9ba1dcd5..36ed8160 100644 --- a/device/lib/_strcpy.c +++ b/device/lib/_strcpy.c @@ -22,15 +22,26 @@ what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ #include "string.h" +#include + #define NULL (void *)0 char _generic *strcpy ( char _generic *d, char _generic *s) { +#if _SDCC_Z80_STYLE_LIB_OPT + register char _generic *to = d; + register char _generic *from = s; + + while (*to++ = *from++) ; + + return d; +#else register char _generic *d1 = d; while (*d1++ = *s++) ; return d; +#endif } diff --git a/device/lib/z80/crt0.s b/device/lib/z80/crt0.s index dee9a4bf..c05ae1d1 100644 --- a/device/lib/z80/crt0.s +++ b/device/lib/z80/crt0.s @@ -42,7 +42,7 @@ init: .area _CODE __clock:: ld a,#2 - out (0xff),a + rst 0x08 ret _getsp:: diff --git a/device/lib/z80/div.s b/device/lib/z80/div.s index ba074239..c66aca33 100644 --- a/device/lib/z80/div.s +++ b/device/lib/z80/div.s @@ -1,7 +1,7 @@ ;; Originally from GBDK by Pascal Felber. .area _CODE -__divschar_rr_s:: +__divschar_rrx_s:: ld hl,#2+1 add hl,sp @@ -10,7 +10,7 @@ __divschar_rr_s:: ld l,(hl) ;; Fall through -__divschar_rr_hds:: +__divschar_rrx_hds:: ld c,l call .div8 @@ -20,7 +20,7 @@ __divschar_rr_hds:: ret -__modschar_rr_s:: +__modschar_rrx_s:: ld hl,#2+1 add hl,sp @@ -29,7 +29,7 @@ __modschar_rr_s:: ld l,(hl) ;; Fall through -__modschar_rr_hds:: +__modschar_rrx_hds:: ld c,l call .div8 @@ -39,7 +39,7 @@ __modschar_rr_hds:: ret -__divsint_rr_s:: +__divsint_rrx_s:: ld hl,#2+3 add hl,sp @@ -53,7 +53,7 @@ __divsint_rr_s:: ld h,a ;; Fall through -__divsint_rr_hds:: +__divsint_rrx_hds:: ld b,h ld c,l @@ -64,7 +64,7 @@ __divsint_rr_hds:: ret -__modsint_rr_s:: +__modsint_rrx_s:: ld hl,#2+3 add hl,sp @@ -78,7 +78,7 @@ __modsint_rr_s:: ld h,a ;; Fall through -__modsint_rr_hds:: +__modsint_rrx_hds:: ld b,h ld c,l @@ -90,7 +90,7 @@ __modsint_rr_hds:: ret ;; Unsigned -__divuchar_rr_s:: +__divuchar_rrx_s:: ld hl,#2+1 add hl,sp @@ -99,7 +99,7 @@ __divuchar_rr_s:: ld l,(hl) ;; Fall through -__divuchar_rr_hds:: +__divuchar_rrx_hds:: ld c,l call .divu8 @@ -108,7 +108,7 @@ __divuchar_rr_hds:: ret -__moduchar_rr_s:: +__moduchar_rrx_s:: ld hl,#2+1 add hl,sp @@ -117,7 +117,7 @@ __moduchar_rr_s:: ld l,(hl) ;; Fall through -__moduchar_rr_hds:: +__moduchar_rrx_hds:: ld c,l call .divu8 @@ -126,7 +126,7 @@ __moduchar_rr_hds:: ret -__divuint_rr_s:: +__divuint_rrx_s:: ld hl,#2+3 add hl,sp @@ -140,7 +140,7 @@ __divuint_rr_s:: ld h,a ;; Fall through -__divuint_rr_hds:: +__divuint_rrx_hds:: ld b,h ld c,l call .divu16 @@ -150,7 +150,7 @@ __divuint_rr_hds:: ret -__moduint_rr_s:: +__moduint_rrx_s:: ld hl,#2+3 add hl,sp @@ -164,7 +164,7 @@ __moduint_rr_s:: ld h,a ;; Fall through -__moduint_rr_hds:: +__moduint_rrx_hds:: ld b,h ld c,l diff --git a/device/lib/z80/mul.s b/device/lib/z80/mul.s index f0817aef..4f3e793a 100644 --- a/device/lib/z80/mul.s +++ b/device/lib/z80/mul.s @@ -2,7 +2,7 @@ .area _CODE -__mulschar_rr_s:: +__mulschar_rrx_s:: ld hl,#2 add hl,sp @@ -11,7 +11,7 @@ __mulschar_rr_s:: ld l,(hl) ;; Fall through -__mulschar_rr_hds:: +__mulschar_rrx_hds:: ;; Need to sign extend before going in. ld c,l @@ -27,7 +27,7 @@ __mulschar_rr_hds:: jp .mul16 -__muluchar_rr_s:: +__muluchar_rrx_s:: ld hl,#2 add hl,sp @@ -43,8 +43,8 @@ __muluchar_rr_s:: jp .mulu16 -__mulsint_rr_s:: -__muluint_rr_s:: +__mulsint_rrx_s:: +__muluint_rrx_s:: ld hl,#2 add hl,sp @@ -59,9 +59,9 @@ __muluint_rr_s:: ;; Fall through -__muluchar_rr_hds:: -__mulsint_rr_hds:: -__muluint_rr_hds:: +__muluchar_rrx_hds:: +__mulsint_rrx_hds:: +__muluint_rrx_hds:: ;; Parameters: ;; HL, DE (left, right irrelivent) ld b,h diff --git a/device/lib/z80/shift.s b/device/lib/z80/shift.s index e1485682..f09de382 100644 --- a/device/lib/z80/shift.s +++ b/device/lib/z80/shift.s @@ -1,5 +1,5 @@ ;; -__rrulong_rr_s:: +__rrulong_rrx_s:: ld hl,#2+4 add hl,sp @@ -27,7 +27,7 @@ __rrulong_rr_s:: dec a jp 1$ -__rrslong_rr_s:: +__rrslong_rrx_s:: ld hl,#2+4 add hl,sp @@ -55,8 +55,8 @@ __rrslong_rr_s:: dec a jp 1$ -__rlslong_rr_s:: -__rlulong_rr_s:: +__rlslong_rrx_s:: +__rlulong_rrx_s:: ld hl,#2+4 add hl,sp diff --git a/device/lib/z80/stubs.s b/device/lib/z80/stubs.s index f6ce5372..7ef8a2cf 100644 --- a/device/lib/z80/stubs.s +++ b/device/lib/z80/stubs.s @@ -7,21 +7,123 @@ .globl __modulong .globl __divslong .globl __divulong - -__mulslong_rr_s:: + .globl __divschar_rrx_s + .globl __divsint_rrx_s + .globl __divuchar_rrx_s + .globl __divuint_rrx_s + .globl __mulschar_rrx_s + .globl __mulsint_rrx_s + .globl __muluchar_rrx_s + .globl __muluint_rrx_s + .globl __moduchar_rrx_s + .globl __modschar_rrx_s + .globl __moduint_rrx_s + .globl __modsint_rrx_s + .globl __rrulong_rrx_s + .globl __rrslong_rrx_s + .globl __rlulong_rrx_s + .globl __rlslong_rrx_s + +__mulslong_rrx_s:: +__mulslong_rrf_s:: jp __mulslong -__mululong_rr_s:: +__mululong_rrx_s:: +__mululong_rrf_s:: jp __mululong -__modslong_rr_s:: +__modslong_rrx_s:: +__modslong_rrf_s:: jp __modslong -__modulong_rr_s:: +__modulong_rrx_s:: +__modulong_rrf_s:: jp __modulong -__divslong_rr_s:: +__divslong_rrx_s:: +__divslong_rrf_s:: jp __divslong -__divulong_rr_s:: +__divulong_rrx_s:: +__divulong_rrf_s:: jp __divulong + +__mulsint_rrf_s:: + ld a,#5 + rst 0x08 + jp __mulsint_rrx_s + +__divsint_rrf_s:: + ld a,#5 + rst 0x08 + jp __divsint_rrx_s + +__muluint_rrf_s:: + ld a,#5 + rst 0x08 + jp __muluint_rrx_s + +__divuint_rrf_s:: + ld a,#5 + rst 0x08 + jp __divuint_rrx_s + +__mulschar_rrf_s:: + ld a,#5 + rst 0x08 + jp __mulschar_rrx_s + +__divschar_rrf_s:: + ld a,#5 + rst 0x08 + jp __divschar_rrx_s + +__muluchar_rrf_s:: + ld a,#5 + rst 0x08 + jp __muluchar_rrx_s + +__divuchar_rrf_s:: + ld a,#5 + rst 0x08 + jp __divuchar_rrx_s + +__modschar_rrf_s:: + ld a,#5 + rst 0x08 + jp __modschar_rrx_s + +__moduchar_rrf_s:: + ld a,#5 + rst 0x08 + jp __moduchar_rrx_s + +__modsint_rrf_s:: + ld a,#5 + rst 0x08 + jp __modsint_rrx_s + +__moduint_rrf_s:: + ld a,#5 + rst 0x08 + jp __moduint_rrx_s + +__rrulong_rrf_s:: + ld a,#5 + rst 0x08 + jp __rrulong_rrx_s + +__rrslong_rrf_s:: + ld a,#5 + rst 0x08 + jp __rrslong_rrx_s + +__rlulong_rrf_s:: + ld a,#5 + rst 0x08 + jp __rlulong_rrx_s + +__rlslong_rrf_s:: + ld a,#5 + rst 0x08 + jp __rlslong_rrx_s diff --git a/src/SDCCglobl.h b/src/SDCCglobl.h index a12cea74..b887e795 100644 --- a/src/SDCCglobl.h +++ b/src/SDCCglobl.h @@ -217,7 +217,7 @@ struct options int noRegParams; /* Disable passing some parameters in registers */ int verbose; /* Show what the compiler is doing */ int shortis8bits; /* treat short like int or char */ - + int profile; /* Turn on extra profiling information */ char *calleeSaves[128]; /* list of functions using callee save */ char *excludeRegs[32]; /* registers excluded from saving */ diff --git a/src/SDCCmain.c b/src/SDCCmain.c index 9c9e63a4..1be19dfb 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -188,7 +188,8 @@ optionsTable[] = { { 0, "--nostdinc", &options.nostdinc, "Do not include the standard include directory in the search path" }, { 0, "--verbose", &options.verbose, "Trace calls to the preprocessor, assembler, and linker" }, { 0, OPTION_LESS_PEDANTIC, NULL, "Disable some of the more pedantic warnings" }, - { 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8bits (for old times sake)" } + { 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8bits (for old times sake)" }, + { 0, "--profile", &options.profile, "On supported ports, generate extra profiling information" } }; /** Table of all unsupported options and help text to display when one diff --git a/src/z80/gen.c b/src/z80/gen.c index 8c3df03f..666926a1 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -2,7 +2,7 @@ gen.c - Z80 specific code generator. Benchmarks on dhry.c 2.1 with 32766 loops and a 10ms clock: - ticks dhry size + ticks dhry size Base with asm strcpy / strcmp / memcpy: 23198 141 1A14 Improved WORD push 22784 144 19AE With label1 on 22694 144 197E @@ -19,7 +19,17 @@ 5/3/00 17741 185 17B6 With reg params for mul and div 16234 202 162D - Michael Hope 2000 + 1. Starting again at 3 Aug 01 34965 93 219C + No asm strings + Includes long mul/div in code + 2. Optimised memcpy for acc use 32102 102 226B + 3. Optimised strcpy for acc use 27819 117 2237 + 3a Optimised memcpy fun + 4. Optimised strcmp fun 21999 149 2294 + 5. Optimised strcmp further 21660 151 228C + 6. Optimised memcpy by unroling 20885 157 2201 + + Michael Hope 2000 Based on the mcs51 generator - Sandeep Dutta . sandeep.dutta@usa.net (1998) and - Jean-Louis VERN.jlvern@writeme.com (1999) @@ -81,6 +91,11 @@ IX is used as an index register to the top of the local variable area. ix-0 is the top most local variable. */ + +enum { + DISABLE_DEBUG = 1 +}; + static char *_z80_return[] = {"l", "h", "e", "d"}; static char *_gbz80_return[] = @@ -201,12 +216,9 @@ _tidyUp (char *buf) } static void -emit2 (const char *szFormat,...) +_vemit2 (const char *szFormat, va_list ap) { char buffer[256]; - va_list ap; - - va_start (ap, szFormat); tvsprintf (buffer, szFormat, ap); @@ -218,6 +230,33 @@ emit2 (const char *szFormat,...) _G.lines.current->isInline = _G.lines.isInline; } +static void +emit2 (const char *szFormat,...) +{ + va_list ap; + + va_start (ap, szFormat); + + _vemit2 (szFormat, ap); + + va_end (ap); +} + +static void +emitDebug (const char *szFormat,...) +{ + if (!DISABLE_DEBUG) + { + va_list ap; + + va_start (ap, szFormat); + + _vemit2 (szFormat, ap); + + va_end (ap); + } +} + /*-----------------------------------------------------------------*/ /* emit2 - writes the code into a file : for now it is simple */ /*-----------------------------------------------------------------*/ @@ -418,7 +457,7 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool requires_a) /* Assign depending on the storage class */ if (sym->onStack || sym->iaccess) { - emit2 ("; AOP_STK for %s", sym->rname); + emitDebug ("; AOP_STK for %s", sym->rname); sym->aop = aop = newAsmop (AOP_STK); aop->size = getSize (sym->type); aop->aopu.aop_stk = sym->stack; @@ -443,7 +482,7 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool requires_a) sym->aop = aop = newAsmop (AOP_SFR); aop->aopu.aop_dir = sym->rname; aop->size = getSize (sym->type); - emit2 ("; AOP_SFR for %s", sym->rname); + emitDebug ("; AOP_SFR for %s", sym->rname); return aop; } } @@ -452,7 +491,7 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool requires_a) /* in which case DPTR gets the address */ if (IS_GB) { - emit2 ("; AOP_HL for %s", sym->rname); + emitDebug ("; AOP_HL for %s", sym->rname); sym->aop = aop = newAsmop (AOP_HL); } else @@ -1011,7 +1050,7 @@ fetchPairLong (PAIR_ID pairId, asmop * aop, int offset) emit2 ("ld l,a"); break; default: - emit2 ("; WARNING: mlh woosed out. This code is invalid."); + emitDebug ("; WARNING: mlh woosed out. This code is invalid."); } } else if (IS_Z80 && aop->type == AOP_IY) { @@ -1139,14 +1178,14 @@ aopGet (asmop * aop, int offset, bool bit16) case AOP_DIR: wassert (IS_GB); - emit2 ("ld a,(%s+%d) ; x", aop->aopu.aop_dir, offset); + emit2 ("ld a,(%s+%d)", aop->aopu.aop_dir, offset); sprintf (s, "a"); return gc_strdup(s); case AOP_SFR: wassert (IS_GB); - emit2 ("ldh a,(%s+%d) ; x", aop->aopu.aop_dir, offset); + emit2 ("ldh a,(%s+%d)", aop->aopu.aop_dir, offset); sprintf (s, "a"); return gc_strdup(s); @@ -1178,7 +1217,7 @@ aopGet (asmop * aop, int offset, bool bit16) { if (aop->aopu.aop_stk >= 0) offset += _G.stack.param_offset; - tsprintf (s, "!*ixx ; x", aop->aopu.aop_stk + offset); + tsprintf (s, "!*ixx", aop->aopu.aop_stk + offset); } return gc_strdup(s); @@ -1378,7 +1417,7 @@ aopPut (asmop * aop, const char *s, int offset) if (offset > 0) { - emit2 ("; Error aopPut AOP_ACC"); + emitDebug ("; Error aopPut AOP_ACC"); } else { @@ -1489,7 +1528,7 @@ outBitCLong (operand * result, bool swap_sense) /* if the result is bit */ if (AOP_TYPE (result) == AOP_CRY) { - emit2 ("; Note: outBitC form 1"); + emitDebug ("; Note: outBitC form 1"); aopPut (AOP (result), "blah", 0); } else @@ -1512,7 +1551,7 @@ outBitC (operand * result) /* toBoolean - emit code for orl a,operator(sizeop) */ /*-----------------------------------------------------------------*/ void -toBoolean (operand * oper) +_toBoolean (operand * oper) { int size = AOP_SIZE (oper); int offset = 0; @@ -1557,7 +1596,7 @@ genNot (iCode * ic) wassert (0); } - toBoolean (IC_LEFT (ic)); + _toBoolean (IC_LEFT (ic)); /* Not of A: If A == 0, !A = 1 @@ -1767,7 +1806,7 @@ _saveRegsForCall(iCode *ic, int sendSetSize) deSending = (sendSetSize > 1); - emit2 ("; _saveRegsForCall: sendSetSize: %u deInUse: %u bcInUse: %u deSending: %u", sendSetSize, deInUse, bcInUse, deSending); + emitDebug ("; _saveRegsForCall: sendSetSize: %u deInUse: %u bcInUse: %u deSending: %u", sendSetSize, deInUse, bcInUse, deSending); if (bcInUse && bcInRet == FALSE) { _push(PAIR_BC); @@ -1965,7 +2004,7 @@ _opUsesPair (operand * op, iCode * ic, PAIR_ID pairId) { if (pairId == PAIR_DE) { - emit2 ("; name %s", aop->aopu.aop_reg[i]->name); + emitDebug ("; name %s", aop->aopu.aop_reg[i]->name); if (!strcmp (aop->aopu.aop_reg[i]->name, "e")) ret++; if (!strcmp (aop->aopu.aop_reg[i]->name, "d")) @@ -1973,7 +2012,7 @@ _opUsesPair (operand * op, iCode * ic, PAIR_ID pairId) } else if (pairId == PAIR_BC) { - emit2 ("; name %s", aop->aopu.aop_reg[i]->name); + emitDebug ("; name %s", aop->aopu.aop_reg[i]->name); if (!strcmp (aop->aopu.aop_reg[i]->name, "c")) ret++; if (!strcmp (aop->aopu.aop_reg[i]->name, "b")) @@ -2077,7 +2116,7 @@ emitCall (iCode * ic, bool ispcall) if (isLitWord (AOP (IC_LEFT (ic)))) { - emit2 ("; Special case where the pCall is to a constant"); + emitDebug ("; Special case where the pCall is to a constant"); emit2 ("call %s", aopGetLitWordLong (AOP (IC_LEFT (ic)), 0, FALSE)); } else @@ -2258,15 +2297,6 @@ resultRemat (iCode * ic) extern set *publics; -/* Steps: - o Check genFunction - o Check emitCall and clean up - o Check genReturn - o Check return puller - - PENDING: Remove this. -*/ - /*-----------------------------------------------------------------*/ /* genFunction - generated code for function entry */ /*-----------------------------------------------------------------*/ @@ -2305,6 +2335,11 @@ genFunction (iCode * ic) emit2 ("__%s_start:", sym->rname); emit2 ("!functionlabeldef", sym->rname); + if (options.profile) + { + emit2 ("!profileenter"); + } + fetype = getSpec (operandType (IC_LEFT (ic))); /* if critical function then turn interrupts off */ @@ -2419,6 +2454,12 @@ genEndFunction (iCode * ic) } #endif + if (options.profile) + { + emit2 ("!profileexit"); + } + + /* Both baned and non-banked just ret */ emit2 ("ret"); @@ -2529,7 +2570,7 @@ genPlusIncr (iCode * ic) if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) return FALSE; - emit2 ("; genPlusIncr"); + emitDebug ("; genPlusIncr"); icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit); @@ -2601,7 +2642,9 @@ genPlusIncr (iCode * ic) if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic)))) { while (icount--) - emit2 ("inc %s", aopGet (AOP (IC_LEFT (ic)), 0, FALSE)); + { + emit2 ("inc %s", aopGet (AOP (IC_LEFT (ic)), 0, FALSE)); + } return TRUE; } @@ -2680,7 +2723,7 @@ genPlus (iCode * ic) if (genPlusIncr (ic) == TRUE) goto release; - emit2 ("; genPlusIncr failed"); + emitDebug ("; genPlusIncr failed"); size = getDataSize (IC_RESULT (ic)); @@ -2773,7 +2816,7 @@ genPlus (iCode * ic) } else if (size == 4) { - emit2 ("; WARNING: This add is probably broken.\n"); + emitDebug ("; WARNING: This add is probably broken.\n"); } } } @@ -2831,26 +2874,6 @@ genMinusDec (iCode * ic) size = getDataSize (IC_RESULT (ic)); -#if 0 - /* if increment 16 bits in register */ - if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) && - (size > 1) && - (icount == 1)) - { - symbol *tlbl = newiTempLabel (NULL); - emit2 ("dec %s", aopGet (AOP (IC_RESULT (ic)), LSB, FALSE)); - emit2 ("jp np," LABEL_STR, tlbl->key + 100); - - emit2 ("dec %s", aopGet (AOP (IC_RESULT (ic)), MSB16, FALSE)); - if (size == 4) - { - wassert (0); - } - emitLabel (tlbl->key + 100); - return TRUE; - } -#endif - /* if decrement 16 bits in register */ if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) && (size > 1) && isPair (AOP (IC_RESULT (ic)))) @@ -2870,6 +2893,22 @@ genMinusDec (iCode * ic) return TRUE; } + /* if increment 16 bits in register */ + if (sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) && + (size == 2)) + { + fetchPair (PAIR_HL, AOP (IC_RESULT (ic))); + + while (icount--) { + emit2 ("dec hl"); + } + aopPut (AOP (IC_RESULT (ic)), "l", LSB); + aopPut (AOP (IC_RESULT (ic)), "h", MSB16); + + return TRUE; + } + + /* if the sizes are greater than 1 then we cannot */ if (AOP_SIZE (IC_RESULT (ic)) > 1 || AOP_SIZE (IC_LEFT (ic)) > 1) @@ -2965,7 +3004,7 @@ genMinus (iCode * ic) } else if (size == 4) { - emit2 ("; WARNING: This sub is probably broken.\n"); + emitDebug ("; WARNING: This sub is probably broken.\n"); } } } @@ -3274,7 +3313,7 @@ genCmp (operand * left, operand * right, else { /* Subtract through, propagating the carry */ - emit2 ("sbc a,%s ; 2", aopGet (AOP (right), offset++, FALSE)); + emit2 ("sbc a,%s", aopGet (AOP (right), offset++, FALSE)); } } } @@ -3404,7 +3443,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl) { while (size--) { - emit2 ("ld a,%s ; 2", aopGet (AOP (left), offset, FALSE)); + emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE)); if ((AOP_TYPE (right) == AOP_LIT) && lit == 0) emit2 ("or a,a"); else @@ -3429,7 +3468,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl) emit2 ("jp nz,!tlabel", lbl->key + 100); else { - emit2 ("cp %s ; 4", aopGet (AOP (right), offset, FALSE)); + emit2 ("cp %s", aopGet (AOP (right), offset, FALSE)); emit2 ("jp nz,!tlabel", lbl->key + 100); } offset++; @@ -3442,7 +3481,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl) while (size--) { _moveA (aopGet (AOP (right), offset, FALSE)); - emit2 ("cp %s ; 5", aopGet (AOP (left), offset, FALSE)); + emit2 ("cp %s", aopGet (AOP (left), offset, FALSE)); emit2 ("!shortjp nz,!tlabel", lbl->key + 100); offset++; } @@ -3479,7 +3518,7 @@ genCmpEq (iCode * ic, iCode * ifx) aopOp ((right = IC_RIGHT (ic)), ic, FALSE, FALSE); aopOp ((result = IC_RESULT (ic)), ic, TRUE, FALSE); - emit2("; genCmpEq: left %u, right %u, result %u\n", AOP_SIZE(IC_LEFT(ic)), AOP_SIZE(IC_RIGHT(ic)), AOP_SIZE(IC_RESULT(ic))); + emitDebug ("; genCmpEq: left %u, right %u, result %u\n", AOP_SIZE(IC_LEFT(ic)), AOP_SIZE(IC_RIGHT(ic)), AOP_SIZE(IC_RESULT(ic))); /* Swap operands if it makes the operation easier. ie if: 1. Left is a literal. @@ -3604,9 +3643,9 @@ genAndOp (iCode * ic) else { tlbl = newiTempLabel (NULL); - toBoolean (left); + _toBoolean (left); emit2 ("!shortjp z,!tlabel", tlbl->key + 100); - toBoolean (right); + _toBoolean (right); emitLabel (tlbl->key + 100); outBitAcc (result); } @@ -3641,9 +3680,9 @@ genOrOp (iCode * ic) else { tlbl = newiTempLabel (NULL); - toBoolean (left); + _toBoolean (left); emit2 ("!shortjp nz,!tlabel", tlbl->key + 100); - toBoolean (right); + _toBoolean (right); emitLabel (tlbl->key + 100); outBitAcc (result); } @@ -3714,10 +3753,10 @@ genAnd (iCode * ic, iCode * ifx) aopOp ((result = IC_RESULT (ic)), ic, TRUE, FALSE); #ifdef DEBUG_TYPE - emit2 ("; Type res[%d] = l[%d]&r[%d]", + emitDebug ("; Type res[%d] = l[%d]&r[%d]", AOP_TYPE (result), AOP_TYPE (left), AOP_TYPE (right)); - emit2 ("; Size res[%d] = l[%d]&r[%d]", + emitDebug ("; Size res[%d] = l[%d]&r[%d]", AOP_SIZE (result), AOP_SIZE (left), AOP_SIZE (right)); #endif @@ -3946,10 +3985,10 @@ genOr (iCode * ic, iCode * ifx) aopOp ((result = IC_RESULT (ic)), ic, TRUE, FALSE); #if 1 - emit2 ("; Type res[%d] = l[%d]&r[%d]", + emitDebug ("; Type res[%d] = l[%d]&r[%d]", AOP_TYPE (result), AOP_TYPE (left), AOP_TYPE (right)); - emit2 ("; Size res[%d] = l[%d]&r[%d]", + emitDebug ("; Size res[%d] = l[%d]&r[%d]", AOP_SIZE (result), AOP_SIZE (left), AOP_SIZE (right)); #endif @@ -4302,6 +4341,26 @@ genGetHbit (iCode * ic) freeAsmop (result, NULL, ic); } +static void +emitRsh2 (asmop *aop, int size, int is_signed) +{ + int offset = 0; + + while (size--) + { + const char *l = aopGet (aop, size, FALSE); + if (offset == 0) + { + emit2 ("%s %s", is_signed ? "sra" : "srl", l); + } + else + { + emit2 ("rr %s", l); + } + offset++; + } +} + /*-----------------------------------------------------------------*/ /* shiftR2Left2Result - shift right two bytes from left to result */ /*-----------------------------------------------------------------*/ @@ -4311,9 +4370,7 @@ shiftR2Left2Result (operand * left, int offl, int shCount, int is_signed) { int size = 2; - int offset = 0; symbol *tlbl, *tlbl1; - const char *l; movLeft2Result (left, offl, result, offr, 0); movLeft2Result (left, offl + 1, result, offr + 1, 0); @@ -4322,31 +4379,23 @@ shiftR2Left2Result (operand * left, int offl, tlbl = newiTempLabel (NULL); tlbl1 = newiTempLabel (NULL); - + /* Left is already in result - so now do the shift */ - if (shCount > 1) + if (shCount <= 2) { - emit2 ("ld a,!immedbyte+1", shCount); - emit2 ("!shortjp !tlabel", tlbl1->key + 100); - emitLabel (tlbl->key + 100); - } - - offset = 0; - while (size--) - { - l = aopGet (AOP (result), size, FALSE); - if (offset == 0) - { - emit2 ("%s %s", is_signed ? "sra" : "srl", l); - } - else + while (shCount--) { - emit2 ("rr %s", l); + emitRsh2 (AOP (result), size, is_signed); } - offset++; } - if (shCount > 1) + else { + emit2 ("ld a,!immedbyte+1", shCount); + emit2 ("!shortjp !tlabel", tlbl1->key + 100); + emitLabel (tlbl->key + 100); + + emitRsh2 (AOP (result), size, is_signed); + emitLabel (tlbl1->key + 100); emit2 ("dec a"); emit2 ("!shortjp nz,!tlabel", tlbl->key + 100); @@ -4577,7 +4626,7 @@ genLeftShiftLiteral (operand * left, size = getSize (operandType (result)); #if VIEW_SIZE - emit2 ("; shift left result %d, left %d", size, + emitDebug ("; shift left result %d, left %d", size, AOP_SIZE (left)); #endif @@ -4827,7 +4876,7 @@ genRightShiftLiteral (operand * left, size = getSize (operandType (result)); - emit2 ("; shift right result %d, left %d", size, + emitDebug ("; shift right result %d, left %d", size, AOP_SIZE (left)); /* I suppose that the left size >= result size */ @@ -5167,7 +5216,7 @@ genIfx (iCode * ic, iCode * popIc) /* get the value into acc */ if (AOP_TYPE (cond) != AOP_CRY) - toBoolean (cond); + _toBoolean (cond); else isbit = 1; /* the result is now in the accumulator */ @@ -5264,7 +5313,7 @@ genAssign (iCode * ic) /* Dont bother assigning if they are the same */ if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic))) { - emit2 ("; (operands are equal %u)", operandsEqu (IC_RESULT (ic), IC_RIGHT (ic))); + emitDebug ("; (operands are equal %u)", operandsEqu (IC_RESULT (ic), IC_RIGHT (ic))); return; } #endif @@ -5275,7 +5324,7 @@ genAssign (iCode * ic) /* if they are the same registers */ if (sameRegs (AOP (right), AOP (result))) { - emit2 ("; (registers are the same)"); + emitDebug ("; (registers are the same)"); goto release; } @@ -5476,7 +5525,7 @@ genCast (iCode * ic) const char *l = aopGet (AOP (right), AOP_SIZE (right) - 1, FALSE); _moveA (l); - emit2 ("; genCast: sign extend untested."); + emitDebug ("; genCast: sign extend untested."); emit2 ("rla "); emit2 ("sbc a,a"); while (size--) @@ -5545,7 +5594,7 @@ genZ80Code (iCode * lic) if (cln != ic->lineno) { - emit2 ("; %s %d", ic->filename, ic->lineno); + emitDebug ("; %s %d", ic->filename, ic->lineno); cln = ic->lineno; } /* if the result is marked as @@ -5559,22 +5608,22 @@ genZ80Code (iCode * lic) switch (ic->op) { case '!': - emit2 ("; genNot"); + emitDebug ("; genNot"); genNot (ic); break; case '~': - emit2 ("; genCpl"); + emitDebug ("; genCpl"); genCpl (ic); break; case UNARYMINUS: - emit2 ("; genUminus"); + emitDebug ("; genUminus"); genUminus (ic); break; case IPUSH: - emit2 ("; genIpush"); + emitDebug ("; genIpush"); genIpush (ic); break; @@ -5589,83 +5638,83 @@ genZ80Code (iCode * lic) ic->next->op == IFX && regsInCommon (IC_LEFT (ic), IC_COND (ic->next))) { - emit2 ("; genIfx"); + emitDebug ("; genIfx"); genIfx (ic->next, ic); } else { - emit2 ("; genIpop"); + emitDebug ("; genIpop"); genIpop (ic); } break; case CALL: - emit2 ("; genCall"); + emitDebug ("; genCall"); genCall (ic); break; case PCALL: - emit2 ("; genPcall"); + emitDebug ("; genPcall"); genPcall (ic); break; case FUNCTION: - emit2 ("; genFunction"); + emitDebug ("; genFunction"); genFunction (ic); break; case ENDFUNCTION: - emit2 ("; genEndFunction"); + emitDebug ("; genEndFunction"); genEndFunction (ic); break; case RETURN: - emit2 ("; genRet"); + emitDebug ("; genRet"); genRet (ic); break; case LABEL: - emit2 ("; genLabel"); + emitDebug ("; genLabel"); genLabel (ic); break; case GOTO: - emit2 ("; genGoto"); + emitDebug ("; genGoto"); genGoto (ic); break; case '+': - emit2 ("; genPlus"); + emitDebug ("; genPlus"); genPlus (ic); break; case '-': - emit2 ("; genMinus"); + emitDebug ("; genMinus"); genMinus (ic); break; case '*': - emit2 ("; genMult"); + emitDebug ("; genMult"); genMult (ic); break; case '/': - emit2 ("; genDiv"); + emitDebug ("; genDiv"); genDiv (ic); break; case '%': - emit2 ("; genMod"); + emitDebug ("; genMod"); genMod (ic); break; case '>': - emit2 ("; genCmpGt"); + emitDebug ("; genCmpGt"); genCmpGt (ic, ifxForOp (IC_RESULT (ic), ic)); break; case '<': - emit2 ("; genCmpLt"); + emitDebug ("; genCmpLt"); genCmpLt (ic, ifxForOp (IC_RESULT (ic), ic)); break; @@ -5680,67 +5729,67 @@ genZ80Code (iCode * lic) break; case EQ_OP: - emit2 ("; genCmpEq"); + emitDebug ("; genCmpEq"); genCmpEq (ic, ifxForOp (IC_RESULT (ic), ic)); break; case AND_OP: - emit2 ("; genAndOp"); + emitDebug ("; genAndOp"); genAndOp (ic); break; case OR_OP: - emit2 ("; genOrOp"); + emitDebug ("; genOrOp"); genOrOp (ic); break; case '^': - emit2 ("; genXor"); + emitDebug ("; genXor"); genXor (ic, ifxForOp (IC_RESULT (ic), ic)); break; case '|': - emit2 ("; genOr"); + emitDebug ("; genOr"); genOr (ic, ifxForOp (IC_RESULT (ic), ic)); break; case BITWISEAND: - emit2 ("; genAnd"); + emitDebug ("; genAnd"); genAnd (ic, ifxForOp (IC_RESULT (ic), ic)); break; case INLINEASM: - emit2 ("; genInline"); + emitDebug ("; genInline"); genInline (ic); break; case RRC: - emit2 ("; genRRC"); + emitDebug ("; genRRC"); genRRC (ic); break; case RLC: - emit2 ("; genRLC"); + emitDebug ("; genRLC"); genRLC (ic); break; case GETHBIT: - emit2 ("; genGetHBIT"); + emitDebug ("; genGetHBIT"); genGetHbit (ic); break; case LEFT_OP: - emit2 ("; genLeftShift"); + emitDebug ("; genLeftShift"); genLeftShift (ic); break; case RIGHT_OP: - emit2 ("; genRightShift"); + emitDebug ("; genRightShift"); genRightShift (ic); break; case GET_VALUE_AT_ADDRESS: - emit2 ("; genPointerGet"); + emitDebug ("; genPointerGet"); genPointerGet (ic); break; @@ -5748,43 +5797,43 @@ genZ80Code (iCode * lic) if (POINTER_SET (ic)) { - emit2 ("; genAssign (pointer)"); + emitDebug ("; genAssign (pointer)"); genPointerSet (ic); } else { - emit2 ("; genAssign"); + emitDebug ("; genAssign"); genAssign (ic); } break; case IFX: - emit2 ("; genIfx"); + emitDebug ("; genIfx"); genIfx (ic, NULL); break; case ADDRESS_OF: - emit2 ("; genAddrOf"); + emitDebug ("; genAddrOf"); genAddrOf (ic); break; case JUMPTABLE: - emit2 ("; genJumpTab"); + emitDebug ("; genJumpTab"); genJumpTab (ic); break; case CAST: - emit2 ("; genCast"); + emitDebug ("; genCast"); genCast (ic); break; case RECEIVE: - emit2 ("; genReceive"); + emitDebug ("; genReceive"); genReceive (ic); break; case SEND: - emit2 ("; addSet"); + emitDebug ("; addSet"); addSet (&_G.sendSet, ic); break; diff --git a/src/z80/main.c b/src/z80/main.c index 9fb9b075..f27157b2 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -294,10 +294,11 @@ _setDefaultOptions (void) params is the parameter format policy format: - rs + rsp where: r is 'r' for reentrant, 's' for static functions s is 'c' for callee saves, 'r' for caller saves + p is 'p' for profiling on, 'x' for profiling off examples: rr - reentrant, caller saves params format: @@ -313,14 +314,10 @@ _mangleSupportFunctionName(char *original) if (TARGET_IS_Z80) { - if (options.noRegParams) - { - sprintf(buffer, "%s_rr_s", original); - } - else - { - sprintf(buffer, "%s_rr_bds", original); - } + sprintf(buffer, "%s_rr%s_%s", original, + options.profile ? "f" : "x", + options.noRegParams ? "s" : "bds" + ); } else { diff --git a/src/z80/mappings.i b/src/z80/mappings.i index e61aaada..d2887dc1 100644 --- a/src/z80/mappings.i +++ b/src/z80/mappings.i @@ -27,6 +27,14 @@ static const ASM_MAPPING _asxxxx_gb_mapping[] = { }, { "adjustsp", "lda sp,-%d(sp)" }, { "fileprelude", "" }, + { "profileenter", + "ld a,#3\n" + "\trst\t0x08" + }, + { "profileexit", + "ld a,#4\n" + "\trst\t0x08" + }, { NULL, NULL } }; @@ -78,6 +86,14 @@ static const ASM_MAPPING _asxxxx_z80_mapping[] = { "\tpush\thl" }, { "adjustsp", "lda sp,-%d(sp)" }, + { "profileenter", + "ld a,#3\n" + "\trst\t0x08" + }, + { "profileexit", + "ld a,#4\n" + "\trst\t0x08" + }, { NULL, NULL } }; diff --git a/src/z80/peeph-z80.def b/src/z80/peeph-z80.def index 44a07dfb..90336dde 100644 --- a/src/z80/peeph-z80.def +++ b/src/z80/peeph-z80.def @@ -1,17 +1,9 @@ -replace restart { - or a,%1(%2) - or a,a - jp nz,%3 -} by { - or a,%1(%2) - ; Removed redundent OR - jp nz,%3 -} replace restart { ld a,%1(%2) bit %3,a jp %4,%5 } by { + ; Rule 100: Removed redundent load bit %3,%1(%2) jp %4,%5 } diff --git a/src/z80/peeph.def b/src/z80/peeph.def index a866d187..00375bed 100644 --- a/src/z80/peeph.def +++ b/src/z80/peeph.def @@ -6,7 +6,7 @@ replace restart { replace restart { ld %1,%1 } by { - ; Removed redundent load + ; Rule 1: Removed redundent load } replace restart { xor a,a @@ -14,7 +14,6 @@ replace restart { or a,a jp %2,%3 } by { - ; Removed redundent or a,a xor a,a or a,%1 jp %2,%3 @@ -23,7 +22,7 @@ replace restart { cp a,#0x00 jp nz,%1 } by { - ; Rule 3 + ; Rule 3: Changed cp #0 to or or a,a jp nz,%1 } @@ -34,7 +33,7 @@ replace restart { jp %3 %2: } by { - ; Rule 4 + ; Rule 4: Changed jp order jp z,%2 %1: jp %3 @@ -45,7 +44,7 @@ replace restart { jp %2 %1: } by { - ; Rule 5 + ; Rule 5: Changed jump logic jp z,%2 %1: } @@ -54,16 +53,52 @@ replace restart { jp %2 %1: } by { - ; Rule 6 + ; Rule 6: Changed jump logic jp nz,%2 %1: } replace restart { - ld a,%1 - or a,%2 + or a,%1 or a,a } by { - ; Rule 8 - ld a,%1 - or a,%2 + ; Rule 7: Removed redundent or + or a,%1 +} +replace restart { + or a,%1) + or a,a +} by { + ; Rule 8: Removed redundent or for (ix) + or a,%1) +} +replace restart { + xor a,a + or a,%1 + jp nz,%2 + xor a,a + or a,%3 + jp z,%2 +} by { + xor a,a + or a,%1 + jp nz,%2 + or a,%3 + jp z,%2 +} +replace restart { + jp nz,%1 + inc %3) +%1: + jp %2 +} by { + jp nz,%2 + inc %3) +%1: + jp %2 +} +replace restart { + xor a,a + ld a,#0x00 +} by { + xor a,a } diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index fce6009e..79ea8277 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -57,7 +57,9 @@ enum enum { D_ALLOC = 0, - D_ALLOC2 = 0 + D_ALLOC2 = 0, + D_ACCUSE2 = 0, + D_ACCUSE2_VERBOSE = 0 }; #if 1 @@ -306,9 +308,8 @@ allLRs (symbol * sym, eBBlock * ebp, iCode * ic) return 1; } -/*-----------------------------------------------------------------*/ -/* liveRangesWith - applies function to a given set of live range */ -/*-----------------------------------------------------------------*/ +/** liveRangesWith - applies function to a given set of live range + */ set * liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *), eBBlock * ebp, iCode * ic) @@ -342,9 +343,8 @@ liveRangesWith (bitVect * lrs, int (func) (symbol *, eBBlock *, iCode *), } -/*-----------------------------------------------------------------*/ -/* leastUsedLR - given a set determines which is the least used */ -/*-----------------------------------------------------------------*/ +/** leastUsedLR - given a set determines which is the least used + */ symbol * leastUsedLR (set * sset) { @@ -375,9 +375,8 @@ leastUsedLR (set * sset) return sym; } -/*-----------------------------------------------------------------*/ -/* noOverLap - will iterate through the list looking for over lap */ -/*-----------------------------------------------------------------*/ +/** noOverLap - will iterate through the list looking for over lap + */ static int noOverLap (set * itmpStack, symbol * fsym) { @@ -1430,7 +1429,7 @@ packRegsForAssign (iCode * ic, eBBlock * ebp) { iCode *dic, *sic; - D (D_ALLOC, ("packRegsForAssing: running on ic %p\n", ic)); + D (D_ALLOC, ("packRegsForAssign: running on ic %p\n", ic)); if ( /* !IS_TRUE_SYMOP(IC_RESULT(ic)) || */ @@ -2004,25 +2003,48 @@ hluse: OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_HL; } -bool +static bool opPreservesA (iCode * ic, iCode * uic) { - /* if it is a conditional branch then we definitely can */ if (uic->op == IFX) - return FALSE; + { + return TRUE; + + if (getSize (operandType (IC_COND (uic))) == 1 && + IS_OP_LITERAL (IC_COND (uic))) + { + return TRUE; + } + + D (D_ACCUSE2, (" + Dropping as operation is an IFX\n")); + return FALSE; + } if (uic->op == JUMPTABLE) - return FALSE; + { + D (D_ACCUSE2, (" + Dropping as operation is a Jumptable\n")); + return FALSE; + } + + /* A pointer assign preserves A if A is the left value. */ + if (uic->op == '=' && POINTER_SET (uic)) + { + return TRUE; + } /* if the usage has only one operand then we can */ /* PENDING: check */ if (IC_LEFT (uic) == NULL || IC_RIGHT (uic) == NULL) - return FALSE; + { + D (D_ACCUSE2, (" + Dropping as operation has only one operand\n")); + return FALSE; + } /* PENDING: check this rule */ if (getSize (operandType (IC_RESULT (uic))) > 1) { + D (D_ACCUSE2, (" + Dropping as operation has size is too big\n")); return FALSE; } @@ -2042,65 +2064,116 @@ opPreservesA (iCode * ic, iCode * uic) 1 ) { + D (D_ACCUSE2, (" + Dropping as 'its a bad op'\n")); return FALSE; } /* PENDING */ if (!IC_LEFT (uic) || !IC_RESULT (ic)) - return FALSE; + { + D (D_ACCUSE2, (" + Dropping for some reason #1\n")); + return FALSE; + } /** This is confusing :) Guess for now */ if (IC_LEFT (uic)->key == IC_RESULT (ic)->key && (IS_ITEMP (IC_RIGHT (uic)) || (IS_TRUE_SYMOP (IC_RIGHT (uic))))) - return TRUE; + { + return TRUE; + } if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key && (IS_ITEMP (IC_LEFT (uic)) || (IS_TRUE_SYMOP (IC_LEFT (uic))))) - return TRUE; + { + return TRUE; + } + + D (D_ACCUSE2, (" + Dropping as hit default case\n")); return FALSE; } -static void -joinPushes (iCode * ic) +static bool +opIgnoresA (iCode * ic, iCode * uic) { -#if 0 - if (ic->op == IPUSH && - isOperandLiteral (IC_LEFT (ic)) && - getSize (operandType (IC_LEFT (ic))) == 1 && - ic->next->op == IPUSH && - isOperandLiteral (IC_LEFT (ic->next)) && - getSize (operandType (IC_LEFT (ic->next))) == 1) - { - /* This is a bit tricky as michaelh doesnt know what he's doing. - */ - /* First upgrade the size of (first) to int */ - SPEC_NOUN (operandType (IC_LEFT (ic))) = V_INT; - - floatFromVal (AOP /* need some sleep ... */ ); - /* Now get and join the values */ - value *val = aop->aopu.aop_lit; - /* if it is a float then it gets tricky */ - /* otherwise it is fairly simple */ - if (!IS_FLOAT (val->type)) - { - unsigned long v = floatFromVal (val); - - floatFrom ( /* need some sleep ... */ ); - printf ("Size %u\n", getSize (operandType (IC_LEFT (ic)))); - ic->next = ic->next->next; - } + /* A increment of an iTemp by a constant is OK. */ + if ( uic->op == '+' && + IS_ITEMP (IC_LEFT (uic)) && + IS_ITEMP (IC_RESULT (uic)) && + IS_OP_LITERAL (IC_RIGHT (uic))) + { + unsigned int icount = (unsigned int) floatFromVal (IC_RIGHT (uic)->operand.valOperand); + + /* Being an ITEMP means that we're already a symbol. */ + if (icount == 1 && + IC_RESULT (uic)->operand.symOperand->key == IC_LEFT (uic)->operand.symOperand->key + ) + { + return TRUE; + } } -#endif + + return FALSE; } + +/* Some optimisation cases: + + 1. Part of memcpy +; genPointerGet + ld l,-4(ix) + ld h,-3(ix) + ld c,(hl) +; genPlus + inc -4(ix) + jp nz,00108$ + inc -3(ix) +00108$: +; genAssign (pointer) + ld a,c + ld (de),a + + want to optimise down to: + ld hl,-4(ix) ... + ld a,(hl) + inc -4(ix).w ... + ld (de),a + + So genPointer get is OK + genPlus where the right is constant, left is iTemp, and result is same as left + genAssign (pointer) is OK + + 2. Part of _strcpy +; genPointerGet + ld a,(de) + ld c,a +; genIfx + xor a,a + or a,c + jp z,00103$ +; _strcpy.c 40 +; genAssign (pointer) +; AOP_STK for _strcpy_to_1_1 + ld l,-2(ix) + ld h,-1(ix) + ld (hl),c + + want to optimise down to: + ld a,(de) + or a,a + jp z,00103$ + ld (bc),a + + So genIfx where IC_COND has size of 1 and is a constant. +*/ + /** Pack registers for acc use. When the result of this operation is small and short lived it may be able to be stored in the accumulator. - Note that the 'A preserving' list is currently emperical :)e + Note that the 'A preserving' list is currently emperical :) */ static void packRegsForAccUse2 (iCode * ic) @@ -2118,14 +2191,20 @@ packRegsForAccUse2 (iCode * ic) ic->op != EQ_OP && ic->op != CAST && 1) - return; + { + D (D_ACCUSE2, (" + Dropping as not a 'good' source command\n")); + return; + } /* if + or - then it has to be one byte result. MLH: Ok. */ if ((ic->op == '+' || ic->op == '-') && getSize (operandType (IC_RESULT (ic))) > 1) - return; + { + D (D_ACCUSE2, (" + Dropping as it's a big + or -\n")); + return; + } /* if shift operation make sure right side is not a literal. MLH: depends. @@ -2145,6 +2224,7 @@ packRegsForAccUse2 (iCode * ic) /* has only one definition */ if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1) { + D (D_ACCUSE2, (" + Dropping as it has more than one definition\n")); return; } @@ -2160,6 +2240,7 @@ packRegsForAccUse2 (iCode * ic) if (!(uic = hTabItemWithKey (iCodehTab, bitVectFirstBit (OP_USES (IC_RESULT (ic)))))) { + D (D_ACCUSE2, (" + Dropping as usage does not follow first\n")); return; } @@ -2175,20 +2256,59 @@ packRegsForAccUse2 (iCode * ic) next = hTabItemWithKey (iCodehTab, setBit); if (scan->next == next) { + D (D_ACCUSE2_VERBOSE, (" ! Is next in line\n")); + bitVectUnSetBit (uses, setBit); /* Still contigous. */ if (!opPreservesA (ic, next)) { + D (D_ACCUSE2, (" + Dropping as operation doesn't preserve A\n")); return; } + D (D_ACCUSE2_VERBOSE, (" ! Preserves A, so continue scanning\n")); scan = next; } + else if (scan->next == NULL && bitVectnBitsOn (uses) == 1 && next != NULL) + { + if (next->prev == NULL) + { + if (!opPreservesA (ic, next)) + { + D (D_ACCUSE2, (" + Dropping as operation doesn't preserve A #2\n")); + return; + } + bitVectUnSetBit (uses, setBit); + scan = next; + } + else + { + D (D_ACCUSE2, (" + Dropping as last in list and next doesn't start a block\n")); + return; + } + } + else if (scan->next == NULL) + { + D (D_ACCUSE2, (" + Dropping as hit the end of the list\n")); + D (D_ACCUSE2, (" + Next in htab: %p\n", next)); + return; + } else { - return; + if (opIgnoresA (ic, scan->next)) + { + /* Safe for now. */ + scan = scan->next; + D (D_ACCUSE2_VERBOSE, (" ! Op ignores A, so continue scanning\n")); + } + else + { + D (D_ACCUSE2, (" + Dropping as parts are not consecuitive and intermediate might use A\n")); + return; + } } } while (!bitVectIsZero (uses)); + OP_SYMBOL (IC_RESULT (ic))->accuse = ACCUSE_A; return; } @@ -2441,7 +2561,6 @@ packRegisters (eBBlock * ebp) packRegsForAccUse2 (ic); } #endif - joinPushes (ic); } } diff --git a/support/regression/ports/z80/spec.mk b/support/regression/ports/z80/spec.mk index dab2071e..13339495 100644 --- a/support/regression/ports/z80/spec.mk +++ b/support/regression/ports/z80/spec.mk @@ -3,7 +3,7 @@ RRZ80 = $(SDCC_EXTRA_DIR)/emu/rrz80/rrz80 -SDCCFLAGS += --lesspedantic +SDCCFLAGS += --lesspedantic --profile EXEEXT = .bin diff --git a/support/regression/tests/muldiv.c b/support/regression/tests/muldiv.c index a8641d21..36e3ef11 100644 --- a/support/regression/tests/muldiv.c +++ b/support/regression/tests/muldiv.c @@ -6,7 +6,7 @@ */ #include -static void +void testUnsignedModDiv(void) { {attr} {storage} unsigned {type} i; @@ -27,7 +27,7 @@ testUnsignedModDiv(void) ASSERT(result == 32); } -static void +void testUnsignedMul(void) { {attr} {storage} unsigned {type} i; @@ -43,7 +43,7 @@ testUnsignedMul(void) ASSERT(result == ((unsigned {type})444)); } -static void +void testMul(void) { {attr} {storage} signed {type} i; @@ -66,7 +66,7 @@ testMul(void) LOG(("30 == %u\n", (int)i*-3)); } -static void +void testDiv(void) { {attr} {storage} signed {type} i; @@ -84,7 +84,7 @@ testDiv(void) ASSERT(i/-12 == 4); } -static void +void testMod(void) { {attr} {storage} signed {type} i; diff --git a/support/tests/dhrystone/Makefile b/support/tests/dhrystone/Makefile index 934de057..341448c4 100644 --- a/support/tests/dhrystone/Makefile +++ b/support/tests/dhrystone/Makefile @@ -6,11 +6,11 @@ PROC = z80 CC = $(TOPDIR)/bin/sdcc # -DNOENUM is here to make the results more predictable -CFLAGS += -DREG= -DNOSTRUCTASSIGN -DNOENUM -V -m$(PROC) +CFLAGS += -DREG= -DNOSTRUCTASSIGN -DNOENUM -V -m$(PROC) --profile OBJ = dhry.o -all: dhry.ihx +all: dhry.bin dhry.ihx: dhry.c $(CC) $(CFLAGS) dhry.c diff --git a/support/tests/dhrystone/dhry.c b/support/tests/dhrystone/dhry.c index 0180c661..bdba9c41 100644 --- a/support/tests/dhrystone/dhry.c +++ b/support/tests/dhrystone/dhry.c @@ -56,9 +56,11 @@ #define memcpy(d,s,l) memcpyx(d,s,l) #elif defined(__z80) -int _clock(void); +unsigned int _clock(void); + #define clock _clock -#define CLOCKS_PER_SEC 10 +#define CLOCKS_PER_SEC 100 +#define PRINT_T_STATES 1 #else /** For clock() */ @@ -76,7 +78,7 @@ void _printTStates(void); /** Set to one to print more messages about expected values etc. */ -#define DEBUG 1 +#define DEBUG 0 #if DEBUG #define DPRINTF(_a) printf _a @@ -149,7 +151,7 @@ int main(void) #if DEBUG Number_Of_Runs = 3; #else - Number_Of_Runs = 10000; + Number_Of_Runs = 32766; #endif runTime = clock(); @@ -288,12 +290,17 @@ int main(void) printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n"); printf ("\n"); #endif - // printf("Dhrystones/s = %lu\n", (unsigned long)Number_Of_Runs / (runTime/CLOCKS_PER_SEC)); +#if 1 + printf("Number of runs: %u. runTime: %u.\n", Number_Of_Runs, (unsigned)runTime); + printf("Dhrystones/s = %u\n", (unsigned)((unsigned long)Number_Of_Runs / (runTime/CLOCKS_PER_SEC))); printf("MIPS = d/s/1757 = (sigh, need floats...)\n"); +#endif #ifdef PRINT_T_STATES _printTStates(); #endif +#if 1 printf("Time: %lu ticks\n", runTime); +#endif } void Proc_1 (REG Rec_Pointer Ptr_Val_Par)