Added more regression test to the pic port. Added support for <<, >>, ^
authorsdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 30 Sep 2001 03:53:13 +0000 (03:53 +0000)
committersdattalo <sdattalo@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 30 Sep 2001 03:53:13 +0000 (03:53 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1329 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/pic/gen.c
src/pic/gen.h
src/pic/pcode.c
src/pic/pcode.h
src/pic/pcodepeep.c
src/regression/Makefile
src/regression/compare3.c
src/regression/rotate1.c [new file with mode: 0644]
src/regression/rotate2.c [new file with mode: 0644]
src/regression/rotate3.c [new file with mode: 0644]
src/regression/xor.c [new file with mode: 0644]

index 42b0b3756937ea079081612d3e75c9726d30055e..265e9fc0a6d9cb73ff883477711c0062e481f31c 100644 (file)
@@ -61,6 +61,7 @@
 
 static int labelOffset=0;
 static int debug_verbose=1;
+static int optimized_for_speed = 0;
 
 unsigned int pic14aopLiteral (value *val, int offset);
 
@@ -611,10 +612,10 @@ void aopOp (operand *op, iCode *ic, bool result)
     DEBUGpic14_emitcode(";","%d",__LINE__);
     /* if this a literal */
     if (IS_OP_LITERAL(op)) {
-      DEBUGpic14_emitcode(";","%d",__LINE__);
         op->aop = aop = newAsmop(AOP_LIT);
         aop->aopu.aop_lit = op->operand.valOperand;
         aop->size = getSize(operandType(op));
+      DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit);
         return;
     }
 
@@ -631,7 +632,7 @@ void aopOp (operand *op, iCode *ic, bool result)
 
     /* if this is a true symbol */
     if (IS_TRUE_SYMOP(op)) {    
-      DEBUGpic14_emitcode(";","%d",__LINE__);
+      DEBUGpic14_emitcode(";","%d - true symop",__LINE__);
         op->aop = aopForSym(ic,OP_SYMBOL(op),result);
         return ;
     }
@@ -973,7 +974,7 @@ pCodeOp *popCopyReg(pCodeOpReg *pc)
 
   pcor = Safe_calloc(1,sizeof(pCodeOpReg) );
   pcor->pcop.type = pc->pcop.type;
-  if(!(pcor->pcop.name = strdup(pc->pcop.name)))
+  if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name)))
     fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
   pcor->r = pc->r;
   pcor->rIdx = pc->rIdx;
@@ -985,13 +986,13 @@ pCodeOp *popCopyReg(pCodeOpReg *pc)
 /*-----------------------------------------------------------------*/
 /* popCopy - copy a pcode operator                                 */
 /*-----------------------------------------------------------------*/
-pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval)
+pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval)
 {
   pCodeOp *pcop;
 
   pcop = Safe_calloc(1,sizeof(pCodeOpBit) );
   pcop->type = PO_BIT;
-  if(!(pcop->name = strdup(pc->pcop.name)))
+  if(!(pcop->name = Safe_strdup(pc->name)))
     fprintf(stderr,"oops %s %d",__FILE__,__LINE__);
   ((pCodeOpBit *)pcop)->bit = bitval;
 
@@ -1117,8 +1118,11 @@ pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
        int rIdx = aop->aopu.aop_reg[offset]->rIdx;
 
        DEBUGpic14_emitcode(";","%d",__LINE__);
-       pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
-       pcop->type = PO_GPR_REGISTER;
+       if(bit16)
+         pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) );
+       else
+         pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+       //pcop->type = PO_GPR_REGISTER;
        PCOR(pcop)->rIdx = rIdx;
        PCOR(pcop)->r = pic14_regWithIdx(rIdx);
        pcop->type = PCOR(pcop)->r->pc_type;
@@ -1134,7 +1138,7 @@ pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname)
       }
 
     case AOP_CRY:
-      pcop = newpCodeOpBit(aop->aopu.aop_dir,0);
+      pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
       return pcop;
        
     case AOP_LIT:
@@ -2738,9 +2742,11 @@ static void genRet (iCode *ic)
        /* generate a jump to the return label
           if the next is not the return statement */
     if (!(ic->next && ic->next->op == LABEL &&
-         IC_LABEL(ic->next) == returnLabel))
+         IC_LABEL(ic->next) == returnLabel)) {
        
+       emitpcode(POC_GOTO,popGetLabel(returnLabel->key));
        pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset);
+    }
     
 }
 
@@ -2764,7 +2770,8 @@ static void genLabel (iCode *ic)
 //tsd
 static void genGoto (iCode *ic)
 {
-    pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
+  emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key));
+  pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset);
 }
 
 /*-----------------------------------------------------------------*/
@@ -3217,6 +3224,9 @@ release :
 /*-----------------------------------------------------------------*/
 /* genIfxJump :- will create a jump depending on the ifx           */
 /*-----------------------------------------------------------------*/
+/*
+  note: May need to add parameter to indicate when a variable is in bit space.
+*/
 static void genIfxJump (iCode *ic, char *jval)
 {
 
@@ -3230,11 +3240,8 @@ static void genIfxJump (iCode *ic, char *jval)
        else if (strcmp(jval,"c") == 0)
          emitSKPC;
        else {
-         //pCodeOp *p = popGetWithString(jval);
-         //p->type = PO_BIT;
-         //emitpcode(POC_BTFSC,  p);
-         emitpcode(POC_BTFSC,  newpCodeOpBit(jval,0));
-       //pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",jval,jval);
+         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
+         emitpcode(POC_BTFSC,  newpCodeOpBit(jval,-1,1));
        }
 
        emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
@@ -3248,12 +3255,8 @@ static void genIfxJump (iCode *ic, char *jval)
        else if (strcmp(jval,"c") == 0)
          emitSKPNC;
        else {
-         //pCodeOp *p = popGetWithString(jval);
-         //p->type = PO_BIT;
-         //emitpcode(POC_BTFSS,  p);
-         emitpcode(POC_BTFSS,  newpCodeOpBit(jval,0));
-
-       //        pic14_emitcode("btfss","(%s >> 3),(%s & 7)",jval,jval);
+         DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval);         
+         emitpcode(POC_BTFSS,  newpCodeOpBit(jval,-1,1));
        }
 
        emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
@@ -4192,7 +4195,7 @@ static void genAnd (iCode *ic, iCode *ifx)
     int size, offset=0;  
     unsigned long lit = 0L;
     int bytelit = 0;
-    char buffer[10];
+    //    char buffer[10];
 
     DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     aopOp((left = IC_LEFT(ic)),ic,FALSE);
@@ -4288,19 +4291,29 @@ static void genAnd (iCode *ic, iCode *ifx)
         int posbit = isLiteralBit(lit);
         /* left &  2^n */
         if(posbit){
-            posbit--;
-            MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
+         posbit--;
+         //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE));
             // bit = left & 2^n
-            if(size)
-                pic14_emitcode("mov","c,acc.%d",posbit&0x07);
+         if(size)
+           pic14_emitcode("mov","c,acc.%d",posbit&0x07);
             // if(left &  2^n)
-            else{
-                if(ifx){
-                    sprintf(buffer,"acc.%d",posbit&0x07);
-                    genIfxJump(ifx, buffer);
-                }
-                goto release;
-            }
+         else{
+           if(ifx){
+             pCodeOp *pcorb = popGet(AOP(left),0,TRUE,FALSE);
+             PCORB(pcorb)->subtype = PCOP(pcorb)->type;
+             PCOP(pcorb)->type = PO_GPR_BIT;
+             PCORB(pcorb)->bit = posbit;
+             if(IC_TRUE(ifx)) {
+               emitpcode(POC_BTFSC, pcorb); 
+               emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key));
+             } else {
+               emitpcode(POC_BTFSS, pcorb); 
+               emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key));
+             }
+             ifx->generated = 1;
+           }
+           goto release;
+         }
         } else {
             symbol *tlbl = newiTempLabel(NULL);
             int sizel = AOP_SIZE(left);
@@ -4345,9 +4358,11 @@ static void genAnd (iCode *ic, iCode *ifx)
          case 0x00:
            /*  and'ing with 0 has clears the result */
            pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
+           emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
            break;
          case 0xff:
            pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
+           emitpcode(POC_MOVWF,popGet(AOP(right),offset,FALSE,FALSE));
            break;
 
          default:
@@ -4356,18 +4371,25 @@ static void genAnd (iCode *ic, iCode *ifx)
              if(p>=0) {
                /* only one bit is set in the literal, so use a bcf instruction */
                pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p);
+               emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE));
              } else {
                pic14_emitcode("movlw","0x%x", (lit & 0xff));
-               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p);
+               pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
+               emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
+               emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE));
              }
            }    
          }
        } else {
-         if (AOP_TYPE(left) == AOP_ACC) 
-           pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-         else {                    
+         if (AOP_TYPE(left) == AOP_ACC) {
+           pic14_emitcode("?iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
+           emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
+
+         } else {                  
            pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
+           pic14_emitcode("?iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE));
+           emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
+           emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
 
          }
        }
@@ -4406,12 +4428,15 @@ static void genAnd (iCode *ic, iCode *ifx)
              case 0x00:
                pic14_emitcode("clrf","%s",
                         aopGet(AOP(result),offset,FALSE,FALSE));
+               emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE));
                break;
              case 0xff:
                pic14_emitcode("movf","%s,w",
                         aopGet(AOP(left),offset,FALSE,FALSE));
                pic14_emitcode("movwf","%s",
                         aopGet(AOP(result),offset,FALSE,FALSE));
+               emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
+               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
                break;
              default:
                pic14_emitcode("movlw","0x%x",t);
@@ -4420,18 +4445,25 @@ static void genAnd (iCode *ic, iCode *ifx)
                pic14_emitcode("movwf","%s",
                         aopGet(AOP(result),offset,FALSE,FALSE));
              
+               emitpcode(POC_MOVLW, popGetLit(t));
+               emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
+               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
              }
              continue;
            }
 
