* src/pic/gen.c (popGet): changed assert to allow for
authortecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 4 Jul 2005 10:48:49 +0000 (10:48 +0000)
committertecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 4 Jul 2005 10:48:49 +0000 (10:48 +0000)
  bit operands
* (popGetAddr): changed signature to provide
  an additional index, patched all call sites
* (genCmpEq): handle literal-like operands correctly
* (genAddrOf): added sanity checks on __code/__data pointers
* (genAssign): added handling of symbols from __code section
* (gencjne): do not generate code for comparisons whose result
  is neither stored nor used, fixes bug #1171114
* (AccLsh, AccRsh): operate on operand instead of WREG
* (shift{Left,Right}_Left2ResultLit): NEW, size independant
  replacement for Shift{LR}{12}Left2Result; shift (byte/int/long)
  by known count
* rewrote complete shift-by-literal logic, commented unused
  functions out
* (genConstPointerGet): get multiple bytes (if result size > 1),
  fixed handling of non-immediate addresses
* (genPointerGet): handle CODE pointers like CONST pointers
* (genpic14Code): insert C-SRC lines as Cource-pCodes
* ({aop,op}_isLitLike): NEW, single place to decide whether an
  operand is to be treated as a literal or not
* (mov2w,genPcall,genCmpEq),
  src/pic/genarith.c: use aop_isLitLike() to decide between
  literal/register contents
* (addSign): added missing offset
* src/pic/gen.h: remove newline after FENTRY/FEXIT comments,
  only emit comment in debug-mode,
  use {aop,op}_isLitLike throughout the file
* src/pic/glue.c: fix initializers for pointers (work in progress)
* src/pic/pcode.c (get_op): honor index on _const symbols
* ({reset,dump}pCodeStatistics): NEW, estimate code size
* (dumppBlock): added pCode size estimation
* src/pic/ralloc.c (deassignLRs,serialRegAssign,packRegisters):
  check for IS_SYMOP before OP_SYMBOL'ing
* fixed indentation, compacted switch-statements
* (allocReg): find free register and allocate it instead of
  allocating new registers all the time
* (deassignLRs): prevent POINTER_GET's from being assigned the same
  registers as its operands (necessary only for multibyte GETs)

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3793 4a8a32a2-be11-0410-ad9d-d568d2c75423

ChangeLog
src/pic/gen.c
src/pic/gen.h
src/pic/genarith.c
src/pic/glue.c
src/pic/pcode.c
src/pic/pcode.h
src/pic/ralloc.c

index 3017b6da9cdda7297919fd710b05dda81af524db..5687854c25554a583b79c71f88a5b11f76ecbdb2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,49 @@
+2005-07-04 Raphael Neider <rneider AT web.de>
+
+       * src/pic/gen.c (popGet): changed assert to allow for
+         bit operands
+       * (popGetAddr): changed signature to provide
+         an additional index, patched all call sites
+       * (genCmpEq): handle literal-like operands correctly
+       * (genAddrOf): added sanity checks on __code/__data pointers
+       * (genAssign): added handling of symbols from __code section
+       * (gencjne): do not generate code for comparisons whose result
+         is neither stored nor used, fixes bug #1171114
+       * (AccLsh, AccRsh): operate on operand instead of WREG
+       * (shift{Left,Right}_Left2ResultLit): NEW, size independant
+         replacement for Shift{LR}{12}Left2Result; shift (byte/int/long)
+         by known count
+       * rewrote complete shift-by-literal logic, commented unused
+         functions out
+       * (genConstPointerGet): get multiple bytes (if result size > 1),
+         fixed handling of non-immediate addresses
+       * (genPointerGet): handle CODE pointers like CONST pointers
+       * (genpic14Code): insert C-SRC lines as Cource-pCodes
+       * ({aop,op}_isLitLike): NEW, single place to decide whether an
+         operand is to be treated as a literal or not
+       * (mov2w,genPcall,genCmpEq),
+         src/pic/genarith.c: use aop_isLitLike() to decide between
+         literal/register contents
+       * (addSign): added missing offset
+       * src/pic/gen.h: remove newline after FENTRY/FEXIT comments,
+         only emit comment in debug-mode,
+         use {aop,op}_isLitLike throughout the file
+       * src/pic/glue.c: fix initializers for pointers (work in progress)
+       * src/pic/pcode.c (get_op): honor index on _const symbols
+       * ({reset,dump}pCodeStatistics): NEW, estimate code size
+       * (dumppBlock): added pCode size estimation
+       * src/pic/ralloc.c (deassignLRs,serialRegAssign,packRegisters):
+         check for IS_SYMOP before OP_SYMBOL'ing
+       * fixed indentation, compacted switch-statements
+       * (allocReg): find free register and allocate it instead of
+         allocating new registers all the time
+       * (deassignLRs): prevent POINTER_GET's from being assigned the same
+         registers as its operands (necessary only for multibyte GETs)
+
 2005-07-01 Raphael Neider <rneider AT web.de>
 
        * src/pic/gen.h: added prototypes emitpComment, popGetAddr and
-         debugging .asm-output macros FENRY + FEXIT
+         debugging .asm-output macros FENTRY + FEXIT
        * src/pic/gen.c (Safe_vsnprintf): NEW, is there a more generic
          way... I wonder...
        * (emitpComment): NEW, printf to pCode
index c85d097f1eb5c2d2303276e3fa37c1ebe57c5bf8..5d1e22ba1f483fc508c466aecbc8ae1167f149c5 100644 (file)
@@ -1352,8 +1352,13 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        /* offset is greater than
        size then zero */
 
-       assert (offset >= 0 && offset < aop->size);
+       if (!(offset >= 0 && ((offset < aop->size) || (aop->size == 0))))
+       {
+         fprintf (stderr, "%s:%u: offset=%d, aop-type:%s, size:%d\n", __FILE__, __LINE__, offset, AopType (aop->type), aop->size);
+       }
+       assert (offset >= 0 && ((offset < aop->size) || (aop->size == 0)));
        
+       /* XXX: still needed for BIT operands (AOP_CRY) */
        if (offset > (aop->size - 1) &&
                aop->type != AOP_LIT)
                return NULL;  //zero;
@@ -1439,7 +1444,7 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
                DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset,
                        __LINE__, 
                        ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
-               emitpComment ("popGet; name %s, offset: %i\n", aop->aopu.pcop->name, offset);
+               //emitpComment ("popGet; name %s, offset: %i, pcop-type: %s\n", aop->aopu.pcop->name, offset, pCodeOpType (aop->aopu.pcop));
                switch (aop->aopu.pcop->type)
                {
                case PO_IMMEDIATE:
@@ -1469,19 +1474,19 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 /* popGetAddr - access the low/high word of a symbol (immediate)   */
 /*              (for non-PO_IMMEDIATEs this is the same as poGet)  */
 /*-----------------------------------------------------------------*/
-pCodeOp *popGetAddr (asmop *aop, int offset)
+pCodeOp *popGetAddr (asmop *aop, int offset, int index)
 {
   if (aop->type == AOP_PCODE && aop->aopu.pcop->type == PO_IMMEDIATE)
   {
     pCodeOp *pcop = aop->aopu.pcop;
-    emitpComment ("popGet; name %s, offset: %i\n", pcop->name, offset);
     pcop = pCodeOpCopy (pcop);
     /* usually we want to access the memory at "<symbol> + offset" (using ->index),
      * but sometimes we want to access the high byte of the symbol's address (using ->offset) */
     PCOI(pcop)->offset += offset;
+    PCOI(pcop)->index += index;
     return pcop;
   } else {
-    return popGet (aop, offset);
+    return popGet (aop, offset + index);
   }
 }
 
@@ -1727,10 +1732,8 @@ void mov2w (asmop *aop, int offset)
        
        DEBUGpic14_emitcode ("; ***","%s  %d  offset=%d",__FUNCTION__,__LINE__,offset);
        
-       if ( aop->type == AOP_PCODE ||
-               aop->type == AOP_LIT ||
-               aop->type == AOP_IMMD )
-               emitpcode(POC_MOVLW,popGet(aop,offset));
+       if ( aop_isLitLike (aop) )
+               emitpcode(POC_MOVLW,popGetAddr(aop,offset,0));
        else
                emitpcode(POC_MOVFW,popGet(aop,offset));
        
@@ -2598,11 +2601,11 @@ static void genPcall (iCode *ic)
        emitpcode(POC_GOTO,pcop);
        emitpLabel(albl->key);
        
-       poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
+       poc = ( aop_isLitLike (AOP(left)) ? POC_MOVLW : POC_MOVFW );
        
-       emitpcode(poc,popGet(AOP(left),1));
+       emitpcode(poc,popGetAddr(AOP(left),1,0));
        emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
-       emitpcode(poc,popGet(AOP(left),0));
+       emitpcode(poc,popGetAddr(AOP(left),0,0));
        emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
        
        emitpLabel(blbl->key);
@@ -3060,7 +3063,7 @@ static void genRet (iCode *ic)
                                        AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
                                        ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
                                        ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
-                                       emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset));
+                                       emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                }else {
                                        emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
                                }
@@ -4529,7 +4532,6 @@ static void genc16bit2lit(operand *op, int lit, int offset)
        else
                i=0;
        
