X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic%2Fgen.c;h=c3d8251e538ec7c077f6caed664756723e2d601f;hb=3062f96ccb55d1d05caf9c8782f4961f87b341ce;hp=652e84880a26e1e5d655a1fc54aa4ee85928f5fb;hpb=393452609b32a44881a3e964423d41c810e09001;p=fw%2Fsdcc diff --git a/src/pic/gen.c b/src/pic/gen.c index 652e8488..c3d8251e 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -44,11 +44,6 @@ #include "gen.h" #include "glue.h" -/* When changing these, you must also update the assembler template - * in device/lib/libsdcc/macros.inc */ -#define GPTRTAG_DATA 0x00 -#define GPTRTAG_CODE 0x80 - /* The PIC port(s) need not differentiate between POINTER and FPOINTER. */ #define PIC_IS_DATA_PTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x)) #define PIC_IS_FARPTR(x) (PIC_IS_DATA_PTR(x)) @@ -69,6 +64,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); @@ -81,8 +77,8 @@ kludgy & hacky stuff. This is what it is all about CODE GENERATION for a specific MCU . some of the routines may be reusable, will have to see */ -static char *zero = "#0x00"; -static char *one = "#0x01"; +static char *zero = "0x00"; +static char *one = "0x01"; static char *spname = "sp"; char *fReturnpic14[] = {"temp1","temp2","temp3","temp4" }; @@ -115,7 +111,7 @@ typedef struct resolvedIfx { extern int pic14_ptrRegReq ; extern int pic14_nRegs; -extern FILE *codeOutFile; +extern struct dbuf_s *codeOutBuf; static void saverbank (int, iCode *,bool); static lineNode *lineHead = NULL; @@ -300,7 +296,7 @@ void pic14_emitcode (char *inst,char *fmt, ...) { va_list ap; char lb[INITIAL_INLINEASM]; - unsigned char *lbp = (unsigned char *)lb; + char *lbp = lb; va_start(ap,fmt); @@ -321,6 +317,7 @@ void pic14_emitcode (char *inst,char *fmt, ...) (lineHead = newLineNode(lb))); lineCurr->isInline = _G.inLine; lineCurr->isDebug = _G.debugLine; + lineCurr->isLabel = (lbp[strlen (lbp) - 1] == ':'); if(debug_verbose) addpCode2pBlock(pb,newpCodeCharP(lb)); @@ -514,84 +511,7 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) if (sym->aop) return sym->aop; -#if 0 - /* 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) { - sym->aop = aop = newAsmop(0); - aop->aopu.aop_ptr = getFreePtr(ic,&aop,result); - aop->size = getSize(sym->type); - - /* now assign the address of the variable to - the pointer register */ - if (aop->type != AOP_STK) { - - if (sym->onStack) { - if ( _G.accInUse ) - pic14_emitcode("push","acc"); - - pic14_emitcode("mov","a,_bp"); - pic14_emitcode("add","a,#0x%02x", - ((sym->stack < 0) ? - ((char)(sym->stack - _G.nRegsSaved )) : - ((char)sym->stack)) & 0xff); - pic14_emitcode("mov","%s,a", - aop->aopu.aop_ptr->name); - - if ( _G.accInUse ) - pic14_emitcode("pop","acc"); - } else - pic14_emitcode("mov","%s,#%s", - aop->aopu.aop_ptr->name, - sym->rname); - aop->paged = space->paged; - } else - aop->aopu.aop_stk = sym->stack; - return aop; - } - - if (sym->onStack && options.stack10bit) - { - /* It's on the 10 bit stack, which is located in - * far data space. - */ - - //DEBUGpic14_emitcode(";","%d",__LINE__); - - if ( _G.accInUse ) - pic14_emitcode("push","acc"); - - pic14_emitcode("mov","a,_bp"); - pic14_emitcode("add","a,#0x%02x", - ((sym->stack < 0) ? - ((char)(sym->stack - _G.nRegsSaved )) : - ((char)sym->stack)) & 0xff); - - genSetDPTR(1); - pic14_emitcode ("mov","dpx1,#0x40"); - pic14_emitcode ("mov","dph1,#0x00"); - pic14_emitcode ("mov","dpl1, a"); - genSetDPTR(0); - - if ( _G.accInUse ) - pic14_emitcode("pop","acc"); - - sym->aop = aop = newAsmop(AOP_DPTR2); - aop->size = getSize(sym->type); - return aop; - } -#endif - //DEBUGpic14_emitcode(";","%d",__LINE__); - /* if in bit space */ - if (IN_BITSPACE(space)) { - sym->aop = aop = newAsmop (AOP_CRY); - aop->aopu.aop_dir = sym->rname ; - aop->size = getSize(sym->type); - //DEBUGpic14_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); - return aop; - } /* if it is in direct space */ if (IN_DIRSPACE(space)) { sym->aop = aop = newAsmop (AOP_DIR); @@ -1107,6 +1027,7 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname) //DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* offset is greater than size then zero */ + assert(aop); if (offset > (aop->size - 1) && aop->type != AOP_LIT) return zero; @@ -1234,6 +1155,9 @@ char *aopGet (asmop *aop, int offset, bool bit16, bool dname) pCodeOp *pcop = aop->aopu.pcop; DEBUGpic14_emitcode(";","%d: aopGet AOP_PCODE type %s",__LINE__,pCodeOpType(pcop)); if(pcop->name) { + if (pcop->type == PO_IMMEDIATE) { + offset += PCOI(pcop)->index; + } if (offset) { DEBUGpic14_emitcode(";","%s offset %d",pcop->name,offset); sprintf(s,"(%s+%d)", pcop->name,offset); @@ -2690,13 +2614,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 */ @@ -2848,12 +2777,6 @@ static int resultRemat (iCode *ic) return 0; } -#if defined(__BORLANDC__) || defined(_MSC_VER) -#define STRCASECMP stricmp -#else -#define STRCASECMP strcasecmp -#endif - #if 0 /*-----------------------------------------------------------------*/ /* inExcludeList - return 1 if the string is in exclude Reg list */ @@ -2932,7 +2855,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); @@ -3445,22 +3370,24 @@ static void genDivOneByte (operand *left, operand *result) { int size; + int sign; FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - assert (AOP_SIZE(result) == 1); assert (AOP_SIZE(right) == 1); assert (AOP_SIZE(left) == 1); size = min(AOP_SIZE(result),AOP_SIZE(left)); + sign = !(SPEC_USIGN(operandType(left)) + && SPEC_USIGN(operandType(right))); if (AOP_TYPE(right) == AOP_LIT) { /* XXX: might add specialized code */ } - if (SPEC_USIGN(operandType(left)) && SPEC_USIGN(operandType(right))) + if (!sign) { /* unsigned division */ #if 1 @@ -3520,7 +3447,7 @@ static void genDivOneByte (operand *left, } /* now performed the signed/unsigned division -- extend result */ - addSign(result, 1, !SPEC_USIGN(operandType(result))); + addSign(result, 1, sign); } /*-----------------------------------------------------------------*/ @@ -3562,29 +3489,6 @@ release : freeAsmop(result,NULL,ic,TRUE); } -/*-----------------------------------------------------------------*/ -/* genModbits :- modulus of bits */ -/*-----------------------------------------------------------------*/ -static void genModbits (operand *left, - operand *right, - operand *result) -{ - - char *l; - - FENTRY; - /* the result must be bit */ - pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - l = aopGet(AOP(left),0,FALSE,FALSE); - - MOVA(l); - - pic14_emitcode("div","ab"); - pic14_emitcode("mov","a,b"); - pic14_emitcode("rrc","a"); - aopPut(AOP(result),"c",0); -} - /*-----------------------------------------------------------------*/ /* genModOneByte : 8 bit modulus */ /*-----------------------------------------------------------------*/ @@ -3593,22 +3497,24 @@ static void genModOneByte (operand *left, operand *result) { int size; + int sign; FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - assert (AOP_SIZE(result) == 1); assert (AOP_SIZE(right) == 1); assert (AOP_SIZE(left) == 1); size = min(AOP_SIZE(result),AOP_SIZE(left)); + sign = !(SPEC_USIGN(operandType(left)) + && SPEC_USIGN(operandType(right))); if (AOP_TYPE(right) == AOP_LIT) { /* XXX: might add specialized code */ } - if (SPEC_USIGN(operandType(left)) && SPEC_USIGN(operandType(right))) + if (!sign) { /* unsigned division */ #if 1 @@ -3668,7 +3574,7 @@ static void genModOneByte (operand *left, } /* now we performed the signed/unsigned modulus -- extend result */ - addSign(result, 1, !SPEC_USIGN(operandType(result))); + addSign(result, 1, sign); } /*-----------------------------------------------------------------*/ @@ -3687,14 +3593,6 @@ static void genMod (iCode *ic) aopOp (right,ic,FALSE); aopOp (result,ic,TRUE); - /* special cases first */ - /* both are bits */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right)== AOP_CRY) { - genModbits(left,right,result); - goto release ; - } - /* if both are of size == 1 */ if (AOP_SIZE(left) == 1 && AOP_SIZE(right) == 1 ) { @@ -5479,7 +5377,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; } @@ -5491,7 +5393,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; } @@ -5646,16 +5552,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++; } @@ -10644,7 +10563,9 @@ void genpic14Code (iCode *lic) } if (options.iCodeInAsm) { + char *iLine = printILine(ic); emitpComment ("[ICODE] %s:%d: %s", ic->filename, ic->lineno, printILine (ic)); + dbuf_free(iLine); } /* if the result is marked as spilt and rematerializable or code for @@ -10854,7 +10775,7 @@ void genpic14Code (iCode *lic) peepHole (&lineHead); } /* now do the actual printing */ - printLine (lineHead,codeOutFile); + printLine (lineHead,codeOutBuf); #ifdef PCODE_DEBUG DFPRINTF((stderr,"printing pBlock\n\n")); @@ -10892,3 +10813,4 @@ op_isLitLike (operand *op) if (IS_PTR(OP_SYM_TYPE(op)) && AOP_TYPE(op) == AOP_PCODE && AOP(op)->aopu.pcop->type == PO_IMMEDIATE) return 1; return 0; } +