* src/pic16/device.c: added some debug lines enabled
authorvrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 5 Mar 2004 15:49:01 +0000 (15:49 +0000)
committervrokas <vrokas@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Fri, 5 Mar 2004 15:49:01 +0000 (15:49 +0000)
with macro DEBUG_CHECK,
* src/pic16/genarith.c: more debug in genPlus,
* (pic16_genUMult8XLit_16, pic16_genUMult8X8_16): removed,
* (pic16_genUMult16X16_16, pic16_genUMult16XLit_16): NEW,
* src/pic16/gen.c: added prototypes for pic16_genMult16X16_16,
* (aopForSym): onStack symbols are re-placed in data memspace,
and onStack flag is cleared,
* (pic16_popGetTempReg, pic16_popReleaseTempReg): modified to
copy temporary pcodeop,
* (genPcall): added warning for not updating PCLATU,
* (genFunction): removed test with IFFUNC_CALLEESAVES, its
always true for pic16 port,
* (genMultOneWord): NEW, supports integer multiplication,
* (genMult): modified to call genMultOneWord,
* (ifxForOp): added warning when return NULL,
* src/pic16/glue.c (pic16emitRegularMap): symbol implicit
flag is set before call to operandFromSymbol for implicit
added structures,
* src/pic16/main.c (_pic16_finaliseOptions): options.float_rent,
options.intlong_rent are set by default,
* (_hasNativeMulFor): modified to allow port generation of integer
multiplication,
* src/pic16/ralloc.c (pic16_allocDirReg): commented out line which
set regtype to REG_SFR for all registers, restricting seting the
accessBank flag for registers 0<= r < 0x80 and 0xf80<=r<=0xfff,

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

ChangeLog
src/pic16/device.c
src/pic16/gen.c
src/pic16/genarith.c
src/pic16/glue.c
src/pic16/main.c
src/pic16/pcode.c
src/pic16/ralloc.c

index 5e6889eed2694ecab892b5f8ef402b2899155fa0..997f4bba45b55e31f646de24c98ee908bfb33864 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2004-03-05 Vangelis Rokas <vrokas AT otenet.gr>
+
+       * src/pic16/device.c: added some debug lines enabled
+       with macro DEBUG_CHECK,
+       * src/pic16/genarith.c: more debug in genPlus,
+       * (pic16_genUMult8XLit_16, pic16_genUMult8X8_16): removed,
+       * (pic16_genUMult16X16_16, pic16_genUMult16XLit_16): NEW,
+       * src/pic16/gen.c: added prototypes for pic16_genMult16X16_16,
+       * (aopForSym): onStack symbols are re-placed in data memspace,
+       and onStack flag is cleared,
+       * (pic16_popGetTempReg, pic16_popReleaseTempReg): modified to
+       copy temporary pcodeop,
+       * (genPcall): added warning for not updating PCLATU,
+       * (genFunction): removed test with IFFUNC_CALLEESAVES, its
+       always true for pic16 port,
+       * (genMultOneWord): NEW, supports integer multiplication,
+       * (genMult): modified to call genMultOneWord,
+       * (ifxForOp): added warning when return NULL,
+       * src/pic16/glue.c (pic16emitRegularMap): symbol implicit
+       flag is set before call to operandFromSymbol for implicit
+       added structures,
+       * src/pic16/main.c (_pic16_finaliseOptions): options.float_rent,
+       options.intlong_rent are set by default,
+       * (_hasNativeMulFor): modified to allow port generation of integer
+       multiplication,
+       * src/pic16/ralloc.c (pic16_allocDirReg): commented out line which
+       set regtype to REG_SFR for all registers, restricting seting the
+       accessBank flag for registers 0<= r < 0x80 and 0xf80<=r<=0xfff,
+
 2004-03-05 Frieder Ferlemann <Frieder.Ferlemann AT web.de>
 
        * src/mcs51/peephole.def: added 251.b and 253.x. 253.x are applied
index 14fe64df26be2362cc8850bc24090f9b9635f4f0..eb66b6e4a9b4028e6fba752c4abb88e56be74a0f 100644 (file)
@@ -604,6 +604,7 @@ char *pic16_processor_base_name(void)
   return pic16->name[0];
 }
 
+#define DEBUG_CHECK    0
 
 /*
  * return 1 if register wasn't found and added, 0 otherwise
@@ -612,6 +613,9 @@ int checkAddReg(set **set, regs *reg)
 {
   regs *tmp;
 
+#if DEBUG_CHECK
+       fprintf(stderr, "%s: about to insert REGister: %s ... ", __FUNCTION__, reg->name);
+#endif
 
        for(tmp = setFirstItem(*set); tmp; tmp = setNextItem(*set)) {
                if(!strcmp(tmp->name, reg->name))break;
@@ -619,9 +623,15 @@ int checkAddReg(set **set, regs *reg)
        
        if(!tmp) {
                addSet(set, reg);
+#if DEBUG_CHECK
+               fprintf(stderr, "added\n");
+#endif
                return 1;
        }
 
+#if DEBUG_CHECK
+       fprintf(stderr, "already added\n");
+#endif
   return 0;
 }
 
@@ -629,15 +639,26 @@ int checkAddSym(set **set, symbol *sym)
 {
   symbol *tmp;
 
+#if DEBUG_CHECK
+       fprintf(stderr, "%s: about to add SYMbol: %s ... ", __FUNCTION__, sym->name);
+#endif
+
        for(tmp = setFirstItem( *set ); tmp; tmp = setNextItem(*set)) {
                if(!strcmp(tmp->name, sym->name))break;
        }
        
        if(!tmp) {
                addSet(set, sym);
+#if DEBUG_CHECK
+               fprintf(stderr, "added\n");
+#endif
                return 1;
        }
 
+#if DEBUG_CHECK
+       fprintf(stderr, "already added\n");
+#endif
+
   return 0;
 }
 
@@ -651,10 +672,14 @@ void pic16_groupRegistersInSection(set *regset)
   regs *reg;
 
        for(reg=setFirstItem(regset); reg; reg = setNextItem(regset)) {
+
+//             fprintf(stderr, "%s:%d group registers in section, reg: %s\n", __FILE__, __LINE__, reg->name);
+
                if(reg->wasUsed
                        && !(reg->regop && SPEC_EXTR(OP_SYM_ETYPE(reg->regop)))) {
 
-//                     fprintf(stderr, "%s:%d register %s\n", __FILE__, __LINE__, reg->name);
+//                     fprintf(stderr, "%s:%d register %s alias:%d fix:%d\n",
+//                             __FILE__, __LINE__, reg->name, reg->alias, reg->isFixed);
 
                        if(reg->alias) {
                                checkAddReg(&pic16_equ_data, reg);
index 95afe3928a37bb0e41b8b05c804ca20f221b5d78..a83211c09cf5117fe0480a360ada5814efcef2f3 100644 (file)
@@ -49,6 +49,8 @@
 extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
 extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *);
 void pic16_genMult8X8_8 (operand *, operand *,operand *);
+void pic16_genMult16X16_16(operand *, operand *, operand *);
+void pic16_genMult32X32_32(operand *, operand *, operand *);
 pCode *pic16_AssembleLine(char *line, int peeps);
 extern void pic16_printpBlock(FILE *of, pBlock *pb);
 static asmop *newAsmop (short type);
@@ -446,20 +448,24 @@ static void genSetDPTR(int n)
 /*-----------------------------------------------------------------*/
 static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
 {
+
+  DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
+
   if(!resIfx) 
     return;
 
-  //  DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__);
 
   resIfx->condition = 1;    /* assume that the ifx is true */
   resIfx->generated = 0;    /* indicate that the ifx has not been used */
 
   if(!ifx) {
     resIfx->lbl = newiTempLabel(NULL);  /* oops, there is no ifx. so create a label */
-/*
+
+#if 1
     DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d",
                        __FUNCTION__,__LINE__,resIfx->lbl->key);
-*/
+#endif
+
   } else {
     if(IC_TRUE(ifx)) {
       resIfx->lbl = IC_TRUE(ifx);
@@ -475,7 +481,7 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx)
 */
   }
 
-  //  DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
+  DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset);
 
 }
 #if 0