-           if (AOP_TYPE(left) == AOP_ACC) 
+           if (AOP_TYPE(left) == AOP_ACC) {
              pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           else {
+             emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE));
+           } else {
              pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
              pic14_emitcode("andwf","%s,w",
                       aopGet(AOP(left),offset,FALSE,FALSE));
+             emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
+             emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE));
            }
            pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
+           emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
          }
        }
     }
@@ -4842,17 +4874,21 @@ static void genXor (iCode *ic, iCode *ifx)
         /* if left is same as result */
         for(;size--; offset++) {
             if(AOP_TYPE(right) == AOP_LIT){
-                if(((lit >> (offset*8)) & 0x0FFL) == 0x00L)
+             int t  = (lit >> (offset*8)) & 0x0FFL;
+                if(t == 0x00L)
                     continue;
                 else
                    if (IS_AOP_PREG(left)) {
                        MOVA(aopGet(AOP(right),offset,FALSE,FALSE));
                        pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE));
                        aopPut(AOP(result),"a",offset);
-                   } else 
-                       pic14_emitcode("xrl","%s,%s",
-                                aopGet(AOP(left),offset,FALSE,TRUE),
-                                aopGet(AOP(right),offset,FALSE,FALSE));
+                   } else {
+                     emitpcode(POC_MOVLW, popGetLit(t));
+                     emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE));
+                     pic14_emitcode("xrl","%s,%s",
+                                    aopGet(AOP(left),offset,FALSE,TRUE),
+                                    aopGet(AOP(right),offset,FALSE,FALSE));
+                   }
             } else {
                if (AOP_TYPE(left) == AOP_ACC)
                    pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE));
@@ -4902,18 +4938,25 @@ static void genXor (iCode *ic, iCode *ifx)
              int t = (lit >> (offset*8)) & 0x0FFL;
              switch(t) { 
              case 0x00:
+               emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE));
+               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
                pic14_emitcode("movf","%s,w",
                         aopGet(AOP(left),offset,FALSE,FALSE));
                pic14_emitcode("movwf","%s",
                         aopGet(AOP(result),offset,FALSE,FALSE));
                break;
              case 0xff:
+               emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE));
+               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
                pic14_emitcode("comf","%s,w",
                         aopGet(AOP(left),offset,FALSE,FALSE));
                pic14_emitcode("movwf","%s",
                         aopGet(AOP(result),offset,FALSE,FALSE));
                break;
              default:
+               emitpcode(POC_MOVLW, popGetLit(t));
+               emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
+               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
                pic14_emitcode("movlw","0x%x",t);
                pic14_emitcode("xorwf","%s,w",
                         aopGet(AOP(left),offset,FALSE,FALSE));
@@ -4926,14 +4969,19 @@ static void genXor (iCode *ic, iCode *ifx)
 
             // faster than result <- left, anl result,right
             // and better if result is SFR
-           if (AOP_TYPE(left) == AOP_ACC)
+           if (AOP_TYPE(left) == AOP_ACC) {
+               emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE));
                pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
-           else {
+           } else {
+               emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE));
+               emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE));
                pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE));
                pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE));
            }
-           if ( AOP_TYPE(result) != AOP_ACC)
+           if ( AOP_TYPE(result) != AOP_ACC){
+               emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE));
              pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE));
+           }
         }
     }
 
@@ -5171,6 +5219,7 @@ static void AccRsh (int shCount)
     }
 }
 
+#if 0
 /*-----------------------------------------------------------------*/
 /* AccSRsh - signed right shift accumulator by known count                 */
 /*-----------------------------------------------------------------*/
@@ -5200,6 +5249,36 @@ static void AccSRsh (int shCount)
         }
     }
 }
+#endif
+/*-----------------------------------------------------------------*/
+/* shiftR1Left2Result - shift right one byte from left to result   */
+/*-----------------------------------------------------------------*/
+static void shiftR1Left2ResultSigned (operand *left, int offl,
+                                operand *result, int offr,
+                                int shCount)
+{
+  int same;
+
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+  same = (left == result) || (AOP(left) == AOP(result));
+
+  switch(shCount) {
+  case 1:
+    emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
+    if(same) 
+      emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
+    else {
+      emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
+      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+    }
+
+    break;
+
+  default:
+    break;
+  }
+}
 
 /*-----------------------------------------------------------------*/
 /* shiftR1Left2Result - shift right one byte from left to result   */
@@ -5208,14 +5287,103 @@ static void shiftR1Left2Result (operand *left, int offl,
                                 operand *result, int offr,
                                 int shCount, int sign)
 {
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-    /* shift right accumulator */
-    if(sign)
-        AccSRsh(shCount);
-    else
-        AccRsh(shCount);
-    aopPut(AOP(result),"a",offr);
+  int same;
+
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+  same = (left == result) || (AOP(left) == AOP(result));
+
+  /* Copy the msb into the carry if signed. */
+  if(sign) {
+    shiftR1Left2ResultSigned(left,offl,result,offr,shCount);
+    return;
+  }
+
+
+
+  switch(shCount) {
+  case 1:
+    emitCLRC;
+    if(same) 
+      emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
+    else {
+      emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
+      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+    }
+    break;
+  case 2:
+    emitCLRC;
+    if(same) {
+      emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
+    } else {
+      emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
+      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+    }
+    emitCLRC;
+    emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
+
+    break;
+  case 3:
+    if(same) 
+      emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
+    else {
+      emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
+      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+    }
+
+    emitpcode(POC_RLFW,  popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_RLFW,  popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_ANDLW, popGetLit(0x1f));
+    emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+    break;
+      
+  case 4:
+    emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
+    emitpcode(POC_ANDLW, popGetLit(0x1f));
+    emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+    break;
+
+  case 5:
+    emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE));
+    emitpcode(POC_ANDLW, popGetLit(0x1f));
+    emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+    emitCLRC;
+    emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
+
+    break;
+  case 6:
+
+    emitpcode(POC_RLFW,  popGet(AOP(left),offr,FALSE,FALSE));
+    emitpcode(POC_ANDLW, popGetLit(0x80));
+    emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_RLF,   popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_RLF,   popGet(AOP(result),offr,FALSE,FALSE));
+    break;
+
+  case 7:
+
+    emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
+    emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
+
+    break;
+
+  default:
+    break;
+  }
+
+
+#if 0
+    
+  MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+
+  /* shift right accumulator */
+  if(sign)
+    AccSRsh(shCount);
+  else
+    AccRsh(shCount);
+  aopPut(AOP(result),"a",offr);
+#endif
 }
 
 /*-----------------------------------------------------------------*/
@@ -5224,13 +5392,71 @@ static void shiftR1Left2Result (operand *left, int offl,
 static void shiftL1Left2Result (operand *left, int offl,
                                 operand *result, int offr, int shCount)
 {
-    char *l;
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    l = aopGet(AOP(left),offl,FALSE,FALSE);
-    MOVA(l);
+  int same;
+
+  //    char *l;
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+  same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr);
+  DEBUGpic14_emitcode ("; ***","same =  %d",same);
+    //    l = aopGet(AOP(left),offl,FALSE,FALSE);
+    //    MOVA(l);
     /* shift left accumulator */
-    AccLsh(shCount);
-    aopPut(AOP(result),"a",offr);
+    //AccLsh(shCount); // don't comment out just yet...
+  //    aopPut(AOP(result),"a",offr);
+
+  switch(shCount) {
+  case 1:
+    /* Shift left 1 bit position */
+    emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
+    if(same) {
+      emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE));
+    } else {
+      emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE));
+      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+    }
+    break;
+  case 2:
+    emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
+    emitpcode(POC_ANDLW,popGetLit(0x7e));
+    emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
+    break;
+  case 3:
+    emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE));
+    emitpcode(POC_ANDLW,popGetLit(0x3e));
+    emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
+    break;
+  case 4:
+    emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
+    emitpcode(POC_ANDLW, popGetLit(0xf0));
+    emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
+    break;
+  case 5:
+    emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
+    emitpcode(POC_ANDLW, popGetLit(0xf0));
+    emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
+    break;
+  case 6:
+    emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
+    emitpcode(POC_ANDLW, popGetLit(0x30));
+    emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_RLF,  popGet(AOP(result),offr,FALSE,FALSE));
+    break;
+  case 7:
+    emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
+    emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
+    emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
+    break;
+
+  default:
+    DEBUGpic14_emitcode ("; ***","%s  %d, shift count is %d",__FUNCTION__,__LINE__,shCount);
+  }
+
 }
 
 /*-----------------------------------------------------------------*/
