improved bit-wise operations with literal RHS
[fw/sdcc] / src / ds390 / gen.c
index e899101b0f05997153087c3c22431a902998f3b9..6d86b60dfeda5982e878a4acbf3c10dfc5bedacf 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include "SDCCglobl.h"
+
+#include <common.h>
+#include "ralloc.h"
+#include "gen.h"
 
 #ifdef HAVE_SYS_ISA_DEFS_H
 #include <sys/isa_defs.h>
 #ifdef HAVE_ENDIAN_H
 #include <endian.h>
 #else
-#ifndef __BORLANDC__
+#if !defined(__BORLANDC__) && !defined(_MSC_VER)
 #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"
-#include "ralloc.h"
-#include "gen.h"
-
 char *aopLiteral (value *val, int offset);
+#if 0
+//REMOVE ME!!!
 extern int allocInfo;
+#endif
 
 /* this is the down and dirty file with all kinds of 
    kludgy & hacky stuff. This is what it is all about
@@ -82,10 +83,8 @@ static struct {
     set *sendSet;
 } _G;
 
-extern int ds390_ptrRegReq ;
-extern int ds390_nRegs;
-extern FILE *codeOutFile;
 static void saverbank (int, iCode *,bool);
+
 #define RESULTONSTACK(x) \
                          (IC_RESULT(x) && IC_RESULT(x)->aop && \
                          IC_RESULT(x)->aop->type == AOP_STK )
@@ -241,7 +240,8 @@ static asmop *newAsmop (short type)
     return aop;
 }
 
-/* #define LAZY_DPS_OPT */ /* turn this on after some more testing. */
+/* Turn this off if the world goes to hell. */
+#define LAZY_DPS_OPT
 
 static int _currentDPS;          /* Current processor DPS. */
 static int _desiredDPS;          /* DPS value compiler thinks we should be using. */
@@ -349,7 +349,7 @@ static void _endLazyDPSEvaluation(void)
 /*-----------------------------------------------------------------*/
 /* pointerCode - returns the code for a pointer type               */
 /*-----------------------------------------------------------------*/
-static int pointerCode (link *etype)
+static int pointerCode (sym_link *etype)
 {
 
     return PTR_TYPE(SPEC_OCLS(etype));
@@ -710,12 +710,21 @@ static void aopOp (operand *op, iCode *ic, bool result, bool useDP2)
             return;  
        }
 
-        if (sym->ruonly ) {
+        if (sym->ruonly) {
             int i;
+            
+            if (useDP2)
+            {
+                /* a AOP_STR uses DPTR, but DPTR is already in use; 
+                 * we're just hosed.
+                 */
+                fprintf(stderr, "*** Internal error: AOP_STR with DPTR in use!\n");
+            }
+            
             aop = op->aop = sym->aop = newAsmop(AOP_STR);
             aop->size = getSize(sym->type);
             for ( i = 0 ; i < fReturnSize_390 ; i++ )
-                aop->aopu.aop_str[i] = fReturn[i];
+             aop->aopu.aop_str[i] = fReturn[i];
             return;
         }
 
@@ -1181,32 +1190,6 @@ static void aopPut (asmop *aop, char *s, int offset)
 }
 
 
-#if 0
-/*-----------------------------------------------------------------*/
-/* pointToEnd :- points to the last byte of the operand            */
-/*-----------------------------------------------------------------*/
-static void pointToEnd (asmop *aop)
-{
-    int count ;
-    if (!aop)
-        return ;
-
-    aop->coff = count = (aop->size - 1);
-    switch (aop->type) {
-        case AOP_R0 :
-        case AOP_R1 :
-            while (count--)
-                emitcode("inc","%s",aop->aopu.aop_ptr->name);
-            break;
-        case AOP_DPTR :
-            while (count--)
-                emitcode("inc","dptr");
-            break;
-    }
-
-}
-#endif
-
 /*-----------------------------------------------------------------*/
 /* reAdjustPreg - points a register back to where it should        */
 /*-----------------------------------------------------------------*/