-       emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i);
        switch( BYTEofLONG(lit,i)) { 
        case 0:
                emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
@@ -4547,7 +4549,6 @@ static void genc16bit2lit(operand *op, int lit, int offset)
        
        i ^= 1;
        
-       emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i);
        switch( BYTEofLONG(lit,i)) { 
        case 0:
                emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
@@ -4583,6 +4584,10 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
        
        unsigned long lit = 0L;
        FENTRY;
+       if (!ifx && (!result || AOP_TYPE(result) == AOP_CRY)) {
+         emitpComment ("gencjne: no ifx, no (real) result -- comparison ignored");
+         return;
+       }
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        DEBUGpic14_AopType(__LINE__,left,right,result);
        if(result)
@@ -4642,7 +4647,8 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
                int lbl_key = lbl->key;
                
                if(result) {
-                       emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
+                       if (AOP_TYPE(result) != AOP_CRY)
+                               emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
                        //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
                }else {
                        DEBUGpic14_emitcode ("; ***","%s  %d -- ERROR",__FUNCTION__,__LINE__);
@@ -4814,8 +4820,8 @@ static void genCmpEq (iCode *ic, iCode *ifx)
        /* if literal, literal on the right or 
        if the right is in a pointer register and left 
        is not */
-       if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || 
-               (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
+       if (aop_isLitLike (AOP(IC_LEFT(ic)))
+                       || (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
                operand *tmp = right ;
                right = left;
                left = tmp;
@@ -4980,8 +4986,8 @@ static void genCmpEq (iCode *ic, iCode *ifx)
                                tlbl = newiTempLabel(NULL);
                                
                                while(size--) {
-                                       emitpcode(POC_MOVFW,popGet(AOP(left),offset));
-                                       emitpcode(POC_XORFW,popGet(AOP(right),offset));
+                                       mov2w (AOP(right),offset); /* right might be litLike() */
+                                       emitpcode(POC_XORFW,popGet(AOP(left),offset));
                                        
                                        if ( IC_TRUE(ifx) ) {
                                                if(size) {
@@ -5928,6 +5934,7 @@ static void genXor (iCode *ic, iCode *ifx)
                                                pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
                                                goto release;
                                        } else {
+                                               assert ( !"incomplete genXor" );
                                                pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
                                                pic14_emitcode("cpl","c");
                                        }
@@ -6318,30 +6325,17 @@ static void AccLsh (operand *op,int offset,int shCount)
 {
        FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       if(shCount != 0){
-               /*
-               if(shCount == 1) {
-                       pic14_emitcode("add","a,acc");
+       if(shCount != 0) {
+               if (shCount == 1)
+               {
                        emitCLRC;
-                       emitpcode(POC_RLF,popGet(AOP(op),offset));
+                       emitpcode (POC_RLF, popGet (AOP(op), 0));
                } else {
-                       if(shCount == 2) {
-                               pic14_emitcode("add","a,acc");
-                               emitCLRC;
-                               emitpcode(POC_RLF,popGet(AOP(op),offset));
-                               pic14_emitcode("add","a,acc");
-                               emitCLRC;
-                               emitpcode(POC_RLF,popGet(AOP(op),offset));
-                       } else {
-               */
-               {
-                       {
-                               /* rotate left accumulator */
-                               AccRol(op,offset,shCount);
-                               /* and kill the lower order bits */
-                               pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
-                               emitpcode(POC_ANDLW,popGetLit(SLMask[shCount]));
-                       }
+                       /* rotate left accumulator */
+                       AccRol(op,offset,shCount);
+                       /* and kill the lower order bits */
+                       emitpcode(POC_MOVLW,popGetLit(SLMask[shCount]));
+                       emitpcode (POC_ANDWF, popGet (AOP(op),0));
                }
        }
 }
@@ -6355,13 +6349,14 @@ static void AccRsh (operand *op,int offset,int shCount)
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        if(shCount != 0){
                if(shCount == 1){
-                       CLRC;
-                       pic14_emitcode("rrc","a");
+                       emitCLRC;
+                       emitpcode (POC_RRF, popGet (AOP(op), 0));
                } else {
                        /* rotate right accumulator */
                        AccRol(op,offset,8 - shCount);
                        /* and kill the higher order bits */
-                       pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
+                       emitpcode (POC_MOVLW, popGetLit (SRMask[shCount]));
+                       emitpcode (POC_ANDWF, popGet (AOP(op),0));
                }
        }
 }
@@ -6396,7 +6391,7 @@ static void AccSRsh (int shCount)
                }
        }
 }
-#endif
+
 /*-----------------------------------------------------------------*/
 /* shiftR1Left2Result - shift right one byte from left to result   */
 /*-----------------------------------------------------------------*/
@@ -6676,6 +6671,7 @@ static void shiftL1Left2Result (operand *left, int offl,
        }
        
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* movLeft2Result - move byte from left to result                  */
@@ -6699,6 +6695,194 @@ static void movLeft2Result (operand *left, int offl,
        }
 }
 
+/*-----------------------------------------------------------------*/
+/* shiftLeft_Left2ResultLit - shift left by known count            */
+/*-----------------------------------------------------------------*/
+
+static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount)
+{
+       int size, same, offr, i;
+
+       size = AOP_SIZE(left);
+       if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+       
+       same = pic14_sameRegs (AOP(left), AOP(result));
+       
+       offr = shCount / 8;
+       shCount = shCount & 0x07;
+
+       size -= offr;
+
+       switch (shCount)
+       {
+       case 0: /* takes 0 or 2N cycles (for offr==0) */
+               if (!same || offr) {
+                       for (i=size-1; i >= 0; i--)
+                               movLeft2Result (left, i, result, offr + i);
+               } // if
+               break;
+               
+       case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */
+               if (same && offr) {
+                       shiftLeft_Left2ResultLit (left, result, 8 * offr);
+                       shiftLeft_Left2ResultLit (result, result, shCount);
+                       return; /* prevent clearing result again */
+               } else {
+                       emitCLRC;
+                       for (i=0; i < size; i++) {
+                               if (same && !offr) {
+                                       emitpcode (POC_RLF, popGet (AOP(left), i));
+                               } else {
+                                       emitpcode (POC_RLFW, popGet (AOP(left), i));
+                                       emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+                               } // if
+                       } // for
+               } // if (offr)
+               break;
+               
+       case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */
+               /* works in-place/with offr as well */
+               emitpcode (POC_SWAPFW, popGet (AOP(left), size-1));
+               emitpcode (POC_ANDLW, popGetLit (0xF0));
+               emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr));
+
+               for (i = size - 2; i >= 0; i--)
+               {
+                       emitpcode (POC_SWAPFW, popGet (AOP(left), i));
+                       emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+                       emitpcode (POC_ANDLW, popGetLit (0x0F));
+                       emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1));
+                       emitpcode (POC_XORWF, popGet (AOP(result), i + offr));
+               } // for i
+               break;
+               
+       case 7: /* takes 2(N-1)+3 = 2N+1 cycles */
+               /* works in-place/with offr as well */
+               emitpcode (POC_RRFW, popGet (AOP(left), size-1));
+               for (i = size-2; i >= 0; i--) {
+                       emitpcode (POC_RRFW, popGet (AOP(left), i));
+                       emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1));
+               } // for i
+               emitpcode (POC_CLRF, popGet (AOP(result), offr));
+               emitpcode (POC_RRF, popGet (AOP(result), offr));
+               break;
+       
+       default:
+               shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1);
+               shiftLeft_Left2ResultLit (result, result, 1);
+               return; /* prevent clearing result again */
+               break;
+       } // switch
+
+       while (0 < offr--)
+       {
+               emitpcode (POC_CLRF, popGet (AOP(result), offr));
+       } // while
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftRight_Left2ResultLit - shift right by known count          */
+/*-----------------------------------------------------------------*/
+
+static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign)
+{
+       int size, same, offr, i;
+
+       size = AOP_SIZE(left);
+       if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+       
+       same = pic14_sameRegs (AOP(left), AOP(result));
+       
+       offr = shCount / 8;
+       shCount = shCount & 0x07;
+
+       size -= offr;
+
+       if (size)
+       {
+               switch (shCount)
+               {
+               case 0: /* takes 0 or 2N cycles (for offr==0) */
+                       if (!same || offr) {
+                               for (i=0; i < size; i++)
+                                       movLeft2Result (left, i + offr, result, i);
+                       } // if
+                       break;
+                       
+               case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */
+                       emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr);
+                       if (same && offr) {
+                               shiftRight_Left2ResultLit (left, result, 8 * offr, sign);
+                               shiftRight_Left2ResultLit (result, result, shCount, sign);
+                               return; /* prevent sign-extending result again */
+                       } else {
+                               emitCLRC;
+                               if (sign) {
+                                       emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0));
+                                       emitSETC;
+                               }
+                               for (i = size-1; i >= 0; i--) {
+                                       if (same && !offr) {
+                                               emitpcode (POC_RRF, popGet (AOP(left), i));
+                                       } else {
+                                               emitpcode (POC_RRFW, popGet (AOP(left), i + offr));
+                                               emitpcode (POC_MOVWF, popGet (AOP(result), i));
+                                       }
+                               } // for i
+                       } // if (offr)
+                       break;
+                       
+               case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */
+                       /* works in-place/with offr as well */
+                       emitpcode (POC_SWAPFW, popGet (AOP(left), offr));
+                       emitpcode (POC_ANDLW, popGetLit (0x0F));
+                       emitpcode (POC_MOVWF, popGet(AOP(result), 0));
+
+                       for (i = 1; i < size; i++)
+                       {
+                               emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr));
+                               emitpcode (POC_MOVWF, popGet (AOP(result), i));
+                               emitpcode (POC_ANDLW, popGetLit (0xF0));
+                               emitpcode (POC_IORWF, popGet (AOP(result), i - 1));
+                               emitpcode (POC_XORWF, popGet (AOP(result), i));
+                       } // for i
+
+                       if (sign)
+                       {
+                               emitpcode (POC_MOVLW, popGetLit (0xF0));
+                               emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0));
+                               emitpcode (POC_IORWF, popGet (AOP(result), size-1));
+                       } // if
+                       break;
+                       
+               case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */
+                       /* works in-place/with offr as well */
+                       emitpcode (POC_RLFW, popGet (AOP(left), offr));
+                       for (i = 0; i < size-1; i++) {
+                               emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1));
+                               emitpcode (POC_MOVWF, popGet (AOP(result), i));
+                       } // for i
+                       emitpcode (POC_CLRF, popGet (AOP(result), size-1));
+                       if (!sign) {
+                               emitpcode (POC_RLF, popGet (AOP(result), size-1));
+                       } else {
+                               emitSKPNC;
+                               emitpcode (POC_DECF, popGet (AOP(result), size-1));
+                       }
+                       break;
+               
+               default:
+                       shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign);
+                       shiftRight_Left2ResultLit (result, result, 1, sign);
+                       return; /* prevent sign extending result again */
+                       break;
+               } // switch
+       } // if
+
+       addSign (result, size, sign);
+}
+
+#if 0
 /*-----------------------------------------------------------------*/
 /* shiftL2Left2Result - shift left two bytes from left to result   */
 /*-----------------------------------------------------------------*/