@@ -5248,9 +5474,12 @@ static void movLeft2Result (operand *left, int offl,
             pic14_emitcode("mov","a,%s",l);
             aopPut(AOP(result),"a",offr);
         } else {
-            if(!sign)
-                aopPut(AOP(result),l,offr);
-            else{
+         if(!sign) {
+           emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
+           emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+
+           //aopPut(AOP(result),l,offr);
+         }else{
                 /* MSB sign in acc.7 ! */
                 if(pic14_getDataSize(left) == offl+1){
                     pic14_emitcode("mov","a,%s",l);
@@ -5284,7 +5513,7 @@ static void AccAXLrl1 (char *x)
     pic14_emitcode("xch","a,%s",x);
     pic14_emitcode("rlc","a");
 }
-
+#if 0
 /*-----------------------------------------------------------------*/
 /* AccAXLsh1 - left shift a:x<-0 by 1                              */
 /*-----------------------------------------------------------------*/
@@ -5296,7 +5525,8 @@ static void AccAXLsh1 (char *x)
     pic14_emitcode("xch","a,%s",x);
     pic14_emitcode("rlc","a");
 }
-
+#endif
+#if 0
 /*-----------------------------------------------------------------*/
 /* AccAXLsh - left shift a:x by known count (0..7)                 */
 /*-----------------------------------------------------------------*/
@@ -5348,7 +5578,7 @@ static void AccAXLsh (char *x, int shCount)
             break;
     }
 }
-
+#endif
 /*-----------------------------------------------------------------*/
 /* AccAXRsh - right shift a:x known count (0..7)                   */
 /*-----------------------------------------------------------------*/
@@ -5481,22 +5711,129 @@ static void AccAXRshS (char *x, int shCount)
 static void shiftL2Left2Result (operand *left, int offl,
                                 operand *result, int offr, int shCount)
 {
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if(pic14_sameRegs(AOP(result), AOP(left)) &&
-       ((offl + MSB16) == offr)){
-       /* don't crash result[offr] */
-       MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-       pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
-    } else {
-       movLeft2Result(left,offl, result, offr, 0);
-       MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
+
+
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+  if(pic14_sameRegs(AOP(result), AOP(left))) {
+    switch(shCount) {
+    case 0:
+      break;
+    case 1:
+    case 2:
+    case 3:
+
+      emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_RLF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+
+      while(--shCount) {
+       emitCLRC;
+       emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
+       emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      }
+
+      break;
+    case 4:
+    case 5:
+      emitpcode(POC_MOVLW, popGetLit(0x0f));
+      emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      if(shCount >=5) {
+       emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
+       emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      }
+      break;
+    case 6:
+      emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_ANDLW,popGetLit(0xc0));
+      emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      break;
+    case 7:
+      emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
     }
-    /* ax << shCount (x = lsb(result))*/
-    AccAXLsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
-    aopPut(AOP(result),"a",offr+MSB16);
-}
 
+  } else {
+    switch(shCount) {
+    case 0:
+      break;
+    case 1:
+    case 2:
+      /* note, use a mov/add for the shift since the mov has a
+        chance of getting optimized out */
+      emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE));
+      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_RLFW,  popGet(AOP(left),offl+MSB16,FALSE,FALSE));
+      emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+
+      while(--shCount) {
+       emitCLRC;
+       emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
+       emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      }
+      break;
+    case 3:
+    case 4:
+    case 5:
+      emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE));
+      emitpcode(POC_ANDLW, popGetLit(0xF0));
+      emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE));
+      emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_ANDLW, popGetLit(0xF0));
+      emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+
+      if(shCount == 3) {
+       emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+       emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE));
+      }
+      if(shCount == 5) {
+       emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE));
+       emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      }
+      break;
+    case 6:
+      emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
+      emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE));
+      emitpcode(POC_MOVWF,  popGet(AOP(result),offr,FALSE,FALSE));
+
+      emitpcode(POC_RRF,  popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_ANDLW,popGetLit(0xc0));
+      emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      break;
+    case 7:
+      emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE));
+      emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE));
+      emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE));
+      emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE));
+      emitpcode(POC_RRF,  popGet(AOP(result),offr,FALSE,FALSE));
+    }
+  }
 
+}
 /*-----------------------------------------------------------------*/
 /* shiftR2Left2Result - shift right two bytes from left to result  */
 /*-----------------------------------------------------------------*/
@@ -5504,23 +5841,30 @@ static void shiftR2Left2Result (operand *left, int offl,
                                 operand *result, int offr,
                                 int shCount, int sign)
 {
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    if(pic14_sameRegs(AOP(result), AOP(left)) &&
-       ((offl + MSB16) == offr)){
-       /* don't crash result[offr] */
-       MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
-       pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
-    } else {
-       movLeft2Result(left,offl, result, offr, 0);
-       MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
-    }
-    /* a:x >> shCount (x = lsb(result))*/
-    if(sign)
-        AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
-    else
-        AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
+  int same=0;
+
+  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+  if(pic14_sameRegs(AOP(result), AOP(left)) &&
+     ((offl + MSB16) == offr)){
+    same=1;
+    /* don't crash result[offr] */
+    MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+    pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
+  } else {
+    movLeft2Result(left,offl, result, offr, 0);
+    MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE));
+  }
+  /* a:x >> shCount (x = lsb(result))*/
+  if(sign)
+    AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
+  else {
+      //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount);
+    
+    //    switch() {
+    //}
     if(pic14_getDataSize(result) > 1)
-        aopPut(AOP(result),"a",offr+MSB16);
+      aopPut(AOP(result),"a",offr+MSB16);
+  }
 }
 
 /*-----------------------------------------------------------------*/
@@ -5584,7 +5928,7 @@ static void genlshTwo (operand *result,operand *left, int shCount)
             else 
                 movLeft2Result(left, LSB, result, MSB16, 0);
         }
-        aopPut(AOP(result),zero,LSB);   
+       emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
     }
 
     /*  1 <= shCount <= 7 */
@@ -5826,9 +6170,7 @@ static void genLeftShift (iCode *ic)
     more that 32 bits make no sense anyway, ( the
     largest size of an object can be only 32 bits ) */  
 
-    pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
-    pic14_emitcode("inc","b");
-    freeAsmop (right,NULL,ic,TRUE);
+    
     aopOp(left,ic,FALSE);
     aopOp(result,ic,FALSE);
 
@@ -5851,26 +6193,47 @@ static void genLeftShift (iCode *ic)
         }
     }
 
-    tlbl = newiTempLabel(NULL);
     size = AOP_SIZE(result);
-    offset = 0 ;   
-    tlbl1 = newiTempLabel(NULL);
 
     /* if it is only one byte then */
     if (size == 1) {
-       symbol *tlbl1 = newiTempLabel(NULL);
+      if(optimized_for_speed) {
+       emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE));
+       emitpcode(POC_ANDLW,  popGetLit(0xf0));
+       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0));
+       emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
+       emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
+       emitpcode(POC_BTFSS,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0));
+       emitpcode(POC_ADDWF,  popGet(AOP(result),0,FALSE,FALSE));
+       emitpcode(POC_RLFW,   popGet(AOP(result),0,FALSE,FALSE));
+       emitpcode(POC_ANDLW,  popGetLit(0xfe));
+       emitpcode(POC_ADDFW,  popGet(AOP(result),0,FALSE,FALSE));
+       emitpcode(POC_BTFSC,  newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0));
+       emitpcode(POC_ADDWF,  popGet(AOP(result),0,FALSE,FALSE));
+      } else {
+
+       tlbl = newiTempLabel(NULL);
+       if (!pic14_sameRegs(AOP(left),AOP(result))) {
+         emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
+         emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
+       }
 
-        l = aopGet(AOP(left),0,FALSE,FALSE);
-        MOVA(l);
-       pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
-        pic14_emitcode("","%05d_DS_:",tlbl->key+100);
-        pic14_emitcode("add","a,acc");
-       pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
-        pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);      
-        aopPut(AOP(result),"a",0);
-        goto release ;
+       emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
+       emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
+       emitpLabel(tlbl->key+100+labelOffset);
+       emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
+       emitpcode(POC_ADDLW,  popGetLit(1));
+       emitSKPC;
+       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
+      }
+      goto release ;
     }
     
+
+    tlbl = newiTempLabel(NULL);
+    offset = 0 ;   
+    tlbl1 = newiTempLabel(NULL);
+
     reAdjustPreg(AOP(result));    
     
     pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); 
@@ -5890,6 +6253,7 @@ static void genLeftShift (iCode *ic)
     pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
     pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
 release:
