* src/pic16/{pcode.h,genarith.c}:
authortecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 5 Jun 2006 21:38:29 +0000 (21:38 +0000)
committertecodev <tecodev@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Mon, 5 Jun 2006 21:38:29 +0000 (21:38 +0000)
  introduced pCodeOp combining any two pCodeOps (previously only
  two register operands could be combined), removed pcop2 from
  pCodepReg, replaced pCodeOpReg2 with pCodeOp2, fixes #1492366
* src/pic16/pcodepeep.c (pic16_pCodeOpCopy): added case for PO_TWO_OPS
* src/pic16/gen.c (pic16_popGet2,pic16_popGet2p,pic16_popCombine2):
  rewritten to use new PO_TWO_OPS
* src/pic16/main.c (_hasNativeMulFor): cover more cases natively,
* src/pic16/pcode.c (pic16_newpCodeOpImmd): initialize rIdx field,
  (pic16_newpCodeOp): catch invalid attempts on PO_TWO_OPS,
  (pic16_newpCodeOp2): NEW, create combined pCodeOp,
  (pic16_get_op): embraced return arg to allow #define return(x),
    added new case for combined opcodes
  (pic16_get_op2): reduced to use pic16_get_op() on second pCodeOp,
  (pic16_pCode2str,pic16_getRegFrompCodeOp,
   pic16_getRegFromInstruction2): fixed/added handling of new pCodeOp

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

ChangeLog
src/pic16/gen.c
src/pic16/genarith.c
src/pic16/main.c
src/pic16/pcode.c
src/pic16/pcode.h
src/pic16/pcodepeep.c

index b6c0995c650aa7b77eeff7089481e66ca3a09ebe..d4565648e2aea7be14884331b34c20167e7cad6d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2006-06-05 Raphael Neider <rneider AT web.de>
+
+       * src/pic16/{pcode.h,genarith.c}:
+         introduced pCodeOp combining any two pCodeOps (previously only
+         two register operands could be combined), removed pcop2 from
+         pCodepReg, replaced pCodeOpReg2 with pCodeOp2, fixes #1492366
+       * src/pic16/pcodepeep.c (pic16_pCodeOpCopy): added case for PO_TWO_OPS
+       * src/pic16/gen.c (pic16_popGet2,pic16_popGet2p,pic16_popCombine2):
+         rewritten to use new PO_TWO_OPS
+       * src/pic16/main.c (_hasNativeMulFor): cover more cases natively,
+       * src/pic16/pcode.c (pic16_newpCodeOpImmd): initialize rIdx field,
+         (pic16_newpCodeOp): catch invalid attempts on PO_TWO_OPS,
+         (pic16_newpCodeOp2): NEW, create combined pCodeOp,
+         (pic16_get_op): embraced return arg to allow #define return(x),
+           added new case for combined opcodes
+         (pic16_get_op2): reduced to use pic16_get_op() on second pCodeOp,
+         (pic16_pCode2str,pic16_getRegFrompCodeOp,
+          pic16_getRegFromInstruction2): fixed/added handling of new pCodeOp
+
 2006-06-04 Bernhard Held <bernhard AT bernhardheld.de>
 
        * src/SDCCval.c (checkConstantRange): added
index 8e10f9c341811f229d26ffec957b3554d79463bf..b1f315daaac3dde4ad950c5b674b4bb78f719cc7 100644 (file)
@@ -1995,17 +1995,8 @@ static pCodeOp *pic16_popRegFromIdx(int rIdx)
 /*---------------------------------------------------------------------------------*/
 pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
 {
-  pCodeOpReg2 *pcop2;
-  pCodeOp *temp;
-  
-       pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset);
-
-       /* comment the following check, so errors to throw up */
-//     if(!pcop2)return NULL;
-
-       temp = pic16_popGet(aop_dst, offset);
-       pcop2->pcop2 = temp;
-       
+  pCodeOp2 *pcop2 = (pCodeOp2 *)pic16_newpCodeOp2(
+       pic16_popGet(aop_src, offset), pic16_popGet(aop_dst, offset));
   return PCOP(pcop2);
 }
 
