From: michaelh Date: Thu, 9 Mar 2000 04:47:22 +0000 (+0000) Subject: * Changed limit on 256$ to > 256 X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=235bf31f8054d2993642de5ec84b0656908683a9;p=fw%2Fsdcc * Changed limit on 256$ to > 256 * Added IS_LITERAL() patch. * Changed a few ints over to enums to help debugging. * Fixed gbz80 missing struct members bug. * Added heaps of debugging to ralloc() git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@179 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/as/z80/asm.h b/as/z80/asm.h index 00c33f3a..58db9faf 100644 --- a/as/z80/asm.h +++ b/as/z80/asm.h @@ -285,11 +285,11 @@ struct sym */ struct tsym { - struct tsym *t_lnk; /* Link to next */ - char t_num; /* 0-255$ */ - char t_flg; /* flags */ - struct area *t_area; /* Area */ - addr_t t_addr; /* Address */ + struct tsym *t_lnk; /* Link to next */ + int t_num; /* 0-lots$ */ + char t_flg; /* flags */ + struct area *t_area; /* Area */ + addr_t t_addr; /* Address */ }; /* diff --git a/doc/choices.txt b/doc/choices.txt index 2e48bae1..9fa79244 100644 --- a/doc/choices.txt +++ b/doc/choices.txt @@ -86,3 +86,24 @@ PlusIncr on pairs: adc a,b ; 4 ld b,a ; 4 = 30 So n <= 5 (1) is better. + +Frame pointer: +It's nice to use HL as the temp register, but what if I used it as the +frame pointer instead of ix? + +Instead of: + ld e,5(ix) ; 19 + ld d,6(ix) ; 19 = 38 + + ld hl,#5 ; 10 + add hl,sp ; 11 + ld e,(hl) ; 7 + inc hl ; 6 + ld d,(hl) ; 7 = 41 + +Things get better when you access the same set over, as you get rid +of the setup. But they get worse when both ops are on the stack/in +direct space. Easiest this way for now. iy may benifit... + + + diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 883b4ba5..c09a183f 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -648,12 +648,13 @@ link *operandType (operand *op) case TYPE : return op->operand.typeOperand ; + default: + werror (E_INTERNAL_ERROR,__FILE__,__LINE__, + " operand type not known "); + assert (0) ; /* should never come here */ + /* Just to keep the compiler happy */ + return (link *)0; } - werror (E_INTERNAL_ERROR,__FILE__,__LINE__, - " operand type not known "); - assert (0) ; /* should never come here */ - /* Just to keep the compiler happy */ - return (link *)0; } /*-----------------------------------------------------------------*/ @@ -1327,7 +1328,7 @@ operand *geniCodeCast (link *type, operand *op, bool implicit) return op; /* if this is a literal then just change the type & return */ - if (IS_LITERAL(opetype) && !IS_PTR(type) && !IS_PTR(optype)) + if (IS_LITERAL(opetype) && op->type == VALUE && !IS_PTR(type) && !IS_PTR(optype)) return operandFromValue(valCastLiteral(type, operandLitValue(op))); @@ -2202,7 +2203,7 @@ operand *geniCodeAssign (operand *left, operand *right, int nosupdate) /* left is integral type and right is literal then check if the literal value is within bounds */ - if (IS_INTEGRAL(ltype) && IS_LITERAL(rtype)) { + if (IS_INTEGRAL(ltype) && right->type == VALUE && IS_LITERAL(rtype)) { int nbits = bitsForType(ltype); long v = operandLitValue(right); diff --git a/src/SDCCicode.h b/src/SDCCicode.h index e3be255f..eb0e77b0 100644 --- a/src/SDCCicode.h +++ b/src/SDCCicode.h @@ -37,10 +37,12 @@ enum { EXPRESSION , STATEMENT , LEAF }; -enum optype { + +typedef enum { SYMBOL =1, VALUE , - TYPE }; + TYPE +} OPTYPE; #define IS_SYMOP(op) (op && op->type == SYMBOL) #define ADDTOCHAIN(x) addSetHead(&iCodeChain,x) @@ -68,7 +70,7 @@ enum optype { /* typedef for operand */ typedef struct operand { - unsigned int type: 6 ; /* type of operand */ + OPTYPE type; /* type of operand */ unsigned int isaddr : 1; /* is an address */ unsigned int isvolatile: 1; /* is a volatile operand */ unsigned int isGlobal :1 ; /* is a global operand */ diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index d25cd418..391bf503 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -50,17 +50,20 @@ typedef struct structdef { } structdef ; /* noun definitions */ -enum { V_INT = 0, +typedef enum { + V_INT = 0, V_FLOAT , V_CHAR , V_VOID , V_STRUCT , V_LABEL , V_BIT , - V_SBIT }; + V_SBIT +} NOUN; /* storage class */ -enum { S_FIXED = 0, +typedef enum { + S_FIXED = 0, S_AUTO , S_REGISTER , S_CONSTANT , @@ -75,12 +78,13 @@ enum { S_FIXED = 0, S_STACK , S_XSTACK , S_BIT , - S_EEPROM }; + S_EEPROM +} STORAGE_CLASS; /* specifier is the last in the type-chain */ typedef struct specifier { - unsigned noun ; /* CHAR INT STRUCTURE LABEL */ - unsigned sclass ; /* REGISTER,AUTO,FIX,CONSTANT */ + NOUN noun ; /* CHAR INT STRUCTURE LABEL */ + STORAGE_CLASS sclass ; /* REGISTER,AUTO,FIX,CONSTANT */ struct memmap *oclass ; /* output storage class */ unsigned _long : 1 ; /* 1=long */ unsigned _short: 1 ; /* 1=short int */ @@ -117,7 +121,8 @@ typedef struct specifier { } specifier ; /* types of declarators */ -enum { POINTER = 0, /* pointer to near data */ +typedef enum { + POINTER = 0, /* pointer to near data */ FPOINTER , /* pointer to far data */ CPOINTER , /* pointer to code space */ GPOINTER , /* _generic pointer */ @@ -126,10 +131,11 @@ enum { POINTER = 0, /* pointer to near data */ UPOINTER , /* unknown pointer used only when parsing */ EEPPOINTER , /* pointer to eeprom */ ARRAY , - FUNCTION }; + FUNCTION +} DECLARATOR_TYPE; typedef struct declarator { - short dcl_type; /* POINTER,ARRAY or FUNCTION */ + DECLARATOR_TYPE dcl_type; /* POINTER,ARRAY or FUNCTION */ short num_elem; /* # of elems if type==array */ short ptr_const :1; /* pointer is constant */ short ptr_volatile:1; /* pointer is volatile */ diff --git a/src/z80/gbz80.c b/src/z80/gbz80.c index 114d7205..33a9bc7f 100644 --- a/src/z80/gbz80.c +++ b/src/z80/gbz80.c @@ -27,6 +27,8 @@ static void _gbz80_init(void) static void _gbz80_finaliseOptions(void) { + port->mem.default_local_map = data; + port->mem.default_globl_map = data; } static void _gbz80_setDefaultOptions(void) @@ -103,7 +105,9 @@ PORT gbz80_port = { "_RSEG", "_GSINIT", "_OVERLAY", - "_GSFINAL" + "_GSFINAL", + NULL, + NULL }, { -1, 0, 0, 4, 0 diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index ec0a4864..93f4e37b 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -50,6 +50,14 @@ enum { LIMITED_PACK_ACC = 1 }; +#define D_ALLOC 1 + +#if 0 +#define D(_a, _s) if (_a) { printf _s; fflush(stdout); } +#else +#define D(_a, _s) +#endif + /*-----------------------------------------------------------------*/ /* At this point we start getting processor specific although */ /* some routines are non-processor specific & can be reused when */ @@ -124,9 +132,11 @@ static regs *allocReg (short type) if (currFunc) currFunc->regsUsed = bitVectSetBit(currFunc->regsUsed,i); + D(D_ALLOC, ("allocReg: alloced %zr\n", ®sZ80[i])); return ®sZ80[i]; } } + D(D_ALLOC, ("allocReg: No free.\n")); return NULL; } @@ -139,7 +149,7 @@ regs *regWithIdx (int idx) for (i=0;i < _nRegs;i++) if (regsZ80[i].rIdx == idx) return ®sZ80[i]; - + werror(E_INTERNAL_ERROR,__FILE__,__LINE__, "regWithIdx not found"); exit(1); @@ -151,6 +161,7 @@ static void freeReg (regs *reg) { wassert(!reg->isFree); reg->isFree = 1; + D(D_ALLOC, ("freeReg: freed %zr\n", reg)); } @@ -339,14 +350,12 @@ static int noOverLap (set *itmpStack, symbol *fsym) { symbol *sym; - for (sym = setFirstItem(itmpStack); sym; sym = setNextItem(itmpStack)) { if (sym->liveTo > fsym->liveFrom ) return 0; } - return 1; } @@ -384,6 +393,8 @@ symbol *createStackSpil (symbol *sym) { symbol *sloc= NULL; + D(D_ALLOC, ("createStackSpil: for sym %zs\n", sym)); + /* first go try and find a free one that is already existing on the stack */ if (applyToSet(stackSpil,isFree,&sloc, sym)) { @@ -392,6 +403,7 @@ symbol *createStackSpil (symbol *sym) sym->stackSpil= 1; sloc->isFree = 0; addSetHead(&sloc->usl.itmpStack,sym); + D(D_ALLOC, ("createStackSpil: found existing\n")); return sym; } @@ -433,6 +445,8 @@ symbol *createStackSpil (symbol *sym) /* add it to the set of itempStack set of the spill location */ addSetHead(&sloc->usl.itmpStack,sym); + + D(D_ALLOC, ("createStackSpil: created new\n")); return sym; } @@ -468,6 +482,9 @@ bool isSpiltOnStack (symbol *sym) static void spillThis (symbol *sym) { int i; + + D(D_ALLOC, ("spillThis: spilling %zs\n", sym)); + /* if this is rematerializable or has a spillLocation we are okay, else we need to create a spillLocation for it */ @@ -503,12 +520,13 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) set *selectS ; symbol *sym; + D(D_ALLOC, ("selectSpil: finding spill for ic %zi\n", ic)); /* get the spillable live ranges */ lrcs = computeSpillable (ic); /* get all live ranges that are rematerizable */ if ((selectS = liveRangesWith(lrcs,rematable,ebp,ic))) { - + D(D_ALLOC, ("selectSpil: using remat.\n")); /* return the least used of these */ return leastUsedLR(selectS); } @@ -564,7 +582,7 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) /* find live ranges with spillocation */ if ((selectS = liveRangesWith(lrcs,hasSpilLoc,ebp,ic))) { - + D(D_ALLOC, ("selectSpil: using with spill.\n")); sym = leastUsedLR(selectS); sym->usl.spillLoc->allocreq = 1; return sym; @@ -574,6 +592,7 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) location on the stack , for which one? the least used ofcourse */ if ((selectS = liveRangesWith(lrcs,noSpilLoc,ebp,ic))) { + D(D_ALLOC, ("selectSpil: creating new spill.\n")); /* return a created spil location */ sym = createStackSpil(leastUsedLR(selectS)); sym->usl.spillLoc->allocreq = 1; @@ -582,6 +601,7 @@ symbol *selectSpil (iCode *ic, eBBlock *ebp, symbol *forSym) /* this is an extreme situation we will spill this one : happens very rarely but it does happen */ + D(D_ALLOC, ("selectSpil: using spillThis.\n")); spillThis ( forSym ); return forSym; @@ -595,6 +615,8 @@ bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym) symbol *ssym; int i ; + D(D_ALLOC, ("spilSomething: spilling on ic %zi\n", ic)); + /* get something we can spil */ ssym = selectSpil(ic,ebp,forSym); @@ -645,6 +667,8 @@ bool spilSomething (iCode *ic, eBBlock *ebp, symbol *forSym) } #endif + D(D_ALLOC, ("spilSomething: done.\n")); + if (ssym == forSym ) return FALSE ; else @@ -657,14 +681,19 @@ regs *getRegGpr (iCode *ic, eBBlock *ebp,symbol *sym) { regs *reg; + D(D_ALLOC, ("getRegGpr: on ic %zi\n")); tryAgain: /* try for gpr type */ - if ((reg = allocReg(REG_GPR))) + if ((reg = allocReg(REG_GPR))) { + D(D_ALLOC, ("getRegGpr: got a reg.\n")); return reg; + } /* we have to spil */ - if (!spilSomething (ic,ebp,sym)) + if (!spilSomething (ic,ebp,sym)) { + D(D_ALLOC, ("getRegGpr: have to spill.\n")); return NULL ; + } /* this looks like an infinite loop but in really selectSpil will abort */ @@ -724,6 +753,8 @@ static void deassignLRs (iCode *ic, eBBlock *ebp) !OP_SYMBOL(IC_LEFT(ic->prev))->isspilt) psym = OP_SYMBOL(IC_LEFT(ic->prev)); + D(D_ALLOC, ("deassignLRs: in loop on sym %zs", sym)); + if (sym->nRegs) { int i = 0; @@ -791,6 +822,8 @@ static void reassignLR (operand *op) symbol *sym = OP_SYMBOL(op); int i; + D(D_ALLOC, ("reassingLR: on sym %zs\n", sym)); + /* not spilt any more */ sym->isspilt = sym->blockSpil = sym->remainSpil = 0; bitVectUnSetBit(spiltSet,sym->key); @@ -822,30 +855,32 @@ static int willCauseSpill ( int nr, int rt) */ static void positionRegs (symbol *result, symbol *opsym, int lineno) { - int count = min(result->nRegs,opsym->nRegs); - int i , j = 0, shared = 0; + int count = min(result->nRegs,opsym->nRegs); + int i , j = 0, shared = 0; + + D(D_ALLOC, ("positionRegs: on result %zs opsum %zs line %u\n", result, opsym, lineno)); - /* if the result has been spilt then cannot share */ - if (opsym->isspilt) - return ; + /* if the result has been spilt then cannot share */ + if (opsym->isspilt) + return ; again: - shared = 0; - /* first make sure that they actually share */ - for ( i = 0 ; i < count; i++ ) { - for (j = 0 ; j < count ; j++ ) { - if (result->regs[i] == opsym->regs[j] && i !=j) { - shared = 1; - goto xchgPositions; - } - } + shared = 0; + /* first make sure that they actually share */ + for ( i = 0 ; i < count; i++ ) { + for (j = 0 ; j < count ; j++ ) { + if (result->regs[i] == opsym->regs[j] && i !=j) { + shared = 1; + goto xchgPositions; + } } + } xchgPositions: - if (shared) { - regs *tmp = result->regs[i]; - result->regs[i] = result->regs[j]; - result->regs[j] = tmp; - goto again; - } + if (shared) { + regs *tmp = result->regs[i]; + result->regs[i] = result->regs[j]; + result->regs[j] = tmp; + goto again; + } } /** Try to allocate a pair of registers to the symbol. @@ -866,9 +901,11 @@ bool tryAllocatingRegPair(symbol *sym) currFunc->regsUsed = bitVectSetBit(currFunc->regsUsed,i+1); } + D(D_ALLOC, ("tryAllocRegPair: succeded for sym %zs\n", sym)); return TRUE; } } + D(D_ALLOC, ("tryAllocRegPair: failed on sym %zs\n", sym)); return FALSE; } @@ -895,8 +932,10 @@ static void serialRegAssign (eBBlock **ebbs, int count) /* if this is an ipop that means some live range will have to be assigned again */ - if (ic->op == IPOP) + if (ic->op == IPOP) { + wassert(0); reassignLR (IC_LEFT(ic)); + } /* if result is present && is a true symbol */ if (IC_RESULT(ic) && ic->op != IFX && @@ -923,19 +962,24 @@ static void serialRegAssign (eBBlock **ebbs, int count) int willCS ; int j; + D(D_ALLOC, ("serialRegAssign: in loop on result %zs\n", sym)); + /* if it does not need or is spilt or is already assigned to registers or will not live beyond this instructions */ if (!sym->nRegs || sym->isspilt || bitVectBitValue(regAssigned,sym->key) || - sym->liveTo <= ic->seq) + sym->liveTo <= ic->seq) { + D(D_ALLOC, ("serialRegAssign: wont live long enough.\n")); continue ; + } /* if some liverange has been spilt at the block level and this one live beyond this block then spil this to be safe */ if (blockSpil && sym->liveTo > ebbs[i]->lSeq) { + D(D_ALLOC, ("serialRegAssign: \"spilling to be safe.\"\n")); spillThis (sym); continue ; } @@ -948,6 +992,7 @@ static void serialRegAssign (eBBlock **ebbs, int count) if ( sym->remat || (willCS && bitVectIsZero(spillable) ) ) { + D(D_ALLOC, ("serialRegAssign: \"remat spill\"\n")); spillThis (sym) ; continue ; @@ -974,6 +1019,7 @@ static void serialRegAssign (eBBlock **ebbs, int count) /* Special case: Try to fit into a reg pair if available */ + D(D_ALLOC, ("serialRegAssign: actually allocing regs!\n")); if ((sym->nRegs == 2)&&tryAllocatingRegPair(sym)) { } else { @@ -1027,8 +1073,7 @@ bitVect *rUmaskForOp (operand *op) rumask = newBitVect(_nRegs); for (j = 0; j < sym->nRegs; j++) { - rumask = bitVectSetBit(rumask, - sym->regs[j]->rIdx); + rumask = bitVectSetBit(rumask, sym->regs[j]->rIdx); } return rumask; @@ -1164,7 +1209,7 @@ char *rematStr (symbol *sym) /*-----------------------------------------------------------------*/ /* regTypeNum - computes the type & number of registers required */ /*-----------------------------------------------------------------*/ -static void regTypeNum () +static void regTypeNum (void) { symbol *sym; int k; @@ -1177,6 +1222,8 @@ static void regTypeNum () if ((sym->liveTo - sym->liveFrom) == 0) continue ; + D(D_ALLOC, ("regTypeNum: loop on sym %zs\n", sym)); + /* if the live range is a temporary */ if (sym->isitmp) { @@ -1197,6 +1244,8 @@ static void regTypeNum () getSize(sym->type = aggrToPtr(sym->type,FALSE)) : getSize(sym->type)); + D(D_ALLOC, ("regTypeNum: setup to assign regs sym %zs\n", sym)); + if (sym->nRegs > 4) { fprintf(stderr,"allocated more than 4 or 0 registers for type "); printTypeChain(sym->type,stderr);fprintf(stderr,"\n"); @@ -1221,6 +1270,8 @@ static void freeAllRegs() { int i; + D(D_ALLOC, ("freeAllRegs: running.\n")); + for (i=0;i< _nRegs;i++ ) regsZ80[i].isFree = 1; } @@ -1241,6 +1292,8 @@ DEFSETFUNC(deallocStackSpil) static int packRegsForAssign (iCode *ic,eBBlock *ebp) { iCode *dic, *sic; + + D(D_ALLOC, ("packRegsForAssing: running on ic %zi\n", ic)); if ( /* !IS_TRUE_SYMOP(IC_RESULT(ic)) ||*/ @@ -1426,6 +1479,8 @@ static int packRegsForSupport (iCode *ic, eBBlock *ebp) /* for the left & right operand :- look to see if the left was assigned a true symbol in far space in that case replace them */ + D(D_ALLOC, ("packRegsForSupport: running on ic %zi\n", ic)); + if (IS_ITEMP(IC_LEFT(ic)) && OP_SYMBOL(IC_LEFT(ic))->liveTo <= ic->seq) { iCode *dic = findAssignToSym(IC_LEFT(ic),ic); @@ -1481,6 +1536,8 @@ static iCode *packRegsForOneuse (iCode *ic, operand *op , eBBlock *ebp) bitVect *uses ; iCode *dic, *sic; + D(D_ALLOC, ("packRegsForOneUse: running on ic %zi\n", ic)); + /* if returning a literal then do nothing */ if (!IS_SYMOP(op)) return NULL; @@ -1810,6 +1867,8 @@ static void packRegsForAccUse2(iCode *ic) { iCode *uic; + D(D_ALLOC, ("packRegsForAccUse2: running on ic %zi\n", ic)); + /* Filter out all but those 'good' commands */ if ( !POINTER_GET(ic) && @@ -1995,6 +2054,8 @@ static void packRegisters (eBBlock *ebp) { iCode *ic ; int change = 0 ; + + D(D_ALLOC, ("packRegisters: entered.\n")); while (1 && !DISABLE_PACK_ASSIGN) { change = 0; @@ -2015,6 +2076,9 @@ static void packRegisters (eBBlock *ebp) /* Safe: address of a true sym is always constant. */ /* if this is an itemp & result of a address of a true sym then mark this as rematerialisable */ + + D(D_ALLOC, ("packRegisters: looping on ic %zi\n", ic)); + if (ic->op == ADDRESS_OF && IS_ITEMP(IC_RESULT(ic)) && IS_TRUE_SYMOP(IC_LEFT(ic)) && @@ -2119,6 +2183,8 @@ void z80_assignRegisters (eBBlock **ebbs, int count) iCode *ic; int i ; + D(D_ALLOC, ("\n-> z80_assignRegisters: entered.\n")); + setToNull((void *)&funcrUsed); stackExtend = dataExtend = 0;