+    freeAsmop (right,NULL,ic,TRUE);
     freeAsmop(left,NULL,ic,TRUE);
     freeAsmop(result,NULL,ic,TRUE);
 }
@@ -6226,7 +6590,6 @@ static void genRightShift (iCode *ic)
 
     pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
     pic14_emitcode("inc","b");
-    freeAsmop (right,NULL,ic,TRUE);
     aopOp(left,ic,FALSE);
     aopOp(result,ic,FALSE);
 
@@ -6256,6 +6619,7 @@ static void genRightShift (iCode *ic)
 
     /* if it is only one byte then */
     if (size == 1) {
+/*
         l = aopGet(AOP(left),0,FALSE,FALSE);
         MOVA(l);
        pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100);
@@ -6265,6 +6629,21 @@ static void genRightShift (iCode *ic)
        pic14_emitcode("","%05d_DS_:",tlbl1->key+100);
         pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100);
         aopPut(AOP(result),"a",0);
+*/
+       tlbl = newiTempLabel(NULL);
+       if (!pic14_sameRegs(AOP(left),AOP(result))) {
+         emitpcode(POC_MOVFW,  popGet(AOP(left),0,FALSE,FALSE));
+         emitpcode(POC_MOVWF,  popGet(AOP(result),0,FALSE,FALSE));
+       }
+
+       emitpcode(POC_COMFW,  popGet(AOP(right),0,FALSE,FALSE));
+       emitpcode(POC_RLF,    popGet(AOP(result),0,FALSE,FALSE));
+       emitpLabel(tlbl->key+100+labelOffset);
+       emitpcode(POC_RRF,    popGet(AOP(result),0,FALSE,FALSE));
+       emitpcode(POC_ADDLW,  popGetLit(1));
+       emitSKPC;
+       emitpcode(POC_GOTO,popGetLabel(tlbl->key));
+
         goto release ;
     }
 
@@ -6285,6 +6664,7 @@ static void genRightShift (iCode *ic)
 
 release:
     freeAsmop(left,NULL,ic,TRUE);
+    freeAsmop (right,NULL,ic,TRUE);
     freeAsmop(result,NULL,ic,TRUE);
 }
 
@@ -7724,16 +8104,28 @@ static void genJumpTab (iCode *ic)
     /* multiply by three */
     pic14_emitcode("add","a,acc");
     pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
-    freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
 
     jtab = newiTempLabel(NULL);
     pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100);
     pic14_emitcode("jmp","@a+dptr");
     pic14_emitcode("","%05d_DS_:",jtab->key+100);
+
+    emitpcode(POC_MOVLW, popGetLabel(jtab->key));
+    emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE));
+    emitSKPNC;
+    emitpcode(POC_INCF, popCopyReg(&pc_pclath));
+    emitpcode(POC_MOVWF, popCopyReg(&pc_pcl));
+    emitpLabel(jtab->key+100+labelOffset);
+
+    freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE);
+
     /* now generate the jump labels */
     for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab;
-         jtab = setNextItem(IC_JTLABELS(ic)))
+         jtab = setNextItem(IC_JTLABELS(ic))) {
         pic14_emitcode("ljmp","%05d_DS_",jtab->key+100);
+       emitpcode(POC_GOTO,popGetLabel(jtab->key));
+       
+    }
 
 }
 
index 3bb90fbed996ac4d53ef8b548b2cc5a3cca00331..8a17d33b57b799f9aafcb2b593526ed12e95ef1d 100644 (file)
@@ -119,18 +119,18 @@ extern unsigned fReturnSizePic;
 /* Macros for emitting skip instructions                           */
 /*-----------------------------------------------------------------*/
 
-#define emitSKPC    emitpcode(POC_BTFSS,popCopyGPR2Bit(&pc_status,PIC_C_BIT))
-#define emitSKPNC   emitpcode(POC_BTFSC,popCopyGPR2Bit(&pc_status,PIC_C_BIT))
-#define emitSKPZ    emitpcode(POC_BTFSS,popCopyGPR2Bit(&pc_status,PIC_Z_BIT))
-#define emitSKPNZ   emitpcode(POC_BTFSC,popCopyGPR2Bit(&pc_status,PIC_Z_BIT))
-#define emitSKPDC   emitpcode(POC_BTFSS,popCopyGPR2Bit(&pc_status,PIC_DC_BIT))
-#define emitSKPNDC  emitpcode(POC_BTFSC,popCopyGPR2Bit(&pc_status,PIC_DC_BIT))
-#define emitCLRZ    emitpcode(POC_BCF,  popCopyGPR2Bit(&pc_status,PIC_Z_BIT))
-#define emitCLRC    emitpcode(POC_BCF,  popCopyGPR2Bit(&pc_status,PIC_C_BIT))
-#define emitCLRDC   emitpcode(POC_BCF,  popCopyGPR2Bit(&pc_status,PIC_DC_BIT))
-#define emitSETZ    emitpcode(POC_BSF,  popCopyGPR2Bit(&pc_status,PIC_Z_BIT))
-#define emitSETC    emitpcode(POC_BSF,  popCopyGPR2Bit(&pc_status,PIC_C_BIT))
-#define emitSETDC   emitpcode(POC_BSF,  popCopyGPR2Bit(&pc_status,PIC_DC_BIT))
+#define emitSKPC    emitpcode(POC_BTFSS,popCopyGPR2Bit(PCOP(&pc_status),PIC_C_BIT))
+#define emitSKPNC   emitpcode(POC_BTFSC,popCopyGPR2Bit(PCOP(&pc_status),PIC_C_BIT))
+#define emitSKPZ    emitpcode(POC_BTFSS,popCopyGPR2Bit(PCOP(&pc_status),PIC_Z_BIT))
+#define emitSKPNZ   emitpcode(POC_BTFSC,popCopyGPR2Bit(PCOP(&pc_status),PIC_Z_BIT))
+#define emitSKPDC   emitpcode(POC_BTFSS,popCopyGPR2Bit(PCOP(&pc_status),PIC_DC_BIT))
+#define emitSKPNDC  emitpcode(POC_BTFSC,popCopyGPR2Bit(PCOP(&pc_status),PIC_DC_BIT))
+#define emitCLRZ    emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_Z_BIT))
+#define emitCLRC    emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_C_BIT))
+#define emitCLRDC   emitpcode(POC_BCF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_DC_BIT))
+#define emitSETZ    emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_Z_BIT))
+#define emitSETC    emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_C_BIT))
+#define emitSETDC   emitpcode(POC_BSF,  popCopyGPR2Bit(PCOP(&pc_status),PIC_DC_BIT))
 
 int pic14_getDataSize(operand *op);
 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop);
@@ -153,7 +153,7 @@ void genMinus (iCode *ic);
 
 pCodeOp *popGetLabel(unsigned int key);
 pCodeOp *popCopyReg(pCodeOpReg *pc);
-pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval);
+pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval);
 pCodeOp *popGetLit(unsigned int lit);
 pCodeOp *popGetWithString(char *str);
 pCodeOp *popRegFromString(char *str);
index 95da354efd3198dab43976dc340230b6cd5fe210..dd15d09c0b03d5b37671a65ac30be36d06ca3f16 100644 (file)
 pCodeOpReg pc_status    = {{PO_STATUS,  "STATUS"}, -1, NULL,NULL};
 pCodeOpReg pc_indf      = {{PO_INDF,    "INDF"}, -1, NULL,NULL};
 pCodeOpReg pc_fsr       = {{PO_FSR,     "FSR"}, -1, NULL,NULL};
+pCodeOpReg pc_pcl       = {{PO_PCL,     "PCL"}, -1, NULL,NULL};
+pCodeOpReg pc_pclath    = {{PO_PCLATH,  "PCLATH"}, -1, NULL,NULL};
 
 static int mnemonics_initialized = 0;
 
-#if 0
-//static char *PIC_mnemonics[] = {
-static char *scpADDLW = "ADDLW";
-static char *scpADDWF = "ADDWF";
-static char *scpANDLW = "ANDLW";
-static char *scpANDWF = "ANDWF";
-static char *scpBCF = "BCF";
-static char *scpBSF = "BSF";
-static char *scpBTFSC = "BTFSC";
-static char *scpBTFSS = "BTFSS";
-static char *scpCALL = "CALL";
-static char *scpCOMF = "COMF";
-static char *scpCLRF = "CLRF";
-static char *scpCLRW = "CLRW";
-static char *scpDECF = "DECF";
-static char *scpDECFSZ = "DECFSZ";
-static char *scpGOTO = "GOTO";
-static char *scpINCF = "INCF";
-static char *scpINCFSZ = "INCFSZ";
-static char *scpIORLW = "IORLW";
-static char *scpIORWF = "IORWF";
-static char *scpMOVF = "MOVF";
-static char *scpMOVLW = "MOVLW";
-static char *scpMOVWF = "MOVWF";
-static char *scpNEGF = "NEGF";
-static char *scpRETLW = "RETLW";
-static char *scpRETURN = "RETURN";
-static char *scpSUBLW = "SUBLW";
-static char *scpSUBWF = "SUBWF";
-static char *scpTRIS = "TRIS";
-static char *scpXORLW = "XORLW";
-static char *scpXORWF = "XORWF";
-#endif
 
 static hTab *pic14MnemonicsHash = NULL;
 