@@ -2017,32 +2008,19 @@ pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset)
 /*--------------------------------------------------------------------------------.-*/
 pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst)
 {
-  pCodeOpReg2 *pcop2;
-       pcop2 = (pCodeOpReg2 *)src;
-       pcop2->pcop2 = dst;
-       
-       return PCOP(pcop2);
+  pCodeOp2 *pcop2;
+  pcop2 = (pCodeOp2 *)pic16_newpCodeOp2(src, dst);
+  return PCOP(pcop2);
 }
 
-
-
 /*---------------------------------------------------------------------------------*/
 /* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with      */
 /*                     movff instruction                                           */
 /*---------------------------------------------------------------------------------*/
 pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc)
 {
-  pCodeOpReg2 *pcop2;
-
-       if(!noalloc) {
-               pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src);
-               pcop2->pcop2 = pic16_popCopyReg(dst);
-       } else {
-               /* the pCodeOp may be already allocated */
-               pcop2 = (pCodeOpReg2 *)(src);
-               pcop2->pcop2 = (pCodeOp *)(dst);
-       }
+  pCodeOp2 *pcop2 = (pCodeOp2 *)pic16_newpCodeOp2(
+       pic16_popCopyReg(src), pic16_popCopyReg(dst) );
 
   return PCOP(pcop2);
 }
index 7766ae7d1e5db660997f778d897cc9da481c987e..1664b0cf493ff6f1edd8cc2c344f133ff98f7171 100644 (file)
@@ -113,6 +113,7 @@ const char *pic16_pCodeOpType(pCodeOp *pcop)
     case PO_STR:               return  "PO_STR";
     case PO_LABEL:             return  "PO_LABEL";
     case PO_WILD:              return  "PO_WILD";
+    case PO_TWO_OPS:           return  "PO_TWO_OPS";
     }
   }
 
@@ -152,6 +153,7 @@ const char *pic16_pCodeOpSubType(pCodeOp *pcop)
     case PO_STR:               return  "PO_STR";
     case PO_LABEL:             return  "PO_LABEL";
     case PO_WILD:              return  "PO_WILD";
+    case PO_TWO_OPS:           return  "PO_TWO_OPS";
     }
   }
 
