* support/regression/tests/structflexarray.c: flexible array members
[fw/sdcc] / src / pic / gen.c
index 4a4a18906c8bd0f0127f55cbb56259bbacc8d1b5..169fc0f3d620bc2bdb6b5aab1db0acde3dc40e94 100644 (file)
@@ -5,7 +5,7 @@
          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
   Bug Fixes  -  Wojciech Stryjewski  wstryj1@tiger.lsu.edu (1999 v2.1.9a)
   PIC port   -  Scott Dattalo scott@dattalo.com (2000)
-    cont'd   -  Raphael Neider rneider@web.de (2005)
+    cont'd   -  Raphael Neider <rneider AT web.de> (2005)
   
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#ifndef __sun__
+#if defined(_MSC_VER)
+       #include "pstdint.h"
+#else
+       #include <stdint.h>
+#endif
+#endif
 #include "SDCCglobl.h"
-#include "newalloc.h"
+#include "newalloc.h" 
 
 #include "common.h"
 #include "SDCCpeeph.h"
@@ -59,6 +66,7 @@ extern void printpBlock(FILE *of, pBlock *pb);
 
 static int labelOffset=0;
 extern int debug_verbose;
+extern int pic14_hasInterrupt;
 //static int optimized_for_speed = 0;
 
 /* max_key keeps track of the largest label number used in 
@@ -189,7 +197,7 @@ void DEBUGpic14_emitcode (char *inst,char *fmt, ...)
 {
        va_list ap;
        char lb[INITIAL_INLINEASM];  
-       unsigned char *lbp = lb;
+       unsigned char *lbp = (unsigned char *)lb;
        
        if(!debug_verbose && !options.debug)
                return;
@@ -292,7 +300,7 @@ void pic14_emitcode (char *inst,char *fmt, ...)
 {
        va_list ap;
        char lb[INITIAL_INLINEASM];  
-       unsigned char *lbp = lb;
+       unsigned char *lbp = (unsigned char *)lb;
        
        va_start(ap,fmt);   
        
@@ -941,9 +949,12 @@ void aopOp (operand *op, iCode *ic, bool result)
                /* else spill location  */
                if (sym->usl.spillLoc)
                {
+                       asmop *oldAsmOp = NULL;
+
                        if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
                        {
                                /* force a new aop if sizes differ */
+                               oldAsmOp = sym->usl.spillLoc->aop;
                                sym->usl.spillLoc->aop = NULL;
                        }
                        DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
@@ -952,6 +963,11 @@ void aopOp (operand *op, iCode *ic, bool result)
                                sym->rname, sym->usl.spillLoc->offset);
                
                        sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+                       if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
+                       {
+                               /* Don't reuse the new aop, go with the last one */
+                               sym->usl.spillLoc->aop = oldAsmOp;
+                       }
                        //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
                        aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, 
                                getSize(sym->type), 
@@ -2595,7 +2611,7 @@ static void genCall (iCode *ic)
 {
        sym_link *dtype;         
        symbol *sym;
-       unsigned char *name;
+       char *name;
        int isExtern;
        
        FENTRY;
@@ -2766,7 +2782,7 @@ static void genPcall (iCode *ic)
        */
        emitpcode(POC_CALL,popGetLabel(albl->key));
        pcop = popGetLabel(blbl->key);
-       emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
+       emitpcode(POC_PAGESEL,pcop); /* Must restore PCLATH before goto, without destroying W */
        emitpcode(POC_GOTO,pcop);
        emitpLabel(albl->key);
        
@@ -2925,6 +2941,7 @@ static void genFunction (iCode *ic)
                emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* during an interrupt PCLATH must be cleared before a goto or call statement */
                
                pBlockConvert2ISR(pb);
+               pic14_hasInterrupt = 1;
 #if 0  
                if (!inExcludeList("acc"))              
                        pic14_emitcode ("push","acc");  
@@ -9351,10 +9368,10 @@ bitpatternFromVal (value *val)
 {
   union {
     float d;
-    unsigned long l;
+    uint32_t l;
   } float_long;
 
-  assert (sizeof (float) == sizeof (long));
+  assert (sizeof (float) == sizeof (uint32_t));
 
   //fprintf (stderr, "%s:%u(%s): val=%lf, type: %d, etype: %d\n", __FILE__, __LINE__, __FUNCTION__, floatFromVal(val), SPEC_NOUN(val->type), SPEC_NOUN(val->etype));
 
@@ -9828,8 +9845,6 @@ static void genIfx (iCode *ic, iCode *popIc)
                pic14_toBoolean(cond);
        else
                isbit = 1;
-       /* the result is now in the accumulator */
-       freeAsmop(cond,NULL,ic,TRUE);
        
        /* if there was something to be popped then do it */
        if (popIc)
@@ -9837,11 +9852,32 @@ static void genIfx (iCode *ic, iCode *popIc)
        
        if (isbit)
        {
-               assert (!"genIfx not implemented for bit variables...");
+               /* This assumes that CARRY is set iff cond is true */
+               if (IC_TRUE(ic))
+               {
+                       assert (!IC_FALSE(ic));
+                       emitpcode(POC_BTFSC, popGet(AOP(cond), 0));
+                       //emitSKPNC;
+                       emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key));
+               } else {
+                       assert (IC_FALSE(ic));
+                       emitpcode(POC_BTFSS, popGet(AOP(cond), 0));
+                       //emitSKPC;
+                       emitpcode(POC_GOTO, popGetLabel(IC_FALSE(ic)->key));
+               }
+               if (0)
+               {
+                       static int hasWarned = 0;
+                       if (!hasWarned)
+                       {
+                               fprintf (stderr, "WARNING: using untested code for %s:%u -- please check the .asm output and report bugs.\n", ic->filename, ic->lineno);
+                               hasWarned = 1;
+                       }
+               }
        }
        else
        {
-               /* now Z if set iff !cond */
+               /* now Z is set iff !cond */
                if (IC_TRUE(ic))
                {
                        assert (!IC_FALSE(ic));
@@ -9855,6 +9891,8 @@ static void genIfx (iCode *ic, iCode *popIc)
        
        ic->generated = 1;
        
+       /* the result is now in the accumulator */
+       freeAsmop(cond,NULL,ic,TRUE);
 }
 
 /*-----------------------------------------------------------------*/