@@ -257,7 +226,6 @@ pCodeInstruction pciCALL = {
   PCC_NONE  // outCond
 };
 
-//fixme - need a COMFW instruction.
 pCodeInstruction pciCOMF = {
   {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
    genericAnalyze,
@@ -267,9 +235,23 @@ pCodeInstruction pciCOMF = {
   "COMF",
   NULL, // operand
   2,    // num ops
+  1,0,  // dest, bit instruction
+  PCC_REGISTER,  // inCond
+  PCC_REGISTER   // outCond
+};
+
+pCodeInstruction pciCOMFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_COMFW,
+  "COMF",
+  NULL, // operand
+  2,    // num ops
   0,0,  // dest, bit instruction
-  PCC_NONE, // inCond
-  PCC_NONE  // outCond
+  PCC_REGISTER,  // inCond
+  PCC_  // outCond
 };
 
 pCodeInstruction pciCLRF = {
@@ -569,6 +551,62 @@ pCodeInstruction pciRETURN = {
 };
 
 
+pCodeInstruction pciRLF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_RLF,
+  "RLF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  (PCC_C | PCC_REGISTER),   // inCond
+  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
+};
+
+pCodeInstruction pciRLFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_RLFW,
+  "RLF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  (PCC_C | PCC_REGISTER),   // inCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
+};
+
+pCodeInstruction pciRRF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_RRF,
+  "RRF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  (PCC_C | PCC_REGISTER),   // inCond
+  (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond
+};
+
+pCodeInstruction pciRRFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_RRFW,
+  "RRF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  (PCC_C | PCC_REGISTER),   // inCond
+  (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
+};
+
 pCodeInstruction pciSUBWF = {
   {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
    genericAnalyze,
@@ -611,6 +649,33 @@ pCodeInstruction pciSUBLW = {
   (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond
 };
 
+pCodeInstruction pciSWAPF = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_SWAPF,
+  "SWAPF",
+  NULL, // operand
+  2,    // num ops
+  1,0,  // dest, bit instruction
+  (PCC_REGISTER),   // inCond
+  (PCC_REGISTER) // outCond
+};
+
+pCodeInstruction pciSWAPFW = {
+  {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
+   genericAnalyze,
+   genericDestruct,
+   genericPrint},
+  POC_SWAPFW,
+  "SWAPF",
+  NULL, // operand
+  2,    // num ops
+  0,0,  // dest, bit instruction
+  (PCC_REGISTER),   // inCond
+  (PCC_W) // outCond
+};
 pCodeInstruction pciTRIS = {
   {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, 
    genericAnalyze,
@@ -775,6 +840,7 @@ void pic14initMnemonics(void)
   pic14Mnemonics[POC_BTFSS] = &pciBTFSS;
   pic14Mnemonics[POC_CALL] = &pciCALL;
   pic14Mnemonics[POC_COMF] = &pciCOMF;
+  pic14Mnemonics[POC_COMFW] = &pciCOMFW;
   pic14Mnemonics[POC_CLRF] = &pciCLRF;
   pic14Mnemonics[POC_CLRW] = &pciCLRW;
   pic14Mnemonics[POC_DECF] = &pciDECF;
@@ -796,9 +862,15 @@ void pic14initMnemonics(void)
   pic14Mnemonics[POC_NEGF] = &pciNEGF;
   pic14Mnemonics[POC_RETLW] = &pciRETLW;
   pic14Mnemonics[POC_RETURN] = &pciRETURN;
+  pic14Mnemonics[POC_RLF] = &pciRLF;
+  pic14Mnemonics[POC_RLFW] = &pciRLFW;
+  pic14Mnemonics[POC_RRF] = &pciRRF;
+  pic14Mnemonics[POC_RRFW] = &pciRRFW;
   pic14Mnemonics[POC_SUBLW] = &pciSUBLW;
   pic14Mnemonics[POC_SUBWF] = &pciSUBWF;
   pic14Mnemonics[POC_SUBFW] = &pciSUBFW;
+  pic14Mnemonics[POC_SWAPF] = &pciSWAPF;
+  pic14Mnemonics[POC_SWAPFW] = &pciSWAPFW;
   pic14Mnemonics[POC_TRIS] = &pciTRIS;
   pic14Mnemonics[POC_XORLW] = &pciXORLW;
   pic14Mnemonics[POC_XORWF] = &pciXORWF;
@@ -1126,7 +1198,7 @@ static void pCodeLabelDestruct(pCode *pc)
 
   unlinkPC(pc);
 
-  if(PCL(pc)->label)
+  if((pc->type == PC_LABEL) && PCL(pc)->label)
     free(PCL(pc)->label);
 
   free(pc);
@@ -1279,7 +1351,7 @@ pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype)
   return pcop;
 }
 
-pCodeOp *newpCodeOpBit(char *s, int bit)
+pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace)
 {
   pCodeOp *pcop;
 
@@ -1288,10 +1360,20 @@ pCodeOp *newpCodeOpBit(char *s, int bit)
   pcop->name = Safe_strdup(s);   
 
   PCOB(pcop)->bit = bit;
-  if(bit>=0)
-    PCOB(pcop)->inBitSpace = 1;
-  else
-    PCOB(pcop)->inBitSpace = 0;
+  PCOB(pcop)->inBitSpace = inBitSpace;
+
+  return pcop;
+}
+
+pCodeOp *newpCodeOpReg(int rIdx)
+{
+  pCodeOp *pcop;
+
+  pcop = Safe_calloc(1,sizeof(pCodeOpReg) );
+
+  PCOR(pcop)->rIdx = rIdx;
+  PCOR(pcop)->r = pic14_regWithIdx(rIdx);
+  pcop->type = PCOR(pcop)->r->pc_type;
 
   return pcop;
 }
@@ -1305,7 +1387,7 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type)
 
   switch(type) {
   case PO_BIT:
-    pcop = newpCodeOpBit(name, -1);
+    pcop = newpCodeOpBit(name, -1,0);
     break;
 
   case PO_LITERAL:
@@ -1409,10 +1491,16 @@ void printpBlock(FILE *of, pBlock *pb)
 
 static void unlinkPC(pCode *pc)
 {
-  if(pc  && pc->prev && pc->next) {
 
-    pc->prev->next = pc->next;
-    pc->next->prev = pc->prev;
+
+  if(pc) {
+
+    if(pc->prev) 
+      pc->prev->next = pc->next;
+    if(pc->next)
+      pc->next->prev = pc->prev;
+
+    pc->prev = pc->next = NULL;
   }
 }
 static void genericDestruct(pCode *pc)
@@ -1449,6 +1537,7 @@ static char *get_op( pCodeInstruction *pcc)
 
     case PO_FSR:
     case PO_GPR_TEMP:
+    case PO_GPR_BIT:
       r = pic14_regWithIdx(PCOR(pcc->pcop)->r->rIdx);
       //fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name);
       pBlockRegs(stderr,pcc->pc.pb);
@@ -1493,7 +1582,9 @@ char *pCode2str(char *str, int size, pCode *pc)
          else
            SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)), 
                          (((pCodeOpBit *)(PCI(pc)->pcop))->bit ));
-       } else
+       } else if(PCI(pc)->pcop->type == PO_GPR_BIT) {
+         SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)),PCORB(PCI(pc)->pcop)->bit);
+       }else
          SAFE_snprintf(&s,&size,"%s,0 ; ?bug", get_op(PCI(pc)));
        //PCI(pc)->pcop->t.bit );
       } else {
@@ -1664,6 +1755,22 @@ static void pCodePrintLabel(FILE *of, pCode *pc)
 
 }
 /*-----------------------------------------------------------------*/
+static void  unlinkpCodeFromBranch(pBranch *pb , pCode *pc)
+{
+  pBranch *b, *bprev;
+
+  bprev = NULL;
+  b = pb;
+  while(b) {
+    if(b->pc == pc) {
+      if(bprev)
+       bprev->next = b->next;
+    }
+    bprev = b;
+    b = b->next;
+  }
+
+}
 
 static pBranch * pBranchAppend(pBranch *h, pBranch *n)
 {
@@ -1799,6 +1906,29 @@ static void genericAnalyze(pCode *pc)
   }
 }
 
+/*-----------------------------------------------------------------*/
+int compareLabel(pCode *pc, pCodeOpLabel *pcop_label)
+{
+  pBranch *pbr;
+
+  if(pc->type == PC_LABEL) {
+    if( ((pCodeLabel *)pc)->key ==  pcop_label->key)
+      return TRUE;
+  }
+  if(pc->type == PC_OPCODE) {
+    pbr = pc->label;
+    while(pbr) {
+      if(pbr->pc->type == PC_LABEL) {
+       if( ((pCodeLabel *)(pbr->pc))->key ==  pcop_label->key)
+         return TRUE;
+      }
+      pbr = pbr->next;
+    }
+  }
+
+  return FALSE;
+}
+
 /*-----------------------------------------------------------------*/
 /* findLabel - Search the pCode for a particular label             */
 /*-----------------------------------------------------------------*/
