+/*-----------------------------------------------------------------*/
+/* packRegsDPTRnuse - color live ranges that can go into extra DPTRS */
+/*-----------------------------------------------------------------*/
+static int packRegsDPTRnuse( operand *op , int dptr)
+{
+ int i,key;
+ iCode *ic;
+
+ if (!IS_SYMOP(op) || !IS_ITEMP(op)) return 0;
+ if (OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly || OP_SYMBOL(op)->dptr)
+ return 0;
+
+ /* first check if any overlapping liverange has already been
+ assigned to this DPTR */
+ if (OP_SYMBOL(op)->clashes) {
+ for (i = 0 ; i < OP_SYMBOL(op)->clashes->size ; i++ ) {
+ symbol *sym;
+ if (bitVectBitValue(OP_SYMBOL(op)->clashes,i)) {
+ sym = hTabItemWithKey(liveRanges,i);
+ if (sym->dptr == dptr) return 0;
+ }
+ }
+ }
+
+ /* future for more dptrs */
+ if (dptr > 1) {
+ OP_SYMBOL(op)->dptr = dptr;
+ return 1;
+ }
+
+ /* DPTR1 is special since it is also used as a scratch by the backend .
+ so we walk thru the entire live range of this operand and make sure
+ DPTR1 will not be used by the backed . The logic here is to find out if
+ more than one operand in an icode is in far space then we give up : we
+ don't keep it live across functions for now
+ */
+
+ ic = hTabFirstItemWK(iCodeSeqhTab,OP_SYMBOL(op)->liveFrom);
+ for (; ic && ic->seq <= OP_SYMBOL(op)->liveTo;
+ ic = hTabNextItem(iCodeSeqhTab,&key)) {
+ int nfs =0;
+
+ if (ic->op == CALL || ic->op == PCALL) return 0;
+
+ /* single operand icode are ok */
+ if (ic->op == IFX || ic->op == IPUSH)
+ continue ;
+
+ if (ic->op == SEND ) {
+ if (ic->argreg != 1 ) return 0;
+ else continue ;
+ }
+ /* two special cases first */
+ if (POINTER_GET(ic) && !isOperandEqual(IC_LEFT(ic),op) && /* pointer get */
+ !OP_SYMBOL(IC_LEFT(ic))->ruonly && /* with result in far space */
+ (isOperandInFarSpace(IC_RESULT(ic)) &&
+ !isOperandInReg(IC_RESULT(ic)))) {
+ return 0;
+ }
+
+ if (POINTER_SET(ic) && !isOperandEqual(IC_RESULT(ic),op) && /* pointer set */
+ !OP_SYMBOL(IC_RESULT(ic))->ruonly && /* with right in far space */
+ (isOperandInFarSpace(IC_RIGHT(ic)) &&
+ !isOperandInReg(IC_RIGHT(ic)))) {
+ return 0;
+ }
+
+ if (IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) && /* if symbol operand */
+ !isOperandEqual(IC_RESULT(ic),op) && /* not the same as this */
+ ((isOperandInFarSpace(IC_RESULT(ic)) || /* in farspace or */
+ OP_SYMBOL(IC_RESULT(ic))->onStack) && /* on the stack */
+ !isOperandInReg(IC_RESULT(ic)))) { /* and not in register */
+ nfs++;
+ }
+ /* same for left */
+ if (IC_LEFT(ic) && IS_SYMOP(IC_LEFT(ic)) && /* if symbol operand */
+ !isOperandEqual(IC_LEFT(ic),op) && /* not the same as this */
+ ((isOperandInFarSpace(IC_LEFT(ic)) || /* in farspace or */
+ OP_SYMBOL(IC_LEFT(ic))->onStack) && /* on the stack */
+ !isOperandInReg(IC_LEFT(ic)))) { /* and not in register */
+ nfs++;
+ }
+ /* same for right */
+ if (IC_RIGHT(ic) && IS_SYMOP(IC_RIGHT(ic)) && /* if symbol operand */
+ !isOperandEqual(IC_RIGHT(ic),op) && /* not the same as this */
+ ((isOperandInFarSpace(IC_RIGHT(ic)) || /* in farspace or */
+ OP_SYMBOL(IC_RIGHT(ic))->onStack) && /* on the stack */
+ !isOperandInReg(IC_RIGHT(ic)))) { /* and not in register */
+ nfs++;
+ }
+
+ if (nfs && IC_RESULT(ic) && IS_SYMOP(IC_RESULT(ic)) &&
+ OP_SYMBOL(IC_RESULT(ic))->ruonly) return 0;
+
+ if (nfs > 1) return 0;
+ }
+ OP_SYMBOL(op)->dptr = dptr;
+ return 1;
+}
+