int ds390_nRegs = 13;
static void spillThis (symbol *);
static void freeAllRegs ();
+static iCode * packRegsDPTRuse (operand *);
/*-----------------------------------------------------------------*/
/* allocReg - allocates register of given type */
return TRUE;
}
+/*-----------------------------------------------------------------*/
+/* isOperandInReg - returns true if operand is currently in regs */
+/*-----------------------------------------------------------------*/
+static int isOperandInReg(operand *op)
+{
+ if (!IS_SYMOP(op)) return 0;
+
+ return bitVectBitValue(_G.totRegAssigned,OP_SYMBOL(op)->key);
+}
+
/*-----------------------------------------------------------------*/
/* computeSpillable - given a point find the spillable live ranges */
/*-----------------------------------------------------------------*/
}
SPEC_EXTR (sloc->etype) = 0;
SPEC_STAT (sloc->etype) = 0;
+ SPEC_VOLATILE(sloc->etype) = 0;
/* we don't allow it to be allocated`
onto the external stack since : so we
int key =0;
if (getenv("DISABLE_FILL_GAPS")) return;
+
+ /* First try to do DPTRuse once more since now we know what got into
+ registers */
+#if 1
+ for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
+ sym = hTabNextItem(liveRanges,&key)) {
+
+ if (sym->uptr && !sym->ruonly && getSize(sym->type) < 4) {
+ if (packRegsDPTRuse(operandFromSymbol(sym))) {
+
+ printf("FILL GAPS: found more DPTR use for %s in func %s\n",sym->name, currFunc ? currFunc->name : "UNKNOWN");
+ /* if this was ssigned to registers then */
+ if (bitVectBitValue(_G.totRegAssigned,sym->key)) {
+
+ /* take it out of the register assigned set */
+ bitVectUnSetBit(_G.totRegAssigned,sym->key);
+ sym->nRegs = 0;
+ } else if (sym->usl.spillLoc) sym->usl.spillLoc->allocreq--;
+
+ sym->isspilt = sym->spillA = 0;
+ }
+ }
+ }
+#endif
/* look for livernages that was spilt by the allocator */
for (sym = hTabFirstItem(liveRanges,&key) ; sym ;
sym = hTabNextItem(liveRanges,&key)) {
int pdone = 0;
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 ++) {
/* packRegsDPTRuse : - will reduce some registers for single Use */
/*-----------------------------------------------------------------*/
static iCode *
-packRegsDPTRuse (iCode * lic, operand * op, eBBlock * ebp)
+packRegsDPTRuse (operand * op)
{
/* go thru entire liveRange of this variable & check for
other possible usage of DPTR , if we don't find it the
for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
ic = hTabNextItem(iCodeSeqhTab,&key)) {
+ if (SKIP_IC3(ic)) continue;
+
/* if PCALL cannot be sure give up */
if (ic->op == PCALL) return NULL;
/* special case of add with a [remat] */
if (ic->op == '+' &&
OP_SYMBOL(IC_LEFT(ic))->remat &&
- !isOperandInFarSpace(IC_RIGHT(ic))) continue ;
+ (!isOperandInFarSpace(IC_RIGHT(ic)) ||
+ isOperandInReg(IC_RIGHT(ic)))) continue ;
- /* special case */
+ /* special cases */
/* pointerGet */
- if (POINTER_GET(ic) && isOperandEqual(IC_RESULT(ic),op) &&
- getSize(operandType(IC_LEFT(ic))) > 1) return NULL ;
+ if (POINTER_GET(ic) && !isOperandEqual(IC_LEFT(ic),op) &&
+ getSize(operandType(IC_LEFT(ic))) > 1 ) return NULL ;
+
+ /* pointerSet */
+ if (POINTER_SET(ic) && !isOperandEqual(IC_RESULT(ic),op) &&
+ getSize(operandType(IC_RESULT(ic))) > 1 ) return NULL;
- if (POINTER_SET(ic) && isOperandEqual(IC_RIGHT(ic),op) &&
- getSize(operandType(IC_RESULT(ic))) > 1) return NULL;
+ /* conditionals can destroy 'b' - make sure B wont be used in this one*/
+ if ((IS_CONDITIONAL(ic) || ic->op == '*' || ic->op == '/' ) &&
+ getSize(operandType(op)) > 3) return NULL;
/* general case */
if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) &&
!isOperandEqual(IC_RESULT(ic),op) &&
- (isOperandInFarSpace(IC_RESULT(ic)) ||
+ ((isOperandInFarSpace(IC_RESULT(ic)) && !isOperandInReg(IC_RESULT(ic))) ||
OP_SYMBOL(IC_RESULT(ic))->ruonly ||
OP_SYMBOL(IC_RESULT(ic))->onStack)) return NULL;
(OP_SYMBOL(IC_RIGHT(ic))->liveTo > ic->seq ||
IS_TRUE_SYMOP(IC_RIGHT(ic)) ||
OP_SYMBOL(IC_RIGHT(ic))->ruonly) &&
- (isOperandInFarSpace(IC_RIGHT(ic)) ||
+ ((isOperandInFarSpace(IC_RIGHT(ic)) && !isOperandInReg(IC_RIGHT(ic)))||
OP_SYMBOL(IC_RIGHT(ic))->onStack)) return NULL;
if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) &&
(OP_SYMBOL(IC_LEFT(ic))->liveTo > ic->seq ||
IS_TRUE_SYMOP(IC_LEFT(ic)) ||
OP_SYMBOL(IC_LEFT(ic))->ruonly) &&
- (isOperandInFarSpace(IC_LEFT(ic)) ||
+ ((isOperandInFarSpace(IC_LEFT(ic)) && !isOperandInReg(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)))
+ (isOperandInFarSpace(IC_LEFT(ic)) && !isOperandInReg(IC_LEFT(ic))) &&
+ (isOperandInFarSpace(IC_RIGHT(ic)) && !isOperandInReg(IC_RIGHT(ic))))
return NULL;
}
OP_SYMBOL(op)->ruonly = 1;
/* make sure that the result of this icode is not on the
stack, since acc is used to compute stack offset */
+#if 0
if (IS_TRUE_SYMOP (IC_RESULT (uic)) &&
OP_SYMBOL (IC_RESULT (uic))->onStack)
return;
+#else
+ if (isOperandOnStack(IC_RESULT(uic)))
+ return;
+#endif
/* if either one of them in far space then we cannot */
if ((IS_TRUE_SYMOP (IC_LEFT (uic)) &&
!isOperandInFarSpace (IC_LEFT (ic)) &&
!options.model) {
- packRegsDPTRuse (ic, IC_LEFT (ic), ebp);
+ packRegsDPTRuse (IC_LEFT (ic));
}
if ((ic->op == CALL && getSize(operandType(IC_RESULT(ic))) <= 4)) {
- packRegsDPTRuse (ic, IC_RESULT (ic), ebp);
+ packRegsDPTRuse (IC_RESULT (ic));
}
/* if pointer set & left has a size more than
!IS_OP_RUONLY (IC_RIGHT (ic)) &&
getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1) {
- packRegsDPTRuse (ic, IC_RESULT (ic), ebp);
+ packRegsDPTRuse (IC_RESULT (ic));
}
/* if pointer get */
!IS_OP_RUONLY (IC_RESULT (ic)) &&
getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) {
- packRegsDPTRuse (ic, IC_LEFT (ic), ebp);
+ packRegsDPTRuse (IC_LEFT (ic));
}
/* if this is cast for intergral promotion then
SPEC_USIGN (fromType) == SPEC_USIGN (toType))
{
- iCode *dic = packRegsDPTRuse (ic, IC_RIGHT (ic), ebp);
+ iCode *dic = packRegsDPTRuse (IC_RIGHT (ic));
if (dic)
{
if (IS_ARITHMETIC_OP (dic))
if (compareType (operandType (IC_RIGHT (ic)),
operandType (IC_LEFT (ic))) == 1)
{
- iCode *dic = packRegsDPTRuse (ic, IC_RIGHT (ic), ebp);
+ iCode *dic = packRegsDPTRuse (IC_RIGHT (ic));
if (dic)
{
bitVectUnSetBit(OP_SYMBOL(IC_RESULT(ic))->defs,ic->key);