X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fgen.c;h=0f97a41d7865426e369cfde6c430ba0640c9894d;hb=59f25f3b7568d46895829357056cfa43cfb68037;hp=7370a3bace7d2812b1c364c66efc2f0431355aa1;hpb=b21f90fcfcda291d97c4fda8295df83dcde6f730;p=fw%2Fsdcc diff --git a/src/pic/gen.c b/src/pic/gen.c index 7370a3ba..0f97a41d 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -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 (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 @@ -35,13 +35,14 @@ #include #include #include "SDCCglobl.h" -#include "newalloc.h" +#include "newalloc.h" #include "common.h" #include "SDCCpeeph.h" #include "ralloc.h" #include "pcode.h" #include "gen.h" +#include "glue.h" /* When changing these, you must also update the assembler template * in device/lib/libsdcc/macros.inc */ @@ -59,6 +60,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 @@ -67,10 +69,10 @@ 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); -unsigned int pic14aopLiteral (value *val, int offset); const char *AopType(short type); #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0x00ff) @@ -189,7 +191,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; @@ -273,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) @@ -292,7 +301,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 +950,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 +964,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), @@ -1200,9 +1217,8 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname) return "AOP_accumulator_bug"; case AOP_LIT: - sprintf(s,"0x%02x", pic14aopLiteral (aop->aopu.aop_lit,offset)); - rs = Safe_calloc(1,strlen(s)+1); - strcpy(rs,s); + sprintf(s, "0x%02x", pic14aopLiteral (aop->aopu.aop_lit, offset)); + rs = Safe_strdup(s); return rs; case AOP_STR: @@ -1427,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) { @@ -2595,7 +2616,7 @@ static void genCall (iCode *ic) { sym_link *dtype; symbol *sym; - unsigned char *name; + char *name; int isExtern; FENTRY; @@ -2670,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 */ @@ -2878,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))); @@ -2909,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); @@ -2925,6 +2956,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"); @@ -5455,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; } @@ -5467,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; } @@ -5622,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++; } @@ -9346,38 +9399,6 @@ static void genPackBits(sym_link *etype,operand *result,operand *right,int p_typ assert( !"bitfields larger than 8 bits or crossing byte boundaries are not yet supported" ); } -unsigned long -bitpatternFromVal (value *val) -{ - union { - float d; - unsigned long l; - } float_long; - - assert (sizeof (float) == sizeof (long)); - - //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)); - - switch (SPEC_NOUN(val->type)) - { - case V_INT: - case V_CHAR: - return (unsigned long)floatFromVal (val); - - case V_FLOAT: - case V_DOUBLE: - float_long.d = floatFromVal (val); - return float_long.l; - - default: - assert( !"unhandled value type" ); - break; - } - - float_long.d = floatFromVal (val); - return float_long.l; -} - /*-----------------------------------------------------------------*/ /* genDataPointerSet - remat pointer to data space */ /*-----------------------------------------------------------------*/ @@ -9396,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); @@ -9413,23 +9437,21 @@ 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) { - /* XXX: might be float... */ - unsigned int lit = bitpatternFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); - lit = lit >> (8*offset); + unsigned int lit = pic14aopLiteral(AOP(IC_RIGHT(ic))->aopu.aop_lit, offset); //fprintf (stderr, "%s:%u: lit %d 0x%x\n", __FUNCTION__,__LINE__, lit, lit); if(lit&0xff) { emitpcode(POC_MOVLW, popGetLit(lit&0xff)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + emitpcode(POC_MOVWF, popGet(AOP(result), offset)); } else { - emitpcode(POC_CLRF, popGet(AOP(result),offset)); + emitpcode(POC_CLRF, popGet(AOP(result), offset)); } } else { //fprintf (stderr, "%s:%u: no lit\n", __FUNCTION__,__LINE__); - emitpcode(POC_MOVFW, popGet(AOP(right),offset)); - emitpcode(POC_MOVWF, popGet(AOP(result),offset)); + emitpcode(POC_MOVFW, popGet(AOP(right), offset)); + emitpcode(POC_MOVWF, popGet(AOP(result), offset)); } offset++; @@ -10080,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) { @@ -10096,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)); @@ -10106,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) { @@ -10585,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)); }