@@ -6826,6 +7010,7 @@ static void shiftL2Left2Result (operand *left, int offl,
        }
        
 }
+
 /*-----------------------------------------------------------------*/
 /* shiftR2Left2Result - shift right two bytes from left to result  */
 /*-----------------------------------------------------------------*/
@@ -6978,7 +7163,6 @@ static void shiftR2Left2Result (operand *left, int offl,
   }
 }
 
-
 /*-----------------------------------------------------------------*/
 /* shiftLLeftOrResult - shift left one byte from left, or to result*/
 /*-----------------------------------------------------------------*/
@@ -6987,13 +7171,12 @@ static void shiftLLeftOrResult (operand *left, int offl,
 {
        FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+       
        /* shift left accumulator */
        AccLsh(left,offl,shCount);
        /* or with result */
-       pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
-       /* back to result */
-       aopPut(AOP(result),"a",offr);
+       emitpcode (POC_IORWF, popGet (AOP(result), offr));
+       assert ( !"broken (modifies left, fails for left==result))" );
 }
 
 /*-----------------------------------------------------------------*/
@@ -7004,13 +7187,12 @@ static void shiftRLeftOrResult (operand *left, int offl,
 {
        FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+       
        /* shift right accumulator */
        AccRsh(left,offl,shCount);
        /* or with result */
-       pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
-       /* back to result */
-       aopPut(AOP(result),"a",offr);
+       emitpcode (POC_IORWF, popGet (AOP(result), offr));
+       assert ( !"broken (modifies left, fails for left==result))" );
 }
 
 /*-----------------------------------------------------------------*/
@@ -7202,7 +7384,9 @@ static void genlshFour (operand *result, operand *left, int shCount)
                shiftL2Left2Result(left, LSB, result, LSB, shCount);
        }
 }
+#endif
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genLeftShiftLiteral - left shifting by known count              */
 /*-----------------------------------------------------------------*/
@@ -7212,7 +7396,7 @@ static void genLeftShiftLiteral (operand *left,
                                                                 iCode *ic)
 {    
        int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
-       int size;
+       //int size;
        
        FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
@@ -7220,7 +7404,7 @@ static void genLeftShiftLiteral (operand *left,
        
        aopOp(left,ic,FALSE);
        aopOp(result,ic,FALSE);
-       
+
        size = getSize(operandType(result));
        
 #if VIEW_SIZE
@@ -7257,6 +7441,7 @@ static void genLeftShiftLiteral (operand *left,
                freeAsmop(left,NULL,ic,TRUE);
                freeAsmop(result,NULL,ic,TRUE);
 }
+#endif
 
 /*-----------------------------------------------------------------*
 * genMultiAsm - repeat assembly instruction for size of register.
@@ -7307,11 +7492,14 @@ static void genLeftShift (iCode *ic)
        result = IC_RESULT(ic);
        
        aopOp(right,ic,FALSE);
+       aopOp(left,ic,FALSE);
+       aopOp(result,ic,FALSE);
+       
        
        /* if the shift count is known then do it 
        as efficiently as possible */
        if (AOP_TYPE(right) == AOP_LIT) {
-               genLeftShiftLiteral (left,right,result,ic);
+               shiftLeft_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit));
                return ;
        }
        
@@ -7322,9 +7510,6 @@ static void genLeftShift (iCode *ic)
        largest size of an object can be only 32 bits ) */  
        
        
