some -xstack related stuff
[fw/sdcc] / src / mcs51 / gen.c
index 93bc1c244b7ccd48e10274543492aeb6589a4a94..a960c041a885466b338f4ae27bdc34ed7829b1ed 100644 (file)
 #ifdef HAVE_ENDIAN_H
 #include <endian.h>
 #else
+#ifndef __BORLANDC__
 #warning "Cannot determine ENDIANESS of this machine assuming LITTLE_ENDIAN"
 #warning "If you running sdcc on an INTEL 80x86 Platform you are okay"
 #endif
 #endif
+#endif
 
 #include "common.h"
 #include "SDCCpeeph.h"
@@ -51,6 +53,7 @@
 #include "gen.h"
 
 char *aopLiteral (value *val, int offset);
+extern int allocInfo;
 
 /* this is the down and dirty file with all kinds of 
    kludgy & hacky stuff. This is what it is all about
@@ -61,10 +64,10 @@ static char *zero = "#0x00";
 static char *one  = "#0x01";
 static char *spname ;
 
-static char *fReturn8051[] = {"dpl","dph","b","a" };
-static char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
+char *fReturn8051[] = {"dpl","dph","b","a" };
+char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
 unsigned fReturnSize = 4; /* shared with ralloc.c */
-static char **fReturn = fReturn8051;
+char **fReturn = fReturn8051;
 static char *accUse[] = {"a","b"};
 
 static short rbank = -1;
@@ -88,7 +91,8 @@ static void saverbank (int, iCode *,bool);
                          IC_RESULT(x)->aop->type == AOP_STK )
 
 #define MOVA(x) if (strcmp(x,"a") && strcmp(x,"acc")) emitcode("mov","a,%s",x);
-#define CLRC    emitcode("clr","c");
+#define CLRC    emitcode("clr","c")
+#define SETC    emitcode("setb","c")
 
 static lineNode *lineHead = NULL;
 static lineNode *lineCurr = NULL;
@@ -230,30 +234,28 @@ static asmop *newAsmop (short type)
     return aop;
 }
 
+static void genSetDPTR(int n)
+{
+    if (!n)
+    {
+        emitcode(";", "Select standard DPTR");
+        emitcode("mov", "dps, #0x00");
+    }
+    else
+    {
+        emitcode(";", "Select alternate DPTR");
+        emitcode("mov", "dps, #0x01");
+    }
+}
+
 /*-----------------------------------------------------------------*/
 /* pointerCode - returns the code for a pointer type               */
 /*-----------------------------------------------------------------*/
 static int pointerCode (link *etype)
 {
-    int p_type;
 
     return PTR_TYPE(SPEC_OCLS(etype));
 
-/*     if (SPEC_OCLS(etype)->codesp ) { */
-/*     p_type = CPOINTER ;      */
-/*     } */
-/*     else */
-/*     if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
-/*         p_type = FPOINTER ; */
-/*     else */
-/*         if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
-/*             p_type = PPOINTER; */
-/*         else */
-/*             if (SPEC_OCLS(etype) == idata ) */
-/*                 p_type = IPOINTER; */
-/*             else */
-/*                 p_type = POINTER ; */
-/*     return p_type; */
 }
 
 /*-----------------------------------------------------------------*/
@@ -271,7 +273,7 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
     /* assign depending on the storage class */
     /* if it is on the stack or indirectly addressable */
     /* space we need to assign either r0 or r1 to it   */    