@@ -1806,29 +1936,15 @@ pCode * findLabel(pCodeOpLabel *pcop_label)
 {
   pBlock *pb;
   pCode  *pc;
-  pBranch *pbr;
 
   if(!the_pFile)
     return NULL;
 
   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
-    for(pc = pb->pcHead; pc; pc = pc->next) {
-      if(pc->type == PC_LABEL) {
-       if( ((pCodeLabel *)pc)->key ==  pcop_label->key)
-         return pc;
-      }
-      if(pc->type == PC_OPCODE) {
-       pbr = pc->label;
-       while(pbr) {
-         if(pbr->pc->type == PC_LABEL) {
-           if( ((pCodeLabel *)(pbr->pc))->key ==  pcop_label->key)
-             return pc;
-         }
-         pbr = pbr->next;
-       }
-      }
-
-    }
+    for(pc = pb->pcHead; pc; pc = pc->next) 
+      if(compareLabel(pc,pcop_label))
+       return pc;
+    
   }
 
   fprintf(stderr,"Couldn't find label %s", pcop_label->pcop.name);
@@ -1954,14 +2070,79 @@ int OptimizepBlock(pBlock *pb)
   if(!pb || !peepOptimizing)
     return 0;
 
-  fprintf(stderr," Optimizing pBlock\n");
-
+  fprintf(stderr," Optimizing pBlock: %c\n",getpBlock_dbName(pb));
   for(pc = pb->pcHead; pc; pc = pc->next)
     matches += pCodePeepMatchRule(pc);
 
   return matches;
 
 }
+
+/*-----------------------------------------------------------------*/
+/* pBlockRemoveUnusedLabels - remove the pCode labels from the     */
+/*-----------------------------------------------------------------*/
+pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs)
+{
+  pCode *pc;
+
+  for(pc = pcs; pc; pc = pc->next) {
+
+    if((pc->type == PC_OPCODE) && 
+       (PCI(pc)->pcop) && 
+       (PCI(pc)->pcop->type == PO_LABEL) &&
+       (PCOLAB(PCI(pc)->pcop)->key == pcl->key))
+      return pc;
+  }
+
+  return NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* pBlockRemoveUnusedLabels - remove the pCode labels from the     */
+/*                            pCode chain if they're not used.     */
+/*-----------------------------------------------------------------*/
+void pBlockRemoveUnusedLabels(pBlock *pb)
+{
+  pCode *pc; pCodeLabel *pcl;
+
+  if(!pb)
+    return;
+
+  for(pc = pb->pcHead; pc; pc = pc->next) {
+
+    if(pc->type == PC_LABEL)
+      pcl = PCL(pc);
+    else if (pc->label)
+      pcl = PCL(pc->label->pc);
+    else continue;
+
+      /* This pCode is a label, so search the pBlock to see if anyone
+       * refers to it */
+
+    if( (pcl->key>0) && (!findInstructionUsingLabel(pcl, pb->pcHead))) {
+      /* Couldn't find an instruction that refers to this label
+       * So, unlink the pCode label from it's pCode chain
+       * and destroy the label */
+
+      fprintf(stderr," !!! REMOVED A LABEL !!! key = %d\n", pcl->key);
+
+      if(pc->type == PC_LABEL) {
+       //unlinkPC(pc);
+       pCodeLabelDestruct(pc);
+      } else {
+       unlinkpCodeFromBranch(pc->label, pc);
+       if(pc->label->next == NULL && pc->label->pc == NULL) {
+         free(pc->label);
+       }
+      }
+
+    }
+  }
+
+}
+
+
 /*-----------------------------------------------------------------*/
 /* pBlockMergeLabels - remove the pCode labels from the pCode      */
 /*                     chain and put them into pBranches that are  */
@@ -1976,18 +2157,22 @@ void pBlockMergeLabels(pBlock *pb)
   if(!pb)
     return;
 
+  /* First, Try to remove any unused labels */
+  //pBlockRemoveUnusedLabels(pb);
+
+  /* Now loop through the pBlock and merge the labels with the opcodes */
+
   for(pc = pb->pcHead; pc; pc = pc->next) {
 
     if(pc->type == PC_LABEL) {
+      fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key);
       if( !(pcnext = findNextInstruction(pc)) ) 
        return;  // Couldn't find an instruction associated with this label
 
       // Unlink the pCode label from it's pCode chain
-      if(pc->prev) 
-       pc->prev->next = pc->next;
-      if(pc->next)
-       pc->next->prev = pc->prev;
+      unlinkPC(pc);
 
+      fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key);
       // And link it into the instruction's pBranch labels. (Note, since
       // it's possible to have multiple labels associated with one instruction
       // we must provide a means to accomodate the additional labels. Thus
@@ -1999,9 +2184,14 @@ void pBlockMergeLabels(pBlock *pb)
       pbr->next = NULL;
 
       pcnext->label = pBranchAppend(pcnext->label,pbr);
+      if(pcnext->prev) 
+       pc = pcnext->prev;
+      else
+       pc = pcnext;
     }
 
   }
+  pBlockRemoveUnusedLabels(pb);
 
 }
 
@@ -2052,6 +2242,8 @@ void AnalyzepCode(char dbName)
   /* First, merge the labels with the instructions */
   for(pb = the_pFile->pbHead; pb; pb = pb->next) {
     if('*' == dbName || getpBlock_dbName(pb) == dbName) {
+
+      fprintf(stderr," analyze and merging block %c\n",dbName);
       pBlockMergeLabels(pb);
       AnalyzepBlock(pb);
     }
index 4f2afc36d3e9ab4f40fcd879d5d4ea0963b697f4..1d5961ebc5c219abcc9cdb9233e8c223e3478e9a 100644 (file)
@@ -105,8 +105,11 @@ typedef enum
   PO_FSR,            // The "file select register" (in 18c it's one of three)
   PO_INDF,           // The Indirect register
   PO_GPR_REGISTER,   // A general purpose register
+  PO_GPR_BIT,        // A bit of a general purpose register
   PO_GPR_TEMP,       // A general purpose temporary register
   PO_SFR_REGISTER,   // A special function register (e.g. PORTA)
+  PO_PCL,            // Program counter Low register
+  PO_PCLATH,         // Program counter Latch high register
   PO_LITERAL,        // A constant
   PO_IMMEDIATE,      //  (8051 legacy)
   PO_DIR,            // Direct memory (8051 legacy)
@@ -174,6 +177,7 @@ typedef enum
   POC_BTFSS,
   POC_CALL,
   POC_COMF,
+  POC_COMFW,
   POC_CLRF,
   POC_CLRW,
   POC_DECF,
@@ -195,9 +199,15 @@ typedef enum
   POC_NEGF,
   POC_RETLW,
   POC_RETURN,
+  POC_RLF,
+  POC_RLFW,
+  POC_RRF,
+  POC_RRFW,
   POC_SUBLW,
   POC_SUBWF,
   POC_SUBFW,
+  POC_SWAPF,
+  POC_SWAPFW,
   POC_TRIS,
   POC_XORLW,
   POC_XORWF,
@@ -296,6 +306,12 @@ typedef struct pCodeOpReg
   struct pBlock *pb;
 } pCodeOpReg;
 
+typedef struct pCodeOpRegBit
+{
+  pCodeOpReg  pcor;       // The Register containing this bit
+  int bit;                // 0-7 bit number.
+  PIC_OPTYPE subtype;     // The type of this register.
+} pCodeOpRegBit;
 
 
 /*************************************************
@@ -550,6 +566,7 @@ typedef struct pCodeOpWild
 #define PCOL(x)   ((pCodeOpLit *)(x))
 #define PCOLAB(x) ((pCodeOpLabel *)(x))
 #define PCOR(x)   ((pCodeOpReg *)(x))
+#define PCORB(x)  ((pCodeOpRegBit *)(x))
 #define PCOW(x)   ((pCodeOpWild *)(x))
 
 #define PBR(x)    ((pBranch *)(x))
@@ -577,7 +594,7 @@ void pCodePeepInit(void);
 
 pCodeOp *newpCodeOpLabel(int key);
 pCodeOp *newpCodeOpLit(int lit);
-pCodeOp *newpCodeOpBit(char *name, int bit);
+pCodeOp *newpCodeOpBit(char *name, int bit,int inBitSpace);
 pCodeOp *newpCodeOp(char *name, PIC_OPTYPE p);
 extern void pcode_test(void);
 
@@ -588,6 +605,8 @@ extern void pcode_test(void);
 extern pCodeOpReg pc_status;
 extern pCodeOpReg pc_indf;
 extern pCodeOpReg pc_fsr;
+extern pCodeOpReg pc_pcl;
+extern pCodeOpReg pc_pclath;
 
 
 ////////////////////   DELETE THIS ///////////////////
index c51bcb42021145988b9d0852f1bd5e23547ee8eb..e23e667c712b5bc5cc9a53aeb1d25f57ae7f7056 100644 (file)
@@ -443,7 +443,7 @@ static void * cvt_altpat_mnem1a(void *pp)
   }
 
   if(pic14Mnemonics[opcode]->bit_inst)
-    pcosubtype = newpCodeOpBit(NULL,-1);
+    pcosubtype = newpCodeOpBit(NULL,-1,0);
   else
     pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER);
 
@@ -1367,7 +1367,7 @@ void pCodePeepInit(void)
     pCodeOp *pcwb;
 
     // Create a new wild operand subtyped as a bit
-    pcwb =  newpCodeOpWild(0,pcp,newpCodeOpBit(NULL,-1));
+    pcwb =  newpCodeOpWild(0,pcp,newpCodeOpBit(NULL,-1,0));
 
     // Create a 
     pb = newpCodeChain(NULL, 'W',newpCode(POC_BTFSC,pcwb));
@@ -1477,7 +1477,30 @@ int pCodeSearchCondition(pCode *pc, unsigned int cond)
 /*-----------------------------------------------------------------*/
 /* pCodePeepMatchLine - Compare source and destination pCodes to   */
 /*                      see they're the same.                      */