-       aopOp(left,ic,FALSE);
-       aopOp(result,ic,FALSE);
-       
        /* now move the left to the result if they are not the
        same */
        if (!pic14_sameRegs(AOP(left),AOP(result)) && 
@@ -7464,6 +7649,7 @@ release:
        freeAsmop(result,NULL,ic,TRUE);
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* genrshOne - right shift a one byte quantity by known count      */
 /*-----------------------------------------------------------------*/
@@ -7512,32 +7698,35 @@ static void genrshTwo (operand *result,operand *left,
 static void shiftRLong (operand *left, int offl,
                                                operand *result, int sign)
 {
+       int size, same;
+       
        FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-       if(!sign)
-               pic14_emitcode("clr","c");
-       MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
-       if(sign)
-               pic14_emitcode("mov","c,acc.7");
-       pic14_emitcode("rrc","a");
-       aopPut(AOP(result),"a",MSB32-offl);
-       if(offl == MSB16)
-               /* add sign of "a" */
-               addSign(result, MSB32, sign);
        
-       MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
-       pic14_emitcode("rrc","a");
-       aopPut(AOP(result),"a",MSB24-offl);
+       size = AOP_SIZE(left);
+       if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
        
-       MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
-       pic14_emitcode("rrc","a");
-       aopPut(AOP(result),"a",MSB16-offl);
-       
-       if(offl == LSB){
-               MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
-               pic14_emitcode("rrc","a");
-               aopPut(AOP(result),"a",LSB);
-       }
+       if (sign)
+               emitpcode (POC_RLFW, popGet (AOP(left), AOP_SIZE(left)-1));
+       else
+               emitCLRC;
+
+       assert (offl >= 0 && offl < size);
+
+       same = pic14_sameRegs (AOP(left), AOP(result));
+
+       /* perform the shift */
+       while (size--)
+       {
+               if (same && !offl) {
+                       emitpcode (POC_RRF, popGet (AOP(result), size));
+               } else {
+                       emitpcode (POC_RRFW, popGet (AOP(left), size));
+                       emitpcode (POC_MOVWF, popGet (AOP(result), size-offl));
+               }
+       } // while
+
+       addSign (result, AOP_SIZE(left) - offl, sign);
 }
 
 /*-----------------------------------------------------------------*/
@@ -7631,7 +7820,7 @@ static void genRightShiftLiteral (operand *left,
        /* I suppose that the left size >= result size */
        if(shCount == 0){
                while(res_size--)
-                       movLeft2Result(left, lsize, result, res_size);
+                       movLeft2Result(left, res_size, result, res_size);
        }
        
        else if(shCount >= (lsize * 8)){
@@ -7676,10 +7865,11 @@ static void genRightShiftLiteral (operand *left,
                }
                
        }
-       
+
        freeAsmop(left,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
 }
+#endif
 
 /*-----------------------------------------------------------------*/
 /* genSignedRightShift - right shift of signed number              */
@@ -7709,7 +7899,8 @@ static void genSignedRightShift (iCode *ic)
        
        
        if ( AOP_TYPE(right) == AOP_LIT) {
-               genRightShiftLiteral (left,right,result,ic,1);
+               shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 1);
+               //genRightShiftLiteral (left,right,result,ic,1);
                return ;
        }
        /* shift count is unknown then we have to form 
@@ -7856,11 +8047,14 @@ static void genRightShift (iCode *ic)
        result = IC_RESULT(ic);
        
        aopOp(right,ic,FALSE);
+       aopOp(left,ic,FALSE);
+       aopOp(result,ic,FALSE);
        
        /* 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);
+               shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 0);
+               //genRightShiftLiteral (left,right,result,ic, 0);
                return ;
        }
        
@@ -7872,8 +8066,6 @@ static void genRightShift (iCode *ic)
        
        pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
        pic14_emitcode("inc","b");
-       aopOp(left,ic,FALSE);
-       aopOp(result,ic,FALSE);
        
        /* now move the left to the result if they are not the
        same */
@@ -8167,7 +8359,7 @@ static void genNearPointerGet (operand *left,
        if (!AOP_INPREG(AOP(left)) && !direct) {
                /* otherwise get a free pointer register */
                DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-               if (PCOP(AOP(result))->type == PO_LITERAL) 
+               if (PCOP(AOP(result))->type == PO_LITERAL) /* XXX: check me */ 
                        emitpcode(POC_MOVLW, popGet(AOP(left),0));
                else
                        emitpcode(POC_MOVFW, popGet(AOP(left),0));
@@ -8475,9 +8667,9 @@ static void genConstPointerGet (operand *left,
                                                                operand *result, iCode *ic)
 {
        //sym_link *retype = getSpec(operandType(result));
-       symbol *albl = newiTempLabel(NULL);
-       symbol *blbl = newiTempLabel(NULL);
+       symbol *albl, *blbl;//, *clbl;
        PIC_OPCODE poc;
+       int i, size, lit;
        pCodeOp *pcop;
        
        FENTRY;
@@ -8485,28 +8677,75 @@ static void genConstPointerGet (operand *left,
        aopOp(left,ic,FALSE);
        aopOp(result,ic,FALSE);
        
+       size = AOP_SIZE(result);
        
        DEBUGpic14_AopType(__LINE__,left,NULL,result);
        
        DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
-       
-       emitpcode(POC_CALL,popGetLabel(albl->key));
-       pcop = popGetLabel(blbl->key);
-       emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
-       emitpcode(POC_GOTO,pcop);
-       emitpLabel(albl->key);
-       
-       poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
-       
-       emitpcode(poc,popGet(AOP(left),1));
-       emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
-       emitpcode(poc,popGet(AOP(left),0));
-       emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
-       
-       emitpLabel(blbl->key);
-       
-       emitpcode(POC_MOVWF,popGet(AOP(result),0));
-       
+
+       lit = aop_isLitLike (AOP(left));
+       poc = lit ? POC_MOVLW : POC_MOVFW;
+
+       if (lit)
+       {
+               for (i = 0; i < size; i++)
+               {
+                       albl = newiTempLabel(NULL);
+                       blbl = newiTempLabel(NULL);
+                       
+                       emitpcode(POC_CALL,popGetLabel(albl->key));
+                       pcop = popGetLabel(blbl->key);
+                       emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
+                       emitpcode(POC_GOTO,pcop);
+                       
+                       emitpLabel(albl->key);
+                       emitpcode(poc,popGetAddr(AOP(left),1,i));
+                       emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
+                       emitpcode(poc,popGetAddr(AOP(left),0,i));
+                       emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
+               
+                       emitpLabel(blbl->key);
+                       emitpcode(POC_MOVWF,popGet(AOP(result),i));
+               } // for
+       } else {
+               albl = newiTempLabel(NULL);
+               blbl = newiTempLabel(NULL);
+               //clbl = newiTempLabel(NULL);
+
+               emitpcode (POC_GOTO, popGetLabel (blbl->key));
+               
+               emitpLabel(albl->key);
+               emitpcode(poc,popGet(AOP(left),1));
+               emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
+               emitpcode(poc,popGet(AOP(left),0));
+               emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
+               
+               emitpLabel(blbl->key);
+               
+               for (i = 0; i < size; i++)
+               {
+                       emitpcode(POC_CALL,popGetLabel(albl->key));
+                       /* the next two instructions (plus clbl) might be useless... */
+                       //pcop = popGetLabel(clbl->key);
+                       //emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
+                       //emitpcode(POC_GOTO,pcop);
+                       //emitpLabel(clbl->key);
+
+                       if (i+1 < size) {
+                               emitpcode (POC_INCF, popGet (AOP(left), 0));
+                               emitSKPNZ;
+                               emitpcode (POC_INCF, popGet (AOP(left), 1));
+                       }
+                       emitpcode(POC_MOVWF,popGet(AOP(result),i));
+               } // for
+               if (size > 1) {
+                       /* restore left's value */
+                       emitpcode (POC_MOVLW, popGetLit (size-1));
+                       emitpcode (POC_SUBWF, popGet (AOP(left), 0));
+                       emitSKPC;
+                       emitpcode (POC_DECF, popGet (AOP(left), 1));
+               } // if
+       } // if (lit)
        
        freeAsmop(left,NULL,ic,TRUE);
        freeAsmop(result,NULL,ic,TRUE);
@@ -8519,7 +8758,7 @@ static void genPointerGet (iCode *ic)
 {
        operand *left, *result ;
        sym_link *type, *etype;
-       int p_type;
+       int p_type = -1;
        
        FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
@@ -8588,11 +8827,14 @@ static void genPointerGet (iCode *ic)
                break;
                
        case GPOINTER:
-               if (IS_PTR_CONST(type))
+               if (IS_CODEPTR(type) || IS_PTR_CONST(type))
                        genConstPointerGet (left,result,ic);
                else
                        genGenPointerGet (left,result,ic);
                break;
+       default:
+               assert ( !"unhandled pointer type" );
+               break;
        }
        
 }
@@ -9373,6 +9615,27 @@ static void genAddrOf (iCode *ic)
        aopOp((result=IC_RESULT(ic)),ic,TRUE);
        
        DEBUGpic14_AopType(__LINE__,left,right,result);
+       assert (IS_SYMOP (left));
+       
+       /* sanity check: generic pointers to code space are not yet supported,
+        * pionters to codespace must not be assigned addresses of __data values. */
+ #if 0
+       fprintf (stderr, "result: %s, left: %s\n", OP_SYMBOL(result)->name, OP_SYMBOL(left)->name);
+       fprintf (stderr, "result->type : "); printTypeChain (OP_SYM_TYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(result)))), IS_CODEPTR(OP_SYM_TYPE(result)), IS_PTR_CONST(OP_SYM_TYPE(result)));
+       fprintf (stderr, "result->etype: "); printTypeChain (OP_SYM_ETYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(result)))), IS_CODEPTR(OP_SYM_ETYPE(result)), IS_PTR_CONST(OP_SYM_ETYPE(result)));
+       fprintf (stderr, "left->type   : "); printTypeChain (OP_SYM_TYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left)))), IS_CODEPTR(OP_SYM_TYPE(left)), IS_PTR_CONST(OP_SYM_TYPE(left)));
+       fprintf (stderr, "left->etype  : "); printTypeChain (OP_SYM_ETYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n",IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(left)))), IS_CODEPTR(OP_SYM_ETYPE(left)), IS_PTR_CONST(OP_SYM_ETYPE(left)));
+#endif
+
+       if (IS_CODEPTR(OP_SYM_TYPE(result)) && !IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left))))) {
+         fprintf (stderr, "trying to assign __code pointer (%s) an address in __data space (&%s) -- expect trouble\n",
+               IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
+               OP_SYMBOL(left)->name);
+       } else if (!IS_CODEPTR (OP_SYM_TYPE(result)) && IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))))) {
+         fprintf (stderr, "trying to assign __data pointer (%s) an address in __code space (&%s) -- expect trouble\n",
+               IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
+               OP_SYMBOL(left)->name);
+       }
        
        size = AOP_SIZE(IC_RESULT(ic));
        offset = 0;
@@ -9450,7 +9713,27 @@ static void genAssign (iCode *ic)
        /* if they are the same registers */
        if (pic14_sameRegs(AOP(right),AOP(result)))
                goto release;
+
+       /* special case: assign from __code */
+       if (!IS_ITEMP(right)                            /* --> iTemps never reside in __code */
+               && IS_SYMOP (right)                     /* --> must be an immediate (otherwise we would be in genConstPointerGet) */
+               && !IS_FUNC(OP_SYM_TYPE(right))         /* --> we would want its address instead of the first instruction */
+               && !IS_CODEPTR(OP_SYM_TYPE(right))      /* --> get symbols address instread */
+               && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(right)))))
+       {
+         emitpComment ("genAssign from CODESPACE");
+         genConstPointerGet (right, result, ic);
+         goto release;
+       }
        
+       /* just for symmetry reasons... */
+       if (!IS_ITEMP(result)
+               && IS_SYMOP (result)
+               && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(result)))))
+       {
+         assert ( !"cannot write to CODESPACE" );
+       }
+
        /* if the result is a bit */
        if (AOP_TYPE(result) == AOP_CRY) {
                
@@ -9827,9 +10110,9 @@ static void genCast (iCode *ic)
                        DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
                
                if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
-                       emitpcode(POC_MOVLW, popGetAddr(AOP(right),0));
+                       emitpcode(POC_MOVLW, popGetAddr(AOP(right),0,0));
                        emitpcode(POC_MOVWF, popGet(AOP(result),0));
-                       emitpcode(POC_MOVLW, popGetAddr(AOP(right),1));
+                       emitpcode(POC_MOVLW, popGetAddr(AOP(right),1,0));
                        emitpcode(POC_MOVWF, popGet(AOP(result),1));
                        if(AOP_SIZE(result) <2)
                                fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
@@ -9896,7 +10179,7 @@ static void genCast (iCode *ic)
                                        DEBUGpic14_emitcode("; ***","%s  %d - pointer cast3",__FUNCTION__,__LINE__);
                                        if ((AOP_TYPE(right) == AOP_PCODE) && 
                                                AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
-                                               emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset));
+                                               emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset,0));
                                                emitpcode(POC_MOVWF, popGet(AOP(result),offset));
                                        } else { 
                                                aopPut(AOP(result),
@@ -10133,6 +10416,7 @@ void genpic14Code (iCode *lic)
 {
        iCode *ic;
        int cln = 0;
+       const char *cline;
        
        FENTRY;
        lineHead = lineCurr = NULL;
@@ -10158,7 +10442,10 @@ void genpic14Code (iCode *lic)
                if (!options.noCcodeInAsm && (cln != ic->lineno)) {
                  cln = ic->lineno;
                  //fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno));
-                 emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, printCLine (ic->filename, cln));
+                 cline = printCLine (ic->filename, ic->lineno);
+                 if (!cline || strlen (cline) == 0) cline = printCLine (ic->filename, ic->lineno);
+                 addpCode2pBlock (pb, newpCodeCSource (ic->lineno, ic->filename, cline));
+                 //emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, cline);
                }
                
                if (options.iCodeInAsm) {
@@ -10379,3 +10666,27 @@ void genpic14Code (iCode *lic)
        
        return;
 }
+
+int
+aop_isLitLike (asmop *aop)
+{
+  assert (aop);
+  if (aop->type == AOP_LIT) return 1;
+  if (aop->type == AOP_IMMD) return 1;
+  if ((aop->type == AOP_PCODE) &&
+               ((aop->aopu.pcop->type == PO_LITERAL) || (aop->aopu.pcop->type == PO_IMMEDIATE)))
+  {
+    /* this should be treated like a literal/immediate (use MOVLW/ADDLW/SUBLW
+     * instead of MOVFW/ADDFW/SUBFW, use popGetAddr instead of popGet) */
+    return 1;
+  }
+  return 0;
+}
+
+int
+op_isLitLike (operand *op)
+{
+  assert (op);
+  if (aop_isLitLike (AOP(op))) return 1;
+  return 0;
+}
index 94603bda2fa1c87fd797cbda1d9522a81cc90c76..cd40bfe0b812e1da35c23e3510238c9ed121a54b 100644 (file)
 #ifndef SDCCGENPIC14_H
 #define SDCCGENPIC14_H
 
-#define FENTRY do { \
+extern int debug_verbose;
+
+#define FENTRY do {                                                                    \
        /*fprintf (stderr, "%s:%u:%s: *{*\n", __FILE__, __LINE__, __FUNCTION__);*/      \
-       emitpComment ("; %s:%u:%s *{*\n", __FILE__, __LINE__, __FUNCTION__);    \
+       if (options.debug || debug_verbose) {                                           \
+               emitpComment ("; %s:%u:%s *{*", __FILE__, __LINE__, __FUNCTION__);      \
+       }                                                                               \
 } while (0)
-#define FEXIT do { \
+#define FEXIT do {                                                                     \
        /*fprintf (stderr, "%s:%u:%s: *}*\n", __FILE__, __LINE__, __FUNCTION__);*/      \
-       emitpComment ("; %s:%u:%s *}*\n", __FILE__, __LINE__, __FUNCTION__);    \
+       if (options.debug || debug.verbose) {                                           \
+               emitpComment ("; %s:%u:%s *}*", __FILE__, __LINE__, __FUNCTION__);      \
+       }                                                                               \
 } while (0)
 
 struct pCodeOp;
