From 272375bec00437e18d3e3912902b32d320c754c8 Mon Sep 17 00:00:00 2001 From: michaelh Date: Sun, 9 Sep 2001 01:47:13 +0000 Subject: [PATCH] * support/regression/tests/fetchoverlap.c: Added new test case. * support/regression/tests/bp.c: Added new test case. * support/regression/tests/bug-448984.c: Added new test case. * support/regression/tests/pow2shifts.c: Added new test case. * src/z80/gen.c: Turned off the noise it normally generates for the release. (genlshTwo): Fixed right shift for count > 8. * src/z80/ralloc.c: Disabled most of the ACC packing rules as they weren't getting hit and weren't at all safe. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1244 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 15 ++ src/z80/gen.c | 180 ++++-------------------- src/z80/ralloc.c | 78 ++-------- support/regression/tests/bp.c | 43 ++++++ support/regression/tests/bug-448984.c | 16 +++ support/regression/tests/fetchoverlap.c | 33 +++++ support/regression/tests/pow2shifts.c | 22 +++ support/tests/dhrystone/Makefile | 4 +- 8 files changed, 170 insertions(+), 221 deletions(-) create mode 100644 support/regression/tests/bp.c create mode 100644 support/regression/tests/bug-448984.c create mode 100644 support/regression/tests/fetchoverlap.c create mode 100644 support/regression/tests/pow2shifts.c diff --git a/ChangeLog b/ChangeLog index cc43b873..12b0ac99 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2001-09-08 Michael Hope + + * support/regression/tests/fetchoverlap.c: Added new test case. + + * support/regression/tests/bp.c: Added new test case. + + * support/regression/tests/bug-448984.c: Added new test case. + + * support/regression/tests/pow2shifts.c: Added new test case. + + * src/z80/gen.c: Turned off the noise it normally generates for the release. + (genlshTwo): Fixed right shift for count > 8. + + * src/z80/ralloc.c: Disabled most of the ACC packing rules as they weren't getting hit and weren't at all safe. + 2001-09-08 * src/SDCCicode.c (geniCodeCall): a CPOINTER can be used as a function diff --git a/src/z80/gen.c b/src/z80/gen.c index d348eb55..e0a478f9 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -96,7 +96,7 @@ #include "SDCCglue.h" #include "newalloc.h" -/* this is the down and dirty file with all kinds of kludgy & hacky +/* This is the down and dirty file with all kinds of kludgy & hacky stuff. This is what it is all about CODE GENERATION for a specific MCU. Some of the routines may be reusable, will have to see */ @@ -108,7 +108,7 @@ PENDING: What if the parameter is a long? Everything is caller saves. i.e. the caller must save any registers that it wants to preserve over the call. - The return value is returned in DEHL. DE is normally used as a + GB: The return value is returned in DEHL. DE is normally used as a working register pair. Caller saves allows it to be used for a return value. va args functions do not use register parameters. All arguments @@ -117,8 +117,10 @@ area. ix-0 is the top most local variable. */ -enum { - DISABLE_DEBUG = 0 +enum +{ + /* Set to enable debugging trace statements in the output assembly code. */ + DISABLE_DEBUG = 1 }; static char *_z80_return[] = @@ -133,6 +135,8 @@ static char **_fTmp; extern FILE *codeOutFile; +/** Enum covering all the possible register pairs. + */ typedef enum { PAIR_INVALID, @@ -175,8 +179,13 @@ enum MSB32 }; +/** Code generator persistent data. + */ static struct { + /** Used to optimised setting up of a pair by remebering what it + contains and adjusting instead of reloading where possible. + */ struct { AOP_TYPE last_type; @@ -236,23 +245,6 @@ _getTempPairName(void) return _pairs[_getTempPairId()].name; } -#if 0 -static const char * -_getTempPairPart(int idx) -{ - wassertl (idx == LSB || idx == MSB16, "Invalid pair offset"); - - if (idx == LSB) - { - return _pairs[_getTempPairId()].l; - } - else - { - return _pairs[_getTempPairId()].h; - } -} -#endif - static void _tidyUp (char *buf) { @@ -1475,8 +1467,7 @@ aopPut (asmop * aop, const char *s, int offset) break; if (offset > 0) { - - emitDebug ("; Error aopPut AOP_ACC"); + wassertl (0, "Tried to access past the end of A"); } else { @@ -1542,7 +1533,7 @@ static void movLeft2Result (operand * left, int offl, operand * result, int offr, int sign) { - const char *l; + const char *l; if (!sameRegs (AOP (left), AOP (result)) || (offl != offr)) { l = aopGet (AOP (left), offl, FALSE); @@ -1553,7 +1544,11 @@ movLeft2Result (operand * left, int offl, } else { - wassert (0); + if (getDataSize (left) == offl + 1) + { + emit2 ("ld a,%s", l); + aopPut (AOP (result), "a", offr); + } } } } @@ -1587,7 +1582,6 @@ outBitCLong (operand * result, bool swap_sense) /* if the result is bit */ if (AOP_TYPE (result) == AOP_CRY) { - emitDebug ("; Note: outBitC form 1"); aopPut (AOP (result), "blah", 0); } else @@ -1841,10 +1835,6 @@ assignResultValue (operand * oper) wassert (size <= 4); topInA = requiresHL (AOP (oper)); -#if 0 - if (!IS_GB) - wassert (size <= 2); -#endif if (IS_GB && size == 4 && requiresHL (AOP (oper))) { /* We do it the hard way here. */ @@ -1894,19 +1884,7 @@ _saveRegsForCall(iCode *ic, int sendSetSize) bool bcInRet = FALSE, deInRet = FALSE; bitVect *rInUse; -#if 1 rInUse = bitVectCplAnd (bitVectCopy (ic->rMask), ic->rUsed); -#else - if (IC_RESULT(ic)) - { - rInUse = bitVectCplAnd (bitVectCopy (ic->rMask), z80_rUmaskForOp (IC_RESULT(ic))); - } - else - { - /* Has no result, so in use is all of in use */ - rInUse = ic->rMask; - } -#endif deInUse = bitVectBitValue (rInUse, D_IDX) || bitVectBitValue(rInUse, E_IDX); bcInUse = bitVectBitValue (rInUse, B_IDX) || bitVectBitValue(rInUse, C_IDX); @@ -2223,7 +2201,6 @@ emitCall (iCode * ic, bool ispcall) if (isLitWord (AOP (IC_LEFT (ic)))) { - emitDebug ("; Special case where the pCall is to a constant"); emit2 ("call %s", aopGetLitWordLong (AOP (IC_LEFT (ic)), 0, FALSE)); } else @@ -2425,14 +2402,6 @@ genFunction (iCode * ic) */ _G.receiveOffset = 0; -#if 0 - /* PENDING: hack */ - if (!IS_STATIC (sym->etype)) - { - addSetIfnotP (&publics, sym); - } -#endif - /* Record the last function name for debugging. */ _G.lastFunctionName = sym->rname; @@ -3354,49 +3323,6 @@ genCmp (operand * left, operand * right, } else { -#if 0 - // PENDING: Doesn't work around zero - - /* Special cases: - On the GB: - If the left or the right is a lit: - Load -lit into HL, add to right via, check sense. - */ - if (IS_GB && size == 2 && (AOP_TYPE (right) == AOP_LIT || AOP_TYPE (left) == AOP_LIT)) - { - PAIR_ID id = PAIR_DE; - asmop *lit = AOP (right); - asmop *op = AOP (left); - swap_sense = TRUE; - - if (AOP_TYPE (left) == AOP_LIT) - { - swap_sense = FALSE; - lit = AOP (left); - op = AOP (right); - } - if (sign) - { - emit2 ("ld e,%s", aopGet (op, 0, 0)); - emit2 ("ld a,%s", aopGet (op, 1, 0)); - emit2 ("xor a,!immedbyte", 0x80); - emit2 ("ld d,a"); - } - else - { - id = getPairId (op); - if (id == PAIR_INVALID) - { - fetchPair (PAIR_DE, op); - id = PAIR_DE; - } - } - spillPair (PAIR_HL); - emit2 ("ld hl,%s", fetchLitSpecial (lit, TRUE, sign)); - emit2 ("add hl,%s", _getPairIdName (id)); - goto release; - } -#endif if (AOP_TYPE (right) == AOP_LIT) { lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit); @@ -3910,15 +3836,6 @@ genAnd (iCode * ic, iCode * ifx) aopOp ((right = IC_RIGHT (ic)), ic, FALSE, FALSE); aopOp ((result = IC_RESULT (ic)), ic, TRUE, FALSE); -#ifdef DEBUG_TYPE - emitDebug ("; Type res[%d] = l[%d]&r[%d]", - AOP_TYPE (result), - AOP_TYPE (left), AOP_TYPE (right)); - emitDebug ("; Size res[%d] = l[%d]&r[%d]", - AOP_SIZE (result), - AOP_SIZE (left), AOP_SIZE (right)); -#endif - /* if left is a literal & right is not then exchange them */ if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) || AOP_NEEDSACC (left)) @@ -4142,15 +4059,6 @@ genOr (iCode * ic, iCode * ifx) aopOp ((right = IC_RIGHT (ic)), ic, FALSE, FALSE); aopOp ((result = IC_RESULT (ic)), ic, TRUE, FALSE); -#if 1 - emitDebug ("; Type res[%d] = l[%d]&r[%d]", - AOP_TYPE (result), - AOP_TYPE (left), AOP_TYPE (right)); - emitDebug ("; Size res[%d] = l[%d]&r[%d]", - AOP_SIZE (result), - AOP_SIZE (left), AOP_SIZE (right)); -#endif - /* if left is a literal & right is not then exchange them */ if ((AOP_TYPE (left) == AOP_LIT && AOP_TYPE (right) != AOP_LIT) || AOP_NEEDSACC (left)) @@ -4734,7 +4642,7 @@ genlshTwo (operand * result, operand * left, int shCount) { movLeft2Result (left, LSB, result, MSB16, 0); aopPut (AOP (result), "!zero", 0); - shiftL1Left2Result (left, MSB16, result, MSB16, shCount); + shiftL1Left2Result (left, LSB, result, MSB16, shCount); } else { @@ -4789,11 +4697,6 @@ genLeftShiftLiteral (operand * left, size = getSize (operandType (result)); -#if VIEW_SIZE - emitDebug ("; shift left result %d, left %d", size, - AOP_SIZE (left)); -#endif - /* I suppose that the left size >= result size */ if (shCount == 0) { @@ -4865,7 +4768,7 @@ genLeftShift (iCode * ic) /* now move the left to the result if they are not the same */ -#if 1 + if (!sameRegs (AOP (left), AOP (result))) { @@ -4878,17 +4781,6 @@ genLeftShift (iCode * ic) offset++; } } -#else - size = AOP_SIZE (result); - offset = 0; - while (size--) - { - l = aopGet (AOP (left), offset, FALSE); - aopPut (AOP (result), l, offset); - offset++; - } -#endif - tlbl = newiTempLabel (NULL); size = AOP_SIZE (result); @@ -4989,7 +4881,10 @@ shiftR1Left2Result (operand * left, int offl, _moveA (aopGet (AOP (left), offl, FALSE)); if (sign) { - wassert (0); + while (shCount--) + { + emit2 ("%s a", sign ? "sra" : "srl"); + } } else { @@ -5047,9 +4942,6 @@ genRightShiftLiteral (operand * left, size = getSize (operandType (result)); - emitDebug ("; shift right result %d, left %d", size, - AOP_SIZE (left)); - /* I suppose that the left size >= result size */ if (shCount == 0) { @@ -5480,14 +5372,12 @@ genAssign (iCode * ic) result = IC_RESULT (ic); right = IC_RIGHT (ic); -#if 1 /* Dont bother assigning if they are the same */ if (operandsEqu (IC_RESULT (ic), IC_RIGHT (ic))) { emitDebug ("; (operands are equal %u)", operandsEqu (IC_RESULT (ic), IC_RIGHT (ic))); return; } -#endif aopOp (right, ic, FALSE, FALSE); aopOp (result, ic, TRUE, FALSE); @@ -5682,16 +5572,7 @@ genCast (iCode * ic) goto release; } - /* PENDING: should be OK. */ -#if 0 - /* if the result is of type pointer */ - if (IS_PTR (ctype)) - { - wassert (0); - } -#endif - - /* so we now know that the size of destination is greater + /* So we now know that the size of destination is greater than the size of the source */ /* we move to result for the size of source */ size = AOP_SIZE (right); @@ -5718,7 +5599,6 @@ genCast (iCode * ic) const char *l = aopGet (AOP (right), AOP_SIZE (right) - 1, FALSE); _moveA (l); - emitDebug ("; genCast: sign extend untested."); emit2 ("rla "); emit2 ("sbc a,a"); while (size--) @@ -6271,13 +6151,11 @@ genZ80Code (iCode * lic) break; case ARRAYINIT: - genArrayInit(ic); - break; + genArrayInit(ic); + break; default: ic = ic; - /* piCode(ic,stdout); */ - } } diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index 7027e57b..d15e042c 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -45,15 +45,18 @@ #include "z80.h" +/* Flags to turn off optimisations. + */ enum { DISABLE_PACK_ACC = 0, DISABLE_PACK_ASSIGN = 0, DISABLE_PACK_ONE_USE = 0, DISABLE_PACK_HL = 0, - LIMITED_PACK_ACC = 1, }; +/* Flags to turn on debugging code. + */ enum { D_ALLOC = 0, @@ -2046,16 +2049,10 @@ opPreservesA (iCode * ic, iCode * uic) { if (uic->op == IFX) { + /* If we've gotten this far then the thing to compare must be + small enough and must be in A. + */ 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) @@ -2086,50 +2083,10 @@ opPreservesA (iCode * ic, iCode * uic) return FALSE; } - /* - Bad: - !IS_ARITHMETIC_OP(uic) (sub requires A) - */ - if ( - uic->op != '+' && - !IS_BITWISE_OP (uic) && - uic->op != '=' && - uic->op != EQ_OP && - !POINTER_GET (uic) && - /* - uic->op != LEFT_OP && - uic->op != RIGHT_OP && */ - 1 - ) - { - D (D_ACCUSE2, (" + Dropping as 'its a bad op'\n")); - return FALSE; - } - - /* PENDING */ - if (!IC_LEFT (uic) || !IC_RESULT (ic)) - { - 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; - } - - if (IC_RIGHT (uic)->key == IC_RESULT (ic)->key && - (IS_ITEMP (IC_LEFT (uic)) || - (IS_TRUE_SYMOP (IC_LEFT (uic))))) - { - return TRUE; - } - - D (D_ACCUSE2, (" + Dropping as hit default case\n")); + /* Disabled all of the old rules as they weren't verified and have + caused at least one problem. + */ return FALSE; } @@ -2244,21 +2201,6 @@ packRegsForAccUse2 (iCode * ic) return; } - /* if shift operation make sure right side is not a literal. - MLH: depends. - */ -#if 0 - if (ic->op == RIGHT_OP && - (isOperandLiteral (IC_RIGHT (ic)) || - getSize (operandType (IC_RESULT (ic))) > 1)) - return; - - if (ic->op == LEFT_OP && - (isOperandLiteral (IC_RIGHT (ic)) || - getSize (operandType (IC_RESULT (ic))) > 1)) - return; -#endif - /* has only one definition */ if (bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) > 1) { diff --git a/support/regression/tests/bp.c b/support/regression/tests/bp.c new file mode 100644 index 00000000..bd768a49 --- /dev/null +++ b/support/regression/tests/bp.c @@ -0,0 +1,43 @@ +/* Base pointer tests, specifically for the z80. + */ +#include +#include +#include + +int +verifyBlock(char *p, char val, int len) +{ + while (len--) { + if (*p++ != val) { + return 0; + } + } + return 1; +} + +char +spoil(char a) +{ + return a; +} + +void +testBP(void) +{ + char above[400]; + char f; + char below[200]; + + memset(above, 17, sizeof(above)); + memset(below, 74, sizeof(below)); + + ASSERT(verifyBlock(above, 17, sizeof(above))); + ASSERT(verifyBlock(below, 74, sizeof(below))); + + f = spoil(-5); + spoil(f); + + ASSERT(verifyBlock(above, 17, sizeof(above))); + ASSERT(verifyBlock(below, 74, sizeof(below))); +} + diff --git a/support/regression/tests/bug-448984.c b/support/regression/tests/bug-448984.c new file mode 100644 index 00000000..5ec36049 --- /dev/null +++ b/support/regression/tests/bug-448984.c @@ -0,0 +1,16 @@ +/* bug-448984.c + */ +#include + +void +testRshRem(void) +{ + volatile int rem, quot; + + quot = 4; + rem = 5000; + + rem = rem - (quot*1024); + + ASSERT(rem == 904); +} diff --git a/support/regression/tests/fetchoverlap.c b/support/regression/tests/fetchoverlap.c new file mode 100644 index 00000000..5039b0a4 --- /dev/null +++ b/support/regression/tests/fetchoverlap.c @@ -0,0 +1,33 @@ +/* Test to reproduce a bug in the z80 compiler where A is used as the + left and right of an operand. +*/ +#include +#include + +/* In the previous bug, both *p and val in the compare operation were + assigned into A due to *p being packed for ACC use into A. +*/ +int +verifyBlock(char *p, char val, int len) +{ + while (len--) { + if (*p++ != val) { + return 0; + } + } + return 1; +} + +void +testOverlap(void) +{ + char buf[20]; + memset(buf, 12, sizeof(buf)); + + buf[12] = 13; + ASSERT(!verifyBlock(buf, 12, sizeof(buf))); + + buf[12] = 12; + ASSERT(verifyBlock(buf, 12, sizeof(buf))); +} + diff --git a/support/regression/tests/pow2shifts.c b/support/regression/tests/pow2shifts.c new file mode 100644 index 00000000..a1884da8 --- /dev/null +++ b/support/regression/tests/pow2shifts.c @@ -0,0 +1,22 @@ +/* Test power of 2 based shifts. + sign: signed, unsigned + */ +#include + +void +testIntShift(void) +{ + volatile {sign} int left; + + left = 4; + ASSERT(left * 1024 == 4096); + ASSERT(left * 2048 == 8192); + ASSERT(left * 256 == 1024); + ASSERT(left * 64 == 256); + + left = 4096; + ASSERT(left / 1024 == 4); + ASSERT(left / 2048 == 2); + ASSERT(left / 256 == 16); + ASSERT(left / 4 == 1024); +} diff --git a/support/tests/dhrystone/Makefile b/support/tests/dhrystone/Makefile index 39fc0dfc..4361f5e2 100644 --- a/support/tests/dhrystone/Makefile +++ b/support/tests/dhrystone/Makefile @@ -1,7 +1,7 @@ # Simple Makefile for dhrystone and sdcc TOPDIR = ../../.. -PROC = gbz80 +PROC = z80 CC = $(TOPDIR)/bin/sdcc @@ -27,4 +27,4 @@ native: gcc -g -O2 -DREG= -DNOSTRUCTASSIGN -DNOENUM -o dhry dhry.c clean: - rm -f *~ dhry *.o *.gb *.ihx *.rel + rm -f *~ dhry *.o *.gb *.ihx *.rel *.dump* *.lst *.sym *.map *.asm *.bin *.gb -- 2.30.2