+/*                                                                 */
+/* In this context, "source" refers to the coded generated by gen.c*/
+/* and "destination" refers to a pcode in a peep rule. If the dest-*/
+/* ination has no wild cards, then MatchLine will compare the two  */
+/* pcodes (src and dest) for a one-to-one match. If the destination*/
+/* has wildcards, then those get expanded. When a wild card is     */
+/* encountered for the first time it autmatically is considered a  */
+/* match and the object that matches it is referenced in the       */
+/* variables or opcodes array (depending on the type of match).    */
+/*                                                                 */
+/*                                                                 */
+/* Inputs:                                                         */
+/*  *peepBlock - A pointer to the peepBlock that contains the      */
+/*               entire rule to which the destination pcode belongs*/
+/*  *pcs - a pointer to the source pcode                           */
+/*  *pcd - a pointer to the destination pcode                      */
+/*                                                                 */
+/* Returns:                                                        */
+/*  1 - pcodes match                                               */
+/*  0 - pcodes don't match                                         */
+/*                                                                 */
+/*                                                                 */
 /*-----------------------------------------------------------------*/
+
 int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
 {
   int index;   // index into wild card arrays
@@ -1524,11 +1547,14 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
            if(peepBlock->vars[index])
              return  (strcmp(peepBlock->vars[index],n) == 0);
            else {
+             fprintf(stderr,"first time for a variable: %d, %s\n",index,n);
              peepBlock->vars[index] = n; //PCI(pcs)->pcop->name;
              return 1;
            }
          }
        }
+       /* FIXME - need an else to check the case when the destination 
+        * isn't a wild card */
       } else
        /* The pcd has no operand. Lines match if pcs has no operand either*/
        return (PCI(pcs)->pcop == NULL);
@@ -1557,12 +1583,13 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
        return 0;
 
       pcl = pcd->label->pc;
-
-      labindex = PCOW(pcl)->id;
+      //labindex = PCOW(pcl)->id;
+      labindex = -PCL(pcl)->key;
+      fprintf(stderr,"label id = %d (labindex = %d)\n",PCL(pcl)->key,labindex);
       if(peepBlock->vars[labindex] == NULL) {
        // First time to encounter this label
        peepBlock->vars[labindex] = PCL(pcs->label->pc)->label;
-       fprintf(stderr,"first time for a label\n");
+       fprintf(stderr,"first time for a label: %d %s\n",labindex, peepBlock->vars[labindex]);
       } else {
        if(strcmp(peepBlock->vars[labindex],PCL(pcs->label->pc)->label) != 0) {
          fprintf(stderr,"labels don't match\n");
@@ -1596,6 +1623,9 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
     if(pcs) {
       fprintf(stderr," (next to match)\n");
       pcs->print(stderr,pcs);
+    } else if(pcd->next) {
+      /* oops, we ran out of code, but there's more to the rule */
+      return 0;
     }
 
     return 1; /*  wild card matches */
@@ -1690,6 +1720,7 @@ static pCodeOp *pCodeOpCopy(pCodeOp *pcop)
 
   case PO_GPR_REGISTER:
   case PO_GPR_TEMP:
+  case PO_GPR_BIT:
     fprintf(stderr,"pCodeOpCopy GPR register\n");
     pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) );
     PCOR(pcopnew)->r = PCOR(pcop)->r;
@@ -1706,6 +1737,8 @@ static pCodeOp *pCodeOpCopy(pCodeOp *pcop)
   case PO_STATUS:
   case PO_FSR:
   case PO_INDF:
+  case PO_PCL:
+  case PO_PCLATH:
 
     fprintf(stderr,"pCodeOpCopy register type %d\n", pcop->type);
     pcopnew = Safe_calloc(1,sizeof(pCodeOp) );
@@ -1784,7 +1817,7 @@ int pCodePeepMatchRule(pCode *pc)
        fprintf(stderr," end of rule\n");
     }
 