@@ -172,7 +178,7 @@ pCodeOp *popGetLit(unsigned int lit);
 pCodeOp *popGetWithString(char *str, int isExtern);
 pCodeOp *popRegFromString(char *str, int size, int offset);
 pCodeOp *popGet (asmop *aop, int offset);//, bool bit16, bool dname);
-pCodeOp *popGetAddr (asmop *aop, int offset);
+pCodeOp *popGetAddr (asmop *aop, int offset, int index);
 pCodeOp *popGetTempReg(void);
 void popReleaseTempReg(pCodeOp *pcop);
 
@@ -186,6 +192,7 @@ void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop);
 void mov2w (asmop *aop, int offset);
 const char *pCodeOpType(  pCodeOp *pcop);
 
-
+int aop_isLitLike (asmop *aop);
+int op_isLitLike (operand *op);
 
 #endif
index bdb8f8d437f3cd7d6960e87e1846d58294c7059f..66bb1e24a60d1caec11bf293b96e3118d9300c58 100644 (file)
@@ -1024,11 +1024,9 @@ void genPlus (iCode *ic)
                                else {
                                        PIC_OPCODE poc = POC_ADDFW;
                                        
-                                       if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                                               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                                               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
+                                       if (op_isLitLike (IC_LEFT (ic)))
                                                poc = POC_ADDLW;
-                                       emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0));
+                                       emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0,0));
                                        if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC)
                                                emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
                                }
@@ -1041,14 +1039,13 @@ void genPlus (iCode *ic)
                
                if(size){
                        if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
-                               if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
+                               if (op_isLitLike (IC_LEFT(ic)))
+                               {
                                        while(size--){
                                                emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
                                                emitSKPNC;
                                                emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset));
-                                               emitpcode(POC_ADDLW,   popGetAddr(AOP(IC_LEFT(ic)),offset));
+                                               emitpcode(POC_ADDLW,   popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                                emitpcode(POC_MOVWF,   popGet(AOP(IC_RESULT(ic)),offset));
                                                offset++;
                                        }
@@ -1063,13 +1060,11 @@ void genPlus (iCode *ic)
                                }
                        } else {
                                PIC_OPCODE poc = POC_MOVFW;
-                               if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
+                               if (op_isLitLike (IC_LEFT(ic)))
                                        poc = POC_MOVLW;
                                while(size--){
                                        if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-                                               emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset));
+                                               emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                                emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
                                        }
                                        emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
@@ -1094,12 +1089,10 @@ void genPlus (iCode *ic)
                if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) { 
                        int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic));
                        PIC_OPCODE poc = POC_MOVFW;
-                       if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                               (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
+                       if (op_isLitLike (IC_LEFT(ic)))
                                poc = POC_MOVLW;
                        while(leftsize-- > 0) {
-                               emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset));
+                               emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset));
                                emitSKPNC;
                                emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset));
@@ -1281,8 +1274,7 @@ void addSign(operand *result, int offset, int sign)
                                emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0));
                                emitpcode(POC_MOVLW, popGetLit(0xff));
                                while(size--)
-                                       emitpcode(POC_MOVWF, popGet(AOP(result),size));
-                               
+                                       emitpcode(POC_MOVWF, popGet(AOP(result),offset+size));
                        }
                } else
                        while(size--)
@@ -1616,28 +1608,23 @@ void genMinus (iCode *ic)
                if(size){
                        if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) {
                                int lit = 0;
-                               if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) {
+                               if (op_isLitLike (IC_LEFT(ic)))
                                        lit = 1;
-                               }
                                while(size--){
                                        emitpcode(POC_MOVFW,   popGet(AOP(IC_RIGHT(ic)),offset));
                                        emitSKPC;
                                        emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset));
-                                       emitpcode(lit?POC_SUBLW:POC_SUBFW,   popGetAddr(AOP(IC_LEFT(ic)),offset));
+                                       emitpcode(lit?POC_SUBLW:POC_SUBFW,   popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                        emitpcode(POC_MOVWF,   popGet(AOP(IC_RESULT(ic)),offset));
                                        offset++;
                                }
                        } else {
                                PIC_OPCODE poc = POC_MOVFW;
-                               if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && (
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || 
-                                       (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE)))
+                               if (op_isLitLike (IC_LEFT(ic)))
                                        poc = POC_MOVLW;
                                while(size--){
                                        if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
-                                               emitpcode(poc,  popGetAddr(AOP(IC_LEFT(ic)),offset));
+                                               emitpcode(poc,  popGetAddr(AOP(IC_LEFT(ic)),offset,0));
                                                emitpcode(POC_MOVWF,  popGet(AOP(IC_RESULT(ic)),offset));
                                        }
                                        emitpcode(POC_MOVFW,  popGet(AOP(IC_RIGHT(ic)),offset));
index 85d49a3a8495e55a82336710034aa7e623cb2631..79184f0d3cda64c45a8c4e584a111578ef87c803 100644 (file)
@@ -27,6 +27,7 @@
 #include "ralloc.h"
 #include "pcode.h"
 #include "newalloc.h"
+#include "gen.h"
 
 
 #ifdef WORDS_BIGENDIAN
