* src/pic/device.c (create_pic,ram_map): add memRange entries to PIC
[fw/sdcc] / src / pic / gen.c
index 931f82d364af143c72046511004cb05caf370fa4..0f97a41d7865426e369cfde6c430ba0640c9894d 100644 (file)
@@ -69,6 +69,7 @@ for the next function.
 */
 static int max_key=0;
 static int GpsuedoStkPtr=0;
+static int pic14_inISR = 0;
 
 pCodeOp *popGetImmd(char *name, unsigned int offset, int index,int is_func);
 extern char *get_op( pCodeOp *pcop,char *buff,size_t buf_size);
@@ -274,8 +275,15 @@ void emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop)
 {
        if(pcop)
                addpCode2pBlock(pb,newpCode(poc,pcop));
-       else
+       else {
+               static int has_warned = 0;
+               
                DEBUGpic14_emitcode(";","%s  ignoring NULL pcop",__FUNCTION__);
+               if (!has_warned) {
+                       has_warned = 1;
+                       fprintf( stderr, "WARNING: encountered NULL pcop--this is probably a compiler bug...\n" );
+               }
+       }
 }
 
 void emitpcodeNULLop(PIC_OPCODE poc)
@@ -1435,10 +1443,15 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname)
 
        assert (aop);
 
+
        /* XXX: still needed for BIT operands (AOP_CRY) */
        if (offset > (aop->size - 1) &&
-               aop->type != AOP_LIT)
+               aop->type != AOP_LIT &&
+               aop->type != AOP_PCODE)
+       {
+               printf( "%s: (offset[%d] > AOP_SIZE(op)[%d]-1) && AOP_TYPE(op) != AOP_LIT)\n", __FUNCTION__, offset, aop->size);
                return NULL;  //zero;
+       }
        
        /* depending on type */
        switch (aop->type) {
@@ -2678,13 +2691,18 @@ static void genCall (iCode *ic)
        /* make the call */
        sym = OP_SYMBOL(IC_LEFT(ic));
        name = sym->rname[0] ? sym->rname : sym->name;
-       isExtern = IS_EXTERN(sym->etype);
+       isExtern = IS_EXTERN(sym->etype) || pic14_inISR;
        if (isExtern) {
-               emitpcode(POC_PAGESEL,popGetWithString(name,1)); /* Extern functions maybe on another page - must call pagesel */
+               /* Extern functions and ISRs maybe on a different page;
+                * must call pagesel */
+               emitpcode(POC_PAGESEL,popGetWithString(name,1));
        }
        emitpcode(POC_CALL,popGetWithString(name,isExtern));
        if (isExtern) {
-               emitpcode(POC_PAGESEL,popGetWithString("$",0)); /* May have returned from another page - must call pagesel to restore PCLATH before next goto or call instruction */
+               /* May have returned from a different page;
+                * must use pagesel to restore PCLATH before next
+                * goto or call instruction */
+               emitpcode(POC_PAGESEL,popGetWithString("$",0));
        }
        GpsuedoStkPtr=0;
        /* if we need assign a result value */
@@ -2886,6 +2904,9 @@ static void genFunction (iCode *ic)
        pic14_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name);
        pic14_emitcode(";","-----------------------------------------");
        
+       /* prevent this symbol from being emitted as 'extern' */
+       pic14_stringInSet(sym->rname, &pic14_localFunctions, 1);
+
        pic14_emitcode("","%s:",sym->rname);
        addpCode2pBlock(pb,newpCodeFunction(NULL,sym->rname,!IS_STATIC (sym->etype)));
        
@@ -2917,7 +2938,9 @@ static void genFunction (iCode *ic)
 #endif
        
        /* if this is an interrupt service routine */
