* .version: changed version to 2.5.4
[fw/sdcc] / src / pic / ralloc.c
index 4d4bd48fab901389da4869db29ecd62ec6a15064..f7015d2cacdeeda9dcca855fbc5c05be595df8c4 100644 (file)
@@ -88,7 +88,8 @@ static int rDirectIdx=0;
 int pic14_nRegs = 128;   // = sizeof (regspic14) / sizeof (regs);
 
 int Gstack_base_addr=0; /* The starting address of registers that
-* are used to pass and return parameters */
+                        * are used to pass and return parameters */
+int Gstack_size = 0;
 
 
 
@@ -134,7 +135,7 @@ static void
 
        fprintf (debugF, "%s", buffer);
        /*
-       while (isspace(*bufferP)) bufferP++;
+       while (isspace((unsigned char)*bufferP)) bufferP++;
 
        if (bufferP && *bufferP) 
                lineCurr = (lineCurr ?
@@ -371,7 +372,7 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
        dReg->reglives.assignedpFlows = newSet();
        
        hTabAddItem(&dynDirectRegNames, regname2key(name), dReg);
-       
+
        return dReg;
 }
 
@@ -478,13 +479,17 @@ void initStack(int base_address, int size)
        int i;
        
        Gstack_base_addr = base_address;
-       //fprintf(stderr,"initStack");
+       Gstack_size = size;
+       //fprintf(stderr,"initStack [base:0x%02x, size:%d]\n", base_address, size);
        
        for(i = 0; i<size; i++) {
-               regs *r = newReg(REG_STK, PO_GPR_TEMP,base_address,NULL,1,0);
+               char buffer[16];
+               SNPRINTF(&buffer[0], 16, "STK%02d", i);
+               regs *r = newReg(REG_STK, PO_GPR_TEMP,base_address,buffer,1,0);
                r->address = base_address; // Pseudo stack needs a fixed location that can be known by all modules
                r->isFixed = 1;
-               r->name[0] = 's';
+               r->isPublic = 1;
+               //r->name[0] = 's';
                r->alias = 0x180; // Using shared memory for pseudo stack
                addSet(&dynStackRegs,r);
                base_address--;
@@ -586,10 +591,11 @@ allocNewDirReg (sym_link *symlnk,const char *name)
 {
        regs *reg;
        int address = 0;
+       sym_link *spec = getSpec (symlnk);
        
        /* if this is at an absolute address, then get the address. */