@@ -424,7 +425,7 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist,
 {
        initList *iloop;
        unsigned size = 0;
-       
+
        if(!pb)
                return;
        if (ilist) {
@@ -474,6 +475,89 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist,
        return;
 }
 
+/*-----------------------------------------------------------------*/
+/* printIvalPtr - generates code for initial value of pointers     */
+/*-----------------------------------------------------------------*/
+extern value *initPointer (initList *, sym_link *toType);
+
+static void 
+printIvalPtr (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
+{
+       value *val;
+       
+       if (!ilist || !pb)
+               return;
+       
+       fprintf (stderr, "FIXME: initializers for pointers...\n");
+       printTypeChain (type, stderr);
+       
+       fprintf (stderr, "symbol: %s, DCL_TYPE():%d, DCL_ELEM():%d, IS_ARRAY():%d", sym->rname, DCL_TYPE(type), DCL_ELEM(type), IS_ARRAY(type));
+       fprintf (stderr, "ilist: type=%d (INIT_DEEP=%d, INIT_NODE=%d)\n", ilist->type, INIT_DEEP, INIT_NODE);
+
+       if (ilist && (ilist->type == INIT_DEEP))
+         ilist = ilist->init.deep;
+       
+       /* function pointers */
+       if (IS_FUNC (type->next))
+       {
+               assert ( !"function pointers not yet handled" );
+               //printIvalFuncPtr (type, ilist, pb);
+       }
+
+       if (!(val = initPointer (ilist, type)))
+               return;
+       
+       if (IS_CHAR (type->next))
+       {
+               if (printIvalChar (type, ilist, pb, NULL)) return;
+       }
+
+       /* check the type */
+       if (compareType (type, val->type) == 0)
+       {
+               werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG);
+               printFromToType (val->type, type);
+       }
+
+       if (IS_LITERAL (val->etype))
+       {
+               switch (getSize (type))
+               {
+               case 1:
+                       fprintf (stderr, "BYTE: %i\n", (unsigned char)floatFromVal (val) & 0x00FF);
+                       break;
+               case 2:
+                       fprintf (stderr, "WORD: %i\n", (unsigned int)floatFromVal (val) & 0x00FFFF);
+                       break;
+               case 3: /* gneric pointers */
+                       assert ( !"generic pointers not yet handled" );
+               case 4:
+                       fprintf (stderr, "LONG: %i\n", (unsigned int)floatFromVal (val) & 0x0000FFFFFFFF);
+                       break;
+               default:
+                       assert ( !"invaild size of value -- aborting" );
+               } // switch
+
+               return;
+       } // if (IS_LITERAL)
+
+       /* now handle symbolic values */
+       switch (getSize (type))
+       {
+       case 1:
+               fprintf (stderr, "BYTE: %s", val->name);
+               break;
+       case 2:
+               fprintf (stderr, "WORD: %s", val->name);
+               break;
+       case 4:
+               fprintf (stderr, "LONG: %s", val->name);
+               break;
+       default:
+               assert ( !"invalid size of (symbolic) value -- aborting" );
+       } // switch
+}
+
 /*-----------------------------------------------------------------*/
 /* printIval - generates code for initial value                    */
 /*-----------------------------------------------------------------*/
@@ -486,31 +570,31 @@ printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
        /* if structure then    */
        if (IS_STRUCT (type))
        {
-               //fprintf(stderr,"%s struct\n",__FUNCTION__);
+               //fprintf(stderr,"%s struct: %s\n",__FUNCTION__, sym->rname);
                printIvalStruct (sym, type, ilist, pb);
                return;
        }
        
-       /* if this is a pointer */
-       if (IS_PTR (type))
+       /* if this is an array   */
+       if (IS_ARRAY (type))
        {
-               //fprintf(stderr,"%s pointer\n",__FUNCTION__);
-               //printIvalPtr (sym, type, ilist, oFile);
+               //fprintf(stderr,"%s array: %s\n",__FUNCTION__, sym->rname);
+               printIvalArray (sym, type, ilist, pb);
                return;
        }
        
-       /* if this is an array   */
-       if (IS_ARRAY (type))
+       /* if this is a pointer */
+       if (IS_PTR (type))
        {
-               //fprintf(stderr,"%s array\n",__FUNCTION__);
-               printIvalArray (sym, type, ilist, pb);
+               //fprintf(stderr,"%s pointer: %s\n",__FUNCTION__, sym->rname);
+               printIvalPtr (sym, type, ilist, pb);
                return;
        }
        
        /* if type is SPECIFIER */
        if (IS_SPEC (type))
        {
-               //fprintf(stderr,"%s spec\n",__FUNCTION__);
+               //fprintf(stderr,"%s spec %s\n",__FUNCTION__, sym->rname);
                printIvalType (sym, type, ilist, pb);
                return;
        }
@@ -933,6 +1017,9 @@ picglue ()
                werror (E_FILE_OPEN_ERR, buffer);
                exit (1);
        }
+
+       /* prepare statistics */
+       resetpCodeStatistics ();
        
        /* initial comments */
        pic14initialComments (asmFile);
@@ -1019,7 +1106,7 @@ picglue ()
        fprintf (asmFile, "; bit data\n");
        fprintf (asmFile, "%s", iComments2);
        copyFile (asmFile, bit->oFile);