-    if (sym->onStack || sym->iaccess) {
+    if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
         sym->aop = aop = newAsmop(0);
         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
         aop->size = getSize(sym->type);
@@ -281,7 +283,6 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
         if (aop->type != AOP_STK) {
 
             if (sym->onStack) {
-
                     if ( _G.accInUse )
                         emitcode("push","acc");
 
@@ -295,7 +296,6 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
 
                     if ( _G.accInUse )
                         emitcode("pop","acc");
-
             } else
                 emitcode("mov","%s,#%s",
                          aop->aopu.aop_ptr->name,
@@ -305,6 +305,35 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
             aop->aopu.aop_stk = sym->stack;
         return aop;
     }
+    
+    if (sym->onStack && options.stack10bit)
+    {
+        /* It's on the 10 bit stack, which is located in
+         * far data space.
+         */
+         
+        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);
+        
+        genSetDPTR(1);
+        emitcode ("mov","dpx1,#0x40");
+        emitcode ("mov","dph1,#0x00");
+        emitcode ("mov","dpl1, a");
+        genSetDPTR(0);
+       
+        if ( _G.accInUse )
+            emitcode("pop","acc");
+            
+        sym->aop = aop = newAsmop(AOP_DPTR2);
+       aop->size = getSize(sym->type); 
+       return aop;
+    }
 
     /* if in bit space */
     if (IN_BITSPACE(space)) {
@@ -348,26 +377,29 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
 /*-----------------------------------------------------------------*/
 static asmop *aopForRemat (symbol *sym)
 {
-    char *s = buffer;   
     iCode *ic = sym->rematiCode;
     asmop *aop = newAsmop(AOP_IMMD);
+    int val = 0;
 
-    while (1) {
-
-        /* if plus or minus print the right hand side */
-        if (ic->op == '+' || ic->op == '-') {
-            sprintf(s,"0x%04x %c ",(int) operandLitValue(IC_RIGHT(ic)),
-                    ic->op );
-            s += strlen(s);
-            ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
-            continue ;
-        }
-
-        /* we reached the end */
-        sprintf(s,"%s",OP_SYMBOL(IC_LEFT(ic))->rname);
-        break;
+    for (;;) {
+       if (ic->op == '+')
+           val += operandLitValue(IC_RIGHT(ic));
+       else if (ic->op == '-')
+           val -= operandLitValue(IC_RIGHT(ic));
+       else
+           break;
+       
+       ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode;
     }
 
+    if (val)
+       sprintf(buffer,"(%s %c 0x%04x)",
+               OP_SYMBOL(IC_LEFT(ic))->rname, 
+               val >= 0 ? '+' : '-',
+               abs(val) & 0xffff);
+    else
+       strcpy(buffer,OP_SYMBOL(IC_LEFT(ic))->rname);
+
     ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(buffer)+1);
     strcpy(aop->aopu.aop_immd,buffer);    
     return aop;        
@@ -628,12 +660,23 @@ static void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop)
             bitVectUnSetBit(ic->rUsed,R1_IDX);          
 
             getFreePtr(ic,&aop,FALSE);
+            
+            if (options.stack10bit)
+            {
+                /* I'm not sure what to do here yet... */
+                /* #STUB */
+               fprintf(stderr, 
+                       "*** Warning: probably generating bad code for "
+                       "10 bit stack mode.\n");
+            }
+            
             if (stk) {
                 emitcode ("mov","a,_bp");
                 emitcode ("add","a,#0x%02x",((char)stk) & 0xff);
                 emitcode ("mov","%s,a",aop->aopu.aop_ptr->name);
-            } else
+            } else {
                 emitcode ("mov","%s,_bp",aop->aopu.aop_ptr->name);
+            }
 
             while (sz--) {
                 emitcode("pop","acc");
@@ -709,6 +752,13 @@ static char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
        return rs;
        
     case AOP_DPTR:
+    case AOP_DPTR2:
+    
+    if (aop->type == AOP_DPTR2)
+    {
+        genSetDPTR(1);
+    }
+    
        while (offset > aop->coff) {
            emitcode ("inc","dptr");
            aop->coff++;
@@ -724,14 +774,21 @@ static char *aopGet (asmop *aop, int offset, bool bit16, bool dname)
            emitcode("clr","a");
            emitcode("movc","a,@a+dptr");
         }
-       else
+    else {
            emitcode("movx","a,@dptr");
-       return (dname ? "acc" : "a");
+    }
+           
+    if (aop->type == AOP_DPTR2)
+    {
+        genSetDPTR(0);
+    }
+           
+    return (dname ? "acc" : "a");
        
        
     case AOP_IMMD:
        if (bit16) 
-           sprintf (s,"#(%s)",aop->aopu.aop_immd);
+           sprintf (s,"#%s",aop->aopu.aop_immd);
        else
            if (offset) 
                sprintf(s,"#(%s >> %d)",
@@ -839,6 +896,13 @@ static void aopPut (asmop *aop, char *s, int offset)
        break;
        
     case AOP_DPTR:
+    case AOP_DPTR2:
+    
+    if (aop->type == AOP_DPTR2)
+    {
+        genSetDPTR(1);
+    }
+    
        if (aop->code) {
            werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
                   "aopPut writting to code space");
@@ -861,6 +925,11 @@ static void aopPut (asmop *aop, char *s, int offset)
        MOVA(s);        
        
        emitcode ("movx","@dptr,a");
+       
+    if (aop->type == AOP_DPTR2)
+    {
+        genSetDPTR(0);
+    }
        break;
        
     case AOP_R0:
@@ -928,10 +997,11 @@ static void aopPut (asmop *aop, char *s, int offset)
                        
                        if (strcmp(s,"a")) {
                            MOVA(s);
-                       }  
-                       emitcode("cjne","a,#0x01,%05d$",lbl->key+100);
-                       emitcode("","%05d$:",lbl->key+100);
+                       }
+                       emitcode("clr","c");
+                       emitcode("jz","%05d$",lbl->key+100);
                        emitcode("cpl","c");
+                       emitcode("","%05d$:",lbl->key+100);
                        emitcode("mov","%s,c",aop->aopu.aop_dir);
                    }
        }