@@ -1335,7 +1318,7 @@ static void genNotFloat (operand *op, operand *res)
 /*-----------------------------------------------------------------*/ 
 static int opIsGptr(operand *op)
 {
-    link *type = operandType(op);
+    sym_link *type = operandType(op);
     
     if ((AOP_SIZE(op) == GPTRSIZE) && IS_GENPTR(type))
     {
@@ -1353,7 +1336,7 @@ static int getDataSize(operand *op)
     size = AOP_SIZE(op);
     if (size == GPTRSIZE)
     {
-        link *type = operandType(op);
+        sym_link *type = operandType(op);
         if (IS_GENPTR(type))
         {
             /* generic pointer; arithmetic operations
@@ -1372,7 +1355,8 @@ static void outAcc(operand *result)
 {
     int size, offset;
     size = getDataSize(result);
-    if(size){
+    if(size)
+    {
         aopPut(AOP(result),"a",0);
         size--;
         offset = 1;
@@ -1389,9 +1373,12 @@ static void outAcc(operand *result)
 static void outBitC(operand *result)
 {
     /* if the result is bit */
-    if (AOP_TYPE(result) == AOP_CRY) 
+    if (AOP_TYPE(result) == AOP_CRY)
+    {
         aopPut(AOP(result),"c",0);
-    else {
+    }
+    else 
+    {
         emitcode("clr","a");
         emitcode("rlc","a");
         outAcc(result);
@@ -1454,7 +1441,7 @@ static void toBoolean(operand *oper)
 static void genNot (iCode *ic)
 {
     symbol *tlbl;
-    link *optype = operandType(IC_LEFT(ic));
+    sym_link *optype = operandType(IC_LEFT(ic));
 
     D(emitcode(";", "genNot "););
 
@@ -1567,7 +1554,7 @@ static void genUminusFloat(operand *op,operand *result)
 static void genUminus (iCode *ic)
 {
     int offset ,size ;
-    link *optype, *rtype;
+    sym_link *optype, *rtype;
 
     D(emitcode(";", "genUminus "););
 
@@ -1599,7 +1586,6 @@ static void genUminus (iCode *ic)
     /* otherwise subtract from zero */
     size = AOP_SIZE(IC_LEFT(ic));
     offset = 0 ;
-    //CLRC ;
     _startLazyDPSEvaluation();
     while(size--) {
         char *l = aopGet(AOP(IC_LEFT(ic)),offset,FALSE,FALSE,TRUE);
@@ -1641,7 +1627,7 @@ static void saveRegisters(iCode *lic)
     int i;
     iCode *ic;
     bitVect *rsave;
-    link *detype;
+    sym_link *detype;
 
     /* look for call */
     for (ic = lic ; ic ; ic = ic->next) 
@@ -1857,8 +1843,7 @@ static void genIpush (iCode *ic)
     /* then do the push */
     aopOp(IC_LEFT(ic),ic,FALSE, FALSE);
 
-
-       // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
+    // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic)));
     size = AOP_SIZE(IC_LEFT(ic));
 
     _startLazyDPSEvaluation();
@@ -1999,7 +1984,7 @@ static void saverbank (int bank, iCode *ic, bool pushPsw)
 /*-----------------------------------------------------------------*/
 static void genCall (iCode *ic)
 {
-    link *detype;   
+    sym_link *detype;   
 
     D(emitcode(";", "genCall "););
 
@@ -2060,14 +2045,42 @@ static void genCall (iCode *ic)
        /* Not really related to LAZY_DPS_OPT, but don't want
         * another testing flag right now...
         */
-        _G.accInUse++;
-        aopOp(IC_RESULT(ic),ic,FALSE, TRUE);
-        _G.accInUse--;
+#define FAR_RETURN_OPT
+#ifdef FAR_RETURN_OPT   
+       if (isOperandInFarSpace(IC_RESULT(ic))
+        && getSize(operandType(IC_RESULT(ic))) <= 2)
+       {
+           int size =  getSize(operandType(IC_RESULT(ic)));
+           
+            /* Special case for 1 or 2 byte return in far space. */
+           emitcode(";", "Kevin function call abuse #1");
+
+           MOVA(fReturn[0]);
+           if (size > 1)
+           {
+               emitcode("mov", "b,%s", fReturn[1]);
+           }
+    
+           aopOp(IC_RESULT(ic),ic,FALSE, FALSE);
+           aopPut(AOP(IC_RESULT(ic)),"a",0);
+           
+           if (size > 1)
+           {
+               aopPut(AOP(IC_RESULT(ic)),"b",1);
+           }
+           freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);           
+       }
+       else
+#endif 
+       {
+            _G.accInUse++;
+            aopOp(IC_RESULT(ic),ic,FALSE, TRUE);
+            _G.accInUse--;
                                      
-        assignResultValue(IC_RESULT(ic));
+            assignResultValue(IC_RESULT(ic));
                                                   
-        freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
-                                                                      
+            freeAsmop(IC_RESULT(ic),NULL, ic,TRUE);
+        }
 #else
        if (!isOperandInFarSpace(IC_RESULT(ic)))
        {
@@ -2145,7 +2158,7 @@ static void genCall (iCode *ic)
 /*-----------------------------------------------------------------*/
 static void genPcall (iCode *ic)
 {
-    link *detype;
+    sym_link *detype;
     symbol *rlbl = newiTempLabel(NULL);
 
     D(emitcode(";", "genPcall "););
@@ -2277,7 +2290,7 @@ static int resultRemat (iCode *ic)
     return 0;
 }
 
-#ifdef __BORLANDC__
+#if defined(__BORLANDC__) || defined(_MSC_VER)
 #define STRCASECMP stricmp
 #else
 #define STRCASECMP strcasecmp
@@ -2308,7 +2321,7 @@ static bool inExcludeList(char *s)
 static void genFunction (iCode *ic)
 {
     symbol *sym;
-    link *fetype;
+    sym_link *fetype;
 
     D(emitcode(";", "genFunction "););
 
@@ -2927,6 +2940,7 @@ static void adjustArithmeticResult(iCode *ic)
      }
 }
 
+#if 0
 #define AOP_OP_3(ic) \
     aopOp (IC_LEFT(ic),ic,FALSE, FALSE); \
     aopOp (IC_RIGHT(ic),ic,FALSE, TRUE); \
@@ -2938,6 +2952,42 @@ static void adjustArithmeticResult(iCode *ic)
         fprintf(stderr,                                  \
                "Ack: three operands in far space! (%s:%d %s:%d)\n", __FILE__, __LINE__, ic->filename, ic->lineno);   \
     }
+#else
+#define AOP_OP_3(ic) \
+    aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
+    aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
+    aopOp (IC_RESULT(ic),ic,TRUE, (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) || \
+                                 (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
+    if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
+        AOP_TYPE(IC_RESULT(ic)) == AOP_DPTR2) \
+    { \
+        /* werror(E_INTERNAL_ERROR,__FILE__,__LINE__, */ \
+        fprintf(stderr,                                  \
+               "Ack: three operands in far space! (%s:%d %s:%d)\n", __FILE__, __LINE__, ic->filename, ic->lineno);   \
+    }
+    
+#define AOP_OP_3_NOFATAL(ic, rc) \
+    aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
+    aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
+    aopOp (IC_RESULT(ic),ic,TRUE, (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) || \
+                                 (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)); \
+    if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2 && \
+        AOP_TYPE(IC_RESULT(ic)) == AOP_DPTR2) \
+    { \
+       rc = TRUE; \
+       freeAsmop(IC_RESULT(ic), NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); \
+    }  \
+    else \
+    { \
+       rc = FALSE; \
+    }
+
+#define AOP_OP_2(ic) \
+    aopOp (IC_RIGHT(ic),ic,FALSE, FALSE); \
+    aopOp (IC_LEFT(ic),ic,FALSE, (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR));
+    
+#endif
+
 
 #define AOP_SET_LOCALS(ic) \
     left = IC_LEFT(ic); \
@@ -2957,8 +3007,10 @@ static void genPlus (iCode *ic)
 
     /* special cases :- */
 
-    aopOp (IC_LEFT(ic),ic,FALSE, TRUE);
+#if 0
     aopOp (IC_RIGHT(ic),ic,FALSE, FALSE);
+    aopOp (IC_LEFT(ic),ic,FALSE, 
+          (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR));
     if ((AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR2) &&
         (AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR))
     {
@@ -2966,17 +3018,27 @@ static void genPlus (iCode *ic)
     }
     else
     {
-        aopOp (IC_RESULT(ic),ic,TRUE, AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR);
+        aopOp (IC_RESULT(ic),ic,TRUE, 
+               ((AOP_TYPE(IC_RIGHT(ic)) == AOP_DPTR)
+             || (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR)));
+    }
+#else
+    AOP_OP_3_NOFATAL(ic, pushResult);
+#endif    
 
+    if (!pushResult)
+    {
     /* if literal, literal on the right or
        if left requires ACC or right is already
        in ACC */
-    if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
-       (AOP_NEEDSACC(IC_LEFT(ic))) ||
-       AOP_TYPE(IC_RIGHT(ic)) == AOP_ACC ){
+    if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT)
+       || ((AOP_NEEDSACC(IC_LEFT(ic))) && !(AOP_NEEDSACC(IC_RIGHT(ic)))) 
+       || AOP_TYPE(IC_RIGHT(ic)) == AOP_ACC )
+    {
         operand *t = IC_RIGHT(ic);
         IC_RIGHT(ic) = IC_LEFT(ic);
         IC_LEFT(ic) = t;
+        emitcode(";", "Swapped plus args.");
     }
 
     /* if both left & right are in bit
@@ -3012,7 +3074,10 @@ static void genPlus (iCode *ic)
     /* if I can do an increment instead
     of add then GOOD for ME */
     if (genPlusIncr (ic) == TRUE)
+    {
+        emitcode(";", "did genPlusIncr");
         goto release;   
+    }
 
     }
     size = getDataSize(pushResult ? IC_LEFT(ic) : IC_RESULT(ic));
@@ -3083,11 +3148,13 @@ static void genPlus (iCode *ic)
            }
        }
 
+       _startLazyDPSEvaluation();
         while(size--)
         {
             emitcode("pop", "acc");
             aopPut(AOP(IC_RESULT(ic)), "a", --offset);
         }
+        _endLazyDPSEvaluation();
     }
 
     adjustArithmeticResult(ic);
@@ -3414,7 +3481,7 @@ static void genMultOneByte (operand *left,
                             operand *right,
                             operand *result)
 {
-    link *opetype = operandType(result);
+    sym_link *opetype = operandType(result);
     char *l ;
     symbol *lbl ;
     int size,offset;
@@ -3559,7 +3626,7 @@ static void genDivOneByte (operand *left,
                            operand *right,
                            operand *result)
 {
-    link *opetype = operandType(result);
+    sym_link *opetype = operandType(result);
     char *l ;
     symbol *lbl ;
     int size,offset;
@@ -3701,7 +3768,7 @@ static void genModOneByte (operand *left,
                            operand *right,
                            operand *result)
 {
-    link *opetype = operandType(result);
+    sym_link *opetype = operandType(result);
     char *l ;
     symbol *lbl ;
 
@@ -3848,44 +3915,15 @@ static void genIfxJump (iCode *ic, char *jval)
 /* genCmp :- greater or less than comparison                       */
 /*-----------------------------------------------------------------*/
 static void genCmp (operand *left,operand *right,
-                    operand *result, iCode *ifx, int sign)
+                   iCode *ic, iCode *ifx, int sign)
 {
-    int size, offset = 0 ;
-    unsigned long lit = 0L;
-    bool swappedOps = FALSE;
+    int                size, offset = 0 ;
+    unsigned long      lit = 0L;
+    operand            *result;
 
     D(emitcode(";", "genCmp"););
 
-#if 0
-    /* If left if lit and right isn't, swap 'em. */
-    if (AOP_TYPE(left) == AOP_LIT &&
-        AOP_TYPE(right) != AOP_LIT)
-    {
-        operand *tmp = left;
-        left = right;
-        right = tmp;
-        D(emitcode(";", "kevin literal hack"););
-        swappedOps = !swappedOps;
-    }
-
-    if (AOP_NEEDSACC(right))
-    {
-        if (AOP_NEEDSACC(left))
-        {
-            werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
-                   "both CMP operands need ACC!");
-            exit(1);
-        }
-        else
-        {
-            operand *tmp = left;
-            left = right;
-            right = tmp;
-            D(emitcode(";", "kevin ACC hack"););
-            swappedOps = !swappedOps;
-        }
-    }
-#endif
+    result = IC_RESULT(ic);
 
     /* if left & right are bit variables */
     if (AOP_TYPE(left) == AOP_CRY &&
@@ -3908,21 +3946,36 @@ static void genCmp (operand *left,operand *right,
                      lbl->key+100);
             emitcode("","%05d$:",lbl->key+100);
         } else {
-            if(AOP_TYPE(right) == AOP_LIT){
+            if (AOP_TYPE(right) == AOP_LIT)
+            {
                 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
                 /* optimize if(x < 0) or if(x >= 0) */
-                if(lit == 0L){
-                    if(!sign){
+                if(lit == 0L)
+                {
+                    if(!sign)
+                    {
                         CLRC;
                     }
-                    else{
+                    else
+                    {
                         MOVA(aopGet(AOP(left),AOP_SIZE(left)-1,FALSE,FALSE,TRUE));
-                        if(!(AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) && ifx){
+                        
+                       freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+                       freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+                        
+                        aopOp(result,ic,FALSE, FALSE);
+                        
+                        if(!(AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) && ifx)
+                        {
+                            freeAsmop(result,NULL,ic,TRUE);
                             genIfxJump (ifx,"acc.7");
                             return;
                         }
-                        else    
+                        else
+                        {
                             emitcode("rlc","a");
+                        }
+                        goto release_freedLR;
                     }
                     goto release;
                 }
@@ -3989,24 +4042,34 @@ static void genCmp (operand *left,operand *right,
     }
 
 release:
-    if (swappedOps)
-    {
-        D(emitcode(";","kevHack: flip carry."););
-        emitcode("cpl", "c");
-    }
+/* Don't need the left & right operands any more; do need the result. */
+    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+                        
+    aopOp(result,ic,FALSE, FALSE);
+
+release_freedLR:
 
-    if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) {
+    if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) 
+    {
         outBitC(result);
-    } else {
+    } 
+    else 
+    {
         /* if the result is used in the next
         ifx conditional branch then generate
         code a little differently */
         if (ifx )
+        {
             genIfxJump (ifx,"c");
+        }
         else
+        {
             outBitC(result);
+        }
         /* leave the result in acc */
     }
+    freeAsmop(result,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/
@@ -4014,32 +4077,23 @@ release:
 /*-----------------------------------------------------------------*/
 static void genCmpGt (iCode *ic, iCode *ifx)
 {
-    operand *left, *right, *result;
-    link *letype , *retype;
+    operand *left, *right;
+    sym_link *letype , *retype;
     int sign ;
 
     D(emitcode(";", "genCmpGt "););
 
     left = IC_LEFT(ic);
     right= IC_RIGHT(ic);
-    result = IC_RESULT(ic);
 
     letype = getSpec(operandType(left));
     retype =getSpec(operandType(right));
     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
-    /* assign the amsops */
-    AOP_OP_3(ic);
-#if 0
-    aopOp (left,ic,FALSE, TRUE);
-    aopOp (right,ic,FALSE, FALSE);
-    aopOp (result,ic,TRUE, FALSE);
-#endif
 
-    genCmp(right, left, result, ifx, sign);
+    /* assign the left & right amsops */
+    AOP_OP_2(ic);
 
-    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE); 
+    genCmp(right, left, ic, ifx, sign);
 }
 
 /*-----------------------------------------------------------------*/
@@ -4047,33 +4101,23 @@ static void genCmpGt (iCode *ic, iCode *ifx)
 /*-----------------------------------------------------------------*/
 static void genCmpLt (iCode *ic, iCode *ifx)
 {
-    operand *left, *right, *result;
-    link *letype , *retype;
+    operand *left, *right;
+    sym_link *letype , *retype;
     int sign ;
 
     D(emitcode(";", "genCmpLt "););
 
     left = IC_LEFT(ic);
     right= IC_RIGHT(ic);
-    result = IC_RESULT(ic);
 
     letype = getSpec(operandType(left));
     retype =getSpec(operandType(right));
     sign =  !(SPEC_USIGN(letype) | SPEC_USIGN(retype));
 
-    /* assign the amsops */
-    AOP_OP_3(ic);
-#if 0
-    aopOp (left,ic,FALSE, FALSE);
-    aopOp (right,ic,FALSE, TRUE);
-    aopOp (result,ic,TRUE, FALSE);
-#endif
-
-    genCmp(left, right, result, ifx, sign);
+    /* assign the left & right amsops */
+    AOP_OP_2(ic);
 
-    freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    freeAsmop(result,NULL,ic,TRUE); 
+    genCmp(left, right, ic, ifx, sign);
 }
 
 /*-----------------------------------------------------------------*/
@@ -4687,29 +4731,47 @@ static void genAnd (iCode *ic, iCode *ifx)
                 outBitC(result);
             } else if(ifx)
                 jmpTrueOrFalse(ifx, tlbl);
-        } else {
-           for(;(size--);offset++) {
+        } else 
+        {
+           for(;(size--);offset++) 
+           {
                // normal case
                // result = left & right
-               if(AOP_TYPE(right) == AOP_LIT){
-                   if((bytelit = (int)((lit >> (offset*8)) & 0x0FFL)) == 0x0FF){
+               if(AOP_TYPE(right) == AOP_LIT)
+               {
+                   if((bytelit = (int)((lit >> (offset*8)) & 0x0FFL)) == 0x0FF)
+                   {
                        aopPut(AOP(result),
                               aopGet(AOP(left),offset,FALSE,FALSE,FALSE),
                               offset);
                        continue;
-                   } else if(bytelit == 0){
+                   } 
+                   else if (bytelit == 0)
+                   {
                        aopPut(AOP(result),zero,offset);
                        continue;
                    }
+                    D(emitcode(";", "better literal AND."););
+                    MOVA(aopGet(AOP(left),offset,FALSE,FALSE,TRUE));
+                    emitcode("anl", "a, %s", aopGet(AOP(right),offset,
+                                               FALSE,FALSE,FALSE));
+                   
                }
-               // faster than result <- left, anl result,right
-               // and better if result is SFR
-               if (AOP_TYPE(left) == AOP_ACC) 
-                   emitcode("anl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE,FALSE));
-               else {
-                   MOVA(aopGet(AOP(right),offset,FALSE,FALSE,TRUE));
-                   emitcode("anl","a,%s",
-                            aopGet(AOP(left),offset,FALSE,FALSE,FALSE));
+               else
+               {
+                   // faster than result <- left, anl result,right
+                   // and better if result is SFR
+                   if (AOP_TYPE(left) == AOP_ACC) 
+                   {
+                       emitcode("anl","a,%s",aopGet(AOP(right),offset,
+                                                    FALSE,FALSE,FALSE));
+                   }
+                   else 
+                   {
+                       MOVA(aopGet(AOP(right),offset,FALSE,FALSE,TRUE));
+                       emitcode("anl","a,%s",
+                                aopGet(AOP(left),offset,FALSE,FALSE,FALSE));
+                   }
                }
                aopPut(AOP(result),"a",offset);
            }
@@ -4735,11 +4797,11 @@ static void genOr (iCode *ic, iCode *ifx)
 
     AOP_OP_3(ic);
     AOP_SET_LOCALS(ic);
-    #if 0
+#if 0
     aopOp((left = IC_LEFT(ic)),ic,FALSE, FALSE);
     aopOp((right= IC_RIGHT(ic)),ic,FALSE, TRUE);
     aopOp((result=IC_RESULT(ic)),ic,TRUE, FALSE);
-    #endif
+#endif
 
 #ifdef DEBUG_TYPE
     emitcode("","; Type res[%d] = l[%d]&r[%d]",
@@ -4864,37 +4926,59 @@ static void genOr (iCode *ic, iCode *ifx)
     }
 
     /* if left is same as result */
-    if(sameRegs(AOP(result),AOP(left))){
-        for(;size--; offset++) {
+    if(sameRegs(AOP(result),AOP(left)))
+    {
+        for(;size--; offset++) 
+        {
             if(AOP_TYPE(right) == AOP_LIT){
                 if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
+                {
                     continue;
+                }
                 else 
-                   if (IS_AOP_PREG(left)) {
+                {
+                   if (IS_AOP_PREG(left)) 
+                   {
                        MOVA(aopGet(AOP(right),offset,FALSE,FALSE,TRUE));
                        emitcode("orl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE,FALSE));
                        aopPut(AOP(result),"a",offset);
-                   } else
+                   } 
+                   else
+                   {
                        emitcode("orl","%s,%s",
                                 aopGet(AOP(left),offset,FALSE,TRUE,FALSE),
                                 aopGet(AOP(right),offset,FALSE,FALSE,FALSE));
-            } else {
-               if (AOP_TYPE(left) == AOP_ACC) 
+                   }
+               }
+            } 
+            else 
+            {
+               if (AOP_TYPE(left) == AOP_ACC)
+               { 
                    emitcode("orl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE,FALSE));
-               else {              
+               }
+               else 
+               {                   
                    MOVA(aopGet(AOP(right),offset,FALSE,FALSE,TRUE));
-                   if (IS_AOP_PREG(left)) {
+                   if (IS_AOP_PREG(left)) 
+                   {
                        emitcode("orl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE,FALSE));
                        aopPut(AOP(result),"a",offset);
-                   } else
+                   } 
+                   else
+                   {
                        emitcode("orl","%s,a",
                                 aopGet(AOP(left),offset,FALSE,TRUE,FALSE));
+                   }
                }
             }
         }
-    } else {
+    }
+    else
+    {
         // left & result in different registers
-        if(AOP_TYPE(result) == AOP_CRY){
+        if(AOP_TYPE(result) == AOP_CRY)
+        {
             // result = bit
             // if(size), result in bit
             // if(!size && ifx), conditional oper: if(left | right)
@@ -4915,27 +4999,46 @@ static void genOr (iCode *ic, iCode *ifx)
                 outBitC(result);
             } else if(ifx)
                 jmpTrueOrFalse(ifx, tlbl);
-        } else for(;(size--);offset++){
-            // normal case
-            // result = left & right
-            if(AOP_TYPE(right) == AOP_LIT){
-                if(((lit >> (offset*8)) & 0x0FFL) == 0x00L){
-                    aopPut(AOP(result),
-                           aopGet(AOP(left),offset,FALSE,FALSE,FALSE),
-                           offset);
-                    continue;
+        } 
+        else 
+        {
+            for(;(size--);offset++)
+            {
+                // normal case
+                // result = left & right
+                if(AOP_TYPE(right) == AOP_LIT)
+                {
+                    if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
+                    {
+                       aopPut(AOP(result),
+                               aopGet(AOP(left),offset,FALSE,FALSE,FALSE),
+                               offset);
+                        continue;
+                    }
+                    D(emitcode(";", "better literal OR."););
+                    MOVA(aopGet(AOP(left),offset,FALSE,FALSE,TRUE));
+                    emitcode("orl", "a, %s", aopGet(AOP(right),offset,
+                                               FALSE,FALSE,FALSE));
+                     
                 }
+                else
+                {
+                    // faster than result <- left, anl result,right
+                    // and better if result is SFR
+                   if (AOP_TYPE(left) == AOP_ACC) 
+                   {
+                       emitcode("orl","a,%s",aopGet(AOP(right),offset,
+                                                    FALSE,FALSE,FALSE));
+                   }
+                   else 
+                   {
+                       MOVA(aopGet(AOP(right),offset,FALSE,FALSE,TRUE));
+                       emitcode("orl","a,%s",
+                                aopGet(AOP(left),offset,FALSE,FALSE,FALSE));
+                   }
+               }
+               aopPut(AOP(result),"a",offset);                 
             }
-            // faster than result <- left, anl result,right
-            // and better if result is SFR
-           if (AOP_TYPE(left) == AOP_ACC) 
-               emitcode("orl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE,FALSE));
-           else {
-               MOVA(aopGet(AOP(right),offset,FALSE,FALSE,TRUE));
-               emitcode("orl","a,%s",
-                        aopGet(AOP(left),offset,FALSE,FALSE,FALSE));
-           }
-           aopPut(AOP(result),"a",offset);                     
         }
     }
 
@@ -5129,25 +5232,39 @@ static void genXor (iCode *ic, iCode *ifx)
                 outBitC(result);
             } else if(ifx)
                 jmpTrueOrFalse(ifx, tlbl);
-        } else for(;(size--);offset++){
+        } else for(;(size--);offset++)
+        {
             // normal case
             // result = left & right
-            if(AOP_TYPE(right) == AOP_LIT){
-                if(((lit >> (offset*8)) & 0x0FFL) == 0x00L){
+            if(AOP_TYPE(right) == AOP_LIT)
+            {
+                if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
+                {
                     aopPut(AOP(result),
                            aopGet(AOP(left),offset,FALSE,FALSE,FALSE),
                            offset);
                     continue;
                 }
+                D(emitcode(";", "better literal XOR."););
+                MOVA(aopGet(AOP(left),offset,FALSE,FALSE,TRUE));
+                emitcode("xrl", "a, %s", aopGet(AOP(right),offset,
+                                               FALSE,FALSE,FALSE));                
             }
-            // faster than result <- left, anl result,right
-            // and better if result is SFR
-           if (AOP_TYPE(left) == AOP_ACC)
-               emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE,FALSE));
-           else {
-               MOVA(aopGet(AOP(right),offset,FALSE,FALSE,TRUE));
-               emitcode("xrl","a,%s",
-                        aopGet(AOP(left),offset,FALSE,TRUE,FALSE));
+            else
+            {
+                // faster than result <- left, anl result,right
+                // and better if result is SFR
+               if (AOP_TYPE(left) == AOP_ACC)
+               {
+                   emitcode("xrl","a,%s",aopGet(AOP(right),offset,
+                            FALSE,FALSE,FALSE));
+               }
+               else 
+               {
+                   MOVA(aopGet(AOP(right),offset,FALSE,FALSE,TRUE));
+                   emitcode("xrl","a,%s",
+                            aopGet(AOP(left),offset,FALSE,TRUE,FALSE));
+               }
            }
            aopPut(AOP(result),"a",offset);
         }
@@ -5397,6 +5514,8 @@ static void AccRsh (int shCount)
     }
 }
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* AccSRsh - signed right shift accumulator by known count                 */
 /*-----------------------------------------------------------------*/
@@ -5425,7 +5544,10 @@ static void AccSRsh (int shCount)
         }
     }
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* shiftR1Left2Result - shift right one byte from left to result   */
 /*-----------------------------------------------------------------*/
@@ -5441,7 +5563,10 @@ static void shiftR1Left2Result (operand *left, int offl,
         AccRsh(shCount);
     aopPut(AOP(result),"a",offr);
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* shiftL1Left2Result - shift left one byte from left to result    */
 /*-----------------------------------------------------------------*/
@@ -5455,7 +5580,10 @@ static void shiftL1Left2Result (operand *left, int offl,
     AccLsh(shCount);
     aopPut(AOP(result),"a",offr);
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* movLeft2Result - move byte from left to result                  */
 /*-----------------------------------------------------------------*/
@@ -5482,7 +5610,10 @@ static void movLeft2Result (operand *left, int offl,
         }
     }
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* AccAXRrl1 - right rotate c->a:x->c by 1                         */
 /*-----------------------------------------------------------------*/
@@ -5493,7 +5624,10 @@ static void AccAXRrl1 (char *x)
     emitcode("rrc","a");
     emitcode("xch","a,%s", x);
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* AccAXLrl1 - left rotate c<-a:x<-c by 1                          */
 /*-----------------------------------------------------------------*/
@@ -5504,7 +5638,10 @@ static void AccAXLrl1 (char *x)
     emitcode("xch","a,%s",x);
     emitcode("rlc","a");
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* AccAXLsh1 - left shift a:x<-0 by 1                              */
 /*-----------------------------------------------------------------*/
@@ -5515,7 +5652,10 @@ static void AccAXLsh1 (char *x)
     emitcode("xch","a,%s",x);
     emitcode("rlc","a");
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* AccAXLsh - left shift a:x by known count (0..7)                 */
 /*-----------------------------------------------------------------*/
@@ -5566,7 +5706,10 @@ static void AccAXLsh (char *x, int shCount)
             break;
     }
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* AccAXRsh - right shift a:x known count (0..7)                   */
 /*-----------------------------------------------------------------*/
@@ -5620,7 +5763,10 @@ static void AccAXRsh (char *x, int shCount)
             break;
     }
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* AccAXRshS - right shift signed a:x known count (0..7)           */
 /*-----------------------------------------------------------------*/
@@ -5690,7 +5836,10 @@ static void AccAXRshS (char *x, int shCount)
             break;
     }
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* shiftL2Left2Result - shift left two bytes from left to result   */
 /*-----------------------------------------------------------------*/
@@ -5710,8 +5859,10 @@ static void shiftL2Left2Result (operand *left, int offl,
     AccAXLsh( aopGet(AOP(result),offr,FALSE,FALSE,FALSE), shCount);
     aopPut(AOP(result),"a",offr+MSB16);
 }
+#endif
 
-
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* shiftR2Left2Result - shift right two bytes from left to result  */
 /*-----------------------------------------------------------------*/
@@ -5736,7 +5887,10 @@ static void shiftR2Left2Result (operand *left, int offl,
     if(getDataSize(result) > 1)
         aopPut(AOP(result),"a",offr+MSB16);
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
 /*-----------------------------------------------------------------*/
@@ -5751,7 +5905,10 @@ static void shiftLLeftOrResult (operand *left, int offl,
     /* back to result */
     aopPut(AOP(result),"a",offr);
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* shiftRLeftOrResult - shift right one byte from left,or to result*/
 /*-----------------------------------------------------------------*/
@@ -5766,7 +5923,10 @@ static void shiftRLeftOrResult (operand *left, int offl,
     /* back to result */
     aopPut(AOP(result),"a",offr);
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* genlshOne - left shift a one byte quantity by known count       */
 /*-----------------------------------------------------------------*/
@@ -5775,7 +5935,10 @@ static void genlshOne (operand *result, operand *left, int shCount)
     D(emitcode(";", "genlshOne "););
     shiftL1Left2Result(left, LSB, result, LSB, shCount);
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* genlshTwo - left shift two bytes by known amount != 0           */
 /*-----------------------------------------------------------------*/
@@ -5808,7 +5971,10 @@ static void genlshTwo (operand *result,operand *left, int shCount)
             shiftL2Left2Result(left, LSB, result, LSB, shCount);
     }
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* shiftLLong - shift left one long from left to result            */
 /* offl = LSB or MSB16                                             */
@@ -5869,7 +6035,10 @@ static void shiftLLong (operand *left, operand *result, int offr )
     if(offr != LSB)
         aopPut(AOP(result),zero,LSB);       
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* genlshFour - shift four byte by a known amount != 0             */
 /*-----------------------------------------------------------------*/
@@ -5953,7 +6122,10 @@ static void genlshFour (operand *result, operand *left, int shCount)
         shiftL2Left2Result(left, LSB, result, LSB, shCount);
     }
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* genLeftShiftLiteral - left shifting by known count              */
 /*-----------------------------------------------------------------*/
@@ -6008,6 +6180,7 @@ static void genLeftShiftLiteral (operand *left,
     freeAsmop(left,NULL,ic,TRUE);
     freeAsmop(result,NULL,ic,TRUE);
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genLeftShift - generates code for left shifting                 */
@@ -6027,14 +6200,14 @@ static void genLeftShift (iCode *ic)
 
     aopOp(right,ic,FALSE, FALSE);
 
-    #if 0
+#if 0
     /* if the shift count is known then do it 
     as efficiently as possible */
     if (AOP_TYPE(right) == AOP_LIT) {
         genLeftShiftLiteral (left,right,result,ic);
         return ;
     }
-    #endif
+#endif
 
     /* shift count is unknown then we have to form 
     a loop get the loop count in B : Note: we take
@@ -6114,6 +6287,8 @@ release:
     freeAsmop(result,NULL,ic,TRUE);
 }
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* genrshOne - right shift a one byte quantity by known count      */
 /*-----------------------------------------------------------------*/
@@ -6123,7 +6298,10 @@ static void genrshOne (operand *result, operand *left,
     D(emitcode(";", "genrshOne"););
     shiftR1Left2Result(left, LSB, result, LSB, shCount, sign);
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* genrshTwo - right shift two bytes by known amount != 0          */
 /*-----------------------------------------------------------------*/
@@ -6147,7 +6325,10 @@ static void genrshTwo (operand *result,operand *left,
     else
         shiftR2Left2Result(left, LSB, result, LSB, shCount, sign); 
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* shiftRLong - shift right one long from left to result           */
 /* offl = LSB or MSB16                                             */
@@ -6180,7 +6361,10 @@ static void shiftRLong (operand *left, int offl,
         aopPut(AOP(result),"a",LSB);
     }
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* genrshFour - shift four byte by a known amount != 0             */
 /*-----------------------------------------------------------------*/
@@ -6239,7 +6423,10 @@ static void genrshFour (operand *result, operand *left,
         }
     }
 }
+#endif
 
+#if 0
+//REMOVE ME!!!
 /*-----------------------------------------------------------------*/
 /* genRightShiftLiteral - right shifting by known count            */
 /*-----------------------------------------------------------------*/
@@ -6300,6 +6487,7 @@ static void genRightShiftLiteral (operand *left,
         freeAsmop(result,NULL,ic,TRUE);
     }
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genSignedRightShift - right shift of signed number              */
@@ -6322,13 +6510,13 @@ static void genSignedRightShift (iCode *ic)
 
     aopOp(right,ic,FALSE, FALSE);
 
-    #if 0
+#if 0
     if ( AOP_TYPE(right) == AOP_LIT) {
        genRightShiftLiteral (left,right,result,ic,1);
        return ;
     }
-    #endif
-        /* shift count is unknown then we have to form 
+#endif
+    /* shift count is unknown then we have to form 
        a loop get the loop count in B : Note: we take
        only the lower order byte since shifting
        more that 32 bits make no sense anyway, ( the
@@ -6411,7 +6599,7 @@ release:
 static void genRightShift (iCode *ic)
 {
     operand *right, *left, *result;
-    link *retype ;
+    sym_link *retype ;
     int size, offset;
     char *l;
     symbol *tlbl, *tlbl1 ;
@@ -6440,14 +6628,14 @@ static void genRightShift (iCode *ic)
 
     aopOp(right,ic,FALSE, FALSE);
 
-    #if 0
+#if 0
     /* if the shift count is known then do it 
     as efficiently as possible */
     if (AOP_TYPE(right) == AOP_LIT) {
         genRightShiftLiteral (left,right,result,ic, 0);
         return ;
     }
-    #endif
+#endif
 
     /* shift count is unknown then we have to form 
     a loop get the loop count in B : Note: we take
@@ -6530,7 +6718,7 @@ static void genUnpackBits (operand *result, char *rname, int ptype)
 {    
     int shCnt ;
     int rlen = 0 ;
-    link *etype;
+    sym_link *etype;
     int offset = 0 ;
 
     D(emitcode(";", "genUnpackBits "););
@@ -6615,7 +6803,7 @@ static void genUnpackBits (operand *result, char *rname, int ptype)
 
        rlen -= 8;            
        /* if we are done */
-       if ( rlen <= 0 )
+       if ( rlen < 8 )
            break ;
        
        aopPut(AOP(result),"a",offset++);
@@ -6623,7 +6811,7 @@ static void genUnpackBits (operand *result, char *rname, int ptype)
     }
     
     if (rlen) {
-       emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(-rlen));
+       emitcode("anl","a,#0x%02x",((unsigned char)-1)>>(rlen));
        aopPut(AOP(result),"a",offset);        
     }
     
@@ -6670,13 +6858,14 @@ static void genNearPointerGet (operand *left,
     asmop *aop = NULL;
     regs *preg = NULL ;
     char *rname ;
-    link *rtype, *retype;
-    link *ltype = operandType(left);    
+    sym_link *rtype, *retype, *letype;
+    sym_link *ltype = operandType(left);    
     char buffer[80];
 
     rtype = operandType(result);
     retype= getSpec(rtype);
-    
+    letype= getSpec(ltype);
+
     aopOp(left,ic,FALSE, FALSE);
     
     /* if left is rematerialisable and
@@ -6685,6 +6874,7 @@ static void genNearPointerGet (operand *left,
        lower 128 bytes of space */
     if (AOP_TYPE(left) == AOP_IMMD &&
        !IS_BITVAR(retype)         &&
+       !IS_BITVAR(letype)         &&
        DCL_TYPE(ltype) == POINTER) {
        genDataPointerGet (left,result,ic);
        return ;
@@ -6707,7 +6897,7 @@ static void genNearPointerGet (operand *left,
     aopOp (result,ic,FALSE, FALSE);
     
       /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) 
+    if (IS_BITVAR(retype) || IS_BITVAR(letype)
        genUnpackBits (result,rname,POINTER);
     else {
        /* we have can just get the values */
@@ -6763,12 +6953,12 @@ static void genPagedPointerGet (operand *left,
 {
     asmop *aop = NULL;
     regs *preg = NULL ;
-    char *rname ;
-    link *rtype, *retype;    
+    char *rname;
+    sym_link *rtype, *retype, *letype;    
 
     rtype = operandType(result);
     retype= getSpec(rtype);
-    
+    letype= getSpec(operandType(left));
     aopOp(left,ic,FALSE, FALSE);
 
   /* if the value is already in a pointer register
@@ -6788,7 +6978,7 @@ static void genPagedPointerGet (operand *left,
     aopOp (result,ic,FALSE, FALSE);
 
     /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) 
+    if (IS_BITVAR(retype) || IS_BITVAR(letype)
        genUnpackBits (result,rname,PPOINTER);
     else {
        /* we have can just get the values */
@@ -6840,8 +7030,8 @@ static void genFarPointerGet (operand *left,
                               operand *result, iCode *ic)
 {
     int size, offset ;
-    link *retype = getSpec(operandType(result));
-
+    sym_link *retype = getSpec(operandType(result));
+    sym_link *letype = getSpec(operandType(left));
     D(emitcode(";", "genFarPointerGet"););
 
     aopOp(left,ic,FALSE, FALSE);
@@ -6882,18 +7072,25 @@ static void genFarPointerGet (operand *left,
     aopOp(result,ic,FALSE, TRUE);
 
     /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
+    if (IS_BITVAR(retype) || IS_BITVAR(letype)
         genUnpackBits(result,"dptr",FPOINTER);
     else {
         size = AOP_SIZE(result);
         offset = 0 ;
 
+       _startLazyDPSEvaluation();
         while (size--) {
+            
+            genSetDPTR(0);
+            _flushLazyDPS();
+            
             emitcode("movx","a,@dptr");
-            aopPut(AOP(result),"a",offset++);
             if (size)
-                emitcode("inc","dptr");
+                emitcode("inc","dptr");            
+
+            aopPut(AOP(result),"a",offset++);
         }
+        _endLazyDPSEvaluation();
     }
 
     freeAsmop(result,NULL,ic,TRUE);
@@ -6906,7 +7103,7 @@ static void emitcodePointerGet (operand *left,
                                 operand *result, iCode *ic)
 {
     int size, offset ;
-    link *retype = getSpec(operandType(result));
+    sym_link *retype = getSpec(operandType(result));
 
     aopOp(left,ic,FALSE, FALSE);
 
@@ -6915,18 +7112,34 @@ static void emitcodePointerGet (operand *left,
     if (AOP_TYPE(left) != AOP_STR) {
         /* if this is remateriazable */
         if (AOP_TYPE(left) == AOP_IMMD)
+        {
             emitcode("mov","dptr,%s",aopGet(AOP(left),0,TRUE,FALSE,FALSE));
-        else { /* we need to get it byte by byte */
+        }
+        else
+        { /* we need to get it byte by byte */
             _startLazyDPSEvaluation();
-            emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
-            emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
-            emitcode("mov","dpx,%s",aopGet(AOP(left),2,FALSE,FALSE,TRUE));
-            _endLazyDPSEvaluation();
+            if (AOP_TYPE(left) != AOP_DPTR)
+            {
+               emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
+               emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
+                       emitcode("mov","dpx,%s",aopGet(AOP(left),2,FALSE,FALSE,TRUE));
+            }
+            else
+            {
+                 /* We need to generate a load to DPTR indirect through DPTR. */
+                 D(emitcode(";", "gencodePointerGet -- indirection special case."););
+                 emitcode("push", "%s", aopGet(AOP(left),0,FALSE,TRUE,TRUE));
+                 emitcode("push", "%s", aopGet(AOP(left),1,FALSE,TRUE,TRUE));
+                 emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE,TRUE));
+                 emitcode("pop", "dph");
+                 emitcode("pop", "dpl");
+            }     
+            _endLazyDPSEvaluation();       
         }
     }
     /* so dptr know contains the address */
     freeAsmop(left,NULL,ic,TRUE);
-    aopOp(result,ic,FALSE, FALSE);
+    aopOp(result,ic,FALSE, TRUE);
 
     /* if bit then unpack */
     if (IS_BITVAR(retype)) 
@@ -6935,13 +7148,19 @@ static void emitcodePointerGet (operand *left,
         size = AOP_SIZE(result);
         offset = 0 ;
 
-        while (size--) {
+       _startLazyDPSEvaluation();
+        while (size--) 
+        {
+            genSetDPTR(0);
+            _flushLazyDPS();
+                              
             emitcode("clr","a");
             emitcode("movc","a,@a+dptr");
-            aopPut(AOP(result),"a",offset++);
             if (size)
-                emitcode("inc","dptr");
+                emitcode("inc","dptr");            
+            aopPut(AOP(result),"a",offset++);
         }
+        _endLazyDPSEvaluation();
     }
 
     freeAsmop(result,NULL,ic,TRUE);
@@ -6954,7 +7173,8 @@ static void genGenPointerGet (operand *left,
                               operand *result, iCode *ic)
 {
     int size, offset ;
-    link *retype = getSpec(operandType(result));
+    sym_link *retype = getSpec(operandType(result));
+    sym_link *letype = getSpec(operandType(left));
 
     aopOp(left,ic,FALSE, TRUE);
 
@@ -6970,15 +7190,8 @@ static void genGenPointerGet (operand *left,
             _startLazyDPSEvaluation();
             emitcode("mov","dpl,%s",aopGet(AOP(left),0,FALSE,FALSE,TRUE));
             emitcode("mov","dph,%s",aopGet(AOP(left),1,FALSE,FALSE,TRUE));
-            if (options.model == MODEL_FLAT24)
-            {
-               emitcode("mov", "dpx,%s",aopGet(AOP(left),2,FALSE,FALSE,TRUE));
-               emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE,TRUE));
-            }
-            else
-            {
-               emitcode("mov","b,%s",aopGet(AOP(left),2,FALSE,FALSE,TRUE));
-            }
+            emitcode("mov","dpx,%s",aopGet(AOP(left),2,FALSE,FALSE,TRUE));
+            emitcode("mov","b,%s",aopGet(AOP(left),3,FALSE,FALSE,TRUE));
             _endLazyDPSEvaluation();
         }
     }
@@ -6987,7 +7200,7 @@ static void genGenPointerGet (operand *left,
     aopOp(result,ic,FALSE, TRUE);
 
     /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
+    if (IS_BITVAR(retype) || IS_BITVAR(letype)
         genUnpackBits(result,"dptr",GPOINTER);
     else {
         size = AOP_SIZE(result);
@@ -7010,7 +7223,7 @@ static void genGenPointerGet (operand *left,
 static void genPointerGet (iCode *ic)
 {
     operand *left, *result ;
-    link *type, *etype;
+    sym_link *type, *etype;
     int p_type;
 
     D(emitcode(";", "genPointerGet "););
@@ -7028,21 +7241,6 @@ static void genPointerGet (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 ; */
     }
 
     /* now that we have the pointer type we assign
@@ -7076,7 +7274,7 @@ static void genPointerGet (iCode *ic)
 /*-----------------------------------------------------------------*/
 /* genPackBits - generates code for packed bit storage             */
 /*-----------------------------------------------------------------*/
-static void genPackBits (link    *etype ,
+static void genPackBits (sym_link    *etype ,
                          operand *right ,
                          char *rname, int p_type)
 {
@@ -7158,7 +7356,7 @@ static void genPackBits (link    *etype ,
         l = aopGet(AOP(right),offset++,FALSE,TRUE,FALSE);
 
         rLen -= 8 ;
-        if (rLen <= 0 )
+        if (rLen < 8 )
             break ;
 
         switch (p_type) {
@@ -7207,7 +7405,7 @@ static void genPackBits (link    *etype ,
                 break;
         }
 
-        emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) );
+        emitcode ("anl","a,#0x%02x",((unsigned char)-1 << rLen) );
         emitcode ("orl","a,b");
     }
 
@@ -7266,10 +7464,11 @@ static void genNearPointerSet (operand *right,
     asmop *aop = NULL;
     regs *preg = NULL ;
     char *rname , *l;
-    link *retype;
-    link *ptype = operandType(result);
+    sym_link *retype, *letype;
+    sym_link *ptype = operandType(result);
     
     retype= getSpec(operandType(right));
+    letype= getSpec(ptype);
 
     aopOp(result,ic,FALSE, FALSE);
     
@@ -7277,7 +7476,8 @@ static void genNearPointerSet (operand *right,
        in data space & not a bit variable */
     if (AOP_TYPE(result) == AOP_IMMD &&
        DCL_TYPE(ptype) == POINTER   &&
-       !IS_BITVAR(retype)) {
+       !IS_BITVAR(retype) &&
+       !IS_BITVAR(letype)) {
        genDataPointerSet (right,result,ic);
        return;
     }
@@ -7299,8 +7499,8 @@ static void genNearPointerSet (operand *right,
     aopOp (right,ic,FALSE, FALSE);
 
     /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) 
-        genPackBits (retype,right,rname,POINTER);
+    if (IS_BITVAR(retype) || IS_BITVAR(letype)
+        genPackBits ((IS_BITVAR(retype) ? retype : letype),right,rname,POINTER);
     else {
         /* we have can just get the values */
         int size = AOP_SIZE(right);
@@ -7355,9 +7555,10 @@ static void genPagedPointerSet (operand *right,
     asmop *aop = NULL;
     regs *preg = NULL ;
     char *rname , *l;
-    link *retype;
+    sym_link *retype, *letype;
        
     retype= getSpec(operandType(right));
+    letype= getSpec(operandType(result));
     
     aopOp(result,ic,FALSE, FALSE);
     
@@ -7378,8 +7579,8 @@ static void genPagedPointerSet (operand *right,
     aopOp (right,ic,FALSE, FALSE);
 
     /* if bitfield then unpack the bits */
-    if (IS_BITVAR(retype)) 
-       genPackBits (retype,right,rname,PPOINTER);
+    if (IS_BITVAR(retype) || IS_BITVAR(letype)
+       genPackBits ((IS_BITVAR(retype) ? retype : letype) ,right,rname,PPOINTER);
     else {
        /* we have can just get the values */
        int size = AOP_SIZE(right);
@@ -7431,7 +7632,8 @@ static void genFarPointerSet (operand *right,
                               operand *result, iCode *ic)
 {
     int size, offset ;
-    link *retype = getSpec(operandType(right));
+    sym_link *retype = getSpec(operandType(right));
+    sym_link *letype = getSpec(operandType(result));
 
     aopOp(result,ic,FALSE, FALSE);
 
@@ -7449,7 +7651,7 @@ static void genFarPointerSet (operand *right,
            {
                emitcode("mov","dpl,%s",aopGet(AOP(result),0,FALSE,FALSE,TRUE));
                emitcode("mov","dph,%s",aopGet(AOP(result),1,FALSE,FALSE,TRUE));
-                       emitcode("mov", "dpx,%s",aopGet(AOP(result),2,FALSE,FALSE,TRUE));
+                       emitcode("mov","dpx,%s",aopGet(AOP(result),2,FALSE,FALSE,TRUE));
             }
             else
             {
@@ -7469,8 +7671,8 @@ static void genFarPointerSet (operand *right,
     aopOp(right,ic,FALSE, TRUE);
 
     /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genPackBits(retype,right,"dptr",FPOINTER);
+    if (IS_BITVAR(retype) || IS_BITVAR(letype)
+        genPackBits((IS_BITVAR(retype)?retype:letype),right,"dptr",FPOINTER);
     else {
         size = AOP_SIZE(right);
         offset = 0 ;
@@ -7479,6 +7681,10 @@ static void genFarPointerSet (operand *right,
         while (size--) {
             char *l = aopGet(AOP(right),offset++,FALSE,FALSE,TRUE);
             MOVA(l);
+            
+            genSetDPTR(0);
+            _flushLazyDPS();
+            
             emitcode("movx","@dptr,a");
             if (size)
                 emitcode("inc","dptr");
@@ -7496,7 +7702,8 @@ static void genGenPointerSet (operand *right,
                               operand *result, iCode *ic)
 {
     int size, offset ;
-    link *retype = getSpec(operandType(right));
+    sym_link *retype = getSpec(operandType(right));
+    sym_link *letype = getSpec(operandType(result));
 
     aopOp(result,ic,FALSE, TRUE);
 
@@ -7522,19 +7729,25 @@ static void genGenPointerSet (operand *right,
     aopOp(right,ic,FALSE, TRUE);
 
     /* if bit then unpack */
-    if (IS_BITVAR(retype)) 
-        genPackBits(retype,right,"dptr",GPOINTER);
+    if (IS_BITVAR(retype) || IS_BITVAR(letype)
+        genPackBits((IS_BITVAR(retype)?retype:letype),right,"dptr",GPOINTER);
     else {
         size = AOP_SIZE(right);
         offset = 0 ;
 
+       _startLazyDPSEvaluation();
         while (size--) {
             char *l = aopGet(AOP(right),offset++,FALSE,FALSE,TRUE);
             MOVA(l);
+            
+            genSetDPTR(0);
+            _flushLazyDPS();
+            
             emitcode("lcall","__gptrput");
             if (size)
                 emitcode("inc","dptr");
         }
+        _endLazyDPSEvaluation();
     }
 
     freeAsmop(right,NULL,ic,TRUE);
@@ -7546,7 +7759,7 @@ static void genGenPointerSet (operand *right,
 static void genPointerSet (iCode *ic)
 {    
     operand *right, *result ;
-    link *type, *etype;
+    sym_link *type, *etype;
     int p_type;
 
     D(emitcode(";", "genPointerSet "););
@@ -7565,21 +7778,6 @@ static void genPointerSet (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 ; */
     }
 
     /* now that we have the pointer type we assign
@@ -7850,15 +8048,15 @@ static void genAssign (iCode *ic)
        (AOP_TYPE(result) != AOP_REG) &&
        (AOP_TYPE(right) == AOP_LIT) &&
        !IS_FLOAT(operandType(right)) 
-#ifndef LAZY_DPS_OPT       
+#ifndef LAZY_DPS_OPT
        && (lit < 256L)
 #endif       
        )
     {
-#ifdef LAZY_DPS_OPT    
+#ifdef LAZY_DPS_OPT
        D(emitcode(";", "Kevin's better literal load code"););
        _startLazyDPSEvaluation();
-       while (size && ((unsigned int)((lit >> (offset*8)) & 0xff) != 0))
+    while (size && ((unsigned int)(lit >> (offset*8)) != 0))
        {
            aopPut(AOP(result),
                   aopGet(AOP(right),offset,FALSE,FALSE,TRUE),
@@ -7946,8 +8144,8 @@ static void genJumpTab (iCode *ic)
 static void genCast (iCode *ic)
 {
     operand *result = IC_RESULT(ic);
-    link *ctype = operandType(IC_LEFT(ic));
-    link *rtype = operandType(IC_RIGHT(ic));
+    sym_link *ctype = operandType(IC_LEFT(ic));
+    sym_link *rtype = operandType(IC_RIGHT(ic));
     operand *right = IC_RIGHT(ic);
     int size, offset ;
 
@@ -8012,7 +8210,7 @@ static void genCast (iCode *ic)
     if (IS_PTR(ctype)) {
 
        int p_type;
-       link *type = operandType(right);
+       sym_link *type = operandType(right);
 
        /* pointer to generic pointer */
        if (IS_GENPTR(ctype)) {
@@ -8044,7 +8242,7 @@ static void genCast (iCode *ic)
                 *
                 * char _generic *gp = (char _xdata *)(intVar);
                 */
-               link *etype = getSpec(type);             
+               sym_link *etype = getSpec(type);                 
 
                /* we have to go by the storage class */
                if (SPEC_OCLS(etype) != generic)
@@ -8132,10 +8330,18 @@ static void genCast (iCode *ic)
     /* 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(rtype) || !IS_SPEC(rtype)) {
+    /* also, if the source is a bit, we don't need to sign extend, because
+     * it can't possibly have set the sign bit.
+     */
+    if (SPEC_USIGN(rtype) || !IS_SPEC(rtype) || AOP_TYPE(right) == AOP_CRY) 
+    {
         while (size--)
+        {
             aopPut(AOP(result),zero,offset++);
-    } else {
+        }
+    } 
+    else 
+    {
         /* we need to extend the sign :{ */
         char *l = aopGet(AOP(right),AOP_SIZE(right) - 1,
                          FALSE,FALSE,TRUE);
@@ -8244,7 +8450,7 @@ static void genReceive (iCode *ic)
 }
 
 /*-----------------------------------------------------------------*/
-/* gen390Code - generate code for 8051 based controllers            */
+/* gen390Code - generate code for Dallas 390 based controllers     */
 /*-----------------------------------------------------------------*/
 void gen390Code (iCode *lic)
 {
@@ -8253,12 +8459,15 @@ void gen390Code (iCode *lic)
 
     lineHead = lineCurr = NULL;
 
+#if 0
+    //REMOVE ME!!!
     /* print the allocation information */
     if (allocInfo)
        printAllocInfo( currFunc, codeOutFile);
+#endif
     /* if debug information required */
-/*     if (options.debug && currFunc) { */
-    if (currFunc) {
+    if (options.debug && currFunc) {
+    //jwk if (currFunc) {
        cdbSymbol(currFunc,cdbFile,FALSE,TRUE);
        _G.debugLine = 1;
        if (IS_STATIC(currFunc->etype))