-       
+
        /* copy the interrupt vector table */
        if (mainf && IFFUNC_HASBODY(mainf->type)) {
                copyFile (asmFile, vFile);
@@ -1070,6 +1157,8 @@ picglue ()
        
        /* unknown */
        copypCode(asmFile, 'P');
+
+       dumppCodeStatistics (asmFile);
        
        fprintf (asmFile,"\tend\n");
        
index d28f0b3d3ced0df4d032eaae46883a23ac7f529f..4e226db9c1b3a20b130aaf164ab0805217418604 100644 (file)
@@ -82,6 +82,11 @@ int debug_verbose = 0;                /* Set true to inundate .asm file */
 // static int GpCodeSequenceNumber = 1;
 int GpcFlowSeq = 1;
 
+/* statistics (code size estimation) */
+static unsigned int pcode_insns = 0;
+static unsigned int pcode_doubles = 0;
+
+
 unsigned maxIdx; /* This keeps track of the maximum register index for call tree register reuse */
 unsigned peakIdx; /* This keeps track of the peak register index for call tree register reuse */
 
@@ -1639,7 +1644,7 @@ void copypCode(FILE *of, char dbName)
        
        if(!of || !the_pFile)
                return;
-       
+
        for(pb = the_pFile->pbHead; pb; pb = pb->next) {
                if(getpBlock_dbName(pb) == dbName) {
                        pBlockStats(of,pb);
@@ -1649,6 +1654,21 @@ void copypCode(FILE *of, char dbName)
        }
        
 }
+
+void resetpCodeStatistics (void)
+{
+  pcode_insns = pcode_doubles = 0;
+}
+
+void dumppCodeStatistics (FILE *of)
+{
+       /* dump statistics */
+       fprintf (of, "\n");
+       fprintf (of, ";\tcode size estimation:\n");
+       fprintf (of, ";\t%5u+%5u = %5u instructions (%5u byte)\n", pcode_insns, pcode_doubles, pcode_insns + pcode_doubles, 2*(pcode_insns + 2*pcode_doubles));
+       fprintf (of, "\n");
+}
+
 void pcode_test(void)
 {
        
@@ -1994,7 +2014,7 @@ pCodeFlowLink *newpCodeFlowLink(pCodeFlow *pcflow)
 /* newpCodeCSource - create a new pCode Source Symbol              */
 /*-----------------------------------------------------------------*/
 
-pCode *newpCodeCSource(int ln, char *f, char *l)
+pCode *newpCodeCSource(int ln, char *f, const char *l)
 {
        
        pCodeCSource *pccs;
@@ -2610,9 +2630,19 @@ void printpBlock(FILE *of, pBlock *pb)
        if(!of)
                of = stderr;
        
-       for(pc = pb->pcHead; pc; pc = pc->next)
+       for(pc = pb->pcHead; pc; pc = pc->next) {
                printpCode(of,pc);
-       
+
+               if (isPCI(pc))
+               {
+                       if (isPCI(pc) && (PCI(pc)->op == POC_PAGESEL || PCI(pc)->op == POC_BANKSEL)) {
+                               pcode_doubles++;
+                       } else {
+                               pcode_insns++;
+                       }
+               }
+       } // for
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -2968,22 +2998,24 @@ char *get_op(pCodeOp *pcop,char *buffer, size_t size)
                        s = buffer;
                        if(PCOI(pcop)->_const) {
                                
-                               if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
+                               if( PCOI(pcop)->offset >= 0 && PCOI(pcop)->offset<4) {
                                        switch(PCOI(pcop)->offset) {
                                        case 0:
-                                               SAFE_snprintf(&s,&size,"low %s",pcop->name);
+                                               SAFE_snprintf(&s,&size,"low (%s+%d)",pcop->name, PCOI(pcop)->index);
                                                break;
                                        case 1:
-                                               SAFE_snprintf(&s,&size,"high %s",pcop->name);
+                                               SAFE_snprintf(&s,&size,"high (%s+%d)",pcop->name, PCOI(pcop)->index);
                                                break;
                                        default:
+                                               fprintf (stderr, "PO_IMMEDIATE/_const/offset=%d\n", PCOI(pcop)->offset);
+                                               assert ( !"offset too large" );
                                                SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)",
                                                        pcop->name,
                                                        PCOI(pcop)->index,
                                                        8 * PCOI(pcop)->offset );
                                        }
                                } else
-                                       SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index);
+                                       SAFE_snprintf(&s,&size,"LOW (%s+%d)",pcop->name,PCOI(pcop)->index);
                        } else {
                                if( !PCOI(pcop)->offset) { // && PCOI(pcc->pcop)->offset<4) {
                                        SAFE_snprintf(&s,&size,"(%s + %d)",
@@ -2998,6 +3030,8 @@ char *get_op(pCodeOp *pcop,char *buffer, size_t size)
                                                SAFE_snprintf(&s,&size,"high (%s + %d)",pcop->name, PCOI(pcop)->index);
                                                break;
                                        default:
+                                               fprintf (stderr, "PO_IMMEDIATE/mutable/offset=%d\n", PCOI(pcop)->offset);
+                                               assert ( !"offset too large" );
                                                SAFE_snprintf(&s,&size,"((%s + %d) >> %d)&0xff",pcop->name, PCOI(pcop)->index, 8*PCOI(pcop)->offset);
                                                break;
                                        }
index cc6cf13518e8cfab0fe7883ef56ae2e2590a68c7..89b6bb828541eba7a7a0f12f5430977b4de4f39e 100644 (file)
@@ -831,7 +831,7 @@ pCode *newpCodeCharP(char *cP);              // Create a new pCode given a char
 pCode *newpCodeInlineP(char *cP);            // Create a new pCode given a char *
 pCode *newpCodeFunction(char *g, char *f,int); // Create a new function
 pCode *newpCodeLabel(char *name,int key);    // Create a new label given a key
-pCode *newpCodeCSource(int ln, char *f, char *l); // Create a new symbol line 
+pCode *newpCodeCSource(int ln, char *f, const char *l); // Create a new symbol line 
 pCode *findNextInstruction(pCode *pci);
 pCode *findNextpCode(pCode *pc, PC_TYPE pct);
 pCode *pCodeInstructionCopy(pCodeInstruction *pci,int invert);
@@ -867,6 +867,8 @@ int isPCinFlow(pCode *pc, pCode *pcflow);
 struct regs * getRegFromInstruction(pCode *pc);
 
 extern void pcode_test(void);
+void resetpCodeStatistics (void);
+void dumppCodeStatistics (FILE *of);
 
 /*-----------------------------------------------------------------*
  * pCode objects.
index dad9f52261ad1bb01cd72b4c225b2b0309378212..4d4bd48fab901389da4869db29ecd62ec6a15064 100644 (file)
@@ -5,23 +5,23 @@
        Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
        Added Pic Port T.scott Dattalo scott@dattalo.com (2000)
        
-         This program is free software; you can redistribute it and/or modify it
-         under the terms of the GNU General Public License as published by the
-         Free Software Foundation; either version 2, or (at your option) any
-         later version.
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of the GNU General Public License as published by the
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
          
-               This program is distributed in the hope that it will be useful,
-               but WITHOUT ANY WARRANTY; without even the implied warranty of
-               MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-               GNU General Public License for more details.
-               
-                 You should have received a copy of the GNU General Public License
-                 along with this program; if not, write to the Free Software
-                 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+               
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
                  
-                       In other words, you are welcome to use, share and improve this program.
-                       You are forbidden to forbid anyone else to use, share and improve
-                       what you give them.   Help stamp out software-hoarding!  
+  In other words, you are welcome to use, share and improve this program.
+  You are forbidden to forbid anyone else to use, share and improve
+  what you give them.   Help stamp out software-hoarding!  
 -------------------------------------------------------------------------*/
 
 #include "common.h"
@@ -193,208 +193,107 @@ static char *
 
        switch (op)
        {
-       case IDENTIFIER:
-               return "IDENTIFIER";
-       case TYPE_NAME:
-               return "TYPE_NAME";
-       case CONSTANT:
-               return "CONSTANT";
-       case STRING_LITERAL:
-               return "STRING_LITERAL";
-       case SIZEOF:
-               return "SIZEOF";
-       case PTR_OP:
-               return "PTR_OP";
-       case INC_OP:
-               return "INC_OP";
-       case DEC_OP:
-               return "DEC_OP";
-       case LEFT_OP:
-               return "LEFT_OP";
-       case RIGHT_OP:
-               return "RIGHT_OP";
-       case LE_OP:
-               return "LE_OP";
-       case GE_OP:
-               return "GE_OP";
-       case EQ_OP:
-               return "EQ_OP";
-       case NE_OP:
-               return "NE_OP";
-       case AND_OP:
-               return "AND_OP";
-       case OR_OP:
-               return "OR_OP";
-       case MUL_ASSIGN:
-               return "MUL_ASSIGN";
-       case DIV_ASSIGN:
-               return "DIV_ASSIGN";
-       case MOD_ASSIGN:
-               return "MOD_ASSIGN";
-       case ADD_ASSIGN:
-               return "ADD_ASSIGN";
-       case SUB_ASSIGN:
-               return "SUB_ASSIGN";
-       case LEFT_ASSIGN:
-               return "LEFT_ASSIGN";
-       case RIGHT_ASSIGN:
-               return "RIGHT_ASSIGN";
-       case AND_ASSIGN:
-               return "AND_ASSIGN";
-       case XOR_ASSIGN:
-               return "XOR_ASSIGN";
-       case OR_ASSIGN:
-               return "OR_ASSIGN";
-       case TYPEDEF:
-               return "TYPEDEF";
-       case EXTERN:
-               return "EXTERN";
-       case STATIC:
-               return "STATIC";
-       case AUTO:
-               return "AUTO";
-       case REGISTER:
-               return "REGISTER";
-       case CODE:
-               return "CODE";
-       case EEPROM:
-               return "EEPROM";
-       case INTERRUPT:
-               return "INTERRUPT";
-       case SFR:
-               return "SFR";
-       case AT:
-               return "AT";
-       case SBIT:
-               return "SBIT";
-       case REENTRANT:
-               return "REENTRANT";
-       case USING:
-               return "USING";
-       case XDATA:
-               return "XDATA";
-       case DATA:
-               return "DATA";
-       case IDATA:
-               return "IDATA";
-       case PDATA:
-               return "PDATA";
-       case VAR_ARGS:
-               return "VAR_ARGS";
-       case CRITICAL:
-               return "CRITICAL";
-       case NONBANKED:
-               return "NONBANKED";
-       case BANKED:
-               return "BANKED";
-       case CHAR:
-               return "CHAR";
-       case SHORT:
-               return "SHORT";
-       case INT:
-               return "INT";
-       case LONG:
-               return "LONG";
-       case SIGNED:
-               return "SIGNED";
-       case UNSIGNED:
-               return "UNSIGNED";
-       case FLOAT:
-               return "FLOAT";
-       case DOUBLE:
-               return "DOUBLE";
-       case CONST:
-               return "CONST";
-       case VOLATILE:
-               return "VOLATILE";
-       case VOID:
-               return "VOID";
-       case BIT:
-               return "BIT";
-       case STRUCT:
-               return "STRUCT";
-       case UNION:
-               return "UNION";
-       case ENUM:
-               return "ENUM";
-       case ELIPSIS:
-               return "ELIPSIS";
-       case RANGE:
-               return "RANGE";
-       case FAR:
-               return "FAR";
-       case CASE:
-               return "CASE";
-       case DEFAULT:
-               return "DEFAULT";
-       case IF:
-               return "IF";
-       case ELSE:
-               return "ELSE";
-       case SWITCH:
-               return "SWITCH";
-       case WHILE:
-               return "WHILE";
-       case DO:
-               return "DO";
-       case FOR:
-               return "FOR";
-       case GOTO:
-               return "GOTO";
-       case CONTINUE:
-               return "CONTINUE";
-       case BREAK:
-               return "BREAK";
-       case RETURN:
-               return "RETURN";
-       case INLINEASM:
-               return "INLINEASM";
-       case IFX:
-               return "IFX";
-       case ADDRESS_OF:
-               return "ADDRESS_OF";
-       case GET_VALUE_AT_ADDRESS:
-               return "GET_VALUE_AT_ADDRESS";
-       case SPIL:
-               return "SPIL";
-       case UNSPIL:
-               return "UNSPIL";
-       case GETHBIT:
-               return "GETHBIT";
-       case BITWISEAND:
-               return "BITWISEAND";
-       case UNARYMINUS:
-               return "UNARYMINUS";
-       case IPUSH:
-               return "IPUSH";
-       case IPOP:
-               return "IPOP";
-       case PCALL:
-               return "PCALL";
-       case ENDFUNCTION:
-               return "ENDFUNCTION";
-       case JUMPTABLE:
-               return "JUMPTABLE";
-       case RRC:
-               return "RRC";
-       case RLC:
-               return "RLC";
-       case CAST:
-               return "CAST";
-       case CALL:
-               return "CALL";
-       case PARAM:
-               return "PARAM  ";
-       case NULLOP:
-               return "NULLOP";
-       case BLOCK:
-               return "BLOCK";
-       case LABEL:
-               return "LABEL";
-       case RECEIVE:
-               return "RECEIVE";
-       case SEND:
-               return "SEND";
+       case IDENTIFIER:                return "IDENTIFIER";
+       case TYPE_NAME:                 return "TYPE_NAME";
+       case CONSTANT:                  return "CONSTANT";
+       case STRING_LITERAL:            return "STRING_LITERAL";
+       case SIZEOF:                    return "SIZEOF";
+       case PTR_OP:                    return "PTR_OP";
+       case INC_OP:                    return "INC_OP";
+       case DEC_OP:                    return "DEC_OP";
+       case LEFT_OP:                   return "LEFT_OP";
+       case RIGHT_OP:                  return "RIGHT_OP";
+       case LE_OP:                     return "LE_OP";
+       case GE_OP:                     return "GE_OP";
+       case EQ_OP:                     return "EQ_OP";
+       case NE_OP:                     return "NE_OP";
+       case AND_OP:                    return "AND_OP";
+       case OR_OP:                     return "OR_OP";
+       case MUL_ASSIGN:                return "MUL_ASSIGN";
+       case DIV_ASSIGN:                return "DIV_ASSIGN";
+       case MOD_ASSIGN:                return "MOD_ASSIGN";
+       case ADD_ASSIGN:                return "ADD_ASSIGN";
+       case SUB_ASSIGN:                return "SUB_ASSIGN";
+       case LEFT_ASSIGN:               return "LEFT_ASSIGN";
+       case RIGHT_ASSIGN:              return "RIGHT_ASSIGN";
+       case AND_ASSIGN:                return "AND_ASSIGN";
+       case XOR_ASSIGN:                return "XOR_ASSIGN";
+       case OR_ASSIGN:                 return "OR_ASSIGN";
+       case TYPEDEF:                   return "TYPEDEF";
+       case EXTERN:                    return "EXTERN";
+       case STATIC:                    return "STATIC";
+       case AUTO:                      return "AUTO";
+       case REGISTER:                  return "REGISTER";
+       case CODE:                      return "CODE";
+       case EEPROM:                    return "EEPROM";
+       case INTERRUPT:                 return "INTERRUPT";
+       case SFR:                       return "SFR";
+       case AT:                        return "AT";
+       case SBIT:                      return "SBIT";
+       case REENTRANT:                 return "REENTRANT";
+       case USING:                     return "USING";
+       case XDATA:                     return "XDATA";
+       case DATA:                      return "DATA";
+       case IDATA:                     return "IDATA";
+       case PDATA:                     return "PDATA";
+       case VAR_ARGS:                  return "VAR_ARGS";
+       case CRITICAL:                  return "CRITICAL";
+       case NONBANKED:                 return "NONBANKED";
+       case BANKED:                    return "BANKED";
+       case CHAR:                      return "CHAR";
+       case SHORT:                     return "SHORT";
+       case INT:                       return "INT";
+       case LONG:                      return "LONG";
+       case SIGNED:                    return "SIGNED";
+       case UNSIGNED:                  return "UNSIGNED";
+       case FLOAT:                     return "FLOAT";
+       case DOUBLE:                    return "DOUBLE";
+       case CONST:                     return "CONST";
+       case VOLATILE:                  return "VOLATILE";
+       case VOID:                      return "VOID";
+       case BIT:                       return "BIT";
+       case STRUCT:                    return "STRUCT";
+       case UNION:                     return "UNION";
+       case ENUM:                      return "ENUM";
+       case ELIPSIS:                   return "ELIPSIS";
+       case RANGE:                     return "RANGE";
+       case FAR:                       return "FAR";
+       case CASE:                      return "CASE";
+       case DEFAULT:                   return "DEFAULT";
+       case IF:                        return "IF";
+       case ELSE:                      return "ELSE";
+       case SWITCH:                    return "SWITCH";
+       case WHILE:                     return "WHILE";
+       case DO:                        return "DO";
+       case FOR:                       return "FOR";
+       case GOTO:                      return "GOTO";
+       case CONTINUE:                  return "CONTINUE";
+       case BREAK:                     return "BREAK";
+       case RETURN:                    return "RETURN";
+       case INLINEASM:                 return "INLINEASM";
+       case IFX:                       return "IFX";
+       case ADDRESS_OF:                return "ADDRESS_OF";
+       case GET_VALUE_AT_ADDRESS:      return "GET_VALUE_AT_ADDRESS";
+       case SPIL:                      return "SPIL";
+       case UNSPIL:                    return "UNSPIL";
+       case GETHBIT:                   return "GETHBIT";
+       case BITWISEAND:                return "BITWISEAND";
+       case UNARYMINUS:                return "UNARYMINUS";
+       case IPUSH:                     return "IPUSH";
+       case IPOP:                      return "IPOP";
+       case PCALL:                     return "PCALL";
+       case ENDFUNCTION:               return "ENDFUNCTION";
+       case JUMPTABLE:                 return "JUMPTABLE";
+       case RRC:                       return "RRC";
+       case RLC:                       return "RLC";
+       case CAST:                      return "CAST";
+       case CALL:                      return "CALL";
+       case PARAM:                     return "PARAM  ";
+       case NULLOP:                    return "NULLOP";
+       case BLOCK:                     return "BLOCK";
+       case LABEL:                     return "LABEL";
+       case RECEIVE:                   return "RECEIVE";
+       case SEND:                      return "SEND";
        }
        sprintf (buffer, "unknown op %d %c", op, op & 0xff);
        return buffer;
@@ -407,12 +306,9 @@ debugLogRegType (short type)
        
        switch (type)
        {
-       case REG_GPR:
-               return "REG_GPR";
-       case REG_PTR:
-               return "REG_PTR";
-       case REG_CND:
-               return "REG_CND";
+       case REG_GPR:   return "REG_GPR";
+       case REG_PTR:   return "REG_PTR";
+       case REG_CND:   return "REG_CND";
        }
        
        sprintf (buffer, "unknown reg type %d", type);
@@ -456,7 +352,6 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i
                sprintf(buffer,"r0x%02X", dReg->rIdx);
                dReg->name = Safe_strdup(buffer);
        }
-       //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx);
        dReg->isFree = 0;
        dReg->wasUsed = 1;
        if (type == REG_SFR)
@@ -628,12 +523,20 @@ allocInternalRegister(int rIdx, char * name, short po_type, int alias)
 static regs *
 allocReg (short type)
 {
+       regs *reg;
        
        debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type));
        //fprintf(stderr,"allocReg\n");
        