@@ -1004,9 +1074,21 @@ static void reAdjustPreg (asmop *aop)
             while (size--)
                 emitcode("dec","%s",aop->aopu.aop_ptr->name);
             break;          
-        case AOP_DPTR : 
+        case AOP_DPTR :
+        case AOP_DPTR2:
+            if (aop->type == AOP_DPTR2)
+           {
+                genSetDPTR(1);
+           } 
             while (size--)
+            {
                 emitcode("lcall","__decdptr");
+            }
+                
+           if (aop->type == AOP_DPTR2)
+           {
+                genSetDPTR(0);
+           }                
             break;  
 
     }   
@@ -1020,7 +1102,8 @@ static void reAdjustPreg (asmop *aop)
                        AOP_TYPE(x) == AOP_R0))
 
 #define AOP_NEEDSACC(x) (AOP(x) && (AOP_TYPE(x) == AOP_CRY ||  \
-                        AOP_TYPE(x) == AOP_DPTR || AOP(x)->paged)) 
+                        AOP_TYPE(x) == AOP_DPTR || AOP_TYPE(x) == AOP_DPTR2 || \
+                         AOP(x)->paged)) 
 
 #define AOP_INPREG(x) (x && (x->type == AOP_REG &&                        \
                       (x->aopu.aop_reg[0] == mcs51_regWithIdx(R0_IDX) || \
@@ -1286,15 +1369,19 @@ static void genUminus (iCode *ic)
     /* otherwise subtract from zero */
     size = AOP_SIZE(IC_LEFT(ic));
     offset = 0 ;
-    CLRC ;
+    //CLRC ;
     while(size--) {
         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE);
         if (!strcmp(l,"a")) {
-            emitcode("cpl","a");
-            emitcode("inc","a");
+         if (offset==0)
+           SETC;
+         emitcode("cpl","a");
+         emitcode("addc","a,#0");
         } else {
-            emitcode("clr","a");
-            emitcode("subb","a,%s",l);
+         if (offset==0)
+           CLRC;
+         emitcode("clr","a");
+         emitcode("subb","a,%s",l);
         }       
         aopPut(AOP(IC_RESULT(ic)),"a",offset++);
     }
@@ -1871,6 +1958,12 @@ static int resultRemat (iCode *ic)
     return 0;
 }
 
+#ifdef __BORLANDC__
+#define STRCASECMP stricmp
+#else
+#define STRCASECMP strcasecmp
+#endif
+
 /*-----------------------------------------------------------------*/
 /* inExcludeList - return 1 if the string is in exclude Reg list   */
 /*-----------------------------------------------------------------*/
@@ -1879,12 +1972,12 @@ static bool inExcludeList(char *s)
     int i =0;
     
     if (options.excludeRegs[i] &&
-       strcasecmp(options.excludeRegs[i],"none") == 0)
+    STRCASECMP(options.excludeRegs[i],"none") == 0)
        return FALSE ;
 
     for ( i = 0 ; options.excludeRegs[i]; i++) {
        if (options.excludeRegs[i] &&
-           strcasecmp(s,options.excludeRegs[i]) == 0)
+        STRCASECMP(s,options.excludeRegs[i]) == 0)
            return TRUE;
     }
     return FALSE ;