index 5547e34edfb66044e8e6880448c1cdce98d00eca..c27a2bdfd07cf0f09dbee6d9f53deaadcb31689b 100644 (file)
@@ -914,25 +914,80 @@ _pic16_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
  * False to convert it to function call */
 static bool _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
 {
-//     fprintf(stderr,"checking for native mult for %c (size: %d)\n", ic->op, getSize(OP_SYMBOL(IC_RESULT(ic))->type));
+  //fprintf(stderr,"checking for native mult for %c (size: %d)\n", ic->op, getSize(OP_SYMBOL(IC_RESULT(ic))->type));
+
+  /* Checks to enable native multiplication.
+   * PICs do not offer native division at all...
+   *
+   * Ideas:
+   * (  i) if result is just one byte, use native MUL
+   *       (regardless of the operands)
+   * ( ii) if left and right are unsigned 8-bit operands,
+   *       use native MUL
+   * (iii) if left or right is a literal in the range of [0..255)
+   *       and the other is an unsigned byte, use native MUL
+   */
+  if (ic->op == '*')
+  {
+    int symL, symR, symRes, sizeL = 0, sizeR = 0, sizeRes = 0;
 
-#if 1
-       /* multiplication is fixed */
-       /* support mul for char/int/long */
-       if((ic->op == '*')
-         && (IS_SYMOP(IC_LEFT(ic)))
-         && (getSize(OP_SYMBOL(IC_LEFT(ic))->type ) < 2))
-           return TRUE;
-#endif
+    /* left/right are symbols? */
+    symL = IS_SYMOP(IC_LEFT(ic));
+    symR = IS_SYMOP(IC_RIGHT(ic));
+    symRes = IS_SYMOP(IC_RESULT(ic));
+
+    /* --> then determine their sizes */
+    sizeL = symL ? getSize(OP_SYM_TYPE(IC_LEFT(ic))) : 4;
+    sizeR = symR ? getSize(OP_SYM_TYPE(IC_RIGHT(ic))) : 4;
+    sizeRes = symRes ? getSize(OP_SYM_TYPE(IC_RESULT(ic))) : 4;
+
+    /* use native mult for `*: <?> x <?> --> {u8_t, s8_t}' */
+    if (sizeRes == 1) { return TRUE; }
+
+    /* use native mult for `u8_t x u8_t --> { u16_t, s16_t }' */
+    if (sizeL == 1 && symL && SPEC_USIGN(OP_SYM_TYPE(IC_LEFT(ic)))) {
+      sizeL = 1;
+    } else {
+      //printf( "%s: left too large (%u) / signed (%u)\n", __FUNCTION__, sizeL, symL && !SPEC_USIGN(OP_SYM_TYPE(IC_LEFT(ic))));
+      sizeL = 4;
+    }
+    if (sizeR == 1 && symR && SPEC_USIGN(OP_SYM_TYPE(IC_RIGHT(ic)))) {
+      sizeR = 1;
+    } else {
+      //printf( "%s: right too large (%u) / signed (%u)\n", __FUNCTION__, sizeR, symR && !SPEC_USIGN(OP_SYM_TYPE(IC_RIGHT(ic))));
+      sizeR = 4;
+    }
+
+    /* also allow literals [0..256) for left/right operands */
+    if (IS_VALOP(IC_LEFT(ic)))
+    {
+      long l = (long)floatFromVal( OP_VALUE( IC_LEFT(ic) ) );
+      sizeL = 4;
+      //printf( "%s: val(left) = %ld\n", __FUNCTION__, l );
+      if (l >= 0 && l < 256)
+      {
+       sizeL = 1;
+      } else {
+       //printf( "%s: left value %ld outside [0..256)\n", __FUNCTION__, l );
+      }
+    }
+    if (IS_VALOP( IC_RIGHT(ic) ))
+    {
+      long l = (long)floatFromVal( OP_VALUE( IC_RIGHT(ic) ) );
+      sizeR = 4;
+      //printf( "%s: val(right) = %ld\n", __FUNCTION__, l );
+      if (l >= 0 && l < 256)
+      {
+       sizeR = 1;
+      } else {
+       //printf( "%s: right value %ld outside [0..256)\n", __FUNCTION__, l );
+      }
+    }
+
+    /* use native mult iff left and right are (unsigned) 8-bit operands */
+    if (sizeL == 1 && sizeR == 1) { return TRUE; }
+  }
 
-#if 0
-       /* support div for char/int/long */
-       if((ic->op == '/')
-         && (IS_SYMOP(IC_LEFT(ic)))
-         && (getSize(OP_SYMBOL(IC_LEFT(ic))->type ) < 0))
-           return TRUE;
-#endif
-       
   return FALSE;
 }
 
index 52c8e8efd61596a766ca14f43c89b441f44457eb..84947452baa7e0018c4191d85b649f05e9bebe15 100644 (file)
@@ -3525,6 +3525,7 @@ static int RegCond(pCodeOp *pcop)
   return 0;
 }
 
+
 /*-----------------------------------------------------------------*/
 /* pic16_newpCode - create and return a newly initialized pCode          */
 /*                                                                 */
@@ -4141,6 +4142,7 @@ pCodeOp *pic16_newpCodeOpImmd(char *name, int offset, int index, int code_space)
 //                     fprintf(stderr,"%s %s %d\n",__FUNCTION__,name,offset);
        } else {
                pcop->name = NULL;
+               PCOI(pcop)->rIdx = -1;
        }
 
        PCOI(pcop)->index = index;
@@ -4398,6 +4400,11 @@ pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE type)
     else
       pcop = pic16_newpCodeOpReg(-1);
     break;
+    
+  case PO_TWO_OPS:
+    assert( !"Cannot create PO_TWO_OPS from string!" );
+    pcop = NULL;
+    break;
 
   default:
     pcop = Safe_calloc(1,sizeof(pCodeOp) );
@@ -4411,6 +4418,15 @@ pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE type)
   return pcop;
 }
 