+       reg = pic14_findFreeReg (type);
+
+       reg->isFree = 0;
+       reg->wasUsed = 1;
+
+       return reg;
        
-       return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
+       
+       //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0));
        
 }
 
@@ -1998,7 +1901,7 @@ tryAgain:
                        if (sym->regs[j])
                                sym->regs[j]->isFree = 0;
                        
-                               /* this looks like an infinite loop but 
+                       /* this looks like an infinite loop but 
                        in really selectSpil will abort  */
                        goto tryAgain;
 }
@@ -2039,6 +1942,13 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                /* if it does not end here */
                if (sym->liveTo > ic->seq)
                        continue;
+       
+               /* HACK: result and addr must be disjoint for POINTER_GET */
+               if (sym->liveTo == ic->seq && POINTER_GET(ic))
+               {
+                       //piCode (ic, stderr); fprintf (stderr, " -- registers NOT deallocated\n");
+                       continue;
+               }
                
                /* if it was spilt on stack then we can 
                mark the stack spil location as free */
@@ -2054,7 +1964,6 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                
                if (!bitVectBitValue (_G.regAssigned, sym->key))
                        continue;
-               
                /* special case check if this is an IFX &
                the privious one was a pop and the 
                previous one was not spilt then keep track
@@ -2062,6 +1971,7 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                if (ic->op == IFX && ic->prev &&
                        ic->prev->op == IPOP &&
                        !ic->prev->parmPush &&
+                       IS_SYMOP(IC_LEFT (ic->prev)) &&
                        !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt)
                        psym = OP_SYMBOL (IC_LEFT (ic->prev));
                
@@ -2082,6 +1992,7 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                                ic->op == IPOP ||
                                ic->op == RETURN ||
                                POINTER_SET (ic)) &&
+                               IS_SYMOP (IC_RESULT (ic)) &&
                                (result = OP_SYMBOL (IC_RESULT (ic))) &&        /* has a result */
                                result->liveTo > ic->seq &&     /* and will live beyond this */
                                result->liveTo <= ebp->lSeq &&  /* does not go beyond this block */
@@ -2108,7 +2019,7 @@ deassignLRs (iCode * ic, eBBlock * ebp)
                                        _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key);
                                        
                        }
-                       
+
                        /* free the remaining */
                        for (; i < sym->nRegs; i++)
                        {
@@ -2273,7 +2184,6 @@ serialRegAssign (eBBlock ** ebbs, int count)
                /* of all instructions do */
                for (ic = ebbs[i]->sch; ic; ic = ic->next)
                {
-                       
                        debugLog ("  op: %s\n", decodeOp (ic->op));
                        
                        /* if this is an ipop that means some live
@@ -2301,7 +2211,7 @@ serialRegAssign (eBBlock ** ebbs, int count)
                        
                        /* now we need to allocate registers
                        only for the result */
-                       if (IC_RESULT (ic))
+                       if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)))
                        {
                                symbol *sym = OP_SYMBOL (IC_RESULT (ic));
                                bitVect *spillable;
@@ -2387,8 +2297,10 @@ serialRegAssign (eBBlock ** ebbs, int count)
                                
                                /* if we need ptr regs for the right side
                                then mark it */
-                               if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
-                                       <= (unsigned) PTRSIZE)
+                               if (POINTER_GET (ic)
+                                       && IS_SYMOP(IC_LEFT(ic))
+                                       && getSize (OP_SYMBOL (IC_LEFT (ic))->type)
+                                               <= (unsigned) PTRSIZE)
                                {
                                        pic14_ptrRegReq++;
                                        ptrRegSet = 1;
@@ -2416,11 +2328,13 @@ serialRegAssign (eBBlock ** ebbs, int count)
                                /* if it shares registers with operands make sure
                                that they are in the same position */
                                if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) &&
+                                       IS_SYMOP(IC_RESULT(ic)) &&
                                        OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=')
                                        positionRegs (OP_SYMBOL (IC_RESULT (ic)),
                                        OP_SYMBOL (IC_LEFT (ic)), ic->lineno);
                                /* do the same for the right operand */
                                if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) &&
+                                       IS_SYMOP(IC_RESULT(ic)) &&
                                        OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=')
                                        positionRegs (OP_SYMBOL (IC_RESULT (ic)),
                                        OP_SYMBOL (IC_RIGHT (ic)), ic->lineno);
@@ -3918,13 +3832,13 @@ packRegisters (eBBlock * ebp)
                }
                
                /* mark the pointer usages */
-               if (POINTER_SET (ic))
+               if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic)))
                {
                        OP_SYMBOL (IC_RESULT (ic))->uptr = 1;
                        debugLog ("  marking as a pointer (set) =>");
                        debugAopGet ("  result:", IC_RESULT (ic));
                }
-               if (POINTER_GET (ic))
+               if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic)))
                {
                        OP_SYMBOL (IC_LEFT (ic))->uptr = 1;
                        debugLog ("  marking as a pointer (get) =>");
@@ -3996,6 +3910,7 @@ packRegisters (eBBlock * ebp)
                one and right is not in far space */
                if (POINTER_SET (ic) &&
                        !isOperandInFarSpace (IC_RIGHT (ic)) &&
+                       IS_SYMOP(IC_RESULT(ic)) &&
                        !OP_SYMBOL (IC_RESULT (ic))->remat &&
                        !IS_OP_RUONLY (IC_RIGHT (ic)) &&
                        getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1)
@@ -4005,6 +3920,7 @@ packRegisters (eBBlock * ebp)
                /* if pointer get */
                if (POINTER_GET (ic) &&
                        !isOperandInFarSpace (IC_RESULT (ic)) &&
+                       IS_SYMOP(IC_LEFT(ic)) &&
                        !OP_SYMBOL (IC_LEFT (ic))->remat &&
                        !IS_OP_RUONLY (IC_RESULT (ic)) &&
                        getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1)