@@ -504,12 +510,23 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
         return sym->aop;
     }
 
+    /* if symbol was initially placed onStack then we must re-place it
+     * to direct memory, since pic16 does not have a specific stack */
+    if(sym->onStack) {
+       sym->onStack = 0;
+       SPEC_OCLS( sym->etype ) = data;
+       space = data;
+    }
+    
+
+#if 1
     /* assign depending on the storage class */
     /* if it is on the stack or indirectly addressable */
     /* space we need to assign either r0 or r1 to it   */    
     if ((sym->onStack && !options.stack10bit) || sym->iaccess) {
 
-       DEBUGpic16_emitcode("; ***", "sum->onStack || sym->iaccess");
+       DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d",
+               __FUNCTION__, __LINE__, sym->onStack, sym->iaccess);
        
         sym->aop = aop = newAsmop(0);
         aop->aopu.aop_ptr = getFreePtr(ic,&aop,result);
@@ -542,7 +559,8 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
             aop->aopu.aop_stk = sym->stack;
         return aop;
     }
-    
+#endif
+
     if (sym->onStack && options.stack10bit)
     {
         /* It's on the 10 bit stack, which is located in
@@ -1273,6 +1291,12 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname)
 pCodeOp *pic16_popGetTempReg(void)
 {
   pCodeOp *pcop;
+  symbol *cfunc;
+
+//     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+       cfunc = currFunc;
+       currFunc = NULL;
 
        pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP);
        if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
@@ -1280,9 +1304,11 @@ pCodeOp *pic16_popGetTempReg(void)
                PCOR(pcop)->r->isFree=0;
 
                /* push value on stack */
-               pic16_pushpCodeOp( pcop );
+               pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) );
        }
 
+       currFunc = cfunc;
+
   return pcop;
 }
 
@@ -1291,10 +1317,12 @@ pCodeOp *pic16_popGetTempReg(void)
 /*-----------------------------------------------------------------*/
 void pic16_popReleaseTempReg(pCodeOp *pcop)
 {
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
        if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) {
                PCOR(pcop)->r->isFree = 1;
                
-               pic16_poppCodeOp( pcop );
+               pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) );
        }
 }
 /*-----------------------------------------------------------------*/
@@ -1880,6 +1908,7 @@ static void mov2w (asmop *aop, int offset)
 /* push pcop into stack */
 void pic16_pushpCodeOp(pCodeOp *pcop)
 {
+//     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1)));
 }
 
@@ -2799,6 +2828,7 @@ static void genCall (iCode *ic)
                                pic16_emitcode("dec","%s",spname);
        }
 
+#if 0
        /* if register bank was saved then pop them */
        if (ic->bankSaved)
                unsaverbank(FUNC_REGBANK(dtype),ic,TRUE);
@@ -2806,6 +2836,7 @@ static void genCall (iCode *ic)
        /* if we hade saved some registers then unsave them */
        if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype))
                unsaveRegisters (ic);
+#endif
 }
 
 
@@ -2914,7 +2945,12 @@ static void genPcall (iCode *ic)
 // FIXME Disabled writes to PCLATU because of gpsim problems
 #if 0
        pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu)));
+#else
+       fprintf(stderr,
+"WARNING: (%s:%d) PCLATU is not written because of gpsim problems\n\
+Correct this as soon as gpsim bug is fixed\n", __FILE__, __LINE__);
 #endif
        pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath)));
        // note: MOVFF to PCL not allowed
        pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0));
@@ -3294,7 +3330,7 @@ static void genFunction (iCode *ic)
         
 //             fprintf(stderr, "function name: %s\n", sym->name);
                if(strcmp(sym->name, "main")) {
-                       if(!options.ommitFramePtr || sym->regsUsed) {
+                       if(/*!options.ommitFramePtr || */sym->regsUsed) {
                        /* setup the stack frame */
                                pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0));
                                pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0));
@@ -3305,11 +3341,14 @@ static void genFunction (iCode *ic)
 
                /* if callee-save to be used for this function
                * then save the registers being used in this function */
-               if (IFFUNC_CALLEESAVES(sym->type)) {
+//             if (IFFUNC_CALLEESAVES(sym->type))
+               {
                  int i;
-           
-//                     fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed);
-                       
+
+//                     fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size);
+
+//                     pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
+
                        /* if any registers used */
                        if (sym->regsUsed) {
                                /* save the registers used */
@@ -3425,14 +3464,8 @@ static void genEndFunction (iCode *ic)
     }
 #endif
 
-    /* restore the register bank  */    
-    if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type))
-        pic16_emitcode ("pop","psw");
-
        if (IFFUNC_ISISR(sym->type)) {
-
                /* now we need to restore the registers */
-               
                /* if any registers used */
                if (sym->regsUsed) {
                  int i;
@@ -3441,13 +3474,17 @@ static void genEndFunction (iCode *ic)
                        DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
                        for ( i = sym->regsUsed->size; i >= 0; i--) {
                                if (bitVectBitValue(sym->regsUsed,i)) {
-//                                     fprintf(stderr, "%s:%d function %s uses register %s\n",
+
+//                                     fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
 //                                                     __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
 //                                                     pic16_regWithIdx(i)->name);
-        
-                                       pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
-                                                       &pic16_pc_preinc1,
-                                                       PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+
+                                       pic16_poppCodeOp( pic16_popRegFromIdx(i) );
+
+//                                     pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
+//                                                     &pic16_pc_preinc1,
+//                                                     PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+
                                }
                        }
                }
@@ -3485,72 +3522,72 @@ static void genEndFunction (iCode *ic)
                        _G.debugLine = 0;
                }
        
-#if 0
-               pic16_emitpcode(POC_CLRF,   pic16_popCopyReg(&pic16_pc_status));
-               pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave));
-               pic16_emitpcode(POC_MOVWF,  pic16_popCopyReg(&pic16_pc_status));
-               pic16_emitpcode(POC_SWAPF,  pic16_popCopyReg(&pic16_pc_wsave));
-               pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave));
-#endif
-
                pic16_emitpcodeNULLop(POC_RETFIE);