+pCodeOp *pic16_newpCodeOp2(pCodeOp *src, pCodeOp *dst)
+{
+  pCodeOp2 *pcop2 = Safe_calloc(1, sizeof(pCodeOp2));
+  pcop2->pcop.type = PO_TWO_OPS;
+  pcop2->pcopL = src;
+  pcop2->pcopR = dst;
+  return PCOP(pcop2);
+}
+
 /* This is a multiple of two as gpasm pads DB directives to even length,
  * thus the data would be interleaved with \0 bytes...
  * This is a multiple of three in order to have arrays of 3-byte pointers
@@ -4803,6 +4819,7 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
        } 
 
        if(pcop) {
+
                switch(pcop->type) {
                        case PO_W:
                        case PO_WREG:
@@ -4812,17 +4829,17 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
                        case PO_FSR0:
                                if(use_buffer) {
                                        SAFE_snprintf(&buffer,&size,"%s",PCOR(pcop)->r->name);
-                                       return buffer;
+                                       return (buffer);
                                }
-                               return PCOR(pcop)->r->name;
+                               return (PCOR(pcop)->r->name);
                                break;
                        case PO_GPR_TEMP:
                                r = pic16_regWithIdx(PCOR(pcop)->r->rIdx);
                                if(use_buffer) {
                                        SAFE_snprintf(&buffer,&size,"%s",r->name);
-                                       return buffer;
+                                       return (buffer);
                                }
-                               return r->name;
+                               return (r->name);
 
                        case PO_IMMEDIATE:
                                s = buffer;
@@ -4849,7 +4866,7 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
                                                        pcop->name);
                                        }
                                }
-                               return buffer;
+                               return (buffer);
 
                        case PO_GPR_REGISTER:
                        case PO_DIR:
@@ -4862,7 +4879,7 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
                                } else {
                                        SAFE_snprintf(&s,&size,"%s",pcop->name);
                                }
-                               return buffer;
+                               return (buffer);
                        case PO_GPR_BIT:
                                s = buffer;
                                if(PCORB(pcop)->subtype == PO_GPR_TEMP) {
@@ -4875,19 +4892,23 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
                                }
 
                                return (buffer);
+                       case PO_TWO_OPS:
+                               return (pic16_get_op( PCOP2(pcop)->pcopL, use_buffer ? buffer : NULL, size ));
+                               
                        default:
                                if(pcop->name) {
                                        if(use_buffer) {
                                                SAFE_snprintf(&buffer,&size,"%s",pcop->name);
-                                               return buffer;
+                                               return (buffer);
                                        }
-                               return pcop->name;
+                               return (pcop->name);
                                }
 
                }
+               return ("unhandled type for op1");
        }
 
-  return "NO operand1";
+  return ("NO operand1");
 }
 
 /*-----------------------------------------------------------------*/
@@ -4895,95 +4916,10 @@ char *pic16_get_op(pCodeOp *pcop,char *buffer, size_t size)
 /*-----------------------------------------------------------------*/
 char *pic16_get_op2(pCodeOp *pcop,char *buffer, size_t size)
 {
-  regs *r;
-  static char b[128];
-  char *s;
-  int use_buffer = 1;    // copy the string to the passed buffer pointer
-
-       if(!buffer) {
-               buffer = b;
-               size = sizeof(b);
-               use_buffer = 0;     // Don't bother copying the string to the buffer.
-       } 
-
-#if 0
-       fprintf(stderr, "%s:%d second operand %s is %d\tPO_DIR(%d) PO_GPR_TEMP(%d) PO_IMMEDIATE(%d) PO_INDF0(%d) PO_FSR0(%d)\n",
-               __FUNCTION__, __LINE__, PCOR(PCOR2(pcop)->pcop2)->r->name, PCOR2(pcop)->pcop2->type,
-               PO_DIR, PO_GPR_TEMP, PO_IMMEDIATE, PO_INDF0, PO_FSR0);
-#endif
-
-       if(pcop) {
-               switch(PCOR2(pcop)->pcop2->type) {
-                       case PO_W:
-                       case PO_WREG:
-                       case PO_PRODL:
-                       case PO_PRODH:
-                       case PO_INDF0:
-                       case PO_FSR0:
-                               if(use_buffer) {
-                                       SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
-                                       return buffer;
-                               }
-                               return PCOR(PCOR2(pcop)->pcop2)->r->name;
-                               break;
-                       case PO_GPR_TEMP:
-                               r = pic16_regWithIdx(PCOR(PCOR2(pcop)->pcop2)->r->rIdx);
 
-                               if(use_buffer) {
-                                       SAFE_snprintf(&buffer,&size,"%s",r->name);
-                                       return buffer;
-                               }
-                               return r->name;
-
-                       case PO_IMMEDIATE:
-                                       assert( 0 );
-                               break;
-#if 0
-                               s = buffer;
-
-                               if(PCOI(pcop)->_const) {
-                                       if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) {
-                                               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);
-                               } else {
-                                       if( PCOI(pcop)->index) {
-                                               SAFE_snprintf(&s,&size,"(%s + %d)",
-                                                       pcop->name,
-                                                       PCOI(pcop)->index );
-                                       } else {
-                                               if(PCOI(pcop)->offset)
-                                                       SAFE_snprintf(&s,&size,"(%s >> %d)&0xff",pcop->name, 8*PCOI(pcop)->offset);
-                                               else
-                                                       SAFE_snprintf(&s,&size,"%s",pcop->name);
-                                       }
-                               }
-                               return buffer;
-#endif
-                       case PO_DIR:
-                               s = buffer;
-                               if( PCOR(PCOR2(pcop)->pcop2)->instance) {
-                                       SAFE_snprintf(&s,&size,"(%s + %d)",
-                                               PCOR(PCOR2(pcop)->pcop2)->r->name,
-                                               PCOR(PCOR2(pcop)->pcop2)->instance );
-                               } else {
-                                       SAFE_snprintf(&s,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
-                               }
-                               return buffer;
-
-                       default:
-                               if(PCOR(PCOR2(pcop)->pcop2)->r->name) {
-                                       if(use_buffer) {
-                                               SAFE_snprintf(&buffer,&size,"%s",PCOR(PCOR2(pcop)->pcop2)->r->name);
-                                               return buffer;
-                                       }
-                                       return PCOR(PCOR2(pcop)->pcop2)->r->name;
-                               }
-               }
-       }
+  if(pcop && pcop->type == PO_TWO_OPS) {
+    return pic16_get_op( PCOP2(pcop)->pcopR, buffer, size );
+  }
 
   return "NO operand2";
 }
