Fixed bug #621531 (const & volatile confusion in the type chain).
[fw/sdcc] / src / pic / gen.c
index c4a5a8bf023d0d7342aae133ad2ff34324ad7d9d..f8b48f8d243ca284937b96dfdb9a542947fccc0e 100644 (file)
@@ -1,5 +1,5 @@
 /*-------------------------------------------------------------------------
-  SDCCgen51.c - source file for code generation for 8051
+  gen.c - source file for code generation for pic
   
   Written By -  Sandeep Dutta . sandeep.dutta@usa.net (1998)
          and -  Jean-Louis VERN.jlvern@writeme.com (1999)
@@ -60,7 +60,7 @@ static int optimized_for_speed = 0;
 static int max_key=0;
 static int GpsuedoStkPtr=0;
 
-pCodeOp *popGetImmd(char *name, unsigned int offset, int index);
+pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
 unsigned int pic14aopLiteral (value *val, int offset);
 const char *AopType(short type);
 static iCode *ifxForOp ( operand *op, iCode *ic );
@@ -216,7 +216,6 @@ void emitpLabel(int key)
 
 void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
 {
-
   if(pcop)
     addpCode2pBlock(pb,newpCode(poc,pcop));
   else
@@ -230,6 +229,16 @@ void emitpcodeNULLop(PIC_OPCODE poc)
 
 }
 
+void emitpcodePagesel(const char *label)
+{
+
+  char code[81];
+  strcpy(code,"\tpagesel ");
+  strcat(code,label);
+  addpCode2pBlock(pb,newpCodeInlineP(code));
+
+}
+
 /*-----------------------------------------------------------------*/
 /* pic14_emitcode - writes the code into a file : for now it is simple    */
 /*-----------------------------------------------------------------*/
@@ -523,11 +532,19 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
 
     /* special case for a function */
     if (IS_FUNC(sym->type)) {   
+
+      sym->aop = aop = newAsmop(AOP_PCODE);
+      aop->aopu.pcop = popGetImmd(sym->rname,0,0,1);
+      PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
+      PCOI(aop->aopu.pcop)->_function = 1;
+      PCOI(aop->aopu.pcop)->index = 0;
+      aop->size = FPTRSIZE; 
+      /*
         sym->aop = aop = newAsmop(AOP_IMMD);    
-        //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1);
        aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1);
         strcpy(aop->aopu.aop_immd,sym->rname);
         aop->size = FPTRSIZE; 
+      */
        DEBUGpic14_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname);
         return aop;
     }
@@ -537,7 +554,7 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result)
     /* in which case DPTR gets the address */
     sym->aop = aop = newAsmop(AOP_PCODE);
 
-    aop->aopu.pcop = popGetImmd(sym->rname,0,0);
+    aop->aopu.pcop = popGetImmd(sym->rname,0,0,0);
     PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space);
     PCOI(aop->aopu.pcop)->index = 0;
 
@@ -592,8 +609,12 @@ static asmop *aopForRemat (operand *op) // x symbol *sym)
   }
 
   offset = OP_SYMBOL(IC_LEFT(ic))->offset;
-  aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val);
+  aop->aopu.pcop = popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val,0);
+#if 0
   PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op));
+#else
+  PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op));
+#endif
   PCOI(aop->aopu.pcop)->index = val;
 
   DEBUGpic14_emitcode(";","%d: rname %s, val %d, const = %d",
@@ -746,7 +767,11 @@ void aopOp (operand *op, iCode *ic, bool result)
 
     {
       sym_link *type = operandType(op);
+#if 0
       if(IS_PTR_CONST(type))
+#else
+      if(IS_CODEPTR(type))
+#endif
        DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
     }
 
@@ -865,7 +890,11 @@ void aopOp (operand *op, iCode *ic, bool result)
 
     {
       sym_link *type = operandType(op);
+#if 0
       if(IS_PTR_CONST(type)) 
+#else
+      if(IS_CODEPTR(type)) 
+#endif
        DEBUGpic14_emitcode(";","%d aop type is const pointer",__LINE__);
     }
 
@@ -1174,12 +1203,28 @@ pCodeOp *popGetLabel(unsigned int key)
 
   DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
 
-  if(key>max_key)
+  if(key>(unsigned int)max_key)
     max_key = key;
 
   return newpCodeOpLabel(NULL,key+100+labelOffset);
 }
 