-       if (SPEC_ABSA (symlnk) ) {
-               address = SPEC_ADDR (symlnk);
+       if (SPEC_ABSA (spec) ) {
+               address = SPEC_ADDR (spec);
                //fprintf(stderr,"reg %s is at an absolute address: 0x%03x\n",name,address);
        }
        
@@ -602,7 +608,7 @@ allocNewDirReg (sym_link *symlnk,const char *name)
        } else {
                int idx;
                if (address) {
-                       if (IS_BITVAR (symlnk))
+                       if (IS_BITVAR (spec))
                                idx = address >> 3;
                        else
                                idx = address;
@@ -612,20 +618,20 @@ allocNewDirReg (sym_link *symlnk,const char *name)
                reg = newReg(REG_GPR, PO_DIR, idx, (char*)name,getSize (symlnk),0 );
                debugLog ("  -- added %s to hash, size = %d\n", (char*)name,reg->size);
                
-               if (SPEC_ABSA (symlnk) ) {
+               if (SPEC_ABSA (spec) ) {
                        reg->type = REG_SFR;
                }
                
-               if (IS_BITVAR (symlnk)) {
+               if (IS_BITVAR (spec)) {
                        addSet(&dynDirectBitRegs, reg);
                        reg->isBitField = 1;
                } else
                        addSet(&dynDirectRegs, reg);
                
-               if (!IS_STATIC (symlnk)) {
+               if (!IS_STATIC (spec)) {
                        reg->isPublic = 1;
                }
-               if (IS_EXTERN (symlnk)) {
+               if (IS_EXTERN (spec)) {
                        reg->isExtern = 1;
                }
                
@@ -765,7 +771,7 @@ allocDirReg (operand *op )
                        debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
                }
        } else {
-               allocNewDirReg (OP_SYM_ETYPE(op),name);
+               allocNewDirReg (OP_SYM_TYPE(op),name);
        }
        
        return reg;
@@ -796,7 +802,7 @@ allocRegByName (char *name, int size)
                /* Register wasn't found in hash, so let's create
                * a new one and put it in the hash table AND in the 
                * dynDirectRegNames set */
-               //fprintf (stderr,"%s symbol name %s\n", __FUNCTION__,name);
+               //fprintf (stderr,"%s symbol name %s, size:%d\n", __FUNCTION__,name,size);
                reg = newReg(REG_GPR, PO_DIR, rDirectIdx++, name,size,0 );
                for (sym = setFirstItem(sfr->syms); sym; sym = setNextItem(sfr->syms)) {
                        if (strcmp(reg->name+1,sym->name)==0) {
@@ -1184,6 +1190,7 @@ void writeUsedRegs(FILE *of)
        assignRelocatableRegisters(dynAllocRegs,0);
        assignRelocatableRegisters(dynStackRegs,0);
        
+       assignRelocatableRegisters(dynDirectRegs,0);
        /*
        assignRelocatableRegisters(dynDirectRegs,0);
        printf("assignRelocatableRegisters(dynDirectRegs,0);\n");
@@ -1942,14 +1949,36 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                /* if it does not end here */
                if (sym->liveTo > ic->seq)
                        continue;
-       
-               /* HACK: result and addr must be disjoint for POINTER_GET */
-               if (sym->liveTo == ic->seq && POINTER_GET(ic))
+
+               /* Prevent the result from being assigned the same registers as (one)
+                * operand as many genXXX-functions fail otherwise.
+                * POINTER_GET(ic) || ic->op == LEFT_OP || ic->op == RIGHT_OP || ic->op == NOT
+                * are known to fail. */
+               if (sym->liveTo == ic->seq && IC_RESULT(ic))
                {
-                       //piCode (ic, stderr); fprintf (stderr, " -- registers NOT deallocated\n");
-                       continue;
+                       switch (ic->op)
+                       {
+                       case '=':       /* assignment */
+                       case BITWISEAND: /* bitwise AND */
+                       case '|':       /* bitwise OR */
+                       case '^':       /* bitwise XOR */
+                       case '~':       /* bitwise negate */
+                       case RLC:       /* rotate through carry */
+                       case RRC:
+                       case UNARYMINUS:
+                       case '+':       /* addition */
+                       case '-':       /* subtraction */
+                         /* go ahead, these are safe to use with
+                          * non-disjoint register sets */
+                         break;
+
+                       default:
+                               /* do not release operand registers */
+                               //fprintf (stderr, "%s:%u: operand not freed: ", __FILE__, __LINE__); piCode (ic, stderr); fprintf (stderr, "\n");
+                               continue;
+                       } // switch
                }
-               
+       
                /* if it was spilt on stack then we can 
                mark the stack spil location as free */
                if (sym->isspilt)
@@ -3407,10 +3436,22 @@ isBitwiseOptimizable (iCode * ic)
 static void
 packRegsForAccUse (iCode * ic)
 {
-       iCode *uic;
+       //iCode *uic;
        
        debugLog ("%s\n", __FUNCTION__);
+
+       /* result too large for WREG? */
+       if (getSize (operandType (IC_RESULT (ic))) > 1)
+         return;
        
+       /* We have to make sure that OP_SYMBOL(IC_RESULT(ic))
+        * is never used as an operand to an instruction that
+        * cannot have WREG as an operand (e.g. BTFSx cannot
+        * operate on WREG...
+        * For now, store all results into proper registers. */
+       return;
+
+#if 0
        /* if this is an aggregate, e.g. a one byte char array */
        if (IS_AGGREGATE(operandType(IC_RESULT(ic)))) {
                return;
@@ -3547,8 +3588,7 @@ packRegsForAccUse (iCode * ic)
 accuse:
        debugLog ("%s - Yes we are using the accumulator\n", __FUNCTION__);
        OP_SYMBOL (IC_RESULT (ic))->accuse = 1;
-       
-       
+#endif 
 }
 
 /*-----------------------------------------------------------------*/