-       }
-       else {
+       } else {
                if (IFFUNC_ISCRITICAL(sym->type))
                        pic16_emitcode("setb","ea");
        
-       /* if any registers used */
-       if (sym->regsUsed) {
-         int i;
-               /* save the registers used */
-               DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
-               for ( i = sym->regsUsed->size; i >= 0; i--) {
-                       if (bitVectBitValue(sym->regsUsed,i)) {
-//                             fprintf(stderr, "%s:%d function %s uses register %s\n",
-//                                             __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
-//                                             pic16_regWithIdx(i)->name);
-        
-                               pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
-                                       &pic16_pc_preinc1,
-                                       PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+
+//             pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1);
+
+               /* if any registers used */
+               if (sym->regsUsed) {
+                 int i;
+                       /* save the registers used */
+                       DEBUGpic16_emitcode("; **", "Restoring used registers from stack");
+                       for ( i = sym->regsUsed->size; i >= 0; i--) {
+                               if (bitVectBitValue(sym->regsUsed,i)) {
+       
+//                                     fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n",
+//                                                     __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name,
+//                                                     pic16_regWithIdx(i)->name);
+       
+                                       pic16_poppCodeOp( pic16_popRegFromIdx(i) );
+                                       
+//                                     pic16_emitpcode(POC_MOVFF, pic16_popCombine2(
+//                                             &pic16_pc_preinc1,
+//                                             PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0));
+
+                                       _G.nRegsSaved--;
+                               }
                        }
                }
-       }
        
+               pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved);
+               /* if debug then send end of function */
+               if (currFunc) {
+                   _G.debugLine = 1;
+                   pic16_emitcode(";","C$%s$%d$%d$%d ==.",
+                            FileBaseName(ic->filename),currFunc->lastLine,
+                            ic->level,ic->block); 
+                   if (IS_STATIC(currFunc->etype))         
+                       pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
+                   else
+                       pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
+                   _G.debugLine = 0;
+               }
 
-       /* if debug then send end of function */
-       if (currFunc) {
-           _G.debugLine = 1;
-           pic16_emitcode(";","C$%s$%d$%d$%d ==.",
-                    FileBaseName(ic->filename),currFunc->lastLine,
-                    ic->level,ic->block); 
-           if (IS_STATIC(currFunc->etype))         
-               pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); 
-           else
-               pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
-           _G.debugLine = 0;
-       }
-
-       /* insert code to restore stack frame, if user enabled it
-        * and function is not main() */
+               /* insert code to restore stack frame, if user enabled it
+                * and function is not main() */
         
-       if(strcmp(sym->name, "main")) {
-               if(!options.ommitFramePtr || sym->regsUsed) {
-                       /* restore stack frame */
-                       if(STACK_MODEL_LARGE)
+
+               if(strcmp(sym->name, "main")) {
+                       if(/*!options.ommitFramePtr ||*/ sym->regsUsed) {
+                               /* restore stack frame */
+                               if(STACK_MODEL_LARGE)
+                                       pic16_emitpcode(POC_MOVFF,
+                                               pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
                                pic16_emitpcode(POC_MOVFF,
-                                       pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0));
-                       pic16_emitpcode(POC_MOVFF,
-                                       pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
+                                               pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0));
+                       }
                }
-       }
 
-        pic16_emitcode ("return","");
-       pic16_emitpcodeNULLop(POC_RETURN);
+               pic16_emitcode ("return","");
+               pic16_emitpcodeNULLop(POC_RETURN);
 
-       /* Mark the end of a function */
-       pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
-    }
+               /* Mark the end of a function */
+               pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL));
+       }
 
 }
 
@@ -3696,6 +3733,8 @@ jumpret:
 /*-----------------------------------------------------------------*/
 static void genLabel (iCode *ic)
 {
+
+
     /* special case never generate */
     DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     if (IC_LABEL(ic) == entryLabel)
@@ -3742,10 +3781,6 @@ static void genMultOneByte (operand *left,
                             operand *right,
                             operand *result)
 {
-  sym_link *opetype = operandType(result);
-
-  // symbol *lbl ;
-  int size,offset;
 
   DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
   DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
@@ -3759,23 +3794,25 @@ static void genMultOneByte (operand *left,
     left = t;
   }
 
-  size = AOP_SIZE(result);
-  if(size == 1) {
+       /* size is already checked in genMult == 1 */
+//     size = AOP_SIZE(result);
+
+       if (AOP_TYPE(right) == AOP_LIT){
+               pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", 
+                                       pic16_aopGet(AOP(right),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(left),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(result),0,FALSE,FALSE));
+       } else {
+               pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", 
+                                       pic16_aopGet(AOP(right),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(left),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(result),0,FALSE,FALSE));
+       }
+       
+       pic16_genMult8X8_8 (left, right,result);
 
-    if (AOP_TYPE(right) == AOP_LIT){
-      pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", 
-                    pic16_aopGet(AOP(right),0,FALSE,FALSE), 
-                    pic16_aopGet(AOP(left),0,FALSE,FALSE), 
-                    pic16_aopGet(AOP(result),0,FALSE,FALSE));
-    } else {
-      pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", 
-                    pic16_aopGet(AOP(right),0,FALSE,FALSE), 
-                    pic16_aopGet(AOP(left),0,FALSE,FALSE), 
-                    pic16_aopGet(AOP(result),0,FALSE,FALSE));
-    }
-    pic16_genMult8X8_8 (left, right,result);
-  } else {  // (size > 1)
 
+#if 0
     pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", 
                   pic16_aopGet(AOP(right),0,FALSE,FALSE), 
                   pic16_aopGet(AOP(left),0,FALSE,FALSE), 
@@ -3826,49 +3863,146 @@ static void genMultOneByte (operand *left,
        pic16_emitcode("multiply ","size is way greater than 2, so propogate sign");
     //pic16_aopPut(AOP(result),"a",offset++);
   }
+#endif
+
+
 }
 
+/*-----------------------------------------------------------------*/
+/* genMultOneWord : 16 bit multiplication                          */
+/*-----------------------------------------------------------------*/
+static void genMultOneWord (operand *left,
+                            operand *right,
+                            operand *result)
+{
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+       DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
+
+       /* (if two literals, the value is computed before)
+        * if one literal, literal on the right */
+       if (AOP_TYPE(left) == AOP_LIT){
+         operand *t = right;
+               right = left;
+               left = t;
+       }
+
+       /* size is checked already == 2 */
+//     size = AOP_SIZE(result);
+
+       if (AOP_TYPE(right) == AOP_LIT) {
+               pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", 
+                                       pic16_aopGet(AOP(right),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(left),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(result),0,FALSE,FALSE));
+       } else {
+               pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", 
+                                       pic16_aopGet(AOP(right),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(left),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(result),0,FALSE,FALSE));
+       }
+       
+       pic16_genMult16X16_16(left, right,result);
+}
+
+/*-----------------------------------------------------------------*/
+/* genMultOneLong : 32 bit multiplication                          */
+/*-----------------------------------------------------------------*/
+static void genMultOneLong (operand *left,
+                            operand *right,
+                            operand *result)
+{
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+       DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result);
+
+       /* (if two literals, the value is computed before)
+        * if one literal, literal on the right */
+       if (AOP_TYPE(left) == AOP_LIT){
+         operand *t = right;
+               right = left;
+               left = t;
+       }
+
+       /* size is checked already == 4 */
+//     size = AOP_SIZE(result);
+
+       if (AOP_TYPE(right) == AOP_LIT) {
+               pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", 
+                                       pic16_aopGet(AOP(right),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(left),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(result),0,FALSE,FALSE));
+       } else {
+               pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", 
+                                       pic16_aopGet(AOP(right),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(left),0,FALSE,FALSE), 
+                                       pic16_aopGet(AOP(result),0,FALSE,FALSE));
+       }
+       
+       pic16_genMult32X32_32(left, right,result);
+}
+
+
+
 /*-----------------------------------------------------------------*/
 /* genMult - generates code for multiplication                     */
 /*-----------------------------------------------------------------*/
 static void genMult (iCode *ic)
 {
-    operand *left = IC_LEFT(ic);
-    operand *right = IC_RIGHT(ic);
-    operand *result= IC_RESULT(ic);   
+  operand *left = IC_LEFT(ic);
+  operand *right = IC_RIGHT(ic);
+  operand *result= IC_RESULT(ic);   
 
-    DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* assign the amsops */
-    pic16_aopOp (left,ic,FALSE);
-    pic16_aopOp (right,ic,FALSE);
-    pic16_aopOp (result,ic,TRUE);
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+       /* assign the amsops */
+       pic16_aopOp (left,ic,FALSE);
+       pic16_aopOp (right,ic,FALSE);
+       pic16_aopOp (result,ic,TRUE);
 
-  DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
+       DEBUGpic16_pic16_AopType(__LINE__,left,right,result);
 
-    /* special cases first */
-    /* both are bits */
-    if (AOP_TYPE(left) == AOP_CRY &&
-        AOP_TYPE(right)== AOP_CRY) {
-        genMultbits(left,right,result);
-        goto release ;
-    }
+       /* special cases first *
+       * both are bits */
+       if (AOP_TYPE(left) == AOP_CRY
+               && AOP_TYPE(right)== AOP_CRY) {
+               genMultbits(left,right,result);
+         goto release ;
+       }
 
-    /* if both are of size == 1 */
-    if (AOP_SIZE(left) == 1 &&
-        AOP_SIZE(right) == 1 ) {
-        genMultOneByte(left,right,result);
-        goto release ;
-    }
+       /* if both are of size == 1 */
+       if(AOP_SIZE(left) == 1
+               && AOP_SIZE(right) == 1) {
+               genMultOneByte(left,right,result);
+         goto release ;
+       }
+
+       /* if both are of size == 2 */
+       if(AOP_SIZE(left) == 2
+               && AOP_SIZE(right) == 2) {
+               genMultOneWord(left, right, result);
+         goto release;
+       }
+       
+       /* if both are of size == 4 */
+       if(AOP_SIZE(left) == 4
+               && AOP_SIZE(right) == 4) {
+               genMultOneLong(left, right, result);
+         goto release;
+       }
+       
+       pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor.");
 
-    pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor.");
 
-    /* should have been converted to function call */
+       fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right));
+       /* should have been converted to function call */
        assert(0) ;
 
 release :