+/*-------------------------------------------------------------------*/
+/* popGetLabel - create a new pCodeOp of type PO_LABEL with offset=1 */
+/*-------------------------------------------------------------------*/
+pCodeOp *popGetHighLabel(unsigned int key)
+{
+  pCodeOp *pcop;
+  DEBUGpic14_emitcode ("; ***","%s  key=%d, label offset %d",__FUNCTION__,key, labelOffset);
+
+  if(key>(unsigned int)max_key)
+    max_key = key;
+
+  pcop = newpCodeOpLabel(NULL,key+100+labelOffset);
+  PCOLAB(pcop)->offset = 1;
+  return pcop;
+}
+
 /*-----------------------------------------------------------------*/
 /* popCopyReg - copy a pcode operator                              */
 /*-----------------------------------------------------------------*/
@@ -1216,10 +1261,10 @@ pCodeOp *popGetLit(unsigned int lit)
 /*-----------------------------------------------------------------*/
 /* popGetImmd - asm operator to pcode immediate conversion         */
 /*-----------------------------------------------------------------*/
-pCodeOp *popGetImmd(char *name, unsigned int offset, int index)
+pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func)
 {
 
-  return newpCodeOpImmd(name, offset,index, 0);
+  return newpCodeOpImmd(name, offset,index, 0, is_func);
 }
 
 
@@ -1323,7 +1368,7 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
        
     case AOP_IMMD:
       DEBUGpic14_emitcode(";","%d",__LINE__);
-      return popGetImmd(aop->aopu.aop_immd,offset,0);
+      return popGetImmd(aop->aopu.aop_immd,offset,0,0);
 
     case AOP_DIR:
       return popRegFromString(aop->aopu.aop_dir, aop->size, offset);
@@ -1449,7 +1494,7 @@ void aopPut (asmop *aop, char *s, int offset)
              emitpcode(POC_CLRF,popGet(aop,offset));
              break;
            } else
-             emitpcode(POC_MOVLW,popGetImmd(s,offset,0));
+             emitpcode(POC_MOVLW,popGetImmd(s,offset,0,0));
          }
 
          emitpcode(POC_MOVWF,popGet(aop,offset));
@@ -1699,44 +1744,6 @@ static void reAdjustPreg (asmop *aop)
 
 }
 
-/*-----------------------------------------------------------------*/
-/* genNotFloat - generates not for float operations              */
-/*-----------------------------------------------------------------*/
-static void genNotFloat (operand *op, operand *res)
-{
-    int size, offset;
-    char *l;
-    symbol *tlbl ;
-
-    DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-    /* we will put 127 in the first byte of 
-    the result */
-    aopPut(AOP(res),"#127",0);
-    size = AOP_SIZE(op) - 1;
-    offset = 1;
-
-    l = aopGet(op->aop,offset++,FALSE,FALSE);
-    MOVA(l);    
-
-    while(size--) {
-        pic14_emitcode("orl","a,%s",
-                 aopGet(op->aop,
-                        offset++,FALSE,FALSE));
-    }
-    tlbl = newiTempLabel(NULL);
-
-    tlbl = newiTempLabel(NULL);
-    aopPut(res->aop,one,1);
-    pic14_emitcode("jz","%05d_DS_",(tlbl->key+100));
-    aopPut(res->aop,zero,1);
-    pic14_emitcode("","%05d_DS_:",(tlbl->key+100));
-
-    size = res->aop->size - 2;
-    offset = 2;    
-    /* put zeros in the rest */
-    while (size--) 
-        aopPut(res->aop,zero,offset++);
-}
 
 #if 0
 /*-----------------------------------------------------------------*/
@@ -1851,7 +1858,6 @@ void pic14_toBoolean(operand *oper)
 static void genNot (iCode *ic)
 {
   symbol *tlbl;
-  sym_link *optype = operandType(IC_LEFT(ic));
   int size;
 
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
@@ -1873,13 +1879,7 @@ static void genNot (iCode *ic)
     goto release;
   }
 
-  /* if type float then do float */
-  if (IS_FLOAT(optype)) {
-    genNotFloat(IC_LEFT(ic),IC_RESULT(ic));
-    goto release;
-  }
-
-  size = AOP_SIZE(IC_RESULT(ic));
+  size = AOP_SIZE(IC_LEFT(ic));
   if(size == 1) {
     emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
     emitpcode(POC_ANDLW,popGetLit(1));
@@ -2546,6 +2546,7 @@ static void genPcall (iCode *ic)
     }
 */
     emitpcode(POC_CALL,popGetLabel(albl->key));
+    emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
     emitpcode(POC_GOTO,popGetLabel(blbl->key));
     emitpLabel(albl->key);
 
@@ -2683,17 +2684,21 @@ static void genFunction (iCode *ic)
     }
 #endif
 