-    if(matched && pcin) {
+    if(matched) {
 
       /* So far we matched the rule up to the point of the conditions .
        * In other words, all of the opcodes match. Now we need to see
@@ -1795,12 +1828,12 @@ int pCodePeepMatchRule(pCode *pc)
        * the `postFalseCond' as input then we abort the match
        */
       fprintf(stderr,"    matched rule so far, now checking conditions\n");
-      if (peepBlock->postFalseCond && 
+      if (pcin && peepBlock->postFalseCond && 
          (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) )
        matched = 0;
     }
 
-    if(matched && pcin) {
+    if(matched) {
 
       pCode *pcprev;
       pCode *pcr;
@@ -1813,13 +1846,16 @@ int pCodePeepMatchRule(pCode *pc)
       printpCodeString(stderr,peepBlock->target->pcHead,10);
       fprintf(stderr,"first thing matched\n");
       pc->print(stderr,pc);
-      fprintf(stderr,"last thing matched\n");
-      pcin->print(stderr,pcin);
+      if(pcin) {
+       fprintf(stderr,"last thing matched\n");
+       pcin->print(stderr,pcin);
+      }
 
       /* Unlink the original code */
       pcprev = pc->prev;
       pcprev->next = pcin;
-      pcin->prev = pc->prev;
+      if(pcin) 
+       pcin->prev = pc->prev;
 
       {
        /*     DEBUG    */
@@ -1838,7 +1874,8 @@ int pCodePeepMatchRule(pCode *pc)
        }
       }
 
-      pCodeDeleteChain(pc,pcin);
+      if(pcin)
+       pCodeDeleteChain(pc,pcin);
 
       /* Generate the replacement code */
       pc = pcprev;
@@ -1871,7 +1908,8 @@ int pCodePeepMatchRule(pCode *pc)
 
 
        pc = pc->next;
-       pc->print(stderr,pc);
+       if(pc)
+         pc->print(stderr,pc);
        pcr = pcr->next;
       }
 
index a0d97077b073a7411c8d8220ec68b62a2c432512..a2bd9a2a1983ee2ed58160b51db1d5a0382da337 100644 (file)
@@ -62,9 +62,14 @@ SRC = b.c \
        compare2.c \
        compare3.c \
        for.c \
+       rotate1.c \
+       rotate2.c \
+       rotate3.c \
        struct1.c \
        sub.c \
-       while.c
+       switch1.c \
+       while.c \
+       xor.c
 
 COD := $(patsubst %.c, %.cod, $(SRC))
 ASM := $(patsubst %.c, %.asm, $(SRC))
index ce91b6b9126e700a203623e5cf61e2f8971a63d9..4cc21613545168f86dbb628f7f32a08f9f0c61e2 100644 (file)
@@ -190,6 +190,19 @@ void c_abcd(void)
 
 }
 
+// assumes achar1 == 0
+void c_ifelse1(void)
+{
+
+  if(achar0)
+    achar0 = achar1;
+  else
+    achar0 = 0;
+
+  if(achar0)
+    failures++;
+}
+
 void
 main (void)
 {
@@ -214,6 +227,13 @@ main (void)
   aint0 = 0xabcd;
   c_abcd();
 
+  achar0 = 0;
+  achar1 = 0;
+  c_ifelse1();
+
+  achar0 = 1;
+  c_ifelse1();
+
   success = failures;
   done ();
 }
diff --git a/src/regression/rotate1.c b/src/regression/rotate1.c
new file mode 100644 (file)
index 0000000..2402a50
--- /dev/null
@@ -0,0 +1,211 @@
+// Shift bytes left and right by a constant.
+
+unsigned char success=0;
+unsigned char failures=0;
+unsigned char dummy=0;
+
+bit bit0 = 0;
+unsigned int aint0 = 0;
+unsigned int aint1 = 0;
+unsigned char achar0 = 0;
+unsigned char achar1 = 0;
+unsigned char achar2 = 0;
+
+void done()
+{
+
+  dummy++;
+
+}
+
+void check(void)
+{
+  if(achar0 != achar1)
+    failures++;
+}
+
+void shift_left_1(void)
+{
+
+  achar0 <<= 1;
+
+  check();
+}
+
+void shift_left_2(void)
+{
+
+  achar0 <<= 2;
+
+  if(achar0 != achar1)
+    failures++;
+}
+
+
+void shift_left_3(void)
+{
+
+  achar0 <<= 3;
+
+  if(achar0 != achar1)
+    failures++;
+}
+
+void shift_left_4(void)
+{
+
+  achar0 <<= 4;
+
+  if(achar0 != achar1)
+    failures++;
+}
+
+void shift_left_5(void)
+{
+
+  achar0 <<= 5;
+
+  if(achar0 != achar1)
+    failures++;
+}
+
+void shift_left_6(void)
+{
+
+  achar0 <<= 6;
+
+  if(achar0 != achar1)
+    failures++;
+}
+
+void shift_left_7(void)
+{
+
+  achar0 <<= 7;
+
+  if(achar0 != achar1)
+    failures++;
+}
+
+void shift_right_1(void)
+{
+
+  achar0 >>= 1;
+
+  check();
+}
+
+void shift_right_2(void)
+{
+
+  achar0 >>= 2;
+
+  check();
+}
+
+void shift_right_3(void)
+{
+
+  achar0 >>= 3;
+
+  check();
+}
+
+void shift_right_4(void)
+{
+
+  achar0 >>= 4;
+
+  check();
+}
+
+void shift_right_5(void)
+{
+
+  achar0 >>= 5;
+
+  check();
+}
+
+void shift_right_6(void)
+{
+
+  achar0 >>= 6;
+
+  check();
+}
+
+void shift_right_7(void)
+{
+
+  achar0 >>= 7;
+
+  check();
+}
+
+
+void main(void)
+{
+
+  // call with both values zero
+  shift_left_1();
+
+  achar0 = 1;
+  achar1 = 2;
+  for(achar2=0; achar2<6; achar2++) {
+    shift_left_1();
+    achar1 <<=1;
+  }
+
+  achar0 = 1;
+  achar1 = 4;
+  shift_left_2();
+
+  achar0 = 1;
+  achar1 = 8;
+  shift_left_3();
+
+  achar0 = 1;
+  achar1 = 0x10;
+  shift_left_4();
+
+  achar0 = 1;
+  achar1 = 0x20;
+  shift_left_5();
+
+  achar0 = 1;
+  achar1 = 0x40;
+  shift_left_6();
+
+  achar0 = 1;
+  achar1 = 0x80;
+  shift_left_7();
+
+
+
+
+  achar0 = 2;
+  achar1 = 1;
+  shift_right_1();
+
+  achar0 = 4;
+  shift_right_2();
+
+  achar0 = 8;
+  shift_right_3();
+
+  achar0 = 0x10;
+  shift_right_4();
+
+  achar0 = 0x20;
+  shift_right_5();
+
+  achar0 = 0x40;
+  shift_right_6();
+
+  achar0 = 0x80;
+  shift_right_7();
+
+  success=failures;
+  done();
+}
diff --git a/src/regression/rotate2.c b/src/regression/rotate2.c
new file mode 100644 (file)
index 0000000..7891534
--- /dev/null
@@ -0,0 +1,65 @@
+// Shift bytes left and right by a variable.
+
+unsigned char success=0;
+unsigned char failures=0;
+unsigned char dummy=0;
+
+bit bit0 = 0;
+unsigned int aint0 = 0;
+unsigned int aint1 = 0;
+unsigned char achar0 = 0;
+unsigned char achar1 = 0;
+unsigned char achar2 = 0;
+unsigned char achar3 = 0;
+
+void done()
+{
+
+  dummy++;
+
+}
+
+void shift_right_var(void)
+{
+
+  achar0 >>= achar1;
+}
+
+void shift_left_var(void)
+{
+
+  achar0 <<= achar1;
+}
+
+void shift_int_left_1(void)
+{
+
+  aint0 <<= 1;
+
+}
+
+void main(void)
+{
+  char i;
+
+  achar0 = 1;
+  achar1 = 1;
+  shift_left_var();
+
+  if(achar0 !=2)
+    failures++;
+
+  achar0 = 1;
+  achar1 = 1;
+  achar2 = 1;
+  for(i=0; i<7; i++) {
+    shift_left_var();
+    achar2 <<= 1;
+
+    if(achar2 != achar0)
+      failures++;
+  }
+
+  success=failures;
+  done();
+}
diff --git a/src/regression/rotate3.c b/src/regression/rotate3.c
new file mode 100644 (file)
index 0000000..f0f5330
--- /dev/null
@@ -0,0 +1,232 @@
+// Shift ints left and right
+
+unsigned char success=0;
+unsigned char failures=0;
+unsigned char dummy=0;
+
+bit bit0 = 0;
+unsigned int aint0 = 0;
+unsigned int aint1 = 0;
+unsigned char achar0 = 0;
+unsigned char achar1 = 0;
+unsigned char achar2 = 0;
+unsigned char achar3 = 0;
+
+void done()
+{
+
+  dummy++;
+
+}
+
+void shift_int_left_1(void)
+{
+
+  aint0 <<= 1;
+
+}
+
+void shift_int_left_2(void)
+{
+
+  aint0 <<= 2;
+
+}
+
+void shift_int_left_3(void)
+{
+
+  aint0 <<= 3;
+
+}
+
+void shift_int_left_4(void)
+{
+
+  aint0 <<= 4;
+
+}
+
+void shift_int_left_5(void)
+{
+
+  aint0 <<= 5;
+
+}
+
+void shift_int_left_6(void)
+{
+
+  aint0 <<= 6;
+
+}
+
+void shift_int_left_7(void)
+{
+
+  aint0 <<= 7;
+
+}
+
+void shift_int_left_8(void)
+{
+
+  aint0 <<= 8;
+
+}
+
+void shift_int_left_9(void)
+{
+
+  aint0 <<= 9;
+
+}
+
+void shift_int_left_10(void)
+{
+
+  aint0 <<= 10;
+
+}
+
+void shift_int_left_11(void)
+{
+
+  aint0 <<= 11;
+
+}
+
+void shift_int_left_12(void)
+{
+
+  aint0 <<= 12;
+
+}
+
+void shift_int_left_13(void)
+{
+
+  aint0 <<= 13;
+
+}
+
+void shift_int_left_14(void)
+{
+
+  aint0 <<= 14;
+
+}
+
+void shift_int_left_15(void)
+{
+
+  aint0 <<= 15;
+
+}
+
+/*****************************************************/
+void shift_int_right_1(void)
+{
+
+  aint0 >>= 1;
+
+}
+
+/*****************************************************/
+void main(void)
+{
+  char i;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_1();
+  if(aint0 != 0x579a)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_2();
+  if(aint0 != 0xaf34)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_3();
+  if(aint0 != 0x5e68)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_4();
+  if(aint0 != 0xbcd0)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_5();
+  if(aint0 != 0x79a0)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_6();
+  if(aint0 != 0xf340)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_7();
+  if(aint0 != 0xe680)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_8();
+  if(aint0 != 0xcd00)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_9();
+  if(aint0 != 0x9a00)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_10();
+  if(aint0 != 0x3400)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_11();
+  if(aint0 != 0x6800)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_12();
+  if(aint0 != 0xd000)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_13();
+  if(aint0 != 0xa000)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_14();
+  if(aint0 != 0x4000)
+    failures++;
+
+  aint0 = 0xabcd;
+
+  shift_int_left_15();
+  if(aint0 != 0x8000)
+    failures++;
+
+  success=failures;
+  done();
+}
diff --git a/src/regression/xor.c b/src/regression/xor.c
new file mode 100644 (file)
index 0000000..5e77a2a
--- /dev/null
@@ -0,0 +1,58 @@
+unsigned char success=0;
+unsigned char failures=0;
+unsigned char dummy=0;
+
+unsigned char achar0 = 0;
+unsigned char achar1 = 0;
+unsigned char achar2 = 0;
+
+void done()
+{
+
+  dummy++;
+
+}
+
+void xor_chars_0_1(void)
+{
+
+  achar2 = achar0 ^ achar1;
+
+  achar0 = achar0 ^ 0x1;
+
+  achar1 = achar0 ^ achar1 ^ 4;
+}
+
+void xor_if(void)
+{
+
+  if(achar0 ^ achar1) 
+    failures++;
+
+  achar0 ^= 0xff;
+
+  if( !(achar0 ^ achar1) ) 
+    failures++;
+
+}
+
+void main(void)
+{
+
+  xor_chars_0_1();
+
+  if(achar2)
+    failures++;
+
+  if(achar0 != 1)
+    failures++;
+
+  if(achar1 != 5)
+    failures++;
+
+  achar0 = achar1;
+  xor_if();
+
+  success = failures;
+  done();
+}