-    pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
-    pic16_freeAsmop(result,NULL,ic,TRUE); 
+       pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+       pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE));
+       pic16_freeAsmop(result,NULL,ic,TRUE); 
 }
 
 /*-----------------------------------------------------------------*/
@@ -4254,6 +4388,8 @@ static void genSkip(iCode *ifx,int status_bit)
 /*-----------------------------------------------------------------*/
 static void genSkipc(resolvedIfx *rifx)
 {
+  DEBUGpic16_emitcode ("; ***","%s  %d rifx= %p",__FUNCTION__,__LINE__, rifx);
+  
   if(!rifx)
     return;
 
@@ -4262,7 +4398,7 @@ static void genSkipc(resolvedIfx *rifx)
   else
     emitSKPNC;
 
-  pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key));
+  pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key));
   rifx->generated = 1;
 }
 
@@ -4271,6 +4407,8 @@ static void genSkipc(resolvedIfx *rifx)
 /*-----------------------------------------------------------------*/
 static void genSkipz2(resolvedIfx *rifx, int invert_condition)
 {
+  DEBUGpic16_emitcode ("; ***","%s  %d rifx= %p",__FUNCTION__,__LINE__, rifx);
+  
   if(!rifx)
     return;
 
@@ -4413,10 +4551,13 @@ static void genCmp (operand *left,operand *right,
        end the carry flag is set then we know that
        left is greater than right */
 
-    //    {
-
     symbol *lbl  = newiTempLabel(NULL);
 
+#if 0
+       fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n",
+               __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+labelOffset, lbl->key+100+labelOffset);
+#endif
+
 #ifndef _swapp
     if(AOP_TYPE(right) == AOP_LIT) {
 
@@ -4649,6 +4790,7 @@ static void genCmp (operand *left,operand *right,
 
 
       pic16_emitpLabel(lbl->key);
+//     pic16_emitpLabel(truelbl->key);
       //if(emitFinalCheck)
       genSkipc(&rFalseIfx);
       if(sign)
@@ -4924,7 +5066,7 @@ static void genCmp (operand *left,operand *right,
              pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size));
            } else {
              /* this byte of the lit is zero, 
-              *if it's not the last then OR in the variable */
+              * if it's not the last then OR in the variable */
              if(size)
                pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size));
            }
@@ -4934,6 +5076,7 @@ static void genCmp (operand *left,operand *right,
          pic16_emitpLabel(lbl->key);
 
          rFalseIfx.condition ^= 1;
+
          genSkipc(&rFalseIfx);
        }
 
@@ -5749,6 +5892,34 @@ static iCode *ifxForOp ( operand *op, iCode *ic )
     }
 
 
+    /* the code below is completely untested
+     * it just allows ulong2fs.c compile -- VR */
+        
+    ic = ic->next;
+    fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n",
+                                       __FILE__, __FUNCTION__, __LINE__);
+       
+    /* if this has register type condition and
+    the next instruction is ifx with the same operand
+    and live to of the operand is upto the ifx only then */
+    if (ic->next &&
+        ic->next->op == IFX &&
+        IC_COND(ic->next)->key == op->key &&
+        OP_SYMBOL(op)->liveTo <= ic->next->seq )
+        return ic->next;
+
+    if (ic->next &&
+        ic->next->op == IFX &&
+        IC_COND(ic->next)->key == op->key) {
+      DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__);
+      return ic->next;
+    }
+
+    fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n",
+                                       __FILE__, __FUNCTION__, __LINE__);
+
+//  return ic->next->next;             /* this just might work */ /* FIXME FIXME */
+
     return NULL;
 }
 /*-----------------------------------------------------------------*/
@@ -8750,7 +8921,9 @@ static void genDataPointerGet(operand *left,
                DEBUGpic16_emitcode("; ***", "left and result operands are equ/same");
                goto release;
        }
+#endif
 