-    /* if this is an interrupt service routine then
-    save acc, b, dpl, dph  */
+    /* if this is an interrupt service routine */
     if (IFFUNC_ISISR(sym->type)) {
+/*  already done in pic14createInterruptVect() - delete me
       addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
       emitpcodeNULLop(POC_NOP);
       emitpcodeNULLop(POC_NOP);
       emitpcodeNULLop(POC_NOP);
+*/
       emitpcode(POC_MOVWF,  popCopyReg(&pc_wsave));
       emitpcode(POC_SWAPFW, popCopyReg(&pc_status));
       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
       emitpcode(POC_MOVWF,  popCopyReg(&pc_ssave));
+      emitpcode(POC_MOVFW,  popCopyReg(&pc_pclath));
+      emitpcode(POC_MOVWF,  popCopyReg(&pc_psave));
+      emitpcode(POC_CLRF,   popCopyReg(&pc_pclath));/* durring an interrupt PCLATH must be cleared before a goto or call statement */
 
       pBlockConvert2ISR(pb);
 #if 0  
@@ -2928,18 +2933,17 @@ static void genEndFunction (iCode *ic)
                pic14_emitcode(";","XG$%s$0$0 ==.",currFunc->name);
            _G.debugLine = 0;
        }
-       
-        pic14_emitcode ("reti","");
-
-       emitpcode(POC_CLRF,   popCopyReg(&pc_status));
-       emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
-       emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
-       emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
-       emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
-       addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
-
-       emitpcodeNULLop(POC_RETFIE);
 
+        pic14_emitcode ("reti","");
+        emitpcode(POC_MOVFW,  popCopyReg(&pc_psave));
+        emitpcode(POC_MOVWF,  popCopyReg(&pc_pclath));
+        emitpcode(POC_CLRF,   popCopyReg(&pc_status));
+        emitpcode(POC_SWAPFW, popCopyReg(&pc_ssave));
+        emitpcode(POC_MOVWF,  popCopyReg(&pc_status));
+        emitpcode(POC_SWAPF,  popCopyReg(&pc_wsave));
+        emitpcode(POC_SWAPFW, popCopyReg(&pc_wsave));
+        addpCode2pBlock(pb,newpCodeLabel("END_OF_INTERRUPT",-1));
+        emitpcodeNULLop(POC_RETFIE);
     }
     else {
         if (IFFUNC_ISCRITICAL(sym->type))
@@ -5416,7 +5420,7 @@ static void genAnd (iCode *ic, iCode *ifx)
            } else {
              pic14_emitcode("movlw","0x%x", (lit & 0xff));
              pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE));
-             if(know_W != (lit&0xff))
+             if(know_W != (int)(lit&0xff))
                emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
              know_W = lit &0xff;
              emitpcode(POC_ANDWF,popGet(AOP(left),offset));
@@ -5723,7 +5727,7 @@ static void genOr (iCode *ic, iCode *ifx)
              emitpcode(POC_BSF,
                        newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),p,0));
            } else {
-             if(know_W != (lit & 0xff))
+             if(know_W != (int)(lit & 0xff))
                emitpcode(POC_MOVLW, popGetLit(lit & 0xff));
              know_W = lit & 0xff;
              emitpcode(POC_IORWF, popGet(AOP(left),offset));
@@ -8362,6 +8366,7 @@ static void genConstPointerGet (operand *left,
   DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
 
   emitpcode(POC_CALL,popGetLabel(albl->key));
+  emitpcodePagesel(popGetLabel(blbl->key)->name); /* Must restore PCLATH before goto, without destroying W */
   emitpcode(POC_GOTO,popGetLabel(blbl->key));
   emitpLabel(albl->key);
 
@@ -8400,7 +8405,11 @@ static void genPointerGet (iCode *ic)
     type = operandType(left);
     etype = getSpec(type);
 
+#if 0
     if (IS_PTR_CONST(type))
+#else
+    if (IS_CODEPTR(type))
+#endif
       DEBUGpic14_emitcode ("; ***","%d - const pointer",__LINE__);
 
     /* if left is of type of pointer then it is simple */
@@ -8456,9 +8465,11 @@ static void genPointerGet (iCode *ic)
        break;
 
     case GPOINTER:
+#if 0
       if (IS_PTR_CONST(type))
        genConstPointerGet (left,result,ic);
       else
+#endif
        genGenPointerGet (left,result,ic);
       break;
     }
@@ -9320,7 +9331,7 @@ static void genAssign (iCode *ic)
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
     if(AOP_TYPE(right) == AOP_LIT) {
       if(lit&0xff) {
-       if(know_W != (lit&0xff))
+       if(know_W != (int)(lit&0xff))
          emitpcode(POC_MOVLW,popGetLit(lit&0xff));
        know_W = lit&0xff;
        emitpcode(POC_MOVWF, popGet(AOP(result),offset));
@@ -9335,13 +9346,8 @@ static void genAssign (iCode *ic)
        emitpcode(POC_BTFSS, popGet(AOP(right),0));
        emitpcode(POC_INCF, popGet(AOP(result),0));
       }
-    } else if (AOP_TYPE(right) == AOP_IMMD) {
-           DEBUGpic14_emitcode ("; ***","%s  %d AOP_IMMD",__FUNCTION__,__LINE__);
-           emitpcode(POC_MOVLW, popGet(AOP(right),offset));
-           emitpcode(POC_MOVWF, popGet(AOP(result),offset));
     } else {
-  DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
-      emitpcode(POC_MOVFW, popGet(AOP(right),offset));
+      mov2w (AOP(right), offset);
       emitpcode(POC_MOVWF, popGet(AOP(result),offset));
     }
            
@@ -9377,6 +9383,8 @@ static void genJumpTab (iCode *ic)
     pic14_emitcode("jmp","@a+dptr");
     pic14_emitcode("","%05d_DS_:",jtab->key+100);
 
+    emitpcode(POC_MOVLW, popGetHighLabel(jtab->key));
+    emitpcode(POC_MOVWF, popCopyReg(&pc_pclath));
     emitpcode(POC_MOVLW, popGetLabel(jtab->key));
     emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0));
     emitSKPNC;
