fixed sign extension bug
[fw/sdcc] / src / mcs51 / gen.c
index 6277354244c91b9a3db301c850da1362b33a3eff..d26aa0c832776a3b264e5fea5372bb00188dfb2d 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
@@ -60,7 +63,11 @@ char *aopLiteral (value *val, int offset);
 static char *zero = "#0x00";
 static char *one  = "#0x01";
 static char *spname ;
-static char *fReturn[] = {"dpl","dph","b","a" };
+
+char *fReturn8051[] = {"dpl","dph","b","a" };
+char *fReturn390[] = {"dpl","dph","dpx", "b","a" };
+unsigned fReturnSize = 4; /* shared with ralloc.c */
+char **fReturn = fReturn8051;
 static char *accUse[] = {"a","b"};
 
 static short rbank = -1;
@@ -226,27 +233,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;
-    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;
+
+    return PTR_TYPE(SPEC_OCLS(etype));
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -264,7 +272,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);
@@ -274,7 +282,6 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
         if (aop->type != AOP_STK) {
 
             if (sym->onStack) {
-
                     if ( _G.accInUse )
                         emitcode("push","acc");
 
@@ -288,7 +295,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,
@@ -298,6 +304,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)) {
@@ -341,26 +376,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;        
@@ -551,7 +589,7 @@ static void aopOp (operand *op, iCode *ic, bool result)
             int i;
             aop = op->aop = sym->aop = newAsmop(AOP_STR);
             aop->size = getSize(sym->type);
-            for ( i = 0 ; i < 4 ; i++ )
+            for ( i = 0 ; i < fReturnSize ; i++ )
                 aop->aopu.aop_str[i] = fReturn[i];
             return;
         }
@@ -621,12 +659,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");
@@ -702,6 +751,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++;
@@ -717,14 +773,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)",
@@ -832,6 +895,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");
@@ -854,6 +924,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:
@@ -921,10 +996,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);
                    }
        }
@@ -997,9 +1073,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;  
 
     }   
@@ -1013,7 +1101,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) || \
@@ -1864,6 +1953,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   */
 /*-----------------------------------------------------------------*/
@@ -1872,12 +1967,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 ;
@@ -1936,7 +2031,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 :-) */
@@ -2000,8 +2107,10 @@ static void genFunction (iCode *ic)
            emitcode("inc","%s",spname);
        }
        else
+       {
            /* set up the stack */
            emitcode ("push","_bp");     /* save the callers stack  */
+       }
        emitcode ("mov","_bp,%s",spname);
     }
 
@@ -2041,7 +2150,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
@@ -2061,7 +2172,9 @@ static void genEndFunction (iCode *ic)
            emitcode("dec","%s",spname);
        }
        else
+       {
            emitcode ("pop","_bp");
+       }
     }
 
     /* restore the register bank  */    
@@ -2101,7 +2214,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"))
@@ -2150,7 +2272,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 ==.",
@@ -2188,6 +2309,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);
@@ -2241,6 +2363,31 @@ static void genGoto (iCode *ic)
     emitcode ("ljmp","%05d$",(IC_LABEL(ic)->key+100));
 }
 
+/*-----------------------------------------------------------------*/
+/* findLabelBackwards: walks back through the iCode chain looking  */
+/* for the given label. Returns number of iCode instructions      */
+/* between that label and given ic.                               */
+/* Returns zero if label not found.                               */
+/*-----------------------------------------------------------------*/
+static int findLabelBackwards(iCode *ic, int key)
+{
+    int count = 0;
+    
+    while (ic->prev)
+    {
+        ic = ic->prev;
+        count++;
+        
+        if (ic->op == LABEL && IC_LABEL(ic)->key == key)
+        {
+            /* printf("findLabelBackwards = %d\n", count); */
+            return count;
+        }
+    }
+    
+    return 0;
+}
+
 /*-----------------------------------------------------------------*/
 /* genPlusIncr :- does addition with increment if possible         */
 /*-----------------------------------------------------------------*/