+#if 0
        /* if they are the same registers */
        if (pic16_sameRegs(AOP(left),AOP(result))) {
                DEBUGpic16_emitcode("; ***", "left and result registers are same");
index 21d54eb96a43ec91fe3872ca21d9d3ac12f37bc8..a4cfca9ff48b24086e6d7606e8a7890ebfbb7c18 100644 (file)
@@ -981,6 +981,9 @@ void pic16_genPlus (iCode *ic)
                size = min( AOP_SIZE(result), AOP_SIZE(right) );
                offset = 0;
 
+               if(pic16_debug_verbose)
+                       fprintf(stderr, "%s:%d size of operands: %d\n", __FILE__, __LINE__, size);
+
                if ((AOP_TYPE(left) == AOP_PCODE) && (
                                (AOP(left)->aopu.pcop->type == PO_LITERAL) || 
 //                             (AOP(left)->aopu.pcop->type == PO_DIR) ||   // patch 9
@@ -1626,220 +1629,6 @@ void pic16_genMinus (iCode *ic)
   pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
 }
 
-/*-----------------------------------------------------------------*
- * pic_genUMult8XLit_16 - unsigned multiplication of two 8-bit numbers.
- * 
- * 
- *-----------------------------------------------------------------*/
-void pic16_genUMult8XLit_16 (operand *left,
-                            operand *right,
-                            operand *result,
-                            pCodeOpReg *result_hi)
-
-{
-
-  unsigned int lit;
-  unsigned int i,have_first_bit;
-  int same;
-  pCodeOp *temp;
-
-  if (AOP_TYPE(right) != AOP_LIT){
-    fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
-    exit(1);
-  }
-
-
-  if(!result_hi) {
-    result_hi = PCOR(pic16_popGet(AOP(result),1));
-  }
-
-  lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
-  lit &= 0xff;
-  pic16_emitcode(";","Unrolled 8 X 8 multiplication");
-
-  same = pic16_sameRegs(AOP(left), AOP(result));
-
-  if(same) {
-    switch(lit) {
-    case 0:
-      pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(left),0));
-      return;
-    case 2:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 3:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 4:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 5:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 5*F
-      return;
-    case 6:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 7:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 5*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 7*F
-      return;
-    case 8:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 8*F
-      return;
-    case 9:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 10:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 5*F
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 11:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 8*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 11*F
-      return;
-    case 12:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));
-      return;
-    case 13:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 8*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 13*F
-      return;
-    case 14:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 2*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 3*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 5*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 8*F
-      pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0));  // W = 11*F
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(left),0));  // F = 14*F
-      return;
-    case 15:
-      temp = pic16_popGetTempReg();
-      if(!temp) {
-       fprintf(stderr,"ERROR: unable to allocate register. %s:%d\n",__FUNCTION__,__LINE__);
-       exit(1);
-      }
-      pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVWF,  temp);
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_SWAPFW, temp);
-      pic16_emitpcode(POC_SUBWF,  pic16_popGet(AOP(left),0));
-      pic16_popReleaseTempReg(temp);
-      return;
-    case 16:
-      pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
-      return;
-    case 17:
-      pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xf0));
-      pic16_emitpcode(POC_ADDWF,  pic16_popGet(AOP(left),0));
-      return;
-    case 32:
-      pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xe0));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
-      return;
-    case 64:
-      pic16_emitpcode(POC_SWAPF,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_RLCF,   pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_RLCFW,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_ANDLW,  pic16_popGetLit(0xc0));
-      pic16_emitpcode(POC_MOVWF,  pic16_popGet(AOP(left),0));
-      return;
-    case 128:
-      pic16_emitpcode(POC_RRCFW,  pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_CLRF,   pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_RRCF,   pic16_popGet(AOP(left),0));
-      return;
-
-    }
-  } else {
-
-    switch(lit) {
-    case 0:
-      pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-      return;
-    case 2:
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RLCF,  pic16_popCopyReg(result_hi));
-      return;
-    }
-
-  }
-
-  pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
-  pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
-  pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-
-  have_first_bit = 0;
-  for(i=0; i<8; i++) {
-
-    if(lit & 1) {
-      pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
-      have_first_bit = 1;
-    }
-
-    if(have_first_bit) {
-      pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
-    }
-
-    lit >>= 1;
-  }
-
-}
-
 
 /*-----------------------------------------------------------------*
  * pic_genUMult8XLit_8 - unsigned multiplication of two 8-bit numbers.
@@ -1853,6 +1642,9 @@ void pic16_genUMult8XLit_8 (operand *left,
   unsigned int lit;
   int same;
 
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
        if (AOP_TYPE(right) != AOP_LIT){
                fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
                exit(1);
@@ -1871,7 +1663,8 @@ void pic16_genUMult8XLit_8 (operand *left,
                                return;
                        case 2:
                                // its faster to left shift
-                               pic16_emitpcode(POC_RLNCF, pic16_popGet(AOP(left),0));
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
                                return;
 
                        default:
@@ -1888,7 +1681,8 @@ void pic16_genUMult8XLit_8 (operand *left,
                                pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
                                return;
                        case 2:
-                               pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left), 0));
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
                                pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
                                return;
                        default:
@@ -1901,99 +1695,120 @@ void pic16_genUMult8XLit_8 (operand *left,
        }
 }
 
-/*-----------------------------------------------------------------*
- * genUMult8X8_16 - unsigned multiplication of two 8-bit numbers.
- * 
- * 
- *-----------------------------------------------------------------*/
-void pic16_genUMult8X8_16 (operand *left,
-                          operand *right,
-                          operand *result,
-                          pCodeOpReg *result_hi)
-
+/*-----------------------------------------------------------------------*
+ * pic_genUMult16XLit_16 - unsigned multiplication of two 16-bit numbers *
+ *-----------------------------------------------------------------------*/
+void pic16_genUMult16XLit_16 (operand *left,
+                            operand *right,
+                            operand *result)
 {
+  pCodeOp *pct1, *pct2, *pct3, *pct4;
+  unsigned int lit;
+  int same;
 
-  int i;
-  int looped = 1;
-
-  if(!result_hi) {
-    result_hi = PCOR(pic16_popGet(AOP(result),1));
-  }
-
-  if (AOP_TYPE(right) == AOP_LIT) {
-    pic16_genUMult8XLit_16(left,right,result,result_hi);
-    return;
-  }
-
-  if(!looped) {
-    pic16_emitcode(";","Unrolled 8 X 8 multiplication");
-
-    pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-    pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
-    pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-    emitCLRC;
-
-    for(i=0; i<8; i++) {
-      pic16_emitpcode(POC_BTFSC,  pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),i,0));
-      pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
-    }
-
-
-    /*
-      Here's another version that does the same thing and takes the 
-      same number of instructions. The one above is slightly better
-      because the entry instructions have a higher probability of
-      being optimized out.
-    */
-    /*
-      pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0));
-      pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0));
-      pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-
-      for(i=0; i<8; i++) {
-      emitSKPNC;
-      pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
-      pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
-      }
-    */
-
-  } else {
-    symbol  *tlbl = newiTempLabel(NULL);
-    pCodeOp *temp;
-
-    pic16_emitpcomment("; Looped 8 X 8 multiplication");
-    pic16_emitpcode(POC_CLRF,  pic16_popGet(AOP(result),0));
-    pic16_emitpcode(POC_CLRF,  pic16_popCopyReg(result_hi));
-
-    pic16_emitpcode(POC_BSF,   pic16_newpCodeOpBit(pic16_aopGet(AOP(result),0,FALSE,FALSE),7,0));
-
-    pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0));
-
-    temp = pic16_popGetTempReg();
-    pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(PCOR(temp)));
-
-    pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
 
-    pic16_emitpLabel(tlbl->key);
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-    pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(PCOR(temp)));
-    emitSKPNC;
-    pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(result_hi));
+       if (AOP_TYPE(right) != AOP_LIT){
+               fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
+               exit(1);
+       }
 
-    pic16_emitpcode(POC_RRCF,  pic16_popCopyReg(result_hi));
-    pic16_emitpcode(POC_RRCF,  pic16_popGet(AOP(result),0));
+       lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
+       lit &= 0xffff;
 
-    emitSKPC;
-    pic16_emitpcode(POC_GOTO,  pic16_popGetLabel(tlbl->key));
+       same = pic16_sameRegs(AOP(left), AOP(result));
+       if(same) {
+               switch(lit) {
+                       case 0:
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
+                               return;
+                       case 2:
+                               // its faster to left shift
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
+                               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
+                               return;
 
-    pic16_popReleaseTempReg(temp);
-  }
+                       default: {
+                               DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+                               pct1 = pic16_popGetTempReg();
+                               pct2 = pic16_popGetTempReg();
+                               pct3 = pic16_popGetTempReg();
+                               pct4 = pic16_popGetTempReg();
+
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+                                       
+                               /* WREG still holds the low literal */
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+                                       
+                               /* load result */
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pct1, pic16_popGet(AOP(result), 0)));
+                               pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
+                               pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+                               pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+                               pic16_popReleaseTempReg( pct4 );
+                               pic16_popReleaseTempReg( pct3 );
+                               pic16_popReleaseTempReg( pct2 );
+                               pic16_popReleaseTempReg( pct1 );
+                       }; return;
+               }
+       } else {
+               // operands different
+               switch(lit) {
+                       case 0:
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
+                               return;
+                       case 2:
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+                               pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+                               return;
+                       default: {
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+                                       
+                               /* WREG still holds the low literal */
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+                               pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+                               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+
+                       }; return;
+               }
+       }
 }
 