@@ -1943,7 +2036,19 @@ static void genFunction (iCode *ic)
        if (!inExcludeList("dph"))
            emitcode ("push","dph");
        if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
-           emitcode ("push", "dpx");   
+       {
+           emitcode ("push", "dpx");
+           /* Make sure we're using standard DPTR */
+           emitcode ("push", "dps");
+           emitcode ("mov", "dps, #0x00");
+           if (options.stack10bit)
+           {   
+               /* This ISR could conceivably use DPTR2. Better save it. */
+               emitcode ("push", "dpl1");
+               emitcode ("push", "dph1");
+               emitcode ("push", "dpx1");
+           }
+       }
        /* if this isr has no bank i.e. is going to
           run with bank 0 , then we need to save more
           registers :-) */
@@ -2001,14 +2106,27 @@ static void genFunction (iCode *ic)
     if (IS_RENT(sym->etype) || options.stackAuto) {
 
        if (options.useXstack) {
+               /* set up the PAGE for the xternal stack */
+               if (sym->args) {
+                       emitcode("push","dph");
+                       emitcode("push","acc");
+               }
+               emitcode("mov","dph,__page_no__");
+               emitcode("movx","a,@dptr");
+               if (sym->args) {
+                       emitcode("pop","acc");
+                       emitcode("pop","dph");
+               }               
            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);
     }
 
@@ -2048,7 +2166,9 @@ static void genEndFunction (iCode *ic)
     symbol *sym = OP_SYMBOL(IC_LEFT(ic));
 
     if (IS_RENT(sym->etype) || options.stackAuto)
+    {
         emitcode ("mov","%s,_bp",spname);
+    }
 
     /* if use external stack but some variables were
     added to the local stack then decrement the
@@ -2068,7 +2188,9 @@ static void genEndFunction (iCode *ic)
            emitcode("dec","%s",spname);
        }
        else
+       {
            emitcode ("pop","_bp");
+       }
     }
 
     /* restore the register bank  */    
@@ -2108,7 +2230,16 @@ static void genEndFunction (iCode *ic)
        }
 
        if (options.model == MODEL_FLAT24 && !inExcludeList("dpx"))
+       {
+           if (options.stack10bit)
+           {
+               emitcode ("pop", "dpx1");
+               emitcode ("pop", "dph1");
+               emitcode ("pop", "dpl1");
+           }   
+           emitcode ("pop", "dps");
            emitcode ("pop", "dpx");
+       }
        if (!inExcludeList("dph"))
            emitcode ("pop","dph");
        if (!inExcludeList("dpl"))
@@ -2157,7 +2288,6 @@ static void genEndFunction (iCode *ic)
        }
 
        /* if debug then send end of function */
-/*     if (options.debug && currFunc) { */
        if (currFunc) {
            _G.debugLine = 1;
            emitcode("","C$%s$%d$%d$%d ==.",
@@ -2195,6 +2325,7 @@ static void genRet (iCode *ic)
     while (size--) {
            char *l ;
            if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) {
+                   /* #NOCHANGE */
                    l = aopGet(AOP(IC_LEFT(ic)),offset++,
                           FALSE,TRUE);
                    emitcode("push","%s",l);
@@ -2265,13 +2396,11 @@ static int findLabelBackwards(iCode *ic, int key)
         
         if (ic->op == LABEL && IC_LABEL(ic)->key == key)
         {
-            printf("findLabelBackwards = %d\n", count);
+            /* printf("findLabelBackwards = %d\n", count); */
             return count;
         }
     }
     
-    printf("findLabelBackwards: not found.\n");
-    
     return 0;
 }
 
@@ -6171,7 +6300,7 @@ static void genGenPointerGet (operand *left,
     }
     /* so dptr know contains the address */
     freeAsmop(left,NULL,ic,TRUE);
-    aopOp(result,ic,FALSE);
+    aopOp(result,ic,FALSE); 
 
     /* if bit then unpack */
     if (IS_BITVAR(retype)) 
@@ -6833,14 +6962,33 @@ static void genAddrOf (iCode *ic)
             emitcode("mov","a,_bp");
             emitcode("add","a,#0x%02x",((char) sym->stack & 0xff));
             aopPut(AOP(IC_RESULT(ic)),"a",0);       
-        } else 
+        } 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--) 
-            aopPut(AOP(IC_RESULT(ic)),zero,offset++);
+        while (size--)
+        {
+            /* Yuck! */
+            if (options.stack10bit && offset == 2)
+            {
+                aopPut(AOP(IC_RESULT(ic)),"#0x40", offset++);
+            }
+            else
+            {
+               aopPut(AOP(IC_RESULT(ic)),zero,offset++);
+            }
+        }
 
         goto release;
     }