+       pic14_inISR = 0;
        if (IFFUNC_ISISR(sym->type)) {
+               pic14_inISR = 1;
        /*  already done in pic14createInterruptVect() - delete me
        addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("END_OF_INTERRUPT+1",PO_STR)));
        emitpcodeNULLop(POC_NOP);
@@ -5464,7 +5487,11 @@ static void continueIfTrue (iCode *ic)
        FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        if(IC_TRUE(ic))
-               pic14_emitcode("ljmp","%05d_DS_",IC_TRUE(ic)->key+100);
+       {
+               // Why +100?!?
+               emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100));
+               pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
+       }
        ic->generated = 1;
 }
 
@@ -5476,7 +5503,11 @@ static void jumpIfTrue (iCode *ic)
        FENTRY;
        DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
        if(!IC_TRUE(ic))
+       {
+               // Why +100?!?
+               emitpcode(POC_GOTO, popGetLabel(IC_TRUE(ic)->key+100));
                pic14_emitcode("ljmp","%05d_DS_",IC_FALSE(ic)->key+100);
+       }
        ic->generated = 1;
 }
 
@@ -5631,16 +5662,29 @@ static void genAnd (iCode *ic, iCode *ifx)
                                pic14_emitcode("setb","c");
                        while(sizel--){
                                if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){
-                                       MOVA( aopGet(AOP(left),offset,FALSE,FALSE));
+                                       mov2w( AOP(left), offset);
                                        // byte ==  2^n ?
-                                       if((posbit = isLiteralBit(bytelit)) != 0)
+                                       if((posbit = isLiteralBit(bytelit)) != 0) {
+                                               emitpcode(rIfx.condition ? POC_BTFSC : POC_BTFSS, // XXX: or the other way round?
+                                                       newpCodeOpBit(aopGet(AOP(left),offset,FALSE,FALSE),posbit - 1, 0));
                                                pic14_emitcode("jb","acc.%d,%05d_DS_",(posbit-1)&0x07,tlbl->key+100);
+                                       }
                                        else{
+                                               emitpcode(POC_ANDLW, newpCodeOpLit(bytelit & 0x0ff));
+                                               if (rIfx.condition) emitSKPZ;
+                                               else emitSKPNZ;
+                                               
                                                if(bytelit != 0x0FFL)
+                                               {
                                                        pic14_emitcode("anl","a,%s",
                                                        aopGet(AOP(right),offset,FALSE,TRUE));
+                                               }
                                                pic14_emitcode("jnz","%05d_DS_",tlbl->key+100);
                                        }
+
+                                       emitpcode(POC_GOTO, popGetLabel(rIfx.lbl->key));
+                                       ifx->generated = 1;
+                                               
                                }
                                offset++;
                        }
@@ -9373,7 +9417,10 @@ static void genDataPointerSet(operand *right,
        assert (IS_SYMOP(result));
        assert (IS_PTR(OP_SYM_TYPE(result)));
        
-       size = AOP_SIZE(right);
+       if (AOP_TYPE(right) == AOP_LIT)
+         size = 4;
+       else
+         size = AOP_SIZE(right);
        ressize = getSize(OP_SYM_ETYPE(result));
        if (size > ressize) size = ressize;
        //fprintf (stderr, "%s:%u: size(right): %d, size(result): %d\n", __FUNCTION__,__LINE__, AOP_SIZE(right), ressize);
@@ -9390,7 +9437,7 @@ static void genDataPointerSet(operand *right,
        
        // tsd, was l+1 - the underline `_' prefix was being stripped
        while (size--) {
-               emitpComment ("%s:%u: size=%d/%d, offset=%i", __FILE__,__LINE__, size, ressize, offset);
+               emitpComment ("%s:%u: size=%d/%d, offset=%d, AOP_TYPE(res)=%d", __FILE__,__LINE__, size, ressize, offset, AOP_TYPE(result));
                
                if (AOP_TYPE(right) == AOP_LIT) {
                        unsigned int lit = pic14aopLiteral(AOP(IC_RIGHT(ic))->aopu.aop_lit, offset);
@@ -10055,9 +10102,6 @@ static void genAssign (iCode *ic)
        /* general case */
        size = AOP_SIZE(result);
        offset = 0 ;
-       if(AOP_TYPE(right) == AOP_LIT)
-               lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-       
        if( AOP_TYPE(right) == AOP_DIR  && (AOP_TYPE(result) == AOP_REG) && size==1)  {
                DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
                if(aopIdx(AOP(result),0) == 4) {
@@ -10071,8 +10115,10 @@ static void genAssign (iCode *ic)
        
        know_W=-1;
        while (size--) {
+       
                DEBUGpic14_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
                if(AOP_TYPE(right) == AOP_LIT) {
+                       lit = (unsigned long)pic14aopLiteral(AOP(right)->aopu.aop_lit, offset) & 0x0ff;
                        if(lit&0xff) {
                                if(know_W != (int)(lit&0xff))
                                        emitpcode(POC_MOVLW,popGetLit(lit&0xff));
@@ -10081,8 +10127,6 @@ static void genAssign (iCode *ic)
                        } else
                                emitpcode(POC_CLRF, popGet(AOP(result),offset));
                        
-                       lit >>= 8;
-                       
                } else if (AOP_TYPE(right) == AOP_CRY) {
                        emitpcode(POC_CLRF, popGet(AOP(result),offset));
                        if(offset == 0) {
@@ -10560,6 +10604,7 @@ static void genReceive (iCode *ic)
                _G.accInUse++;
                aopOp(IC_RESULT(ic),ic,FALSE);
                _G.accInUse--;
+               GpsuedoStkPtr = ic->parmBytes; // address used arg on stack
                assignResultValue(IC_RESULT(ic));
        }