@@ -5034,10 +4970,14 @@ char *pic16_pCode2str(char *str, size_t size, pCode *pc)
 
     if( (PCI(pc)->num_ops >= 1) && (PCI(pc)->pcop)) {
 
-       if(PCI(pc)->is2MemOp) {
-               SAFE_snprintf(&s,&size, "%s, %s", 
-               pic16_get_op(PCOP(PCI(pc)->pcop), NULL, 0),
-               pic16_get_op2(PCOP(PCI(pc)->pcop), NULL, 0));
+       //if(PCI(pc)->is2MemOp)
+       if (PCI(pc)->pcop->type == PO_TWO_OPS)
+       {
+               /* split into two phases due to static buffer in pic16_get_op() */
+               SAFE_snprintf(&s,&size, "%s", 
+                       pic16_get_op((PCI(pc)->pcop), NULL, 0));
+               SAFE_snprintf(&s, &size, ", %s",
+                       pic16_get_op2((PCI(pc)->pcop), NULL, 0));
                break;
        }
 
@@ -5858,9 +5798,13 @@ regs * pic16_getRegFrompCodeOp (pCodeOp *pcop) {
     
   case PO_WILD:
     break;
+
+  case PO_TWO_OPS:
+    return pic16_getRegFrompCodeOp( PCOP2(pcop)->pcopL );
+    break;
     
   default:
-       fprintf(stderr, "pic16_getRegFromInstruction - unknown reg type %d (%s)\n",pcop->type, dumpPicOptype (pcop->type));
+       fprintf(stderr, "pic16_getRegFrompCodeOp - unknown reg type %d (%s)\n",pcop->type, dumpPicOptype (pcop->type));
 //     assert( 0 );
        break;
   }
@@ -5872,7 +5816,6 @@ regs * pic16_getRegFrompCodeOp (pCodeOp *pcop) {
 /*-----------------------------------------------------------------*/
 regs * pic16_getRegFromInstruction(pCode *pc)
 {
-
   if(!pc                   || 
      !isPCI(pc)            ||
      !PCI(pc)->pcop        ||
@@ -5885,7 +5828,7 @@ regs * pic16_getRegFromInstruction(pCode *pc)
        dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type);
 #endif
 
-  return pic16_getRegFrompCodeOp (PCI(pc)->pcop);
+  return( pic16_getRegFrompCodeOp (PCI(pc)->pcop) );
 }
 
 /*-------------------------------------------------------------------------------*/
@@ -5901,13 +5844,15 @@ regs * pic16_getRegFromInstruction2(pCode *pc)
      (PCI(pc)->num_ops == 1))          // accept only 2 operand commands
     return NULL;
 
+  if (PCI(pc)->pcop->type != PO_TWO_OPS)
+    return NULL;
 
 #if 0
   fprintf(stderr, "pic16_getRegFromInstruction2 - reg type %s (%d)\n",
        dumpPicOptype( PCI(pc)->pcop->type), PCI(pc)->pcop->type);
 #endif
 
-  return pic16_getRegFrompCodeOp (PCOR2(PCI(pc)->pcop)->pcop2);
+  return pic16_getRegFrompCodeOp (PCOP2(PCI(pc)->pcop)->pcopR);
 }
 
 /*-----------------------------------------------------------------*/
@@ -8756,12 +8701,14 @@ char *pic_optype_names[]={
        "PO_BIT",            // bit operand.
        "PO_STR",            //  (8051 legacy)
        "PO_LABEL",
-       "PO_WILD"            // Wild card operand in peep optimizer
+       "PO_WILD",           // Wild card operand in peep optimizer
+       "PO_TWO_OPS"         // combine two operands
 };
 
 
 char *dumpPicOptype(PIC_OPTYPE type)
 {
+       assert( type >= 0 && type < sizeof(pic_optype_names)/sizeof( char *) );
        return (pic_optype_names[ type ]);
 }
 
@@ -11768,9 +11715,9 @@ static void assignValnums (pCode *pc) {
     if (!isSpecial1 && pic16_regIsLocal (reg1) && val && oldval && !pic16_isAlive (SPO_STATUS, pc)) {
       //pc->print (stderr, pc); fprintf (stderr, "lit: %d (%x, %x)\n", lit, lit, val->in_val);
       if (lit == 0) {
-        newpc = pic16_newpCode (POC_CLRF, PCOR2(pci->pcop)->pcop2);
+        newpc = pic16_newpCode (POC_CLRF, PCOP2(pci->pcop)->pcopR);
       } else if (lit == 0x00ff) {
-       newpc = pic16_newpCode (POC_SETF, PCOR2(pci->pcop)->pcop2);
+       newpc = pic16_newpCode (POC_SETF, PCOP2(pci->pcop)->pcopR);
       } else {
         newpc = NULL;
       }
@@ -11810,7 +11757,7 @@ static void assignValnums (pCode *pc) {
            if (copy->val && copy->val == val->in_val) {
              //fprintf (stderr, "found replacement symbol for %s (val %x) <-- %s (assigned %x @ %p)\n", strFromSym(sym1), val->in_val, strFromSym(copy->sym), copy->val, copy->pc);
              if (copy->sym == SPO_WREG) {
-               newpc = pic16_newpCode (POC_MOVWF, pic16_pCodeOpCopy (PCOR2(pci->pcop)->pcop2));
+               newpc = pic16_newpCode (POC_MOVWF, pic16_pCodeOpCopy (PCOP2(pci->pcop)->pcopR));
              } else {
                pCodeOp *pcop = NULL;
                /* the code below fails if we try to replace
@@ -11839,7 +11786,7 @@ static void assignValnums (pCode *pc) {
                assert( pcop );
                 newpc = pic16_newpCode(POC_MOVFF, pic16_popGet2p(
                        pcop,
-                       pic16_pCodeOpCopy (PCOR2(pci->pcop)->pcop2)));
+                       pic16_pCodeOpCopy (PCOP2(pci->pcop)->pcopR)));
              }
              pic16_InsertCommentAfter (pc->prev, "=DF= MOVFF: SRC op %s replaced by %s", strFromSym(sym1), strFromSym(copy->sym));
              pic16_df_saved_bytes += PCI(pc)->isize - PCI(newpc)->isize;
index cf3d19113f359f1e9848a413fe2b8186abb5ccd3..df8b8196a9d162ebeb5b94e36570c003c555f2bd 100644 (file)
@@ -185,7 +185,8 @@ typedef enum
   PO_BIT,            // bit operand.
   PO_STR,            //  (8051 legacy)
   PO_LABEL,
-  PO_WILD            // Wild card operand in peep optimizer
+  PO_WILD,           // Wild card operand in peep optimizer
+  PO_TWO_OPS         // combine two operands
 } PIC_OPTYPE;
 
 
@@ -466,20 +467,14 @@ typedef struct pCodeOpReg
   struct regs *r;
   int instance;    // byte # of Multi-byte registers
   struct pBlock *pb;
-
-  pCodeOp *pcop2;      // second memory operand (NEEDED IN gen.c:pic16_popGet2p (pCodeOpReg casted into pCodeOpReg2) 
 } pCodeOpReg;
 
-typedef struct pCodeOpReg2
+typedef struct pCodeOp2
 {
-  pCodeOp pcop;                // used by default to all references
-  int rIdx;
-  struct regs *r;
-  int instance;                // assume same instance for both operands
-  struct pBlock *pb;
-
-  pCodeOp *pcop2;      // second memory operand
-} pCodeOpReg2;
+  pCodeOp pcop;                // describes this pCodeOp
+  pCodeOp *pcopL;      // reference to left pCodeOp (src)
+  pCodeOp *pcopR;      // reference to right pCodeOp (dest)
+} pCodeOp2;
 
 typedef struct pCodeOpRegBit
 {
@@ -962,12 +957,13 @@ typedef struct peepCommand {
 #define PCINF(x)  ((pCodeInfo *)(x))
 
 #define PCOP(x)   ((pCodeOp *)(x))
+#define PCOP2(x)  ((pCodeOp2 *)(x))
 //#define PCOB(x)   ((pCodeOpBit *)(x))
 #define PCOL(x)   ((pCodeOpLit *)(x))
 #define PCOI(x)   ((pCodeOpImmd *)(x))
 #define PCOLAB(x) ((pCodeOpLabel *)(x))
 #define PCOR(x)   ((pCodeOpReg *)(x))
-#define PCOR2(x)  ((pCodeOpReg2 *)(x))
+//#define PCOR2(x)  ((pCodeOpReg2 *)(x))
 #define PCORB(x)  ((pCodeOpRegBit *)(x))
 #define PCOO(x)   ((pCodeOpOpt *)(x))
 #define PCOLR(x)  ((pCodeOpLocalReg *)(x))
@@ -1044,6 +1040,7 @@ pCodeOp *pic16_newpCodeOpBit_simple (struct asmop *op, int offs, int bit);
 pCodeOp *pic16_newpCodeOpRegFromStr(char *name);
 pCodeOp *pic16_newpCodeOpReg(int rIdx);
 pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p);
+pCodeOp *pic16_newpCodeOp2(pCodeOp *src, pCodeOp *dst);
 pCodeOp *pic16_newpCodeOpRegNotVect(bitVect *bv);
 pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop);
 
index df2e34a9f4e388784fd86b75783f52a7580595fa..e8814db571536fa57f7633a9eebe49d675030ac9 100644 (file)
@@ -1965,7 +1965,7 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
 
          /* now check whether the second operand matches */
          /* assert that optimizations do not touch operations that work on SFRs or INDF registers */
-         if(PCOW2(PCI(pcd)->pcop) && (PCOR2(PCI(pcd)->pcop)->pcop2->type == PO_WILD) && (!(PCOR2(PCI(pcs)->pcop)->pcop2) || ((PCOR2(PCI(pcs)->pcop)->pcop2->type != PO_SFR_REGISTER) && (PCOR2(PCI(pcs)->pcop)->pcop2) && (PCOR2(PCI(pcs)->pcop)->pcop2->type != PO_INDF0)))) {
+         if(PCOW2(PCI(pcd)->pcop) && (PCOP2(PCI(pcd)->pcop)->pcopR->type == PO_WILD) && (!(PCOP2(PCI(pcs)->pcop)->pcopR) || ((PCOP2(PCI(pcs)->pcop)->pcopR->type != PO_SFR_REGISTER) && (PCOP2(PCI(pcs)->pcop)->pcopR) && (PCOP2(PCI(pcs)->pcop)->pcopR->type != PO_INDF0)))) {
        
 //             fprintf(stderr, "%s:%d %s second operand is wild\n", __FILE__, __LINE__, __FUNCTION__);
        
@@ -1978,9 +1978,9 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
                }
 #endif
 
-               PCOW2(PCI(pcd)->pcop)->matched = PCOR2(PCI(pcs)->pcop)->pcop2;
+               PCOW2(PCI(pcd)->pcop)->matched = PCOP2(PCI(pcs)->pcop)->pcopR;
                if(!peepBlock->target.wildpCodeOps[index]) {
-                       peepBlock->target.wildpCodeOps[index] = PCOR2(PCI(pcs)->pcop)->pcop2;
+                       peepBlock->target.wildpCodeOps[index] = PCOP2(PCI(pcs)->pcop)->pcopR;
 
                //if(PCI(pcs)->pcop->type == PO_GPR_TEMP) 
 
@@ -1994,21 +1994,21 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
                                );
                        */
 
-                 return ((havematch==1) && pCodeOpCompare(PCOR2(PCI(pcs)->pcop)->pcop2,
+                 return ((havematch==1) && pCodeOpCompare(PCOP2(PCI(pcs)->pcop)->pcopR,
                                peepBlock->target.wildpCodeOps[index]));
                }
 
-               if(PCOR2(PCI(pcs)->pcop)->pcop2) {
+               if(PCOP2(PCI(pcs)->pcop)->pcopR) {
                  char *n;
 
-                       switch(PCOR2(PCI(pcs)->pcop)->pcop2->type) {
+                       switch(PCOP2(PCI(pcs)->pcop)->pcopR->type) {
                        case PO_GPR_TEMP:
                        case PO_FSR0:
                      //case PO_INDF0:
-                               n = PCOR(PCOR2(PCI(pcs)->pcop)->pcop2)->r->name;
+                               n = PCOR(PCOP2(PCI(pcs)->pcop)->pcopR)->r->name;
                                break;
                        default:
-                               n = PCOR2(PCI(pcs)->pcop)->pcop2->name;
+                               n = PCOP2(PCI(pcs)->pcop)->pcopR->name;
                        }
 
                        if(peepBlock->target.vars[index])
@@ -2020,7 +2020,7 @@ static int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd)
                        }
                }
          
-         } else if (PCOW2(PCI(pcd)->pcop) && (PCOR2(PCI(pcd)->pcop)->pcop2->type == PO_WILD) && PCOR2(PCI(pcs)->pcop)->pcop2)
+         } else if (PCOW2(PCI(pcd)->pcop) && (PCOP2(PCI(pcd)->pcop)->pcopR->type == PO_WILD) && PCOP2(PCI(pcs)->pcop)->pcopR)
            {
              return 0;
            } else {
@@ -2250,6 +2250,11 @@ pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop)
     return pcopnew;
     break;
 
+  case PO_TWO_OPS:
+    pcopnew = pic16_newpCodeOp2( pic16_pCodeOpCopy( PCOP2(pcop)->pcopL ),
+    pic16_pCodeOpCopy( PCOP2(pcop)->pcopR ) );
+    return pcopnew;
+
   default:
     assert ( !"unhandled pCodeOp type copied" );
   } // switch
@@ -2473,11 +2478,11 @@ int pic16_pCodePeepMatchRule(pCode *pc)
              pcop = pic16_pCodeOpCopy(PCI(pcr)->pcop);
          }
 
-         if(PCI(pcr)->is2MemOp && PCOR2(PCI(pcr)->pcop)->pcop2) {
+         if(PCI(pcr)->is2MemOp && PCOP2(PCI(pcr)->pcop)->pcopR) {
            /* The replacing instruction has also a second operand.
             * Is it wild? */
 //             fprintf(stderr, "%s:%d pcop2= %p\n", __FILE__, __LINE__, PCOR2(PCI(pcr)->pcop)->pcop2);
-           if(PCOR2(PCI(pcr)->pcop)->pcop2->type == PO_WILD) {
+           if(PCOP2(PCI(pcr)->pcop)->pcopR->type == PO_WILD) {
              int index = PCOW2(PCI(pcr)->pcop)->id;
 //             fprintf(stderr, "%s:%d replacing index= %d\n", __FUNCTION__, __LINE__, index);
              //DFPRINTF((stderr,"copying wildopcode\n"));
@@ -2488,7 +2493,7 @@ int pic16_pCodePeepMatchRule(pCode *pc)
                DFPRINTF((stderr,"error, wildopcode in replace but not source?\n"));
            } else
              pcop = pic16_popCombine2(pic16_pCodeOpCopy(pcop),
-               pic16_pCodeOpCopy(PCOR2(PCI(pcr)->pcop)->pcop2), 0);
+               pic16_pCodeOpCopy(PCOP2(PCI(pcr)->pcop)->pcopR), 0);
              
          }