+
 /*-----------------------------------------------------------------*
  * genUMult8X8_8 - unsigned multiplication of two 8-bit numbers.
  * 
@@ -2004,12 +1819,14 @@ void pic16_genUMult8X8_8 (operand *left,
                           operand *result)
 
 {
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+
        if (AOP_TYPE(right) == AOP_LIT) {
                pic16_genUMult8XLit_8(left,right,result);
          return;
        }
 
-       pic16_emitpcomment("; Looped 8 X 8 multiplication");
        /* cases:
                A = A x B       B = A x B
                A = B x C
@@ -2046,48 +1863,397 @@ void pic16_genUMult8X8_8 (operand *left,
        }
 }
 
+/*------------------------------------------------------------------*
+ * genUMult16X16_16 - unsigned multiplication of two 16-bit numbers *
+ *------------------------------------------------------------------*/
+void pic16_genUMult16X16_16 (operand *left,
+                          operand *right,
+                          operand *result)
+
+{
+  pCodeOp *pct1, *pct2, *pct3, *pct4;
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+
+       if (AOP_TYPE(right) == AOP_LIT) {
+               pic16_genUMult8XLit_8(left,right,result);
+         return;
+       }
+
+       /* cases:
+               A = A x B       B = A x B
+               A = B x C
+       */
+       /* if result == right then exchange left and right */
+       if(pic16_sameRegs(AOP(result), AOP(right))) {
+         operand *tmp;
+               tmp = left;
+               left = right;
+               right = tmp;
+       }
+
+
+       if(pic16_sameRegs(AOP(result), AOP(left))) {
+
+               pct1 = pic16_popGetTempReg();
+               pct2 = pic16_popGetTempReg();
+               pct3 = pic16_popGetTempReg();
+               pct4 = pic16_popGetTempReg();
+
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+                                       
+               /* WREG still holds the lower left */
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+               
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+                                       
+               /* load result */
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
+               pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
+               pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+               pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+               pic16_popReleaseTempReg( pct4 );
+               pic16_popReleaseTempReg( pct3 );
+               pic16_popReleaseTempReg( pct2 );
+               pic16_popReleaseTempReg( pct1 );
+
+       } else {
+
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+               /* WREG still holds the lower left */
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+               pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+               
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+       }       
+}
+
+
+void pic16_genSMult16X16_16(operand *left,
+                       operand *right,
+                       operand *result)
+{
+
+}
+
+#if 0
 /*-----------------------------------------------------------------*
  * pic16_genSMult8X8_16 - signed multiplication of two 8-bit numbers
  *
  *  this routine will call the unsigned multiply routine and then
  * post-fix the sign bit.
  *-----------------------------------------------------------------*/
-void pic16_genSMult8X8_16 (operand *left,
+void pic16_genSMult8X8_8 (operand *left,
                           operand *right,
                           operand *result,
                           pCodeOpReg *result_hi)
 {
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
 
   if(!result_hi) {
     result_hi = PCOR(pic16_popGet(AOP(result),1));
   }
 
-  pic16_genUMult8X8_16(left,right,result,result_hi);
 
+  pic16_genUMult8X8_8(left,right,result);
+
+  
+#if 0
   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),7,0));
   pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(result_hi));
   pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0));
   pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),7,0));
   pic16_emitpcode(POC_SUBWF, pic16_popGet(AOP(result),1));
-  
+#endif
 }
+#endif
 
 /*-----------------------------------------------------------------*
- * pic16_genMult8X8_8 - multiplication of two 8-bit numbers
- *
- *  this routine will call the unsigned multiply 8X8=>16 routine and
- * then throw away the high byte of the result.
- *
+ * pic16_genMult8X8_8 - multiplication of two 8-bit numbers        *
  *-----------------------------------------------------------------*/
 void pic16_genMult8X8_8 (operand *left,
                         operand *right,
                         operand *result)
 {
-  if (AOP_TYPE(right) == AOP_LIT)
-    pic16_genUMult8XLit_8(left,right,result);
-  else
-    pic16_genUMult8X8_8(left,right,result);
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+       if(AOP_TYPE(right) == AOP_LIT)
+               pic16_genUMult8XLit_8(left,right,result);
+       else
+               pic16_genUMult8X8_8(left,right,result);
+}
+
+
+/*-----------------------------------------------------------------*
+ * pic16_genMult16X16_16 - multiplication of two 16-bit numbers    *
+ *-----------------------------------------------------------------*/
+void pic16_genMult16X16_16 (operand *left,
+                        operand *right,
+                        operand *result)
+{
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+       if (AOP_TYPE(right) == AOP_LIT)
+               pic16_genUMult16XLit_16(left,right,result);
+       else
+               pic16_genUMult16X16_16(left,right,result);
+
+}
+
+
+
+
+/*-----------------------------------------------------------------------*
+ * pic_genUMult32XLit_32 - unsigned multiplication of two 32-bit numbers *
+ *-----------------------------------------------------------------------*/
+void pic16_genUMult32XLit_32 (operand *left,
+                            operand *right,
+                            operand *result)
+{
+  pCodeOp *pct1, *pct2, *pct3, *pct4;
+  unsigned int lit;
+  int same;
+
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+       if (AOP_TYPE(right) != AOP_LIT){
+               fprintf(stderr,"%s %d - right operand is not a literal\n",__FILE__,__LINE__);
+               exit(1);
+       }
+
+       lit = (unsigned int)floatFromVal(AOP(right)->aopu.aop_lit);
+       lit &= 0xffff;
+
+       same = pic16_sameRegs(AOP(left), AOP(result));
+       if(same) {
+               switch(lit) {
+                       case 0:
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0));
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),1));
+                               return;
+                       case 2:
+                               // its faster to left shift
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),0));
+                               pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),1));
+                               return;
+
+                       default: {
+                               DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+                               pct1 = pic16_popGetTempReg();
+                               pct2 = pic16_popGetTempReg();
+                               pct3 = pic16_popGetTempReg();
+                               pct4 = pic16_popGetTempReg();
+
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+                                       
+                               /* WREG still holds the low literal */
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+                                       
+                               /* load result */
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pct1, pic16_popGet(AOP(result), 0)));
+                               pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct2));
+                               pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+                               pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+                               pic16_popReleaseTempReg( pct4 );
+                               pic16_popReleaseTempReg( pct3 );
+                               pic16_popReleaseTempReg( pct2 );
+                               pic16_popReleaseTempReg( pct1 );
+                       }; return;
+               }
+       } else {
+               // operands different
+               switch(lit) {
+                       case 0:
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 0));
+                               pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), 1));
+                               return;
+                       case 2:
+                               emitCLRC;
+                               pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0));
+                               pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+                               return;
+                       default: {
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit & 0xff));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+                               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                                       pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+                                       
+                               /* WREG still holds the low literal */
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 1));
+                               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+                               pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+                                       
+                               pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit>>8 ));
+                               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(left), 0));
+                               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+                               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+
+                       }; return;
+               }
+       }
+}
+
+
+/*------------------------------------------------------------------*
+ * genUMult32X32_32 - unsigned multiplication of two 32-bit numbers *
+ *------------------------------------------------------------------*/
+void pic16_genUMult32X32_32 (operand *left,
+                          operand *right,
+                          operand *result)
+
+{
+  pCodeOp *pct1, *pct2, *pct3, *pct4;
+
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+
+       if (AOP_TYPE(right) == AOP_LIT) {
+               pic16_genUMult8XLit_8(left,right,result);
+         return;
+       }
+
+       /* cases:
+               A = A x B       B = A x B
+               A = B x C
+       */
+       /* if result == right then exchange left and right */
+       if(pic16_sameRegs(AOP(result), AOP(right))) {
+         operand *tmp;
+               tmp = left;
+               left = right;
+               right = tmp;
+       }
+
+
+       if(pic16_sameRegs(AOP(result), AOP(left))) {
+
+               pct1 = pic16_popGetTempReg();
+               pct2 = pic16_popGetTempReg();
+               pct3 = pic16_popGetTempReg();
+               pct4 = pic16_popGetTempReg();
+
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct1)));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodh), pic16_pCodeOpCopy(pct2)));
+                                       
+               /* WREG still holds the lower left */
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct3)));
+               
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_pCodeOpCopy(pct4)));
+                                       
+               /* load result */
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_pCodeOpCopy( pct1 ), pic16_popGet(AOP(result), 0)));
+               pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy( pct2 ));
+               pic16_emitpcode(POC_ADDFW, pic16_pCodeOpCopy(pct3));
+               pic16_emitpcode(POC_ADDFWC, pic16_pCodeOpCopy(pct4));
+               pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1));
+
+               pic16_popReleaseTempReg( pct4 );
+               pic16_popReleaseTempReg( pct3 );
+               pic16_popReleaseTempReg( pct2 );
+               pic16_popReleaseTempReg( pct1 );
+
+       } else {
+
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodl), pic16_popGet(AOP(result), 0)));
+               pic16_emitpcode(POC_MOVFF, pic16_popGet2p(
+                       pic16_popCopyReg(&pic16_pc_prodh), pic16_popGet(AOP(result), 1)));
+
+               /* WREG still holds the lower left */
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 1));
+               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+               pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 1));
+               
+               pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 1));
+               pic16_emitpcode(POC_MULWF, pic16_popGet(AOP(right), 0));
+               pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_prodl));
+               pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result), 1));
+       }       
+}
+
+
+/*-----------------------------------------------------------------*
+ * pic16_genMult32X32_32 - multiplication of two 32-bit numbers    *
+ *-----------------------------------------------------------------*/
+void pic16_genMult32X32_32 (operand *left,
+                        operand *right,
+                        operand *result)
+{
+       DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
+
+       if (AOP_TYPE(right) == AOP_LIT)
+               pic16_genUMult32XLit_32(left,right,result);
+       else
+               pic16_genUMult32X32_32(left,right,result);
+
 }