@@ -9619,9 +9627,17 @@ static void genCast (iCode *ic)
        goto release;
 
       DEBUGpic14_emitcode("; ***","%s  %d",__FUNCTION__,__LINE__);
+#if 0
       if (IS_PTR_CONST(rtype))
+#else
+      if (IS_CODEPTR(rtype))
+#endif
        DEBUGpic14_emitcode ("; ***","%d - right is const pointer",__LINE__);
+#if 0
       if (IS_PTR_CONST(operandType(IC_RESULT(ic))))
+#else
+      if (IS_CODEPTR(operandType(IC_RESULT(ic))))
+#endif
        DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
 
       if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
@@ -9868,10 +9884,10 @@ static int genDjnz (iCode *ic, iCode *ifx)
 /* genReceive - generate code for a receive iCode                  */
 /*-----------------------------------------------------------------*/
 static void genReceive (iCode *ic)
-{    
+{
   DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
 
-  if (isOperandInFarSpace(IC_RESULT(ic)) && 
+  if (isOperandInFarSpace(IC_RESULT(ic)) &&
       ( OP_SYMBOL(IC_RESULT(ic))->isspilt ||
        IS_TRUE_SYMOP(IC_RESULT(ic))) ) {
 
@@ -9882,24 +9898,36 @@ static void genReceive (iCode *ic)
                                    fReturn[fReturnSizePic - offset - 1] : "acc"));
       offset++;
     }
-    aopOp(IC_RESULT(ic),ic,FALSE);  
+    aopOp(IC_RESULT(ic),ic,FALSE);
     size = AOP_SIZE(IC_RESULT(ic));
     offset = 0;
     while (size--) {
       pic14_emitcode ("pop","acc");
       aopPut (AOP(IC_RESULT(ic)),"a",offset++);
     }
-       
+
   } else {
     _G.accInUse++;
-    aopOp(IC_RESULT(ic),ic,FALSE);  
+    aopOp(IC_RESULT(ic),ic,FALSE);
     _G.accInUse--;
-    assignResultValue(IC_RESULT(ic));  
+    assignResultValue(IC_RESULT(ic));
   }
 
   freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
 }
 
+/*-----------------------------------------------------------------*/
+/* genDummyRead - generate code for dummy read of volatiles        */
+/*-----------------------------------------------------------------*/
+static void
+genDummyRead (iCode * ic)
+{
+  pic14_emitcode ("; genDummyRead","");
+  pic14_emitcode ("; not implemented","");
+
+  ic = ic;
+}
+
 /*-----------------------------------------------------------------*/
 /* genpic14Code - generate code for pic14 based controllers        */
 /*-----------------------------------------------------------------*/
@@ -10157,13 +10185,17 @@ void genpic14Code (iCode *lic)
            addSet(&_G.sendSet,ic);
            break;
 
+       case DUMMY_READ_VOLATILE:
+         genDummyRead (ic);
+         break;
+
        default :
            ic = ic;
         }
     }
-    
 
-    /* now we are ready to call the 
+
+    /* now we are ready to call the
        peep hole optimizer */
     if (!options.nopeep) {
       peepHole (&lineHead);