@@ -2264,7 +2411,27 @@ static bool genPlusIncr (iCode *ic)
     if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
         (size > 1) &&
         (icount == 1)) {
-        symbol *tlbl = newiTempLabel(NULL);
+        symbol *tlbl;
+        int emitTlbl;
+        int labelRange;
+
+       /* If the next instruction is a goto and the goto target
+        * is < 10 instructions previous to this, we can generate
+        * jumps straight to that target.
+        */
+        if (ic->next && ic->next->op == GOTO
+            && (labelRange = findLabelBackwards(ic, IC_LABEL(ic->next)->key)) != 0
+            && labelRange <= 10 )
+        {
+           emitcode(";", "tail increment optimized");
+           tlbl = IC_LABEL(ic->next);
+           emitTlbl = 0;
+        }
+        else
+        {
+            tlbl = newiTempLabel(NULL);
+            emitTlbl = 1;
+        }
        emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
        if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
           IS_AOP_PREG(IC_RESULT(ic)))
@@ -2307,7 +2474,11 @@ static bool genPlusIncr (iCode *ic)
            }
            emitcode("inc","%s",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
        }
-       emitcode("","%05d$:",tlbl->key+100);
+       
+       if (emitTlbl)
+       {
+           emitcode("","%05d$:",tlbl->key+100);
+       }
         return TRUE;
     }
     
@@ -2541,7 +2712,7 @@ release:
 static bool genMinusDec (iCode *ic)
 {
     unsigned int icount ;
-       unsigned int size = getDataSize(IC_RESULT(ic));
+    unsigned int size = getDataSize(IC_RESULT(ic));
 
     /* will try to generate an increment */
     /* if the right side is not a literal 
@@ -2554,12 +2725,32 @@ static bool genMinusDec (iCode *ic)
     if ((icount = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit)) > 4)
         return FALSE ;
 
-       size = getDataSize(IC_RESULT(ic));
     /* if decrement 16 bits in register */
     if (sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) &&
         (size > 1) &&
         (icount == 1)) {
-        symbol *tlbl = newiTempLabel(NULL);
+            symbol *tlbl;
+            int emitTlbl;
+            int labelRange;
+
+           /* If the next instruction is a goto and the goto target
+            * is <= 10 instructions previous to this, we can generate
+            * jumps straight to that target.
+            */
+            if (ic->next && ic->next->op == GOTO
+                && (labelRange = findLabelBackwards(ic, IC_LABEL(ic->next)->key)) != 0
+                && labelRange <= 10 )
+            {        
+               emitcode(";", "tail decrement optimized");
+               tlbl = IC_LABEL(ic->next);
+               emitTlbl = 0;
+            }
+            else
+            {
+                tlbl = newiTempLabel(NULL);
+                emitTlbl = 1;
+            }
+        
                emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),LSB,FALSE,FALSE));
                if(AOP_TYPE(IC_RESULT(ic)) == AOP_REG ||
                   IS_AOP_PREG(IC_RESULT(ic)))
@@ -2601,7 +2792,10 @@ static bool genMinusDec (iCode *ic)
                        }
                        emitcode("dec","%s",aopGet(AOP(IC_RESULT(ic)),MSB32,FALSE,FALSE));
                }
-               emitcode("","%05d$:",tlbl->key+100);
+               if (emitTlbl)
+               {
+                   emitcode("","%05d$:",tlbl->key+100);
+               }
         return TRUE;
     }
 
@@ -6090,7 +6284,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)) 
@@ -6130,22 +6324,23 @@ static void genPointerGet (iCode *ic)
     if (IS_PTR(type) && !IS_FUNC(type->next)) 
         p_type = DCL_TYPE(type);
     else {
-
        /* we have to go by the storage class */
-       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 ;
+       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 ; */
     }
 
     /* now that we have the pointer type we assign
@@ -6653,22 +6848,23 @@ static void genPointerSet (iCode *ic)
         p_type = DCL_TYPE(type);
     }
     else {
-
        /* we have to go by the storage class */