+
+
+
+
+
+
+
 #if 0
 /*-----------------------------------------------------------------*/
 /* constMult - generates code for multiplication by a constant     */
index 72037fe2f642bcf812f33927d63c13fd476dcca0..1d9c80d2e0f71869a88b8ca301f67607f7f581a3 100644 (file)
@@ -30,6 +30,7 @@
 #include "gen.h"
 #include "device.h"
 #include "main.h"
+#include <string.h>
 
 
 #ifdef WORDS_BIGENDIAN
@@ -121,17 +122,16 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 
                /* print the area name */
        for (sym = setFirstItem (map->syms); sym; sym = setNextItem (map->syms)) {
+
 #if 0
-               fprintf(stderr, "\t%s: sym: %s\tused: %d\textern: %d\n",
-                       map->sname, sym->name, sym->used, IS_EXTERN(sym->etype));
+               fprintf(stderr, "\t%s: sym: %s\tused: %d\textern: %d\tstatic: %d\n",
+                       map->sname, sym->name, sym->used, IS_EXTERN(sym->etype), IS_STATIC(sym->etype));
                printTypeChain( sym->type, stderr );
-               printf("\n");
+               fprintf(stderr, "\n");
 #endif
                /* if extern then add to externs */
                if (IS_EXTERN (sym->etype)) {
-//                     if(sym->used)                           // fixme
-                               checkAddSym(&externs, sym);
-//                             addSetHead(&externs, sym);
+                       checkAddSym(&externs, sym);
                        continue;
                }
                
@@ -153,14 +153,9 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                        (sym->_isparm && !IS_REGPARM (sym->etype))) &&
                        addPublics &&
                        !IS_STATIC (sym->etype) && !IS_FUNC(sym->type)) {
-//               regs *reg;
                  
                        checkAddSym(&publics, sym);
 //                     addSetHead(&publics, sym);
-
-//                     reg = pic16_allocRegByName(sym->name, sym->size);       //( operandFromSymbol( sym ));
-//                     checkAddReg(&pic16_rel_udata, reg);
-
                } else
                        if(IS_STATIC(sym->etype)) {
                          regs *reg;
@@ -170,6 +165,13 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                                        sym->name, sym->rname, sym->remat);
                                        
                                                //, OP_SYMBOL(operandFromSymbol(sym))->name);
+#define SET_IMPLICIT   1
+
+#if SET_IMPLICIT
+                               if(IS_STRUCT(sym->type))
+                                       sym->implicit = 1;
+#endif
+
                                reg = pic16_allocDirReg( operandFromSymbol( sym ));
                                checkAddReg(&pic16_rel_udata, reg);
                        }
@@ -220,19 +222,24 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                        /* emit only if it is global */
                        if(sym->level == 0) {
                          regs *reg;
-                         operand *op;
 
                                reg = pic16_dirregWithName( sym->name );
                                if(!reg) {
+                                       /* here */
 //                                     fprintf(stderr, "%s:%d: implicit add of symbol = %s\n",
 //                                                     __FUNCTION__, __LINE__, sym->name);
 
-                                       op = operandFromSymbol( sym );
-                                       reg = pic16_allocDirReg( op );
+                                       /* if IS_STRUCT is omitted the following
+                                        * fixes structures but break char/int etc */
+#if SET_IMPLICIT
+                                       if(IS_STRUCT(sym->type))
+                                               sym->implicit = 1;              // mark as implicit
+#endif
+                                       reg = pic16_allocDirReg( operandFromSymbol(sym) );
                                        if(reg) {
                                                if(checkAddReg(&pic16_fix_udata, reg)) {
                                                        /* and add to globals list if not exist */
-                                                       addSetHead(&publics, sym);
+                                                       addSet(&publics, sym);
                                                }
                                        }
                                }
@@ -245,6 +252,11 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                                 * level 0, so we must declare it fine as global */
                                
 //                             fprintf(stderr, "EXTRA symbol declaration sym= %s\n", sym->name);
+
+#if SET_IMPLICIT
+                               if(IS_STRUCT(sym->type))
+                                       sym->implicit = 1;              // mark as implicit
+#endif
                                reg = pic16_allocDirReg( operandFromSymbol( sym ) );
                                if(checkAddReg(&pic16_rel_udata, reg)) {
                                        addSetHead(&publics, sym);
@@ -544,7 +556,7 @@ pic16emitStaticSeg (memmap * map)
        sym = setNextItem (map->syms))
     {
 
-#if 1
+#if 0
        fprintf(stderr, "\t%s: sym: %s\tused: %d\n", map->sname, sym->name, sym->used);
        printTypeChain( sym->type, stderr );
        printf("\n");
index 86036f2d0f462f1b7e5e729b08089655692eb623..5685d878bf4398c209bb479cffaeafa547ea2e84 100644 (file)
@@ -421,7 +421,9 @@ _pic16_finaliseOptions (void)
        port->mem.default_globl_map = data;
 
        options.all_callee_saves = 1;           // always callee saves
-
+       options.float_rent = 1;
+       options.intlong_rent = 1;
+       
        setMainValue("mcu", pic16->name[2] );
        addSet(&preArgvSet, Safe_strdup("-D{mcu}"));
 
@@ -614,14 +616,26 @@ _pic16_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
   return TRUE;
 }
 
-static bool
-_hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
+/* return True if the port can handle the type,
+ * False to convert it to function call */
+static bool _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
 {
   //  sym_link *test = NULL;
   //  value *val;
 
 //  fprintf(stderr,"checking for native mult\n");
 
+       /* support mul for char/int */
+       if((getSize(OP_SYMBOL(IC_RESULT(ic))->type ) <= 2)
+               && (ic->op == '*'))return TRUE;
+       
+       /* support div for char */
+       if((getSize(OP_SYMBOL(IC_RESULT(ic))->type ) < 2)
+               && (ic->op == '/'))return TRUE;
+       
+  return FALSE;
+
+#if 0
   if ( ic->op != '*')
     {
       return FALSE;
@@ -656,6 +670,8 @@ _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
 
   return FALSE;
 */
+#endif
+
 }
 
 /* Indicate which extended bit operations this port supports */
index 1c445ca72d33e41c30d3f91e64fd6780b948b954..743b214e972afe8bdb3677824557e694396adac0 100644 (file)
@@ -3655,6 +3655,10 @@ pCode *pic16_newpCodeLabel(char *name, int key)
   if(s)
     pcl->label = Safe_strdup(s);
 
+//  if(pic16_pcode_verbose)
+//     fprintf(stderr, "%s:%d label name: %s\n", __FILE__, __LINE__, pcl->label);
+
+
   return ( (pCode *)pcl);
 
 }
@@ -5751,7 +5755,8 @@ static void LinkFlow(pBlock *pb)
       else
        fprintf(stderr, "ERROR: %s, couldn't find label. key=%d,lab=%s\n",
                __FUNCTION__,pcol->key,((PCOP(pcol)->name)?PCOP(pcol)->name:"-"));
-  //fprintf(stderr,"pic16_newpCodeOpLabel: key=%d, name=%s\n",key,((s)?s:""));
+
+//     fprintf(stderr,"pic16_newpCodeOpLabel: key=%d, name=%s\n",pcol->key,(PCOP(pcol)->name)?(PCOP(pcol)->name):"<unknown>");
 
       continue;
     }