@@ -6911,12 +7059,13 @@ static void genAssign (iCode *ic)
     aopOp(right,ic,FALSE);
     
     /* special case both in far space */
-    if (AOP_TYPE(right) == AOP_DPTR &&
+    if ((AOP_TYPE(right) == AOP_DPTR ||
+         AOP_TYPE(right) == AOP_DPTR2) &&
        IS_TRUE_SYMOP(result)       &&
        isOperandInFarSpace(result)) {
-
+       
        genFarFarAssign (result,right,ic);
-        return ;
+       return ;
     }
 
     aopOp(result,ic,TRUE);
@@ -6981,7 +7130,7 @@ static void genAssign (iCode *ic)
     }
     
 release:
-    freeAsmop (right,NULL,ic,FALSE);
+    freeAsmop (right,NULL,ic,TRUE);
     freeAsmop (result,NULL,ic,TRUE);
 }   
 
@@ -7020,6 +7169,7 @@ static void genCast (iCode *ic)
 {
     operand *result = IC_RESULT(ic);
     link *ctype = operandType(IC_LEFT(ic));
+    link *rtype = operandType(IC_RIGHT(ic));
     operand *right = IC_RIGHT(ic);
     int size, offset ;
 
@@ -7092,20 +7242,6 @@ static void genCast (iCode *ic)
            else {
                /* we have to go by the storage class */
                p_type = PTR_TYPE(SPEC_OCLS(etype));
-
-/*             if (SPEC_OCLS(etype)->codesp )  */
-/*                 p_type = CPOINTER ;  */
-/*             else */
-/*                 if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) */
-/*                     p_type = FPOINTER ; */
-/*                 else */
-/*                     if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) */
-/*                         p_type = PPOINTER; */
-/*                     else */
-/*                         if (SPEC_OCLS(etype) == idata ) */
-/*                             p_type = IPOINTER ; */
-/*                         else */
-/*                             p_type = POINTER ; */
            }
                
            /* the first two bytes are known */
@@ -7167,10 +7303,10 @@ static void genCast (iCode *ic)
         offset++;
     }
 
-    /* now depending on the sign of the destination */
+    /* now depending on the sign of the source && destination */
     size = AOP_SIZE(result) - AOP_SIZE(right);
     /* if unsigned or not an integral type */
-    if (SPEC_USIGN(ctype) || !IS_SPEC(ctype)) {
+    if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) {
         while (size--)
             aopPut(AOP(result),zero,offset++);
     } else {
@@ -7287,15 +7423,11 @@ void gen51Code (iCode *lic)
     iCode *ic;
     int cln = 0;
 
-    /* Hack-o-matic: change fReturn based on model. */
-    if (options.model == MODEL_FLAT24)
-    {
-        fReturn = fReturn390;
-        fReturnSize = 5;
-    }
-
     lineHead = lineCurr = NULL;
 
+    /* print the allocation information */
+    if (allocInfo)
+       printAllocInfo( currFunc, codeOutFile);
     /* if debug information required */
 /*     if (options.debug && currFunc) { */
     if (currFunc) {
@@ -7531,6 +7663,6 @@ void gen51Code (iCode *lic)
        peepHole (&lineHead);
 
     /* now do the actual printing */
-    printLine (lineHead,codeOutFile);
+    printLine (lineHead,codeOutFile);    
     return;
 }