From 57e571edeac57583ee2bca8f0b1f2eeefb13466a Mon Sep 17 00:00:00 2001 From: sandeep Date: Wed, 14 Nov 2001 07:14:17 +0000 Subject: [PATCH] Many changes. Started a second pass to the register allocator & true 10bit stack fully implemented git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1589 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- src/ds390/gen.c | 390 +++++++++++++++++++++++++++------------------ src/ds390/main.c | 4 +- src/ds390/ralloc.c | 174 +++++++++++++++++--- 3 files changed, 389 insertions(+), 179 deletions(-) diff --git a/src/ds390/gen.c b/src/ds390/gen.c index ebc99f5c..2e25ea96 100644 --- a/src/ds390/gen.c +++ b/src/ds390/gen.c @@ -460,27 +460,29 @@ aopForSym (iCode * ic, symbol * sym, bool result, bool useDP2) if (_G.accInUse) emitcode ("push", "acc"); - emitcode ("mov", "a,_bp"); - emitcode ("add", "a,#0x%02x", - ((sym->stack < 0) ? - ((char) (sym->stack - _G.nRegsSaved)) : - ((char) sym->stack)) & 0xff); - - if (useDP2) - { + emitcode ("mov", "a,_bpx"); + emitcode ("clr","c"); + emitcode ("subb", "a,#0x%02x", + -((sym->stack < 0) ? + ((short) (sym->stack - _G.nRegsSaved)) : + ((short) sym->stack)) & 0xff); + emitcode ("mov","b,a"); + emitcode ("mov","a,#0x%02x",(-((sym->stack < 0) ? + ((short) (sym->stack - _G.nRegsSaved)) : + ((short) sym->stack)) >> 8) & 0xff); + emitcode ("subb","a,_bpx+1"); + if (useDP2) { if (options.model == MODEL_FLAT24) - emitcode ("mov", "dpx1,#0x40"); + emitcode ("mov", "dpx1,#0x40"); TR_DPTR("#2"); - emitcode ("mov", "dph1,#0x00"); - emitcode ("mov", "dpl1, a"); - } - else - { + emitcode ("mov", "dph1,a"); + emitcode ("mov", "dpl1,b"); + } else { if (options.model == MODEL_FLAT24) - emitcode ("mov", "dpx,#0x40"); - emitcode ("mov", "dph,#0x00"); - emitcode ("mov", "dpl, a"); - } + emitcode ("mov", "dpx,#0x40"); + emitcode ("mov", "dph,a"); + emitcode ("mov", "dpl,b"); + } if (_G.accInUse) emitcode ("pop", "acc"); @@ -2353,19 +2355,26 @@ genCall (iCode * ic) /* adjust the stack for parameters if required */ - if (ic->parmBytes) - { - int i; - if (ic->parmBytes > 3) - { - emitcode ("mov", "a,%s", spname); - emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff); - emitcode ("mov", "%s,a", spname); - } - else - for (i = 0; i < ic->parmBytes; i++) - emitcode ("dec", "%s", spname); - } + if (ic->parmBytes) { + if (options.stack10bit) { + emitcode ("clr","c"); + emitcode ("mov","a,sp"); + emitcode ("subb","a,#0x%02x",ic->parmBytes & 0xff); + emitcode ("mov","sp,a"); + emitcode ("mov","a,#0x%02x",(ic->parmBytes >> 8) & 0xff); + emitcode ("subb","a,_ESP"); + emitcode ("mov","_ESP,a"); + } else { + int i; + if (ic->parmBytes > 3) { + emitcode ("mov", "a,%s", spname); + emitcode ("add", "a,#0x%02x", (-ic->parmBytes) & 0xff); + emitcode ("mov", "%s,a", spname); + } else + for (i = 0; i < ic->parmBytes; i++) + emitcode ("dec", "%s", spname); + } + } /* if we hade saved some registers then unsave them */ if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype)) @@ -2789,44 +2798,54 @@ genFunction (iCode * ic) emitcode ("mov", "psw,#0x%02x", (FUNC_REGBANK (sym->type) << 3) & 0x00ff); } - if (IFFUNC_ISREENT (sym->type) || options.stackAuto) - { - - if (options.useXstack) - { - emitcode ("mov", "r0,%s", spname); - emitcode ("mov", "a,_bp"); - emitcode ("movx", "@r0,a"); - emitcode ("inc", "%s", spname); - } - else - { - /* set up the stack */ - emitcode ("push", "_bp"); /* save the callers stack */ - } - emitcode ("mov", "_bp,%s", spname); - } + if (IFFUNC_ISREENT (sym->type) || options.stackAuto) { + if (options.stack10bit) { + emitcode ("push","_bpx"); + emitcode ("push","_bpx+1"); + emitcode ("mov","_bpx,%s",spname); + emitcode ("mov","_bpx+1,_ESP"); + emitcode ("anl","_bpx+1,#3"); + } else { + if (options.useXstack) { + emitcode ("mov", "r0,%s", spname); + emitcode ("mov", "a,_bp"); + emitcode ("movx", "@r0,a"); + emitcode ("inc", "%s", spname); + } else { + /* set up the stack */ + emitcode ("push", "_bp"); /* save the callers stack */ + } + emitcode ("mov", "_bp,%s", spname); + } + } /* adjust the stack for the function */ - if (sym->stack) - { - + if (sym->stack) { int i = sym->stack; - if (i > 256) - werror (W_STACK_OVERFLOW, sym->name); - - if (i > 3 && sym->recvSize < 4) - { - - emitcode ("mov", "a,sp"); - emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); - emitcode ("mov", "sp,a"); - - } - else - while (i--) - emitcode ("inc", "sp"); - } + if (options.stack10bit) { + if ( i > 1024) werror (W_STACK_OVERFLOW, sym->name); + assert (sym->recvSize <= 4); + emitcode ("mov","a,sp"); + emitcode ("add","a,#0x%02x", ((short) sym->stack & 0xff)); + emitcode ("mov","sp,a"); + emitcode ("mov","a,_ESP"); + emitcode ("addc","a,0x%02x", (((short) sym->stack) >> 8) & 0xff); + emitcode ("mov","_ESP,a"); + } else { + if (i > 256) + werror (W_STACK_OVERFLOW, sym->name); + + if (i > 3 && sym->recvSize < 4) { + + emitcode ("mov", "a,sp"); + emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); + emitcode ("mov", "sp,a"); + + } else + while (i--) + emitcode ("inc", "sp"); + } + } if (sym->xstack) { @@ -2854,36 +2873,40 @@ genEndFunction (iCode * ic) return; } - if (IFFUNC_ISREENT (sym->type) || options.stackAuto) - { - emitcode ("mov", "%s,_bp", spname); - } + if (IFFUNC_ISREENT (sym->type) || options.stackAuto) { + if (options.stack10bit) { + emitcode ("mov", "sp,_bpx", spname); + emitcode ("mov", "_ESP,_bpx+1", spname); + } else { + emitcode ("mov", "%s,_bp", spname); + } + } /* if use external stack but some variables were added to the local stack then decrement the local stack */ - if (options.useXstack && sym->stack) - { + if (options.useXstack && sym->stack) { emitcode ("mov", "a,sp"); emitcode ("add", "a,#0x%02x", ((char) -sym->stack) & 0xff); emitcode ("mov", "sp,a"); - } + } - if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) - { - if (options.useXstack) - { + if ((IFFUNC_ISREENT (sym->type) || options.stackAuto)) { + if (options.useXstack) { emitcode ("mov", "r0,%s", spname); emitcode ("movx", "a,@r0"); emitcode ("mov", "_bp,a"); emitcode ("dec", "%s", spname); - } - else - { - emitcode ("pop", "_bp"); - } - } + } else { + if (options.stack10bit) { + emitcode ("pop", "_bpx+1"); + emitcode ("pop", "_bpx"); + } else { + emitcode ("pop", "_bp"); + } + } + } /* restore the register bank */ if (FUNC_REGBANK (sym->type) || IFFUNC_ISISR (sym->type)) @@ -3409,9 +3432,10 @@ adjustArithmeticResult (iCode * ic) // that the IC_RESULT operand is not aopOp'd. #define AOP_OP_3_NOFATAL(ic, rc) \ aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \ - aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \ + aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR) || \ + (OP_SYMBOL(IC_RESULT(ic))->ruonly)); \ if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \ - isOperandInFarSpace(IC_RESULT(ic))) \ + (isOperandInFarSpace(IC_RESULT(ic)) || OP_SYMBOL(IC_RESULT(ic))->ruonly )) \ { \ /* No can do; DPTR & DPTR2 in use, and we need another. */ \ rc = TRUE; \ @@ -3485,7 +3509,22 @@ genPlus (iCode * ic) D (emitcode (";", "genPlus ");); /* special cases :- */ - + if (isOperandEqual(IC_LEFT(ic),IC_RESULT(ic)) && + isOperandLiteral(IC_RIGHT(ic)) && OP_SYMBOL(IC_RESULT(ic))->ruonly) { + aopOp (IC_RIGHT (ic), ic, TRUE, FALSE); + size = floatFromVal (AOP (IC_RIGHT(ic))->aopu.aop_lit); + while (size--) emitcode ("inc","dptr"); + freeAsmop (IC_RIGHT (ic), NULL, ic, FALSE); + return ; + } + if ( IS_SYMOP(IC_LEFT(ic)) && + OP_SYMBOL(IC_LEFT(ic))->remat && + isOperandInFarSpace(IC_RIGHT(ic))) { + operand *op = IC_RIGHT(ic); + IC_RIGHT(ic) = IC_LEFT(ic); + IC_LEFT(ic) = op; + } + AOP_OP_3_NOFATAL (ic, pushResult); if (pushResult) { @@ -5397,18 +5436,20 @@ hasInc (operand *op, iCode *ic) if (IS_BITVAR(retype)||!IS_PTR(type)) return NULL; isize = getSize(type->next); while (lic) { - /* if operand of the form op = op + */ - if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) && - isOperandEqual(IC_RESULT(lic),op) && - isOperandLiteral(IC_RIGHT(lic)) && - operandLitValue(IC_RIGHT(lic)) == isize) { - return lic; - } - /* if the operand used or deffed */ - if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) { - return NULL; - } - lic = lic->next; + /* if operand of the form op = op + */ + if (lic->op == '+' && isOperandEqual(IC_LEFT(lic),op) && + isOperandEqual(IC_RESULT(lic),op) && + isOperandLiteral(IC_RIGHT(lic)) && + operandLitValue(IC_RIGHT(lic)) == isize) { + return lic; + } + /* if the operand used or deffed */ + if (bitVectBitValue(OP_USES(op),lic->key) || (unsigned) lic->defKey == op->key) { + return NULL; + } + /* if GOTO or IFX */ + if (lic->op == IFX || lic->op == GOTO) break; + lic = lic->next; } return NULL; } @@ -8826,7 +8867,6 @@ genFarPointerGet (operand * left, } } /* so dptr know contains the address */ - freeAsmop (left, NULL, ic, TRUE); aopOp (result, ic, FALSE, TRUE); /* if bit then unpack */ @@ -8858,8 +8898,14 @@ genFarPointerGet (operand * left, if (options.model == MODEL_FLAT24) aopPut ( AOP (left), "dpx", 2); pi->generated = 1; + } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 && + (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) { + + size = AOP_SIZE (result) - 1; + while (size--) emitcode ("lcall","__decdptr"); } + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -8935,13 +8981,18 @@ emitcodePointerGet (operand * left, _endLazyDPSEvaluation (); } if (pi && AOP_TYPE (left) != AOP_IMMD) { - aopPut ( AOP (left), "dpl", 0); - aopPut ( AOP (left), "dph", 1); - if (options.model == MODEL_FLAT24) - aopPut ( AOP (left), "dpx", 2); - pi->generated = 1; + aopPut ( AOP (left), "dpl", 0); + aopPut ( AOP (left), "dph", 1); + if (options.model == MODEL_FLAT24) + aopPut ( AOP (left), "dpx", 2); + pi->generated = 1; + } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 && + (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) { + + size = AOP_SIZE (result) - 1; + while (size--) emitcode ("lcall","__decdptr"); } - + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -9033,11 +9084,17 @@ genGenPointerGet (operand * left, aopPut ( AOP (left), "dpl", 0); aopPut ( AOP (left), "dph", 1); if (options.model == MODEL_FLAT24) { - aopPut ( AOP (left), "dpx", 2); - aopPut ( AOP (left), "b", 3); + aopPut ( AOP (left), "dpx", 2); + aopPut ( AOP (left), "b", 3); } else aopPut ( AOP (left), "b", 2); pi->generated = 1; + } else if (OP_SYMBOL(left)->ruonly && AOP_SIZE(result) > 1 && + (OP_SYMBOL (left)->liveTo > ic->seq || ic->depth)) { + + size = AOP_SIZE (result) - 1; + while (size--) emitcode ("lcall","__decdptr"); } + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -9577,11 +9634,16 @@ genFarPointerSet (operand * right, } if (pi && AOP_TYPE (result) != AOP_IMMD) { - aopPut (AOP(result),"dpl",0); - aopPut (AOP(result),"dph",1); - if (options.model == MODEL_FLAT24) - aopPut (AOP(result),"dpx",2); - pi->generated=1; + aopPut (AOP(result),"dpl",0); + aopPut (AOP(result),"dph",1); + if (options.model == MODEL_FLAT24) + aopPut (AOP(result),"dpx",2); + pi->generated=1; + } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 && + (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) { + + size = AOP_SIZE (right) - 1; + while (size--) emitcode ("lcall","__decdptr"); } freeAsmop (result, NULL, ic, TRUE); freeAsmop (right, NULL, ic, TRUE); @@ -9655,15 +9717,20 @@ genGenPointerSet (operand * right, } if (pi && AOP_TYPE (result) != AOP_IMMD) { - aopPut (AOP(result),"dpl",0); - aopPut (AOP(result),"dph",1); - if (options.model == MODEL_FLAT24) { - aopPut (AOP(result),"dpx",2); - aopPut (AOP(result),"b",3); - } else { - aopPut (AOP(result),"b",2); - } - pi->generated=1; + aopPut (AOP(result),"dpl",0); + aopPut (AOP(result),"dph",1); + if (options.model == MODEL_FLAT24) { + aopPut (AOP(result),"dpx",2); + aopPut (AOP(result),"b",3); + } else { + aopPut (AOP(result),"b",2); + } + pi->generated=1; + } else if (OP_SYMBOL(result)->ruonly && AOP_SIZE(right) > 1 && + (OP_SYMBOL (result)->liveTo > ic->seq || ic->depth)) { + + size = AOP_SIZE (right) - 1; + while (size--) emitcode ("lcall","__decdptr"); } freeAsmop (result, NULL, ic, TRUE); freeAsmop (right, NULL, ic, TRUE); @@ -9786,47 +9853,52 @@ genAddrOf (iCode * ic) /* if the operand is on the stack then we need to get the stack offset of this variable */ - if (sym->onStack) - { - /* if it has an offset then we need to compute - it */ - if (sym->stack) - { - emitcode ("mov", "a,_bp"); - emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); - aopPut (AOP (IC_RESULT (ic)), "a", 0); - } - else - { - /* we can just move _bp */ - aopPut (AOP (IC_RESULT (ic)), "_bp", 0); - } - /* fill the result with zero */ - size = AOP_SIZE (IC_RESULT (ic)) - 1; - - - if (options.stack10bit && size < (FPTRSIZE - 1)) - { - fprintf (stderr, - "*** warning: pointer to stack var truncated.\n"); - } + if (sym->onStack) { + + /* if 10 bit stack */ + if (options.stack10bit) { + /* if it has an offset then we need to compute it */ + if (sym->stack) { + emitcode ("mov", "a,_bpx"); + emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); + emitcode ("mov", "b,a"); + emitcode ("mov", "a,_bpx+1"); + emitcode ("addc","a,#0x%02x", (((short) sym->stack) >> 8) & 0xff); + aopPut (AOP (IC_RESULT (ic)), "b", 0); + aopPut (AOP (IC_RESULT (ic)), "a", 1); + aopPut (AOP (IC_RESULT (ic)), "#0x40", 2); + } else { + /* we can just move _bp */ + aopPut (AOP (IC_RESULT (ic)), "_bpx", 0); + aopPut (AOP (IC_RESULT (ic)), "_bpx+1", 1); + aopPut (AOP (IC_RESULT (ic)), "#0x40", 2); + } + } else { + /* if it has an offset then we need to compute it */ + if (sym->stack) { + emitcode ("mov", "a,_bp"); + emitcode ("add", "a,#0x%02x", ((char) sym->stack & 0xff)); + aopPut (AOP (IC_RESULT (ic)), "a", 0); + } else { + /* we can just move _bp */ + aopPut (AOP (IC_RESULT (ic)), "_bp", 0); + } + /* fill the result with zero */ + size = AOP_SIZE (IC_RESULT (ic)) - 1; + + + if (options.stack10bit && size < (FPTRSIZE - 1)) { + fprintf (stderr, + "*** warning: pointer to stack var truncated.\n"); + } - offset = 1; - while (size--) - { - /* Yuck! */ - if (options.stack10bit && offset == 2) - { - aopPut (AOP (IC_RESULT (ic)), "#0x40", offset++); - } - else - { + offset = 1; + while (size--) { aopPut (AOP (IC_RESULT (ic)), zero, offset++); - } - } - + } + } goto release; - } + } /* object not on stack then we need the name */ size = AOP_SIZE (IC_RESULT (ic)); diff --git a/src/ds390/main.c b/src/ds390/main.c index b905d3ce..f343ebaf 100644 --- a/src/ds390/main.c +++ b/src/ds390/main.c @@ -105,9 +105,9 @@ _ds390_finaliseOptions (void) port->s.fptr_size = 3; port->s.gptr_size = 4; - port->stack.isr_overhead++; /* Will save dpx on ISR entry. */ + port->stack.isr_overhead += 2; /* Will save dpx on ISR entry. */ - port->stack.call_overhead++; /* This acounts for the extra byte + port->stack.call_overhead += 2; /* This acounts for the extra byte * of return addres on the stack. * but is ugly. There must be a * better way. diff --git a/src/ds390/ralloc.c b/src/ds390/ralloc.c index 06f1be1c..a4642217 100644 --- a/src/ds390/ralloc.c +++ b/src/ds390/ralloc.c @@ -42,6 +42,7 @@ static struct bitVect *spiltSet; set *stackSpil; bitVect *regAssigned; + bitVect *totRegAssigned; /* final set of LRs that got into registers */ short blockSpil; int slocNum; bitVect *funcrUsed; /* registers used in a function */ @@ -78,6 +79,7 @@ regs regs390[] = }; int ds390_nRegs = 13; static void spillThis (symbol *); +static void freeAllRegs (); /*-----------------------------------------------------------------*/ /* allocReg - allocates register of given type */ @@ -142,6 +144,15 @@ freeReg (regs * reg) reg->isFree = 1; } +/*-----------------------------------------------------------------*/ +/* useReg - marks a register as used */ +/*-----------------------------------------------------------------*/ +static void +useReg (regs * reg) +{ + reg->isFree = 0; +} + /*-----------------------------------------------------------------*/ /* nFreeRegs - returns number of free registers */ @@ -482,9 +493,10 @@ createStackSpil (symbol * sym) if (applyToSet (_G.stackSpil, isFree, &sloc, sym)) { /* found a free one : just update & return */ - sym->usl.spillLoc = sloc; + sym->usl.spillLoc = sloc; sym->stackSpil = 1; sloc->isFree = 0; + sloc->allocreq++; addSetHead (&sloc->usl.itmpStack, sym); return sym; } @@ -596,10 +608,11 @@ spillThis (symbol * sym) /* mark it has spilt & put it in the spilt set */ - sym->isspilt = 1; + sym->isspilt = sym->spillA = 1; _G.spiltSet = bitVectSetBit (_G.spiltSet, sym->key); bitVectUnSetBit (_G.regAssigned, sym->key); + bitVectUnSetBit (_G.totRegAssigned, sym->key); for (i = 0; i < sym->nRegs; i++) @@ -619,7 +632,7 @@ spillThis (symbol * sym) } if (sym->usl.spillLoc && !sym->remat) - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return; } @@ -653,7 +666,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) sym->usl.spillLoc->name)); sym->spildir = 1; /* mark it as allocation required */ - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -698,7 +711,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) sym = leastUsedLR (selectS); /* mark this as allocation required */ - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -707,7 +720,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) { sym = leastUsedLR (selectS); - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -719,7 +732,7 @@ selectSpil (iCode * ic, eBBlock * ebp, symbol * forSym) /* return a created spil location */ sym = createStackSpil (leastUsedLR (selectS)); - sym->usl.spillLoc->allocreq = 1; + sym->usl.spillLoc->allocreq++; return sym; } @@ -743,12 +756,13 @@ spilSomething (iCode * ic, eBBlock * ebp, symbol * forSym) ssym = selectSpil (ic, ebp, forSym); /* mark it as spilt */ - ssym->isspilt = 1; + ssym->isspilt = ssym->spillA = 1; _G.spiltSet = bitVectSetBit (_G.spiltSet, ssym->key); /* mark it as not register assigned & take it away from the set */ bitVectUnSetBit (_G.regAssigned, ssym->key); + bitVectUnSetBit (_G.totRegAssigned, ssym->key); /* mark the registers as free */ for (i = 0; i < ssym->nRegs; i++) @@ -849,6 +863,41 @@ tryAgain: goto tryAgain; } +/*-----------------------------------------------------------------*/ +/* getRegPtrNoSpil - get it cannot split */ +/*-----------------------------------------------------------------*/ +static regs *getRegPtrNoSpil() +{ + regs *reg; + + /* try for a ptr type */ + if ((reg = allocReg (REG_PTR))) + return reg; + + /* try for gpr type */ + if ((reg = allocReg (REG_GPR))) + return reg; + + assert(0); +} + +/*-----------------------------------------------------------------*/ +/* getRegGprNoSpil - get it cannot split */ +/*-----------------------------------------------------------------*/ +static regs *getRegGprNoSpil() +{ + + regs *reg; + if ((reg = allocReg (REG_GPR))) + return reg; + + if (!ds390_ptrRegReq) + if ((reg = allocReg (REG_PTR))) + return reg; + + assert(0); +} + /*-----------------------------------------------------------------*/ /* symHasReg - symbol has a given register */ /*-----------------------------------------------------------------*/ @@ -948,6 +997,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) result->regs[i] = getRegGpr (ic, ebp, result); _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key); + _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, result->key); } @@ -977,10 +1027,11 @@ reassignLR (operand * op) int i; /* not spilt any more */ - sym->isspilt = sym->blockSpil = sym->remainSpil = 0; + sym->isspilt = sym->spillA = sym->blockSpil = sym->remainSpil = 0; bitVectUnSetBit (_G.spiltSet, sym->key); _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); + _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key); _G.blockSpil--; @@ -1030,15 +1081,16 @@ willCauseSpill (int nr, int rt) /* ult and operand, if this happens make sure they are in the same */ /* position as the operand otherwise chaos results */ /*-----------------------------------------------------------------*/ -static void +static int positionRegs (symbol * result, symbol * opsym, int lineno) { int count = min (result->nRegs, opsym->nRegs); int i, j = 0, shared = 0; + int change = 0; /* if the result has been spilt then cannot share */ if (opsym->isspilt) - return; + return 0; again: shared = 0; /* first make sure that they actually share */ @@ -1059,8 +1111,10 @@ xchgPositions: regs *tmp = result->regs[i]; result->regs[i] = result->regs[j]; result->regs[j] = tmp; + change ++; goto again; } + return change ; } /*-----------------------------------------------------------------*/ @@ -1094,7 +1148,7 @@ serialRegAssign (eBBlock ** ebbs, int count) /* if result is present && is a true symbol */ if (IC_RESULT (ic) && ic->op != IFX && IS_TRUE_SYMOP (IC_RESULT (ic))) - OP_SYMBOL (IC_RESULT (ic))->allocreq = 1; + OP_SYMBOL (IC_RESULT (ic))->allocreq++; /* take away registers from live ranges that end at this instruction */ @@ -1182,6 +1236,7 @@ serialRegAssign (eBBlock ** ebbs, int count) } /* else we assign registers to it */ _G.regAssigned = bitVectSetBit (_G.regAssigned, sym->key); + _G.totRegAssigned = bitVectSetBit (_G.totRegAssigned, sym->key); for (j = 0; j < sym->nRegs; j++) { @@ -1218,6 +1273,61 @@ serialRegAssign (eBBlock ** ebbs, int count) } } +/*-----------------------------------------------------------------*/ +/* fillGaps - Try to fill in the Gaps left by Pass1 */ +/*-----------------------------------------------------------------*/ +static void fillGaps() +{ + symbol *sym =NULL; + int key =0; + + return ; /* NOT YET .. MORE TESTING IN PROGRESS */ + /* look for livernages that was spilt by the allocator */ + for (sym = hTabFirstItem(liveRanges,&key) ; sym ; + sym = hTabNextItem(liveRanges,&key)) { + + int i; + + if (!sym->spillA || !sym->clashes || sym->remat) continue ; + + /* find the liveRanges this one clashes with, that are + still assigned to registers & mark the registers as used*/ + for ( i = 0 ; i < sym->clashes->size ; i ++) { + int k; + symbol *clr; + + if (bitVectBitValue(sym->clashes,i) == 0 || /* those that clash with this */ + bitVectBitValue(_G.totRegAssigned,i) == 0) /* and are still assigned to registers */ + continue ; + + assert (clr = hTabItemWithKey(liveRanges,i)); + + /* mark these registers as used */ + for (k = 0 ; k < clr->nRegs ; k++ ) + useReg(clr->regs[k]); + } + + if (willCauseSpill(sym->nRegs,sym->regType)) { + /* NOPE :( clear all registers & and continue */ + freeAllRegs(); + continue ; + } + + /* THERE IS HOPE !!!! */ + for (i=0; i < sym->nRegs ; i++ ) { + if (sym->regType == REG_PTR) + sym->regs[i] = getRegPtrNoSpil (); + else + sym->regs[i] = getRegGprNoSpil (); + } + printf("FILLED GAP for %s in function %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN"); + _G.totRegAssigned = bitVectSetBit(_G.totRegAssigned,sym->key); + sym->isspilt = sym->spillA = 0 ; + sym->usl.spillLoc->allocreq--; + freeAllRegs(); + } +} + /*-----------------------------------------------------------------*/ /* rUmaskForOp :- returns register mask for an operand */ /*-----------------------------------------------------------------*/ @@ -1896,7 +2006,7 @@ packRegsDPTRuse (iCode * lic, operand * op, eBBlock * ebp) sym_link *type, *etype; if (!IS_SYMOP(op)) return NULL; - if (OP_SYMBOL(op)->remat) return NULL; + if (OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly) return NULL; /* first check if any overlapping liverange has already been assigned to DPTR */ @@ -1928,28 +2038,44 @@ packRegsDPTRuse (iCode * lic, operand * op, eBBlock * ebp) /* special case of add with a [remat] */ if (ic->op == '+' && - OP_SYMBOL(IC_LEFT(ic))->remat ) continue ; + OP_SYMBOL(IC_LEFT(ic))->remat && + !isOperandInFarSpace(IC_RIGHT(ic))) continue ; + + /* special case */ + /* pointerGet */ + if (POINTER_GET(ic) && isOperandEqual(IC_RESULT(ic),op) && + getSize(operandType(IC_LEFT(ic))) > 1) return NULL ; + + if (POINTER_SET(ic) && isOperandEqual(IC_RIGHT(ic),op) && + getSize(operandType(IC_RESULT(ic))) > 1) return NULL; /* general case */ if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && !isOperandEqual(IC_RESULT(ic),op) && (isOperandInFarSpace(IC_RESULT(ic)) || + OP_SYMBOL(IC_RESULT(ic))->ruonly || OP_SYMBOL(IC_RESULT(ic))->onStack)) return NULL; if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && !isOperandEqual(IC_RIGHT(ic),op) && (OP_SYMBOL(IC_RIGHT(ic))->liveTo > ic->seq || - IS_TRUE_SYMOP(IC_RIGHT(ic))) && + IS_TRUE_SYMOP(IC_RIGHT(ic)) || + OP_SYMBOL(IC_RIGHT(ic))->ruonly) && (isOperandInFarSpace(IC_RIGHT(ic)) || OP_SYMBOL(IC_RIGHT(ic))->onStack)) return NULL; if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && !isOperandEqual(IC_LEFT(ic),op) && (OP_SYMBOL(IC_LEFT(ic))->liveTo > ic->seq || - IS_TRUE_SYMOP(IC_LEFT(ic)))&& + IS_TRUE_SYMOP(IC_LEFT(ic)) || + OP_SYMBOL(IC_LEFT(ic))->ruonly) && (isOperandInFarSpace(IC_LEFT(ic)) || OP_SYMBOL(IC_LEFT(ic))->onStack)) return NULL; - + + if (IC_LEFT(ic) && IC_RIGHT(ic) && + IS_ITEMP(IC_LEFT(ic)) && IS_ITEMP(IC_RIGHT(ic)) && + isOperandInFarSpace(IC_LEFT(ic)) && isOperandInFarSpace(IC_RIGHT(ic))) + return NULL; } OP_SYMBOL(op)->ruonly = 1; return dic; @@ -2347,6 +2473,10 @@ packRegisters (eBBlock * ebp) packRegsDPTRuse (ic, IC_LEFT (ic), ebp); } + if ((ic->op == CALL && getSize(operandType(IC_RESULT(ic))) <= 4)) { + packRegsDPTRuse (ic, IC_RESULT (ic), ebp); + } + /* if pointer set & left has a size more than one and right is not in far space */ if (POINTER_SET (ic) && @@ -2462,7 +2592,10 @@ ds390_assignRegisters (eBBlock ** ebbs, int count) iCode *ic; int i; - setToNull ((void *) &_G.funcrUsed); + setToNull ((void *) &_G.funcrUsed); + setToNull ((void *) &_G.regAssigned); + setToNull ((void *) &_G.totRegAssigned); + setToNull ((void *) &_G.funcrUsed); ds390_ptrRegReq = _G.stackExtend = _G.dataExtend = 0; ds390_nRegs = 18; if (options.model != MODEL_FLAT24) options.stack10bit = 0; @@ -2481,6 +2614,11 @@ ds390_assignRegisters (eBBlock ** ebbs, int count) /* and serially allocate registers */ serialRegAssign (ebbs, count); + ds390_nRegs = 8; + freeAllRegs (); + fillGaps(); + ds390_nRegs = 18; + /* if stack was extended then tell the user */ if (_G.stackExtend) { -- 2.30.2