@@ -6085,8 +6090,8 @@ static void pBlockRemoveUnusedLabels(pBlock *pb)
     if(pbr && pbr->next) {
       pCode *pcd = pb->pcHead;
 
-      //fprintf(stderr, "multiple labels\n");
-      //pc->print(stderr,pc);
+//     fprintf(stderr, "multiple labels\n");
+//     pc->print(stderr,pc);
 
       pbr = pbr->next;
       while(pbr) {
@@ -6112,7 +6117,7 @@ static void pBlockRemoveUnusedLabels(pBlock *pb)
       pcl = PCL(PCI(pc)->label->pc);
     else continue;
 
-       //fprintf(stderr," found  A LABEL !!! key = %d, %s\n", pcl->key,pcl->label);
+//     fprintf(stderr," found  A LABEL !!! key = %d, %s\n", pcl->key,pcl->label);
 
     /* This pCode is a label, so search the pBlock to see if anyone
      * refers to it */
@@ -6122,7 +6127,7 @@ static void pBlockRemoveUnusedLabels(pBlock *pb)
       /* 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, %s\n", pcl->key,pcl->label);
+//     fprintf(stderr," removed  A LABEL !!! key = %d, %s\n", pcl->key,pcl->label);
 
       DFPRINTF((stderr," !!! REMOVED A LABEL !!! key = %d, %s\n", pcl->key,pcl->label));
       if(pc->type == PC_LABEL) {
index 2ffbce10884f624d012649ece12b84f3754c8d3e..e8ff7b6a6fc93dc2c4127db74d06dbcd939f99e1 100644 (file)
@@ -509,8 +509,10 @@ allocReg (short type)
                reg->isLocal = 1;       /* this is a local frame register */
        }
        
-       if (currFunc)
+       if (currFunc) {
+//             fprintf(stderr, "%s:%d adding %s into function %s regsUsed\n", __FUNCTION__, __LINE__, reg->name, currFunc->name);
                currFunc->regsUsed = bitVectSetBit (currFunc->regsUsed, reg->rIdx);
+       }
  
   return (reg);                // addSet(&pic16_dynAllocRegs,reg);
 
@@ -656,11 +658,26 @@ pic16_allocDirReg (operand *op )
                if(!IS_CONFIG_ADDRESS(address)) {
 //                     fprintf(stderr,"%s:allocating new reg %s\n",__FUNCTION__, name);
 
-                       if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
-       
+                       /* this is an error, why added? -- VR */
+//                     if(SPEC_SCLS(OP_SYM_ETYPE(op)))regtype = REG_SFR;
+
+                       if(OP_SYMBOL(op)->onStack) {
+//                             fprintf(stderr, "%s:%d onStack %s\n", __FILE__, __LINE__, OP_SYMBOL(op)->name);
+                               OP_SYMBOL(op)->onStack = 0;
+                               SPEC_OCLS(OP_SYM_ETYPE(op)) = data;
+                               regtype = REG_GPR;
+                       }
+
                        if(!IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op)))) {                                               // patch 13
                                if(pic16_debug_verbose)                                                                 //
                                {                                                                                       //
+                                       fprintf(stderr, "dispace:%d farspace:%d codespace:%d regspace:%d stack:%d\n",
+                                               IN_DIRSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                                               IN_FARSPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                                               IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                                               IN_REGSP( SPEC_OCLS( OP_SYM_ETYPE(op))),
+                                               IN_STACK( OP_SYM_ETYPE(op)));
+
                                        fprintf(stderr, "%s:%d symbol %s NOT in dirspace\n", __FILE__, __LINE__,        //
                                                OP_SYMBOL(op)->name);                                                   //
                                }                                                                                       //
@@ -683,6 +700,7 @@ pic16_allocDirReg (operand *op )
                                reg->isBitField = 1;
                        } else {
 //                             fprintf(stderr, "%s:%d adding %s in direct registers\n", __FILE__, __LINE__, reg->name);
+//                             addSet(&pic16_dynDirectRegs, reg);
                                checkAddReg(&pic16_dynDirectRegs, reg);
                        }
        
@@ -699,8 +717,8 @@ pic16_allocDirReg (operand *op )
                reg->address = SPEC_ADDR ( OP_SYM_ETYPE(op));
 
                /* work around for user defined registers in access bank */
-               if((reg->address < 0x80)
-                       || (reg->address >= 0xf80))
+               if((reg->address>= 0x00 && reg->address < 0x80)
+                       || (reg->address >= 0xf80 && reg->address <= 0xfff))
                        reg->accessBank = 1;
                
                debugLog ("  -- and it is at a fixed address 0x%02x\n",reg->address);
@@ -2973,6 +2991,13 @@ packRegsForAssign (iCode * ic, eBBlock * ebp)
       OP_SYMBOL (IC_RESULT (ic))->iaccess)
     {
 
+#if 0
+       /* clear the onStack flag, the port doesn't support it yet! FIXME */
+       if(OP_SYMBOL(IC_RESULT(ic))->onStack)
+               OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
+#endif
+       
+
       /* the operation has only one symbol
          operator then we can pack */
       if ((IC_LEFT (dic) && !IS_SYMOP (IC_LEFT (dic))) ||
@@ -3070,6 +3095,11 @@ findAssignToSym (operand * op, iCode * ic)
              OP_SYMBOL (IC_RIGHT (dic))->onStack)
            {
 
+#if 0
+               if(OP_SYMBOL(IC_RESULT(ic))->onStack)
+                       OP_SYMBOL(IC_RESULT(ic))->onStack = 0;
+#endif
+
              if (IC_RESULT (ic)->key != IC_RIGHT (dic)->key &&
                  IC_LEFT (ic)->key != IC_RIGHT (dic)->key &&
                  IC_RIGHT (ic)->key != IC_RIGHT (dic)->key)