-       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 ;
+       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 ; */
     }
 
     /* now that we have the pointer type we assign
@@ -6750,14 +6946,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;
     }
@@ -6828,12 +7043,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);
@@ -6937,6 +7153,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 ;
 
@@ -7002,60 +7219,48 @@ static void genCast (iCode *ic)
 
        /* pointer to generic pointer */
        if (IS_GENPTR(ctype)) {
-               char *l = zero;
-
-               if (IS_PTR(type)) 
-                       p_type = DCL_TYPE(type);
-               else {
-                       /* we have to go by the storage class */
-                       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 ;
-               }
+           char *l = zero;
+           
+           if (IS_PTR(type)) 
+               p_type = DCL_TYPE(type);
+           else {
+               /* we have to go by the storage class */
+               p_type = PTR_TYPE(SPEC_OCLS(etype));
+           }
                
-               /* the first two bytes are known */
-               size = GPTRSIZE - 1; 
-               offset = 0 ;
-               while (size--) {
-                       aopPut(AOP(result),
-                              aopGet(AOP(right),offset,FALSE,FALSE),
-                              offset);
-                       offset++;
-               }
-               /* the last byte depending on type */
-               switch (p_type) {
-               case IPOINTER:
-               case POINTER:
-                       l = zero;
-                       break;
-               case FPOINTER:
-                       l = one;
-                       break;
-               case CPOINTER:
-                       l = "#0x02";
-                       break;                          
-               case PPOINTER:
-                       l = "#0x03";
-                       break;
-                       
-               default:
-                       /* this should never happen */
-                       werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-                              "got unknown pointer type");
-                       exit(1);
-               }
-               aopPut(AOP(result),l, GPTRSIZE - 1);        
-               goto release ;
+           /* the first two bytes are known */
+           size = GPTRSIZE - 1; 
+           offset = 0 ;
+           while (size--) {
+               aopPut(AOP(result),
+                      aopGet(AOP(right),offset,FALSE,FALSE),
+                      offset);
+               offset++;
+           }
+           /* the last byte depending on type */
+           switch (p_type) {
+           case IPOINTER:
+           case POINTER:
+               l = zero;
+               break;
+           case FPOINTER:
+               l = one;
+               break;
+           case CPOINTER:
+               l = "#0x02";
+               break;                          
+           case PPOINTER:
+               l = "#0x03";
+               break;
+               
+           default:
+               /* this should never happen */
+               werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
+                      "got unknown pointer type");
+               exit(1);
+           }
+           aopPut(AOP(result),l, GPTRSIZE - 1);            
+           goto release ;
        }
        
        /* just copy the pointers */
@@ -7082,10 +7287,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 {
@@ -7170,10 +7375,10 @@ static void genReceive (iCode *ic)
          IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
 
        int size = getSize(operandType(IC_RESULT(ic)));
-       int offset =  4 - size;
+       int offset =  fReturnSize - size;
        while (size--) {
-           emitcode ("push","%s", (strcmp(fReturn[3 - offset],"a") ?
-                                   fReturn[3 - offset] : "acc"));
+           emitcode ("push","%s", (strcmp(fReturn[fReturnSize - offset - 1],"a") ?
+                                   fReturn[fReturnSize - offset - 1] : "acc"));
            offset++;
        }
        aopOp(IC_RESULT(ic),ic,FALSE);  
@@ -7204,6 +7409,9 @@ void gen51Code (iCode *lic)
 
     lineHead = lineCurr = NULL;
 
+    /* print the allocation information */
+    if (allocInfo)
+       printAllocInfo( currFunc, codeOutFile);
     /* if debug information required */
 /*     if (options.debug && currFunc) { */
     if (currFunc) {
@@ -7439,6 +7647,6 @@ void gen51Code (iCode *lic)
        peepHole (&lineHead);
 
     /* now do the actual printing */
-    printLine (lineHead,codeOutFile);
+    printLine (lineHead,codeOutFile);    
     return;
 }