From 99bc0b93a68e12551d7c061a435715008835d50a Mon Sep 17 00:00:00 2001 From: spth Date: Thu, 25 Dec 2008 23:26:11 +0000 Subject: [PATCH] Implemented RFE #1899189 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@5299 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 7 +++++ src/z80/gen.c | 72 +++++++++++++++++++++++++++++++++++++++++++ src/z80/main.c | 7 +++++ src/z80/peep.c | 13 ++++++-- src/z80/peeph-z80.def | 2 +- 5 files changed, 97 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5cd3afa5..ece91a9b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-12-26 Philipp Klaus Krause + + * src/z80/peeph-z80.def: fixed a bug in peephole 0zf + * src/z80/peep.c: improved checks for unused data + * src/z80/gen.c, + src/z80/main.c: Implemented RFE #1899189 + 2008-12-25 Borut Razem * support/regression/Makefile.in: diff --git a/src/z80/gen.c b/src/z80/gen.c index 226434d2..d055c7a1 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -4215,6 +4215,72 @@ release: freeAsmop (IC_RESULT (ic), NULL, ic); } +/*-----------------------------------------------------------------*/ +/* genMultChar - generates code for unsigned 8x8 multiplication */ +/*-----------------------------------------------------------------*/ +static void +genMultOneChar (iCode * ic) +{ + symbol *tlbl1, *tlbl2; + bool savedB = FALSE; + + if(IS_GB) + { + wassertl (0, "Multiplication is handled through support function calls on gbz80"); + return; + } + + /* Save b into a if b is in use. */ + if (bitVectBitValue (ic->rMask, B_IDX) && + !(getPairId (AOP (IC_RESULT (ic))) == PAIR_BC)) + { + emit2 ("ld a, b"); + savedB = TRUE; + } + if (isPairInUse (PAIR_DE, ic) && + !(getPairId (AOP (IC_RESULT (ic))) == PAIR_DE)) + { + _push (PAIR_DE); + _G.stack.pushedDE = TRUE; + } + + tlbl1 = newiTempLabel (NULL); + tlbl2 = newiTempLabel (NULL); + + emit2 ("ld e,%s", aopGet (AOP (IC_RIGHT (ic)), LSB, FALSE)); + emit2 ("ld h,%s", aopGet (AOP (IC_LEFT (ic)), LSB, FALSE)); + emit2 ("ld l,#0x00"); + emit2 ("ld d,l"); + emit2 ("ld b,#0x08"); + emitLabel (tlbl1->key + 100); + emit2 ("add hl,hl"); + emit2 ("jp NC,!tlabel", tlbl2->key + 100); + emit2 ("add hl,de"); + emitLabel (tlbl2->key + 100); + emit2 ("djnz !tlabel", tlbl1->key + 100); + + spillPair(PAIR_HL); + + if (IS_Z80 && _G.stack.pushedDE) + { + _pop (PAIR_DE); + _G.stack.pushedDE = FALSE; + } + if (savedB) + { + emit2 ("ld b, a"); + } + + if (AOP_SIZE (IC_RESULT (ic)) == 1) + aopPut (AOP (IC_RESULT (ic)), "l", 0); + else + 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); +} + /*-----------------------------------------------------------------*/ /* genMult - generates code for multiplication */ /*-----------------------------------------------------------------*/ @@ -4249,6 +4315,12 @@ genMult (iCode * ic) IC_LEFT (ic) = t; } + if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) + { + genMultOneChar (ic); + return; + } + wassertl (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT, "Right must be a literal"); val = (int) ulFromVal ( AOP (IC_RIGHT (ic))->aopu.aop_lit); diff --git a/src/z80/main.c b/src/z80/main.c index 86501c99..2f94e361 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -652,6 +652,13 @@ _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right) test = right; val = OP_VALUE (IC_RIGHT (ic)); } + /* 8x8 unsigned multiplication code is shorter than + call overhead for the multiplication routine. */ + else if ( IS_CHAR (right) && IS_UNSIGNED (right) && + IS_CHAR (left) && IS_UNSIGNED(left) && !IS_GB) + { + return TRUE; + } else { return FALSE; diff --git a/src/z80/peep.c b/src/z80/peep.c index 7e27c07e..ff72544b 100644 --- a/src/z80/peep.c +++ b/src/z80/peep.c @@ -229,8 +229,11 @@ z80MightRead(const lineNode *pl, const char *what) strncmp(pl->line, "sub\t", 4) == 0 || strncmp(pl->line, "xor\t", 4) == 0) { - if( strstr(pl->line + 3, what) == 0 && strcmp("a", what)) - return FALSE; + if( strstr(pl->line + 3, what) != 0) + return TRUE; + if( strstr(pl->line + 3, "hl") == 0 && strcmp("a", what) == 0) + return TRUE; + return FALSE; } if(strncmp(pl->line, "pop\t", 4) == 0) @@ -255,6 +258,9 @@ z80MightRead(const lineNode *pl, const char *what) (bool)(strncmp(pl->line, "jr\t", 3)) == 0) return FALSE; + if(strncmp(pl->line, "djnz\t", 5) == 0) + return(strchr(what, 'b') != 0); + if(strncmp(pl->line, "rla", 3) == 0 || strncmp(pl->line, "rlca", 4) == 0) return(strcmp(what, "a") == 0); @@ -275,7 +281,8 @@ static bool z80CondJump(const lineNode *pl) { if((strncmp(pl->line, "jp\t", 3) == 0 || - strncmp(pl->line, "jr\t", 3) == 0) && strchr(pl->line, ',') != 0) + strncmp(pl->line, "jr\t", 3) == 0) && strchr(pl->line, ',') != 0 || + strncmp(pl->line, "djnz\t", 5) == 0) return TRUE; return FALSE; } diff --git a/src/z80/peeph-z80.def b/src/z80/peeph-z80.def index a92ead4e..706c6ead 100644 --- a/src/z80/peeph-z80.def +++ b/src/z80/peeph-z80.def @@ -347,7 +347,7 @@ replace restart { ; peephole 0zf used hl instead of iy. ld hl,#%1 + %2 ld (hl), %4 -} if notUsed('iy'), notUsed('hl') +} if notUsed('iy'), notUsed('hl'), operandsNotRelated(%4 'h'), operandsNotRelated(%4 'l') replace restart { ld e,l -- 2.30.2