X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgen.c;h=1d4021ffa20c56194ec35d41b4f261f46dd6ca9b;hb=ebafd5b16dab393ffce489e5ea7aabcca02b652c;hp=e0cde477cbe746caf41159ebb9779806b7e5e2bf;hpb=e0ea74245f08e1b4b358059b8f314cf36705ba3b;p=fw%2Fsdcc diff --git a/src/pic16/gen.c b/src/pic16/gen.c index e0cde477..1d4021ff 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -6,6 +6,7 @@ Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a) PIC port - Scott Dattalo scott@dattalo.com (2000) PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002) + - Vangelis Rokas vrokas@otenet.gr (2003,2004) 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 @@ -49,15 +50,17 @@ extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); void pic16_genMult8X8_8 (operand *, operand *,operand *); +void pic16_genMult16X16_16(operand *, operand *, operand *); +void pic16_genMult32X32_32(operand *, operand *, operand *); pCode *pic16_AssembleLine(char *line, int peeps); extern void pic16_printpBlock(FILE *of, pBlock *pb); static asmop *newAsmop (short type); -static pCodeOp *pic16_popRegFromString(char *str, int size, int offset); +static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op); extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...); static void mov2w (asmop *aop, int offset); -static int aopIdx (asmop *aop, int offset); +//static int aopIdx (asmop *aop, int offset); -static int labelOffset=0; +int pic16_labelOffset=0; extern int pic16_debug_verbose; static int optimized_for_speed = 0; /* @@ -73,10 +76,19 @@ static int max_key=0; static int GpsuedoStkPtr=0; pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index); +pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst); + unsigned int pic16aopLiteral (value *val, int offset); const char *pic16_AopType(short type); static iCode *ifxForOp ( operand *op, iCode *ic ); +void pic16_pushpCodeOp(pCodeOp *pcop); +void pic16_poppCodeOp(pCodeOp *pcop); + +static bool is_LitOp(operand *op); +static bool is_LitAOp(asmop *aop); + + #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff) /* this is the down and dirty file with all kinds of @@ -88,23 +100,39 @@ static char *zero = "#0x00"; static char *one = "#0x01"; static char *spname = "sp"; + +/* + * Function return value policy (MSB-->LSB): + * 8 bits -> WREG + * 16 bits -> PRODL:WREG + * 24 bits -> PRODH:PRODL:WREG + * 32 bits -> FSR0L:PRODH:PRODL:WREG + * >32 bits -> on stack, and FSR0 points to the beginning + * + */ + + char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" }; //char *fReturn390[] = {"dpl","dph","dpx", "b","a" }; unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */ static char **fReturn = fReturnpic16; -static char *accUse[] = {"a","b"}; +static char *accUse[] = {"WREG"}; //static short rbank = -1; static struct { short r0Pushed; short r1Pushed; + short fsr0Pushed; short accInUse; short inLine; short debugLine; short nRegsSaved; + short ipushRegs; set *sendSet; + int interruptvector; + int usefastretfie; } _G; /* Resolved ifx structure. This structure stores information @@ -159,7 +187,6 @@ static int my_powof2 (unsigned long num) void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result) { - DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d", line_no, ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"), @@ -169,7 +196,6 @@ void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operan ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"), ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"), ((result) ? AOP_SIZE(result) : 0)); - } void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result) @@ -186,15 +212,12 @@ void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, op } -void pic16_emitcomment (char *fmt, ...) +void pic16_emitpcomment (char *fmt, ...) { va_list ap; char lb[INITIAL_INLINEASM]; char *lbp = lb; - if(!pic16_debug_verbose) - return; - va_start(ap,fmt); lb[0] = ';'; @@ -252,7 +275,12 @@ void DEBUGpic16_emitcode (char *inst,char *fmt, ...) void pic16_emitpLabel(int key) { - pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+labelOffset)); + pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,key+100+pic16_labelOffset)); +} + +void pic16_emitpLabelFORCE(int key) +{ + pic16_addpCode2pBlock(pb,pic16_newpCodeLabelFORCE(NULL,key+100+pic16_labelOffset)); } void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop) @@ -316,16 +344,79 @@ void pic16_emitcode (char *inst,char *fmt, ...) #endif +/*-----------------------------------------------------------------*/ +/* pic16_emitDebuggerSymbol - associate the current code location */ +/* with a debugger symbol */ +/*-----------------------------------------------------------------*/ +void +pic16_emitDebuggerSymbol (char * debugSym) +{ + _G.debugLine = 1; + pic16_emitcode (";", "%s ==.", debugSym); + _G.debugLine = 0; +} + + /*-----------------------------------------------------------------*/ /* getFreePtr - returns r0 or r1 whichever is free or can be pushed*/ /*-----------------------------------------------------------------*/ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) { - bool r0iu = FALSE , r1iu = FALSE; - bool r0ou = FALSE , r1ou = FALSE; +// bool r0iu = FALSE , r1iu = FALSE; +// bool r0ou = FALSE , r1ou = FALSE; + bool fsr0iu = FALSE, fsr0ou; + bool fsr2iu = FALSE, fsr2ou; + + fprintf(stderr, "%s:%d: getting free ptr from ic = %c result: %d\n", __FUNCTION__, __LINE__, ic->op, result); + + + fsr2iu = bitVectBitValue(ic->rUsed, IDX_FSR2); + fsr0iu = bitVectBitValue(ic->rUsed, IDX_FSR0); + + fsr2ou = bitVectBitValue(ic->rMask, IDX_FSR2); + fsr0ou = bitVectBitValue(ic->rMask, IDX_FSR0); + + if(bitVectBitValue(ic->rUsed, IDX_WREG)) { + fprintf(stderr, "%s:%d WREG is used by this ic\n", __FILE__, __LINE__); + DEBUGpic16_emitcode("%s:%d WREG is used by this ic", __FILE__, __LINE__); + } + + /* no usage of FSR2 */ + if(!fsr2iu && !fsr2ou) { + ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR2); + (*aopp)->type = AOP_FSR2; + + return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR2); + } + + if(!fsr0iu && !fsr0ou) { + ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0); + (*aopp)->type = AOP_FSR0; + + return ((*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR0)); + } + + /* now we know they both have usage */ + /* if fsr0 not used in this instruction */ + if (!fsr0iu) { + if (!_G.fsr0Pushed) { + pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) ); + pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) ); + _G.fsr0Pushed++; + } + + ic->rUsed = bitVectSetBit (ic->rUsed, IDX_FSR0); + (*aopp)->type = AOP_FSR0; + + return (*aopp)->aopu.aop_ptr = pic16_regWithIdx (IDX_FSR0); + } + - //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op); + fprintf(stderr, "%s:%d could not allocate a free pointer\n", __FILE__, __LINE__); + assert( 0 ); + return NULL; +#if 0 /* the logic: if r0 & r1 used in the instruction then we are in trouble otherwise */ @@ -399,6 +490,7 @@ endOfWorld : werror(E_INTERNAL_ERROR,__FILE__,__LINE__, "getFreePtr should never reach here"); exit(0); +#endif } /*-----------------------------------------------------------------*/ @@ -433,20 +525,24 @@ static void genSetDPTR(int n) /*-----------------------------------------------------------------*/ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) { + + DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + if(!resIfx) return; - // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); resIfx->condition = 1; /* assume that the ifx is true */ resIfx->generated = 0; /* indicate that the ifx has not been used */ if(!ifx) { resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */ -/* + +#if 1 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d", __FUNCTION__,__LINE__,resIfx->lbl->key); -*/ +#endif + } else { if(IC_TRUE(ifx)) { resIfx->lbl = IC_TRUE(ifx); @@ -454,15 +550,16 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) resIfx->lbl = IC_FALSE(ifx); resIfx->condition = 0; } -/* + +#if 1 if(IC_TRUE(ifx)) DEBUGpic16_emitcode("; ***","ifx true is non-null"); if(IC_FALSE(ifx)) DEBUGpic16_emitcode("; ***","ifx false is non-null"); -*/ +#endif } - // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset); + DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,pic16_labelOffset); } #if 0 @@ -476,29 +573,77 @@ static int pointerCode (sym_link *etype) } #endif + /*-----------------------------------------------------------------*/ /* aopForSym - for a true symbol */ /*-----------------------------------------------------------------*/ -static asmop *aopForSym (iCode *ic,symbol *sym,bool result) +static asmop *aopForSym (iCode *ic, operand *op, bool result) { + symbol *sym=OP_SYMBOL(op); asmop *aop; memmap *space= SPEC_OCLS(sym->etype); DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + +// sym = OP_SYMBOL(op); + /* if already has one */ if (sym->aop) { DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__); return sym->aop; } + /* if symbol was initially placed onStack then we must re-place it + * to direct memory, since pic16 does not have a specific stack */ + if(sym->onStack) { + fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name); + } + + +#if 1 /* 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) { + + DEBUGpic16_emitcode("; ***", "%s:%d sym->onStack:%d || sym->iaccess:%d", + __FUNCTION__, __LINE__, sym->onStack, sym->iaccess); + sym->aop = aop = newAsmop(0); aop->aopu.aop_ptr = getFreePtr(ic,&aop,result); aop->size = getSize(sym->type); + fprintf(stderr, "%s:%d\t%s\n", __FILE__, __LINE__, __FUNCTION__); + +#if 1 +// sym->aop = aop = newAsmop (AOP_REG); +// aop->aopu.aop_dir = sym->name; //sym->rname ; +// aop->aopu.aop_reg[0] = pic16_regWithIdx(IDX_PLUSW0); //pic16_pc_plusw2.r; +// aop->size = getSize(sym->type); + DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); + +// if(_G.accInUse) { +// pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) ); +// } + +// pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_fsr2l), pic16_popCopyReg(&pic16_pc_fsr0l))); +// pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popCopyReg(&pic16_pc_fsr2h), pic16_popCopyReg(&pic16_pc_fsr0h))); + + + /* initialise for stack access via frame pointer */ + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack)); + +// pic16_emitpcode(POC_MOVFF, pic16_popGet2p( +// pic16_popCopyReg(&pic16_pc_plusw2), pic16_popCopyReg(&pic16_pc_kzero))); + +// if(_G.accInUse) { +// pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) ); +// } + + return (aop); +#endif + +#if 0 /* now assign the address of the variable to the pointer register */ if (aop->type != AOP_STK) { @@ -525,8 +670,12 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) } else aop->aopu.aop_stk = sym->stack; return aop; +#endif + } - +#endif + +#if 0 if (sym->onStack && options.stack10bit) { /* It's on the 10 bit stack, which is located in @@ -557,14 +706,14 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) aop->size = getSize(sym->type); return aop; } - +#endif //DEBUGpic16_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); - //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); + DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); return aop; } /* if it is in direct space */ @@ -573,9 +722,20 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) aop->aopu.aop_dir = sym->rname ; aop->size = getSize(sym->type); DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); + pic16_allocDirReg( IC_LEFT(ic) ); + return aop; + } + + if (IN_FARSPACE(space)) { + sym->aop = aop = newAsmop (AOP_DIR); + aop->aopu.aop_dir = sym->rname ; + aop->size = getSize(sym->type); + DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); + pic16_allocDirReg( IC_LEFT(ic) ); return aop; } +#if 0 // patch 14 /* special case for a function */ if (IS_FUNC(sym->type)) { sym->aop = aop = newAsmop(AOP_IMMD); @@ -586,30 +746,43 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname); return aop; } +#endif // patch 14 /* only remaining is far space */ /* in which case DPTR gets the address */ sym->aop = aop = newAsmop(AOP_PCODE); - aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0); - PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space); - PCOI(aop->aopu.pcop)->index = 0; +/* change the next if to 1 to revert to good old immediate code */ + if(IN_CODESPACE(space)) { + aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0); + PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space); + PCOI(aop->aopu.pcop)->index = 0; + } else { + /* try to allocate via direct register */ + aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8 +// aop->size = getSize( sym->type ); + } - DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", - __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const); + DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", + __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const); - pic16_allocDirReg (IC_LEFT(ic)); +#if 0 + if(!pic16_allocDirReg (IC_LEFT(ic))) + return NULL; +#endif - aop->size = FPTRSIZE; -/* - DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname); - sym->aop = aop = newAsmop(AOP_DPTR); - pic16_emitcode ("mov","dptr,#%s", sym->rname); - aop->size = getSize(sym->type); + if(IN_DIRSPACE( space )) + aop->size = PTRSIZE; + else if(IN_CODESPACE( space ) || IN_FARSPACE( space )) + aop->size = FPTRSIZE; + else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) ); + else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) ); + else { + assert( 0 ); + } DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size); -*/ /* if it is in code space */ if (IN_CODESPACE(space)) @@ -624,52 +797,83 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) static asmop *aopForRemat (operand *op) // x symbol *sym) { symbol *sym = OP_SYMBOL(op); - iCode *ic = NULL; + iCode *ic = NULL, *oldic; asmop *aop = newAsmop(AOP_PCODE); int val = 0; int offset = 0; + int viaimmd=0; - ic = sym->rematiCode; - DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__); - if(IS_OP_POINTER(op)) { - DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__); - } - for (;;) { - if (ic->op == '+') { - val += (int) operandLitValue(IC_RIGHT(ic)); - } else if (ic->op == '-') { - val -= (int) operandLitValue(IC_RIGHT(ic)); - } else - break; + ic = sym->rematiCode; + + DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__); - ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; - } + if(IS_OP_POINTER(op)) { + DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__); + } + + for (;;) { + oldic = ic; + +// pic16_emitpcomment("ic: %s\n", printILine(ic)); + + if (ic->op == '+') { + val += (int) operandLitValue(IC_RIGHT(ic)); + } else if (ic->op == '-') { + val -= (int) operandLitValue(IC_RIGHT(ic)); + } else + break; + + ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; + } + + offset = OP_SYMBOL(IC_LEFT(ic))->offset; + + if(!op->isaddr)viaimmd++; else viaimmd=0; + +/* set the following if to 1 to revert to good old immediate code */ + if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))) + || viaimmd) { + + DEBUGpic16_emitcode("%s:%d immediate", __FILE__, __LINE__); + + aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val); - offset = OP_SYMBOL(IC_LEFT(ic))->offset; - aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val); #if 0 - PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op)); + PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op)); #else - PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op)); + PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op)); #endif - PCOI(aop->aopu.pcop)->index = val; - DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", - __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname, + PCOI(aop->aopu.pcop)->index = val; + } else { + DEBUGpic16_emitcode("%s:%d dir", __FILE__, __LINE__); + + aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname, + getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op); +// aop->size = AOP_SIZE( IC_LEFT(ic) ); + } + + + DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", + __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname, #if 0 - val, IS_PTR_CONST(operandType(op))); + val, IS_PTR_CONST(operandType(op))); #else - val, IS_CODEPTR(operandType(op))); + val, IS_CODEPTR(operandType(op))); #endif - // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic)))); +// DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic)))); - pic16_allocDirReg (IC_LEFT(ic)); + pic16_allocDirReg (IC_LEFT(ic)); + + if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) )) + aop->code = 1; return aop; } +#if 0 static int aopIdx (asmop *aop, int offset) { if(!aop) @@ -681,6 +885,8 @@ static int aopIdx (asmop *aop, int offset) return aop->aopu.aop_reg[offset]->rIdx; } +#endif + /*-----------------------------------------------------------------*/ /* regsInCommon - two operands have some registers in common */ /*-----------------------------------------------------------------*/ @@ -740,7 +946,8 @@ static bool operandsEqu ( operand *op1, operand *op2) if (sym1 == sym2) return TRUE ; - if (strcmp(sym1->rname,sym2->rname) == 0) + if (sym1->rname[0] && sym2->rname[0] + && strcmp (sym1->rname, sym2->rname) == 0) return TRUE; @@ -771,6 +978,11 @@ bool pic16_sameRegs (asmop *aop1, asmop *aop2 ) if (aop1 == aop2) return TRUE ; + DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s\n", __FUNCTION__, + pic16_AopType(aop1->type), pic16_AopType(aop2->type)); + + if(aop1->type == AOP_ACC && aop2->type == AOP_ACC)return TRUE; + if (aop1->type != AOP_REG || aop2->type != AOP_REG ) return FALSE ; @@ -798,7 +1010,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) if (!op) return ; -// DEBUGpic16_emitcode(";","%d",__LINE__); +// DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__); /* if this a literal */ if (IS_OP_LITERAL(op)) { @@ -832,7 +1044,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) /* if this is a true symbol */ if (IS_TRUE_SYMOP(op)) { DEBUGpic16_emitcode(";","%d - true symop",__LINE__); - op->aop = aopForSym(ic,OP_SYMBOL(op),result); + op->aop = aopForSym(ic, op, result); return ; } @@ -870,16 +1082,22 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) return; } +#if 1 if (sym->accuse) { int i; aop = op->aop = sym->aop = newAsmop(AOP_ACC); aop->size = getSize(sym->type); - for ( i = 0 ; i < 2 ; i++ ) - aop->aopu.aop_str[i] = accUse[i]; + for ( i = 0 ; i < 1 ; i++ ) { + aop->aopu.aop_str[i] = accUse[i]; +// aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset); + } + fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name); DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size); return; } +#endif +#if 1 if (sym->ruonly ) { /* sym->aop = op->aop = aop = newAsmop(AOP_PCODE); @@ -898,7 +1116,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) DEBUGpic16_emitcode(";","%d",__LINE__); return; } - +#endif /* else spill location */ if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) { /* force a new aop if sizes differ */ @@ -913,7 +1131,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset); aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname, getSize(sym->type), - sym->usl.spillLoc->offset); + sym->usl.spillLoc->offset, op); aop->size = getSize(sym->type); return; @@ -959,8 +1177,24 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) /* depending on the asmop type only three cases need work AOP_RO , AOP_R1 && AOP_STK */ -#if 0 +#if 1 switch (aop->type) { + case AOP_FSR0 : + if (_G.fsr0Pushed ) { + if (pop) { + pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0h) ); + pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_fsr0l) ); +// pic16_emitcode ("pop","ar0"); + _G.fsr0Pushed--; + } + } + bitVectUnSetBit(ic->rUsed,IDX_FSR0); + break; + + case AOP_FSR2 : + bitVectUnSetBit(ic->rUsed,IDX_FSR2); + break; + case AOP_R0 : if (_G.r0Pushed ) { if (pop) { @@ -1050,73 +1284,47 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) char *rs; //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* offset is greater than - size then zero */ + + /* offset is greater than size then zero */ if (offset > (aop->size - 1) && aop->type != AOP_LIT) return zero; /* depending on type */ switch (aop->type) { - - case AOP_R0: - case AOP_R1: - DEBUGpic16_emitcode(";","%d",__LINE__); - /* if we need to increment it */ - while (offset > aop->coff) { - pic16_emitcode ("inc","%s",aop->aopu.aop_ptr->name); - aop->coff++; - } - - while (offset < aop->coff) { - pic16_emitcode("dec","%s",aop->aopu.aop_ptr->name); - aop->coff--; - } - - aop->coff = offset ; - if (aop->paged) { - pic16_emitcode("movx","a,@%s",aop->aopu.aop_ptr->name); - return (dname ? "acc" : "a"); - } - sprintf(s,"@%s",aop->aopu.aop_ptr->name); - rs = Safe_calloc(1,strlen(s)+1); - strcpy(rs,s); - return rs; - - case AOP_DPTR: - case AOP_DPTR2: - DEBUGpic16_emitcode(";","%d",__LINE__); - if (aop->type == AOP_DPTR2) - { - genSetDPTR(1); - } - - while (offset > aop->coff) { - pic16_emitcode ("inc","dptr"); - aop->coff++; - } - - while (offset < aop->coff) { - pic16_emitcode("lcall","__decdptr"); - aop->coff--; - } - - aop->coff = offset; - if (aop->code) { - pic16_emitcode("clr","a"); - pic16_emitcode("movc","a,@a+dptr"); + + case AOP_FSR0: + case AOP_FSR2: + sprintf(s, "%s", aop->aopu.aop_ptr->name); + rs = Safe_calloc(1, strlen(s)+1); + strcpy(rs, s); + return (rs); + +#if 0 + /* if we need to increment it */ + while (offset > aop->coff) + { + emitcode ("inc", "%s", aop->aopu.aop_ptr->name); + aop->coff++; } - else { - pic16_emitcode("movx","a,@dptr"); - } - - if (aop->type == AOP_DPTR2) - { - genSetDPTR(0); - } - - return (dname ? "acc" : "a"); - + + while (offset < aop->coff) + { + emitcode ("dec", "%s", aop->aopu.aop_ptr->name); + aop->coff--; + } + aop->coff = offset; + if (aop->paged) + { + emitcode ("movx", "a,@%s", aop->aopu.aop_ptr->name); + return (dname ? "acc" : "a"); + } + sprintf (s, "@%s", aop->aopu.aop_ptr->name); + rs = Safe_calloc (1, strlen (s) + 1); + strcpy (rs, s); + return rs; +#endif + case AOP_IMMD: if (bit16) @@ -1157,8 +1365,12 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) return aop->aopu.aop_dir; case AOP_ACC: - DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__); - return "AOP_accumulator_bug"; + DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d\toffset: %d",__LINE__, offset); +// fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__); +// assert( 0 ); +// return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug"; + rs = Safe_strdup("WREG"); + return (rs); case AOP_LIT: sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset)); @@ -1191,8 +1403,13 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) strcpy(rs,s); return rs; + case AOP_STK: +// pCodeOp *pcop = aop->aop + break; + } + fprintf(stderr, "%s:%d unsupported aop->type: %s\n", __FILE__, __LINE__, pic16_AopType(aop->type)); werror(E_INTERNAL_ERROR,__FILE__,__LINE__, "aopget got unsupported aop->type"); exit(0); @@ -1204,27 +1421,40 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) /*-----------------------------------------------------------------*/ pCodeOp *pic16_popGetTempReg(void) { - pCodeOp *pcop; + symbol *cfunc; - pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP); - if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { - PCOR(pcop)->r->wasUsed=1; - PCOR(pcop)->r->isFree=0; - } +// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + cfunc = currFunc; + currFunc = NULL; + + pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP); + if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { + PCOR(pcop)->r->wasUsed=1; + PCOR(pcop)->r->isFree=0; + + /* push value on stack */ + pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) ); + } + + currFunc = cfunc; return pcop; } /*-----------------------------------------------------------------*/ -/* pic16_popGetTempReg - create a new temporary pCodeOp */ +/* pic16_popReleaseTempReg - create a new temporary pCodeOp */ /*-----------------------------------------------------------------*/ void pic16_popReleaseTempReg(pCodeOp *pcop) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) - PCOR(pcop)->r->isFree = 1; - + if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { + PCOR(pcop)->r->isFree = 1; + + pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) ); + } } /*-----------------------------------------------------------------*/ /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */ @@ -1232,12 +1462,12 @@ void pic16_popReleaseTempReg(pCodeOp *pcop) pCodeOp *pic16_popGetLabel(unsigned int key) { - DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, labelOffset); + DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, pic16_labelOffset); if(key>max_key) max_key = key; - return pic16_newpCodeOpLabel(NULL,key+100+labelOffset); + return pic16_newpCodeOpLabel(NULL,key+100+pic16_labelOffset); } /*-----------------------------------------------------------------*/ @@ -1259,7 +1489,7 @@ pCodeOp *pic16_popCopyReg(pCodeOpReg *pc) pcor->rIdx = pc->rIdx; pcor->r->wasUsed=1; - //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx); +// DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx); return PCOP(pcor); } @@ -1286,7 +1516,6 @@ pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2) /*-----------------------------------------------------------------*/ pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index) { - return pic16_newpCodeOpImmd(name, offset,index, 0); } @@ -1312,14 +1541,14 @@ pCodeOp *pic16_popGetWithString(char *str) /*-----------------------------------------------------------------*/ /* pic16_popRegFromString - */ /*-----------------------------------------------------------------*/ -static pCodeOp *pic16_popRegFromString(char *str, int size, int offset) +static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op) { pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); pcop->type = PO_DIR; - DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str); -// fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size); + DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14 + // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size); if(!str) str = "BAD_STRING"; @@ -1333,13 +1562,14 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset) if(PCOR(pcop)->r == NULL) { // fprintf(stderr, "%s:%d - couldn't find %s in allocated regsters, size= %d ofs= %d\n", // __FUNCTION__, __LINE__, str, size, offset); - PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size); - //fprintf(stderr, "allocating new register -> %s\n", str); - DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset); +// PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size, op); + fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str); + +// DEBUGpic16_emitcode(";","%d %s size= %d offset=%d - had to alloc by reg name",__LINE__,pcop->name,size,offset); } else { - DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset); +// DEBUGpic16_emitcode(";","%d %s size= %d offset=%d",__LINE__,pcop->name,size,offset); } PCOR(pcop)->instance = offset; @@ -1355,6 +1585,7 @@ static pCodeOp *pic16_popRegFromIdx(int rIdx) pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); PCOR(pcop)->rIdx = rIdx; PCOR(pcop)->r = pic16_regWithIdx(rIdx); + PCOR(pcop)->r->isFree = 0; PCOR(pcop)->r->wasUsed = 1; @@ -1391,9 +1622,9 @@ pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset) /*--------------------------------------------------------------------------------.-*/ pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst) { - pCodeOpReg2 *pcop2; + pCodeOpReg2 *pcop2; - pcop2 = (pCodeOpReg2 *) src; + pcop2 = (pCodeOpReg2 *)src; pcop2->pcop2 = dst; return PCOP(pcop2); @@ -1428,17 +1659,16 @@ pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc) pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) { //char *s = buffer ; - //char *rs; - - pCodeOp *pcop; + char *rs; + pCodeOp *pcop; //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* offset is greater than size then zero */ - if (offset > (aop->size - 1) && - aop->type != AOP_LIT) - return NULL; //zero; +// if (offset > (aop->size - 1) && +// aop->type != AOP_LIT) +// return NULL; //zero; /* depending on type */ switch (aop->type) { @@ -1447,41 +1677,83 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) case AOP_R1: case AOP_DPTR: case AOP_DPTR2: - case AOP_ACC: DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type)); fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type)); + assert( 0 ); return NULL; - + + + case AOP_FSR0: + case AOP_FSR2: + pcop = Safe_calloc(1, sizeof(pCodeOpReg)); + PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */ + PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx ); + PCOR(pcop)->r->wasUsed = 1; + PCOR(pcop)->r->isFree = 0; + + PCOR(pcop)->instance = offset; + pcop->type = PCOR(pcop)->r->pc_type; + return (pcop); + case AOP_IMMD: DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__); return pic16_popGetImmd(aop->aopu.aop_immd,offset,0); + case AOP_ACC: + { + int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx; + + fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]); + + DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__); + + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx); + PCOR(pcop)->r->wasUsed=1; + PCOR(pcop)->r->isFree=0; + + PCOR(pcop)->instance = offset; + pcop->type = PCOR(pcop)->r->pc_type; +// rs = aop->aopu.aop_reg[offset]->name; +// DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs); + return pcop; + + +// return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset); +// return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]); + +// assert( 0 ); + } + case AOP_DIR: DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__); - return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset); + return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL); case AOP_REG: { int rIdx = aop->aopu.aop_reg[offset]->rIdx; DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__); + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); +// pcop->type = PO_GPR_REGISTER; PCOR(pcop)->rIdx = rIdx; - PCOR(pcop)->r = pic16_regWithIdx(rIdx); + PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx); PCOR(pcop)->r->wasUsed=1; PCOR(pcop)->r->isFree=0; PCOR(pcop)->instance = offset; pcop->type = PCOR(pcop)->r->pc_type; - //rs = aop->aopu.aop_reg[offset]->name; - //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs); + rs = aop->aopu.aop_reg[offset]->name; + DEBUGpic16_emitcode(";","%d regiser idx = %d name = %s",__LINE__,rIdx,rs); return pcop; } case AOP_CRY: DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__); - pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1); + pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1, PO_GPR_REGISTER); PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir); //if(PCOR(pcop)->r == NULL) //fprintf(stderr,"%d - couldn't find %s in allocated registers\n",__LINE__,aop->aopu.aop_dir); @@ -1506,12 +1778,21 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) */ case AOP_PCODE: - DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop), + DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop), __LINE__, - ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name")); + ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset); pcop = pic16_pCodeOpCopy(aop->aopu.pcop); - PCOI(pcop)->offset = offset; - return pcop; +#if 1 + switch( aop->aopu.pcop->type ) { + case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8 + case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break; + default: + assert( 0 ); /* should never reach here */; + } +#else + PCOI(pcop)->offset = offset; +#endif + return pcop; } werror(E_INTERNAL_ERROR,__FILE__,__LINE__, @@ -1755,28 +2036,30 @@ void pic16_aopPut (asmop *aop, char *s, int offset) static void mov2w (asmop *aop, int offset) { - if(!aop) - return; +// if(!aop) +// return; - DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset); + DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset); - if ( aop->type == AOP_PCODE || - aop->type == AOP_LIT ) - pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset)); - else - pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset)); + if(is_LitAOp(aop)) + pic16_emitpcode(POC_MOVLW,pic16_popGet(aop,offset)); + else + pic16_emitpcode(POC_MOVFW,pic16_popGet(aop,offset)); } -void pic16_pushpCodeOpReg(pCodeOpReg *pcop) +/* push pcop into stack */ +void pic16_pushpCodeOp(pCodeOp *pcop) { - pic16_emitpcode(POC_MOVFF, pic16_popCombine2(pcop, &pic16_pc_postdec1, 0)); +// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1))); } -void pic16_poppCodeOpReg(pCodeOpReg *pcop) +/* pop pcop from stack */ +void pic16_poppCodeOp(pCodeOp *pcop) { - pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, pcop, 0)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop)); } @@ -1932,19 +2215,31 @@ void pic16_outAcc(operand *result) } /*-----------------------------------------------------------------*/ -/* pic16_outBitC - output a bit C */ +/* pic16_outBitC - output a bit C */ +/* Move to result the value of Carry flag -- VR */ /*-----------------------------------------------------------------*/ void pic16_outBitC(operand *result) { + int i; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if the result is bit */ - if (AOP_TYPE(result) == AOP_CRY) + if (AOP_TYPE(result) == AOP_CRY) { + fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__); pic16_aopPut(AOP(result),"c",0); - else { + } else { + + i = AOP_SIZE(result); + while(i--) { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i)); + } + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0)); + +/* pic16_emitcode("clr","a ; %d", __LINE__); pic16_emitcode("rlc","a"); pic16_outAcc(result); +*/ } } @@ -2104,55 +2399,54 @@ static void genUminus (iCode *ic) int size, i; sym_link *optype, *rtype; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + /* assign asmops */ + pic16_aopOp(IC_LEFT(ic),ic,FALSE); + pic16_aopOp(IC_RESULT(ic),ic,TRUE); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* assign asmops */ - pic16_aopOp(IC_LEFT(ic),ic,FALSE); - pic16_aopOp(IC_RESULT(ic),ic,TRUE); - - /* if both in bit space then special - case */ - if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY && - AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { - - pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0)); - pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0)); - pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0)); + /* if both in bit space then special case */ + if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY + && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { - goto release; - } + pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0)); + pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0)); + + goto release; + } - optype = operandType(IC_LEFT(ic)); - rtype = operandType(IC_RESULT(ic)); + optype = operandType(IC_LEFT(ic)); + rtype = operandType(IC_RESULT(ic)); - /* if float then do float stuff */ - if (IS_FLOAT(optype)) { - genUminusFloat(IC_LEFT(ic),IC_RESULT(ic)); - goto release; - } + /* if float then do float stuff */ + if (IS_FLOAT(optype)) { + genUminusFloat(IC_LEFT(ic),IC_RESULT(ic)); + goto release; + } - /* otherwise subtract from zero by taking the 2's complement */ - size = AOP_SIZE(IC_LEFT(ic)); + /* otherwise subtract from zero by taking the 2's complement */ + size = AOP_SIZE(IC_LEFT(ic)); - for(i=0; iaopu.pcop->type == PO_DIR)? + + if(AOP(op)->aopu.pcop->type == PO_IMMEDIATE) { + pic16_emitpcode(POC_MOVFW, src); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset)); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + src, pic16_popGet(AOP(op), offset))); + } +} + /*-----------------------------------------------------------------*/ -/* assignResultValue - */ +/* assignResultValue - assign results to oper, rescall==1 is */ +/* called from genCall() or genPCall() */ /*-----------------------------------------------------------------*/ -static void assignResultValue(operand * oper) +static void assignResultValue(operand * oper, int rescall) { int size = AOP_SIZE(oper); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14 DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL); - if(!GpsuedoStkPtr) { -// DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr); - /* The last byte in the assignment is in W */ - size--; - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size)); - GpsuedoStkPtr++; - } - - while (size--) { -// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); -// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + if(rescall) { + /* assign result from a call/pcall function() */ -#if STACK_SUPPORT - if(USE_STACK) { - popaopidx(AOP(oper), size, GpsuedoStkPtr); + /* function results are stored in a special order, + * see top of file with Function return policy, or manual */ + + if(size <= 4) { + /* 8-bits, result in WREG */ + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0)); + + if(size>1) { + /* 16-bits, result in PRODL:WREG */ + pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl)); + } + + if(size>2) { + /* 24-bits, result in PRODH:PRODL:WREG */ + pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14 + } + + if(size>3) { + /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */ + pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14 + } } else { - pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr)); + /* >32-bits, result on stack, and FSR0 points to beginning. + * Fix stack when done */ + /* FIXME FIXME */ + while (size--) { +// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); +// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + + popaopidx(AOP(oper), size, GpsuedoStkPtr); + GpsuedoStkPtr++; + } + + /* fix stack */ + pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) )); + pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l )); + if(STACK_MODEL_LARGE) { + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h )); + } + } + } else { + if(!GpsuedoStkPtr) { +// DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr); + /* The last byte in the assignment is in W */ + size--; + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size)); + GpsuedoStkPtr++; } -#else - pic16_emitpcode(POC_MOVFW, pic16_popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr)); -#endif /* STACK_SUPPORT */ - GpsuedoStkPtr++; + while (size--) { +// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); +// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + + popaopidx(AOP(oper), size, GpsuedoStkPtr); + GpsuedoStkPtr++; + +#if 0 #if STACK_SUPPORT if(!USE_STACK) pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size)); #else pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size)); +#endif #endif + } } } @@ -2329,8 +2677,22 @@ static void assignResultValue(operand * oper) /*-----------------------------------------------------------------*/ static void genIpush (iCode *ic) { + int size, offset=0; DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); + + + pic16_aopOp(IC_LEFT(ic), ic, FALSE); + + + size = AOP_SIZE( IC_LEFT(ic) ); + + while(size--) { + mov2w( AOP(IC_LEFT(ic)), offset ); + pushw(); + offset++; + } + #if 0 int size, offset = 0 ; char *l; @@ -2533,6 +2895,11 @@ static void genCall (iCode *ic) saverbank(FUNC_REGBANK(dtype),ic,TRUE); + + /* initialise stackParms for IPUSH pushes */ +// stackParms = psuedoStkPtr; +// fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes); + /* if send set is not empty the assign */ if (_G.sendSet) { iCode *sic; @@ -2573,16 +2940,8 @@ static void genCall (iCode *ic) * register. The last byte of the last parameter is * passed in W. */ -#if STACK_SUPPORT - if(USE_STACK) { - pushw(); - --psuedoStkPtr; // sanity check - } else { - pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr)); - } -#else - pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr)); -#endif /* STACK_SUPPORT */ + pushw(); + --psuedoStkPtr; // sanity check } firstTimeThruLoop=0; @@ -2611,7 +2970,7 @@ static void genCall (iCode *ic) pic16_aopOp(IC_RESULT(ic),ic,FALSE); _G.accInUse--; - assignResultValue(IC_RESULT(ic)); + assignResultValue(IC_RESULT(ic), 1); DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, pic16_AopType(AOP_TYPE(IC_RESULT(ic)))); @@ -2619,8 +2978,11 @@ static void genCall (iCode *ic) pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE); } -#if STACK_SUPPORT - if(USE_STACK && stackParms>0) { + if(!stackParms && ic->parmBytes) { + stackParms = ic->parmBytes; + } + + if(stackParms>0) { pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms)); pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l )); if(STACK_MODEL_LARGE) { @@ -2628,7 +2990,181 @@ static void genCall (iCode *ic) pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h )); } } + + /* adjust the stack for parameters if required */ +// fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes); +#if 0 + if (ic->parmBytes) { + int i; + + if (ic->parmBytes > 3) { + pic16_emitcode("mov","a,%s",spname); + pic16_emitcode("add","a,#0x%02x", (- ic->parmBytes) & 0xff); + pic16_emitcode("mov","%s,a",spname); + } else + for ( i = 0 ; i < ic->parmBytes ;i++) + pic16_emitcode("dec","%s",spname); + } +#endif + +#if 0 + /* if register bank was saved then pop them */ + if (ic->bankSaved) + unsaverbank(FUNC_REGBANK(dtype),ic,TRUE); + + /* if we hade saved some registers then unsave them */ + if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype)) + unsaveRegisters (ic); #endif +} + + + +/*-----------------------------------------------------------------*/ // patch 14 +/* genPcall - generates a call by pointer statement */ +/*-----------------------------------------------------------------*/ + +// new version, created from genCall + +static void genPcall (iCode *ic) +{ + sym_link *dtype; + int stackParms=0; + symbol *retlbl = newiTempLabel(NULL); + pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key); + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + /* if caller saves & we have not saved then */ + if (!ic->regsSaved) + saveRegisters(ic); + + /* if we are calling a function that is not using + * the same register bank then we need to save the + * destination registers on the stack */ + dtype = operandType(IC_LEFT(ic)); + if (currFunc && dtype && + (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype)) && + IFFUNC_ISISR(currFunc->type) && + !ic->bankSaved) + + saverbank(FUNC_REGBANK(dtype),ic,TRUE); + + /* if send set is not empty the assign */ + if (_G.sendSet) { + iCode *sic; + + /* For the Pic port, there is no data stack. + * So parameters passed to functions are stored + * in registers. (The pCode optimizer will get + * rid of most of these :). */ + + int psuedoStkPtr=-1; + int firstTimeThruLoop = 1; + + _G.sendSet = reverseSet(_G.sendSet); + + /* First figure how many parameters are getting passed */ + for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) { + pic16_aopOp(IC_LEFT(sic),sic,FALSE); + psuedoStkPtr += AOP_SIZE(IC_LEFT(sic)); + pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE); + } + + stackParms = psuedoStkPtr; + + for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) { + int size, offset = 0; + + pic16_aopOp(IC_LEFT(sic),sic,FALSE); + size = AOP_SIZE(IC_LEFT(sic)); + + while (size--) { + DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, + pic16_AopType(AOP_TYPE(IC_LEFT(sic)))); + DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1); + + if(!firstTimeThruLoop) { + /* If this is not the first time we've been through the loop + * then we need to save the parameter in a temporary + * register. The last byte of the last parameter is + * passed in W. */ + + pushw(); + --psuedoStkPtr; // sanity check + } + + firstTimeThruLoop=0; + + mov2w (AOP(IC_LEFT(sic)), offset); + offset++; + } + pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); + } + _G.sendSet = NULL; + } + + pic16_aopOp(IC_LEFT(ic),ic,FALSE); + + // push return address + // push $ on return stack, then replace with retlbl + + pic16_emitpcodeNULLop(POC_PUSH); + + pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl)); + pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh)); + pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu)); + + /* make the call by writing the pointer into pc */ + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath))); + + // note: MOVFF to PCL not allowed + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl)); + + +// pic16_emitpcode(POC_GOTO, pic16_popGetLabel(retlbl->key)); +// pic16_emitpcodeNULLop(POC_NOP); +// pic16_emitpcodeNULLop(POC_NOP); + + /* return address is here: (X) */ + pic16_emitpLabelFORCE(retlbl->key); + +// pic16_emitpcodeNULLop(POC_NOP); + + pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE); + + GpsuedoStkPtr=0; + /* if we need assign a result value */ + if ((IS_ITEMP(IC_RESULT(ic)) && + (OP_SYMBOL(IC_RESULT(ic))->nRegs || + OP_SYMBOL(IC_RESULT(ic))->spildir )) || + IS_TRUE_SYMOP(IC_RESULT(ic)) ) { + + _G.accInUse++; + pic16_aopOp(IC_RESULT(ic),ic,FALSE); + _G.accInUse--; + + assignResultValue(IC_RESULT(ic), 1); + + DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, + pic16_AopType(AOP_TYPE(IC_RESULT(ic)))); + + pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE); + } + + if(stackParms>0) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms)); + pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l )); + if(STACK_MODEL_LARGE) { + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h )); + } + } /* adjust the stack for parameters if required */ // fprintf(stderr, "%s:%d: %s ic->parmBytes= %d\n", __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, ic->parmBytes); @@ -2654,6 +3190,10 @@ static void genCall (iCode *ic) unsaveRegisters (ic); } + +#if 0 // patch 14 +// old version, kept for reference + /*-----------------------------------------------------------------*/ /* genPcall - generates a call by pointer statement */ /*-----------------------------------------------------------------*/ @@ -2734,7 +3274,7 @@ static void genPcall (iCode *ic) pic16_aopOp(IC_RESULT(ic),ic,FALSE); _G.accInUse--; - assignResultValue(IC_RESULT(ic)); + assignResultValue(IC_RESULT(ic), 1); pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } @@ -2764,6 +3304,8 @@ static void genPcall (iCode *ic) unsaveRegisters (ic); } +#endif // patch 14 + /*-----------------------------------------------------------------*/ /* resultRemat - result is rematerializable */ @@ -2819,135 +3361,170 @@ static void genFunction (iCode *ic) { symbol *sym; sym_link *ftype; + + DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key); - DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key); - - labelOffset += (max_key+4); + pic16_labelOffset += (max_key+4); max_key=0; GpsuedoStkPtr=0; _G.nRegsSaved = 0; + + ftype = operandType(IC_LEFT(ic)); + sym = OP_SYMBOL(IC_LEFT(ic)); + + if(IFFUNC_ISISR(sym->type /*ftype*/)) { + /* create an absolute section at the interrupt vector: + * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */ + symbol *asym; + char asymname[128]; + pBlock *apb; + + { + int i, found=-1; + + sym = OP_SYMBOL( IC_LEFT(ic)); + for(i=0;i<=2;i++) { + if(interrupts[i]->name + && !STRCASECMP(interrupts[i]->name, sym->name)) { + found = i; + break; + } + } + + if(found == -1) { + fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n", + __FILE__, __LINE__, sym->name); + assert( 0 ); + } + _G.interruptvector = found; + } + + sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name); + asym = newSymbol(asymname, 0); + + apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section")); + pic16_addpBlock( apb ); + + pic16_addpCode2pBlock(apb, + pic16_newpCodeCharP(";-----------------------------------------")); + + + pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name)); + + pic16_addpCode2pBlock(apb, + pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname ))); + + /* mark the end of this tiny function */ + pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL)); + + { + absSym *abSym; + + abSym = Safe_calloc(1, sizeof(absSym)); + abSym->name = Safe_strdup( asymname ); + + switch( _G.interruptvector ) { + case 0: abSym->address = 0x000000; break; + case 1: abSym->address = 0x000008; break; + case 2: abSym->address = 0x000018; break; + } + + /* relocate interrupt vectors if needed */ + abSym->address += pic16_options.ivt_loc; + + addSet(&absSymSet, abSym); + } + } + + /* create the function header */ pic16_emitcode(";","-----------------------------------------"); - pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name); + pic16_emitcode(";"," function %s",sym->name); pic16_emitcode(";","-----------------------------------------"); pic16_emitcode("","%s:",sym->rname); pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname)); + { absSym *ab; for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet)) - if(strcmp(ab->name, sym->name)) { + if(!strcmp(ab->name, sym->name)) { pic16_pBlockConvert2Absolute(pb); break; } - + } - ftype = operandType(IC_LEFT(ic)); if(IFFUNC_ISNAKED(ftype)) { DEBUGpic16_emitcode("; ***", "_naked function, no prologue"); return; } - /* if critical function then turn interrupts off */ if (IFFUNC_ISCRITICAL(ftype)) pic16_emitcode("clr","ea"); - /* here we need to generate the equates for the - * register bank if required */ -#if 0 - if (FUNC_REGBANK(ftype) != rbank) { - int i ; - - rbank = FUNC_REGBANK(ftype); - for ( i = 0 ; i < pic16_nRegs ; i++ ) { - if (strcmp(regspic16[i].base,"0") == 0) - pic16_emitcode("","%s = 0x%02x", - regspic16[i].dname, - 8*rbank+regspic16[i].offset); - else - pic16_emitcode ("","%s = %s + 0x%02x", - regspic16[i].dname, - regspic16[i].base, - *rbank+regspic16[i].offset); - } - } -#endif - /* if this is an interrupt service routine then * save acc, b, dpl, dph */ if (IFFUNC_ISISR(sym->type)) { - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave)); - pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status)); - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave)); - - pic16_pBlockConvert2ISR(pb); -#if 0 - if (!inExcludeList("acc")) - pic16_emitcode ("push","acc"); - if (!inExcludeList("b")) - pic16_emitcode ("push","b"); - if (!inExcludeList("dpl")) - pic16_emitcode ("push","dpl"); - if (!inExcludeList("dph")) - pic16_emitcode ("push","dph"); - - if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) { - pic16_emitcode ("push", "dpx"); - - /* Make sure we're using standard DPTR */ - pic16_emitcode ("push", "dps"); - pic16_emitcode ("mov", "dps, #0x00"); - if (options.stack10bit) { - /* This ISR could conceivably use DPTR2. Better save it. */ - pic16_emitcode ("push", "dpl1"); - pic16_emitcode ("push", "dph1"); - pic16_emitcode ("push", "dpx1"); - } + int i; + + _G.usefastretfie = 1; /* use shadow registers by default */ + /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */ + if(!(_G.interruptvector == 1)) { + + /* do not save WREG,STATUS,BSR for high priority interrupts + * because they are stored in the hardware shadow registers already */ + _G.usefastretfie = 0; + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr )); } - /* if this isr has no bank i.e. is going to - * run with bank 0 , then we need to save more - * registers :-) */ - if (!FUNC_REGBANK(sym->type)) { - - /* if this function does not call any other - * function then we can be economical and - * save only those registers that are used */ - if (! IFFUNC_HASFCALL(sym->type)) { - int i; - - /* if any registers used */ - if (sym->regsUsed) { - /* save the registers used */ - for ( i = 0 ; i < sym->regsUsed->size ; i++) { - if (bitVectBitValue(sym->regsUsed,i) || - (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname); + + /* these should really be optimized somehow, because not all + * interrupt handlers modify them */ + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodl )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_prodh )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h )); + +// pic16_pBlockConvert2ISR(pb); + + /* if any registers used */ + if (sym->regsUsed) { + /* save the registers used */ + DEBUGpic16_emitcode("; **", "Saving used registers in stack"); + for ( i = 0 ; i < sym->regsUsed->size ; i++) { + if (bitVectBitValue(sym->regsUsed,i)) { +#if 0 + fprintf(stderr, "%s:%d function %s uses register %s\n", + __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, + pic16_regWithIdx(i)->name); +#endif + + pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); + _G.nRegsSaved++; + + if(!pic16_regWithIdx(i)->wasUsed) { + fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n", + __FILE__, __LINE__, pic16_regWithIdx(i)->name); + + pic16_regWithIdx(i)->wasUsed = 1; } } - - } else { - /* this function has a function call cannot - * determines register usage so we will have the - * entire bank */ - saverbank(0,ic,FALSE); - } + } } -#endif } else { -#if STACK_SUPPORT /* emit code to setup stack frame if user enabled, * and function is not main() */ // fprintf(stderr, "function name: %s\n", sym->name); - if(USE_STACK && strcmp(sym->name, "main")) { - if(!options.ommitFramePtr || sym->regsUsed) { + if(strcmp(sym->name, "main")) { + if(/*!options.ommitFramePtr || */sym->regsUsed) { /* setup the stack frame */ pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr2l, &pic16_pc_postdec1, 0)); pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1l, &pic16_pc_fsr2l, 0)); @@ -2955,34 +3532,47 @@ static void genFunction (iCode *ic) pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0)); } } -#endif /* if callee-save to be used for this function * then save the registers being used in this function */ - if (IFFUNC_CALLEESAVES(sym->type)) { +// if (IFFUNC_CALLEESAVES(sym->type)) + { int i; - -// fprintf(stderr, "%s:%d function sym->regsUsed= %p\n", __FILE__, __LINE__, sym->regsUsed); - + +// fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size); + +// pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1); + /* if any registers used */ - if (sym->regsUsed -#if STACK_SUPPORT - && USE_STACK -#endif - ) { + if (sym->regsUsed) { /* save the registers used */ DEBUGpic16_emitcode("; **", "Saving used registers in stack"); for ( i = 0 ; i < sym->regsUsed->size ; i++) { if (bitVectBitValue(sym->regsUsed,i)) { -// fprintf(stderr, "%s:%d function %s uses register %s\n", -// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, -// pic16_regWithIdx(i)->name); - pic16_pushpCodeOpReg( PCOR(pic16_popRegFromIdx(i) )); +#if 0 + fprintf(stderr, "%s:%d function %s uses register %s (wasUsed: %d, %p)\n", + __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, + pic16_regWithIdx(i)->name, + pic16_regWithIdx(i)->wasUsed, + pic16_regWithIdx(i)); +#endif + + pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); + // pic16_emitpcode(POC_MOVFF, pic16_popCombine2( // PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), // &pic16_pc_postdec1, 0)); + _G.nRegsSaved++; + + if(!pic16_regWithIdx(i)->wasUsed) { + fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n", + __FILE__, __LINE__, pic16_regWithIdx(i)->name); + + pic16_regWithIdx(i)->wasUsed = 1; + } + } } } @@ -3048,6 +3638,8 @@ static void genEndFunction (iCode *ic) return; } + /* add code for ISCRITICAL */ + #if 0 if (IFFUNC_ISREENT(sym->type) || options.stackAuto) { @@ -3080,158 +3672,138 @@ static void genEndFunction (iCode *ic) } #endif - /* restore the register bank */ - if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) - pic16_emitcode ("pop","psw"); - - if (IFFUNC_ISISR(sym->type)) { - - /* now we need to restore the registers */ - /* if this isr has no bank i.e. is going to - run with bank 0 , then we need to save more - registers :-) */ - if (!FUNC_REGBANK(sym->type)) { - - /* if this function does not call any other - function then we can be economical and - save only those registers that are used */ - if (! IFFUNC_HASFCALL(sym->type)) { - int i; - + if (IFFUNC_ISISR(sym->type)) { + /* now we need to restore the registers */ /* if any registers used */ if (sym->regsUsed) { - /* save the registers used */ - for ( i = sym->regsUsed->size ; i >= 0 ; i--) { - if (bitVectBitValue(sym->regsUsed,i) || - (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname); - } - } - - } else { - /* this function has a function call cannot - determines register usage so we will have the - entire bank */ - unsaverbank(0,ic,FALSE); - } - } -#if 0 - if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) - { - if (options.stack10bit) - { - pic16_emitcode ("pop", "dpx1"); - pic16_emitcode ("pop", "dph1"); - pic16_emitcode ("pop", "dpl1"); - } - pic16_emitcode ("pop", "dps"); - pic16_emitcode ("pop", "dpx"); - } - if (!inExcludeList("dph")) - pic16_emitcode ("pop","dph"); - if (!inExcludeList("dpl")) - pic16_emitcode ("pop","dpl"); - if (!inExcludeList("b")) - pic16_emitcode ("pop","b"); - if (!inExcludeList("acc")) - pic16_emitcode ("pop","acc"); - - if (IFFUNC_ISCRITICAL(sym->type)) - pic16_emitcode("setb","ea"); -#endif + int i; - /* if debug then send end of function */ -/* if (options.debug && currFunc) { */ - if (currFunc) { - _G.debugLine = 1; - pic16_emitcode(";","C$%s$%d$%d$%d ==.", - FileBaseName(ic->filename),currFunc->lastLine, - ic->level,ic->block); - if (IS_STATIC(currFunc->etype)) - pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); - else - pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name); - _G.debugLine = 0; - } + /* restore registers used */ + DEBUGpic16_emitcode("; **", "Restoring used registers from stack"); + for ( i = sym->regsUsed->size; i >= 0; i--) { + if (bitVectBitValue(sym->regsUsed,i)) { + +// fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n", +// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, +// pic16_regWithIdx(i)->name); + + pic16_poppCodeOp( pic16_popRegFromIdx(i) ); + +// pic16_emitpcode(POC_MOVFF, pic16_popCombine2( +// &pic16_pc_preinc1, +// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0)); + + } + } + } + + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h )); + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr0l)); + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh )); + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl )); + + if(!(_G.interruptvector == 1)) { + /* do not restore interrupt vector for WREG,STATUS,BSR + * for high priority interrupt, see genFunction */ + + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_bsr )); + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_status )); + pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_wreg )); + } -// pic16_emitcode ("reti",""); + _G.interruptvector = 0; /* sanity check */ - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status)); - pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status)); - pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave)); - pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave)); +// pic16_pBlockConvert2ISR(pb); -#if 0 - pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1)); -#endif - pic16_emitpcodeNULLop(POC_RETFIE); + /* if debug then send end of function */ +/* if (options.debug && currFunc) */ + if (currFunc) { + debugFile->writeEndFunction (currFunc, ic, 1); + } + + if(_G.usefastretfie) + pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1)); + else + pic16_emitpcodeNULLop(POC_RETFIE); + _G.usefastretfie = 0; + } else { + if (IFFUNC_ISCRITICAL(sym->type)) + pic16_emitcode("setb","ea"); + - } - else { - if (IFFUNC_ISCRITICAL(sym->type)) - pic16_emitcode("setb","ea"); +// pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1); + + /* if any registers used */ + if (sym->regsUsed) { + int i; + /* save the registers used */ + DEBUGpic16_emitcode("; **", "Restoring used registers from stack"); + for ( i = sym->regsUsed->size; i >= 0; i--) { + if (bitVectBitValue(sym->regsUsed,i)) { - /* if any registers used */ - if (sym->regsUsed -#if STACK_SUPPORT - && USE_STACK -#endif - ) { - int i; - /* save the registers used */ - DEBUGpic16_emitcode("; **", "Restoring used registers from stack"); - for ( i = sym->regsUsed->size; i >= 0; i--) { - if (bitVectBitValue(sym->regsUsed,i)) { -// fprintf(stderr, "%s:%d function %s uses register %s\n", -// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, -// pic16_regWithIdx(i)->name); - - pic16_emitpcode(POC_MOVFF, pic16_popCombine2( - &pic16_pc_preinc1, - PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0)); +// fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n", +// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, +// pic16_regWithIdx(i)->name); + + pic16_poppCodeOp( pic16_popRegFromIdx(i) ); + +// pic16_emitpcode(POC_MOVFF, pic16_popCombine2( +// &pic16_pc_preinc1, +// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0)); + + _G.nRegsSaved--; + } } } - } +// pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved); + /* if debug then send end of function */ + if (currFunc) { + debugFile->writeEndFunction (currFunc, ic, 1); + } - /* if debug then send end of function */ - if (currFunc) { - _G.debugLine = 1; - pic16_emitcode(";","C$%s$%d$%d$%d ==.", - FileBaseName(ic->filename),currFunc->lastLine, - ic->level,ic->block); - if (IS_STATIC(currFunc->etype)) - pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); - else - pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name); - _G.debugLine = 0; - } - -#if STACK_SUPPORT - /* insert code to restore stack frame, if user enabled it - * and function is not main() */ + /* insert code to restore stack frame, if user enabled it + * and function is not main() */ - if(USE_STACK && strcmp(sym->name, "main")) { - if(!options.ommitFramePtr || sym->regsUsed) { - /* restore stack frame */ - if(STACK_MODEL_LARGE) + + if(strcmp(sym->name, "main")) { + if(/*!options.ommitFramePtr ||*/ sym->regsUsed) { + /* restore stack frame */ + if(STACK_MODEL_LARGE) + pic16_emitpcode(POC_MOVFF, + pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0)); pic16_emitpcode(POC_MOVFF, - pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2h, 0)); - pic16_emitpcode(POC_MOVFF, - pic16_popCombine2( &pic16_pc_postinc1, &pic16_pc_fsr2l, 0)); + pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0)); + } } + + pic16_emitpcodeNULLop(POC_RETURN); + + /* Mark the end of a function */ + pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL)); } -#endif - pic16_emitcode ("return",""); - pic16_emitpcodeNULLop(POC_RETURN); +} + - /* Mark the end of a function */ - pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL)); - } +void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest) +{ + + if(is_LitOp(op)) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); // patch 12 + if(dest->type != PO_WREG) + pic16_emitpcode(POC_MOVWF, dest); + } else { + if(dest->type == PO_WREG && (offset == 0)) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset)); + return; + } + + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popGet(AOP(op), offset), dest)); + } } /*-----------------------------------------------------------------*/ @@ -3239,68 +3811,122 @@ static void genEndFunction (iCode *ic) /*-----------------------------------------------------------------*/ static void genRet (iCode *ic) { - int size,offset = 0 , pushed = 0; - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if we have no return value then - just generate the "ret" */ - if (!IC_LEFT(ic)) - goto jumpret; - - /* we have something to return then - move the return value into place */ - pic16_aopOp(IC_LEFT(ic),ic,FALSE); - size = AOP_SIZE(IC_LEFT(ic)); + int size; + operand *left; + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* if we have no return value then + * just generate the "ret" */ + + if (!IC_LEFT(ic)) + goto jumpret; - while (size--) { - char *l ; - if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) { - /* #NOCHANGE */ - l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, - FALSE,TRUE); - pic16_emitcode("push","%s",l); - pushed++; - } else { - DEBUGpic16_emitcode(";", "%d", __LINE__); - l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, - FALSE,FALSE); - DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l); - if (strcmp(fReturn[offset],l)) { - if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) || - ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) { - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); - }else { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); + /* we have something to return then + * move the return value into place */ + pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE); + size = AOP_SIZE(IC_LEFT(ic)); + + if(size <= 4) { + if(size>3) { + pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l)); +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l))); + } + if(size>2) { + pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh)); +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh))); + } + if(size>1) { + pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl)); +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl))); + } + +// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12 + + pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12 +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg))); + + } else { + /* >32-bits, setup stack and FSR0 */ + while (size--) { +// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); +// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + + pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) ); + +// popaopidx(AOP(oper), size, GpseudoStkPtr); + GpsuedoStkPtr++; + } + + /* setup FSR0 */ + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l))); + + if(STACK_MODEL_LARGE) { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h))); + } else { + pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) ); + } } - if(size) { - pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr)); + +#if 0 + /* old code, left here for reference -- VR */ + while (size--) { + char *l ; + + if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) { + /* #NOCHANGE */ + l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE); + pic16_emitpcomment("push %s",l); + pushed++; + } else { + DEBUGpic16_emitcode(";", "%d", __LINE__); + l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE); + DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l); + + if (strcmp(fReturn[offset],l)) { + if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) + || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); + } else { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); + } + + if(size) { + pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr)); + } + offset++; + } + } + } + + if (pushed) { + while(pushed) { + pushed--; + if (strcmp(fReturn[pushed],"a")) + pic16_emitcode("pop",fReturn[pushed]); + else + pic16_emitcode("pop","acc"); + } } - offset++; - } - } - } +#endif - if (pushed) { - while(pushed) { - pushed--; - if (strcmp(fReturn[pushed],"a")) - pic16_emitcode("pop",fReturn[pushed]); - else - pic16_emitcode("pop","acc"); - } - } - pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE); + + pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE); - jumpret: - /* generate a jump to the return label - if the next is not the return statement */ - if (!(ic->next && ic->next->op == LABEL && - IC_LABEL(ic->next) == returnLabel)) { +jumpret: + /* generate a jump to the return label + * if the next is not the return statement */ + if (!(ic->next && ic->next->op == LABEL + && IC_LABEL(ic->next) == returnLabel)) { - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key)); - pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset); - } - + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key)); + pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset); + } } /*-----------------------------------------------------------------*/ @@ -3308,13 +3934,15 @@ static void genRet (iCode *ic) /*-----------------------------------------------------------------*/ static void genLabel (iCode *ic) { + + /* special case never generate */ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (IC_LABEL(ic) == entryLabel) return ; pic16_emitpLabel(IC_LABEL(ic)->key); - pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset)); + pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + pic16_labelOffset)); } /*-----------------------------------------------------------------*/ @@ -3324,7 +3952,7 @@ static void genLabel (iCode *ic) static void genGoto (iCode *ic) { pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_LABEL(ic)->key)); - pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset); + pic16_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+pic16_labelOffset); } @@ -3354,10 +3982,6 @@ static void genMultOneByte (operand *left, operand *right, operand *result) { - sym_link *opetype = operandType(result); - - // symbol *lbl ; - int size,offset; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); DEBUGpic16_pic16_AopType(__LINE__,left,right,result); @@ -3371,129 +3995,159 @@ static void genMultOneByte (operand *left, left = t; } - size = AOP_SIZE(result); - if(size == 1) { - - if (AOP_TYPE(right) == AOP_LIT){ - pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s", - pic16_aopGet(AOP(right),0,FALSE,FALSE), - pic16_aopGet(AOP(left),0,FALSE,FALSE), - pic16_aopGet(AOP(result),0,FALSE,FALSE)); - pic16_emitcode("call","genMultLit"); - } else { - pic16_emitcode("multiply ","variable :%s by variable %s and store in %s", - pic16_aopGet(AOP(right),0,FALSE,FALSE), - pic16_aopGet(AOP(left),0,FALSE,FALSE), - pic16_aopGet(AOP(result),0,FALSE,FALSE)); - pic16_emitcode("call","pic16_genMult8X8_8"); - - } - pic16_genMult8X8_8 (left, right,result); + /* size is already checked in genMult == 1 */ +// size = AOP_SIZE(result); + if (AOP_TYPE(right) == AOP_LIT){ + pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); + } else { + pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); + } + + pic16_genMult8X8_8 (left, right,result); +} - /* signed or unsigned */ - //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE)); - //l = pic16_aopGet(AOP(left),0,FALSE,FALSE); - //MOVA(l); - //pic16_emitcode("mul","ab"); - /* if result size = 1, mul signed = mul unsigned */ - //pic16_aopPut(AOP(result),"a",0); +/*-----------------------------------------------------------------*/ +/* genMultOneWord : 16 bit multiplication */ +/*-----------------------------------------------------------------*/ +static void genMultOneWord (operand *left, + operand *right, + operand *result) +{ - } else { // (size > 1) + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result); + + /* (if two literals, the value is computed before) + * if one literal, literal on the right */ + if (AOP_TYPE(left) == AOP_LIT){ + operand *t = right; + right = left; + left = t; + } - pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", - pic16_aopGet(AOP(right),0,FALSE,FALSE), - pic16_aopGet(AOP(left),0,FALSE,FALSE), - pic16_aopGet(AOP(result),0,FALSE,FALSE)); + /* size is checked already == 2 */ +// size = AOP_SIZE(result); - if (SPEC_USIGN(opetype)){ - pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result)); - pic16_genUMult8X8_16 (left, right, result, NULL); + if (AOP_TYPE(right) == AOP_LIT) { + pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); + } else { + pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); + } + + pic16_genMult16X16_16(left, right,result); +} - if (size > 2) { - /* for filling the MSBs */ - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2)); - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3)); - } - } - else{ - pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result)); +/*-----------------------------------------------------------------*/ +/* genMultOneLong : 32 bit multiplication */ +/*-----------------------------------------------------------------*/ +static void genMultOneLong (operand *left, + operand *right, + operand *result) +{ - pic16_emitcode("mov","a,b"); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result); + + /* (if two literals, the value is computed before) + * if one literal, literal on the right */ + if (AOP_TYPE(left) == AOP_LIT){ + operand *t = right; + right = left; + left = t; + } - /* adjust the MSB if left or right neg */ + /* size is checked already == 4 */ +// size = AOP_SIZE(result); - /* if one literal */ - if (AOP_TYPE(right) == AOP_LIT){ - pic16_emitcode("multiply ","right is a lit"); - /* AND literal negative */ - if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){ - /* adjust MSB (c==0 after mul) */ - pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE)); + if (AOP_TYPE(right) == AOP_LIT) { + pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); + } else { + pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); } - } - else{ - pic16_genSMult8X8_16 (left, right, result, NULL); - } + + pic16_genMult32X32_32(left, right,result); +} - if(size > 2){ - pic16_emitcode("multiply ","size is greater than 2, so propogate sign"); - /* get the sign */ - pic16_emitcode("rlc","a"); - pic16_emitcode("subb","a,acc"); - } - } - size -= 2; - offset = 2; - if (size > 0) - while (size--) - pic16_emitcode("multiply ","size is way greater than 2, so propogate sign"); - //pic16_aopPut(AOP(result),"a",offset++); - } -} /*-----------------------------------------------------------------*/ /* genMult - generates code for multiplication */ /*-----------------------------------------------------------------*/ static void genMult (iCode *ic) { - operand *left = IC_LEFT(ic); - operand *right = IC_RIGHT(ic); - operand *result= IC_RESULT(ic); - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* assign the amsops */ - pic16_aopOp (left,ic,FALSE); - pic16_aopOp (right,ic,FALSE); - pic16_aopOp (result,ic,TRUE); + operand *left = IC_LEFT(ic); + operand *right = IC_RIGHT(ic); + operand *result= IC_RESULT(ic); - DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* assign the amsops */ + pic16_aopOp (left,ic,FALSE); + pic16_aopOp (right,ic,FALSE); + pic16_aopOp (result,ic,TRUE); + + DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + + /* special cases first * + * both are bits */ + if (AOP_TYPE(left) == AOP_CRY + && AOP_TYPE(right)== AOP_CRY) { + genMultbits(left,right,result); + goto release ; + } - /* special cases first */ - /* both are bits */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right)== AOP_CRY) { - genMultbits(left,right,result); - goto release ; - } + /* if both are of size == 1 */ + if(AOP_SIZE(left) == 1 + && AOP_SIZE(right) == 1) { + genMultOneByte(left,right,result); + goto release ; + } - /* if both are of size == 1 */ - if (AOP_SIZE(left) == 1 && - AOP_SIZE(right) == 1 ) { - genMultOneByte(left,right,result); - goto release ; - } + /* if both are of size == 2 */ + if(AOP_SIZE(left) == 2 + && AOP_SIZE(right) == 2) { + genMultOneWord(left, right, result); + goto release; + } + + /* if both are of size == 4 */ + if(AOP_SIZE(left) == 4 + && AOP_SIZE(right) == 4) { + genMultOneLong(left, right, result); + goto release; + } + + pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor."); - pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor."); - /* should have been converted to function call */ - //assert(0) ; + fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right)); + /* should have been converted to function call */ + assert(0) ; release : - pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(result,NULL,ic,TRUE); + pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -3530,19 +4184,83 @@ static void genDivOneByte (operand *left, symbol *lbl ; int size,offset; + /* result = divident / divisor + * - divident may be a register or a literal, + * - divisor may be a register or a literal, + * so there are 3 cases (literal / literal is optimized + * by the front-end) to handle. + * In addition we must handle signed and unsigned, which + * result in 6 final different cases -- VR */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); size = AOP_SIZE(result) - 1; offset = 1; /* signed or unsigned */ if (SPEC_USIGN(opetype)) { + pCodeOp *pct1, /* count */ + *pct2, /* reste */ + *pct3; /* temp */ + symbol *label1, *label2, *label3;; + + /* unsigned is easy */ - pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE)); - l = pic16_aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - pic16_emitcode("div","ab"); - pic16_aopPut(AOP(result),"a",0); - while (size--) - pic16_aopPut(AOP(result),zero,offset++); + + pct1 = pic16_popGetTempReg(); + pct2 = pic16_popGetTempReg(); + pct3 = pic16_popGetTempReg(); + + label1 = newiTempLabel(NULL); + label2 = newiTempLabel(NULL); + label3 = newiTempLabel(NULL); + + /* the following algorithm is extracted from divuint.c */ + + pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 )); + pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 )); + + pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 )); + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0)); + + pic16_emitpLabel(label1->key); + + emitCLRC; + pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 )); + + + emitCLRC; + pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg )); + + + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 )); + + pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 )); + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0)); + + pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2)); + pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key)); + pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key)); + + pic16_emitpLabel( label3->key ); + pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2)); + pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3)); + + + + pic16_emitpLabel(label2->key); + pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3)); + pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1)); + pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key )); + + /* result is in wreg */ + if(AOP_TYPE(result) != AOP_ACC) + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + + pic16_popReleaseTempReg( pct3 ); + pic16_popReleaseTempReg( pct2 ); + pic16_popReleaseTempReg( pct1 ); + return ; } @@ -3611,6 +4329,12 @@ static void genDiv (iCode *ic) operand *right = IC_RIGHT(ic); operand *result= IC_RESULT(ic); + + /* Division is a very lengthy algorithm, so it is better + * to call support routines than inlining algorithm. + * Division functions written here just in case someone + * wants to inline and not use the support libraries -- VR */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* assign the amsops */ pic16_aopOp (left,ic,FALSE); @@ -3795,11 +4519,11 @@ static void genIfxJump (iCode *ic, char *jval) emitSKPC; else { DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER)); } pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key)); - pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + labelOffset); + pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset); } else { @@ -3810,11 +4534,11 @@ static void genIfxJump (iCode *ic, char *jval) emitSKPNC; else { DEBUGpic16_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); - pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1)); + pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(jval,-1,1, PO_GPR_REGISTER)); } pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key)); - pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + labelOffset); + pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset); } @@ -3823,6 +4547,9 @@ static void genIfxJump (iCode *ic, char *jval) ic->generated = 1; } +#if 0 +// not needed ATM + /*-----------------------------------------------------------------*/ /* genSkip */ /*-----------------------------------------------------------------*/ @@ -3849,7 +4576,7 @@ static void genSkip(iCode *ifx,int status_bit) } pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key)); - // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); + // pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset); } else { @@ -3868,17 +4595,20 @@ static void genSkip(iCode *ifx,int status_bit) break; } pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key)); - // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); + // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset); } } +#endif /*-----------------------------------------------------------------*/ /* genSkipc */ /*-----------------------------------------------------------------*/ static void genSkipc(resolvedIfx *rifx) { + DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx); + if(!rifx) return; @@ -3887,7 +4617,7 @@ static void genSkipc(resolvedIfx *rifx) else emitSKPNC; - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key)); + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key)); rifx->generated = 1; } @@ -3896,6 +4626,8 @@ static void genSkipc(resolvedIfx *rifx) /*-----------------------------------------------------------------*/ static void genSkipz2(resolvedIfx *rifx, int invert_condition) { + DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx); + if(!rifx) return; @@ -3928,9 +4660,9 @@ static void genSkipz(iCode *ifx, int condition) pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key)); if ( IC_TRUE(ifx) ) - pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); + pic16_emitcode("goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset); else - pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); + pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset); } #endif @@ -3944,9 +4676,9 @@ static void genSkipCond(resolvedIfx *rifx,operand *op, int offset, int bit) return; if(rifx->condition) - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER)); else - pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0)); + pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(op),offset,FALSE,FALSE),bit,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key)); @@ -4038,16 +4770,19 @@ static void genCmp (operand *left,operand *right, end the carry flag is set then we know that left is greater than right */ - // { - symbol *lbl = newiTempLabel(NULL); +#if 0 + fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n", + __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset); +#endif + #ifndef _swapp if(AOP_TYPE(right) == AOP_LIT) { //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign); + DEBUGpic16_emitcode(";right lit","%d lit = 0x%x,sign=%d",__LINE__, lit,sign); /* special cases */ @@ -4121,7 +4856,7 @@ static void genCmp (operand *left,operand *right, //genSkipCond(&rFalseIfx,left,size,7); //rFalseIfx.condition ^= 1; - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); if(rFalseIfx.condition) pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); else @@ -4191,7 +4926,7 @@ static void genCmp (operand *left,operand *right, //genSkipCond(&rFalseIfx,left,size,7); - pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); if(rFalseIfx.condition) pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); @@ -4202,7 +4937,7 @@ static void genCmp (operand *left,operand *right, } else { /* lit is positive */ DEBUGpic16_emitcode(";right lit","line = %d signed compare to 0x%x",__LINE__,lit); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); if(rFalseIfx.condition) pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); else @@ -4274,6 +5009,7 @@ static void genCmp (operand *left,operand *right, pic16_emitpLabel(lbl->key); +// pic16_emitpLabel(truelbl->key); //if(emitFinalCheck) genSkipc(&rFalseIfx); if(sign) @@ -4372,7 +5108,8 @@ static void genCmp (operand *left,operand *right, } if(ifx) ifx->generated = 1; - //goto check_carry; + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + goto check_carry; return; } else { @@ -4399,7 +5136,7 @@ static void genCmp (operand *left,operand *right, int s = size; if(rFalseIfx.condition) { - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); } @@ -4442,7 +5179,7 @@ static void genCmp (operand *left,operand *right, //rFalseIfx.condition ^= 1; //genSkipCond(&rFalseIfx,left,size,7); //rFalseIfx.condition ^= 1; - pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); if(rFalseIfx.condition) @@ -4461,7 +5198,7 @@ static void genCmp (operand *left,operand *right, //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0)); //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); if(rFalseIfx.condition) pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); else @@ -4549,7 +5286,7 @@ static void genCmp (operand *left,operand *right, pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); } else { /* this byte of the lit is zero, - *if it's not the last then OR in the variable */ + * if it's not the last then OR in the variable */ if(size) pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); } @@ -4559,6 +5296,7 @@ static void genCmp (operand *left,operand *right, pic16_emitpLabel(lbl->key); rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); } @@ -4576,12 +5314,16 @@ static void genCmp (operand *left,operand *right, if(sign) { /* Sigh. thus sucks... */ if(size) { + pCodeOp *pctemp; + + pctemp = pic16_popGetTempReg(); pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size)); - pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(pic16_Gstack_base_addr)); + pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr)); pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_XORWF, pic16_popRegFromIdx(pic16_Gstack_base_addr)); + pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr)); pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size)); - pic16_emitpcode(POC_SUBFW, pic16_popRegFromIdx(pic16_Gstack_base_addr)); + pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr)); + pic16_popReleaseTempReg(pctemp); } else { /* Signed char comparison */ /* Special thanks to Nikolai Golovchenko for this snippet */ @@ -4636,9 +5378,13 @@ static void genCmp (operand *left,operand *right, } - // check_carry: - if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) { +check_carry: + if ((AOP_TYPE(result) != AOP_CRY) + && AOP_SIZE(result)) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key ); + pic16_outBitC(result); } else { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -4713,6 +5459,10 @@ static void genCmpLt (iCode *ic, iCode *ifx) pic16_freeAsmop(result,NULL,ic,TRUE); } +#if 0 +// not needed ATM +// FIXME reenable literal optimisation when the pic16 port is stable + /*-----------------------------------------------------------------*/ /* genc16bit2lit - compare a 16 bit value to a literal */ /*-----------------------------------------------------------------*/ @@ -4763,7 +5513,10 @@ static void genc16bit2lit(operand *op, int lit, int offset) } } +#endif +#if 0 +// not needed ATM /*-----------------------------------------------------------------*/ /* gencjneshort - compare and jump if not equal */ /*-----------------------------------------------------------------*/ @@ -4774,15 +5527,18 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) int res_offset = 0; /* the result may be a different size then left or right */ int res_size = AOP_SIZE(result); resolvedIfx rIfx; - symbol *lbl; + symbol *lbl, *lbl_done; unsigned long lit = 0L; + int preserve_result = 0; /* don't touch result before we are done, if left/right == result */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); DEBUGpic16_pic16_AopType(__LINE__,left,right,result); if(result) DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__); resolveIfx(&rIfx,ifx); lbl = newiTempLabel(NULL); + lbl_done = newiTempLabel(NULL); /* if the left side is a literal or @@ -4797,16 +5553,28 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) if(AOP_TYPE(right) == AOP_LIT) lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + if ( regsInCommon(left, result) || regsInCommon(right, result) ) + preserve_result = 1; + + if(result && !preserve_result) + { + int i; + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + } + + /* if the right side is a literal then anything goes */ if (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR ) { switch(size) { case 2: genc16bit2lit(left, lit, 0); - emitSKPNZ; + emitSKPZ; pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); break; default: + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); while (size--) { if(lit & 0xff) { pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset)); @@ -4815,7 +5583,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset)); } - emitSKPNZ; + emitSKPZ; pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); offset++; if(res_offset < res_size-1) @@ -4836,7 +5604,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) int lbl_key = lbl->key; if(result) { - pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset)); + // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset)); //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset)); }else { DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__); @@ -4844,7 +5612,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) __FUNCTION__,__LINE__); return; } - + /* switch(size) { */ /* case 2: */ /* genc16bit2lit(left, lit, 0); */ @@ -4868,8 +5636,8 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) break; case 1: pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset)); - //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); + //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset)); + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); emit_skip=0; break; case 0xff: @@ -4945,17 +5713,38 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) } } - pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset)); + if(result && preserve_result) + { + int i; + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + } + + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); + + if(result && preserve_result) + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key)); + if(!rIfx.condition) pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key)); pic16_emitpLabel(lbl->key); + if(result && preserve_result) + { + int i; + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + + pic16_emitpLabel(lbl_done->key); + } + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(ifx) ifx->generated = 1; } +#endif #if 0 /*-----------------------------------------------------------------*/ @@ -4965,20 +5754,157 @@ static void gencjne(operand *left, operand *right, iCode *ifx) { symbol *tlbl = newiTempLabel(NULL); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - gencjneshort(left, right, lbl); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + gencjneshort(left, right, lbl); + + pic16_emitcode("mov","a,%s",one); + pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100); + pic16_emitcode("","%05d_DS_:",lbl->key+100); + pic16_emitcode("clr","a"); + pic16_emitcode("","%05d_DS_:",tlbl->key+100); + + pic16_emitpLabel(lbl->key); + pic16_emitpLabel(tlbl->key); + +} +#endif + + +/*-----------------------------------------------------------------*/ +/* is_LitOp - check if operand has to be treated as literal */ +/*-----------------------------------------------------------------*/ +static bool is_LitOp(operand *op) +{ + return (AOP_TYPE(op) == AOP_LIT) + || ( (AOP_TYPE(op) == AOP_PCODE) + && ( (AOP(op)->aopu.pcop->type == PO_LITERAL) + || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) )); +} + +/*-----------------------------------------------------------------*/ +/* is_LitAOp - check if operand has to be treated as literal */ +/*-----------------------------------------------------------------*/ +static bool is_LitAOp(asmop *aop) +{ + return (aop->type == AOP_LIT) + || ( (aop->type == AOP_PCODE) + && ( (aop->aopu.pcop->type == PO_LITERAL) + || (aop->aopu.pcop->type == PO_IMMEDIATE) )); +} + + + +/*-----------------------------------------------------------------*/ +/* genCmpEq - generates code for equal to */ +/*-----------------------------------------------------------------*/ +static void genCmpEq (iCode *ic, iCode *ifx) +{ + operand *left, *right, *result; + symbol *falselbl = newiTempLabel(NULL); + symbol *donelbl = newiTempLabel(NULL); + + int preserve_result = 0; + int generate_result = 0; + int i=0; + + pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE); + pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE); + pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + + if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) ) + { + DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__); + fprintf(stderr, "%s %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__); + goto release; + } + + if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC)) + { + operand *tmp = right ; + right = left; + left = tmp; + } + + if ( regsInCommon(left, result) || regsInCommon(right, result) ) + preserve_result = 1; + + if(result && AOP_SIZE(result)) + generate_result = 1; + + if(generate_result && !preserve_result) + { + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + } + + for(i=0; i < AOP_SIZE(left); i++) + { + if(AOP_TYPE(left) != AOP_ACC) + { + if(is_LitOp(left)) + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i)); + else + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i)); + } + if(is_LitOp(right)) + pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i)); + else + pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i)); + + pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key)); + } + + // result == true + + if(generate_result && preserve_result) + { + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + } + + if(generate_result) + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true + + if(generate_result && preserve_result) + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key)); + + if(ifx && IC_TRUE(ifx)) + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key)); + + if(ifx && IC_FALSE(ifx)) + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key)); + + pic16_emitpLabel(falselbl->key); + + // result == false - pic16_emitcode("mov","a,%s",one); - pic16_emitcode("sjmp","%05d_DS_",tlbl->key+100); - pic16_emitcode("","%05d_DS_:",lbl->key+100); - pic16_emitcode("clr","a"); - pic16_emitcode("","%05d_DS_:",tlbl->key+100); + if(ifx && IC_FALSE(ifx)) + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key)); - pic16_emitpLabel(lbl->key); - pic16_emitpLabel(tlbl->key); + if(generate_result && preserve_result) + { + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + } + + pic16_emitpLabel(donelbl->key); + + if(ifx) + ifx->generated = 1; + +release: + pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(result,NULL,ic,TRUE); } -#endif + + +#if 0 +// old version kept for reference /*-----------------------------------------------------------------*/ /* genCmpEq - generates code for equal to */ @@ -5052,7 +5978,7 @@ static void genCmpEq (iCode *ic, iCode *ifx) pic16_emitcode("jc","%05d_DS_",tlbl->key+100); pic16_emitcode("ljmp","%05d_DS_",IC_FALSE(ifx)->key+100); } - pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset); + pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset); { /* left and right are both bit variables, result is carry */ @@ -5169,11 +6095,11 @@ static void genCmpEq (iCode *ic, iCode *ifx) if ( IC_TRUE(ifx) ) { emitSKPNZ; pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key)); - // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); + // pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset); } else { emitSKPZ; pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key)); - // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); + // pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset); } } else { @@ -5193,7 +6119,7 @@ static void genCmpEq (iCode *ic, iCode *ifx) DEBUGpic16_emitcode (";","\tIC_TRUE emitSKPZ"); pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key)); - pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+labelOffset); + pic16_emitcode(" goto","_%05d_DS_",tlbl->key+100+pic16_labelOffset); } else { emitSKPNZ; @@ -5201,7 +6127,7 @@ static void genCmpEq (iCode *ic, iCode *ifx) pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key)); - pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+labelOffset); + pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ifx)->key+100+pic16_labelOffset); } } else { emitSKPZ; @@ -5209,13 +6135,13 @@ static void genCmpEq (iCode *ic, iCode *ifx) DEBUGpic16_emitcode (";","\tnot IC_TRUE emitSKPZ"); pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key)); - pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); + pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset); } offset++; } if(s>1 && IC_TRUE(ifx)) { pic16_emitpLabel(tlbl->key); - pic16_emitcode("","_%05d_DS_:",tlbl->key+100+labelOffset); + pic16_emitcode("","_%05d_DS_:",tlbl->key+100+pic16_labelOffset); } } } @@ -5297,6 +6223,7 @@ release: pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); pic16_freeAsmop(result,NULL,ic,TRUE); } +#endif /*-----------------------------------------------------------------*/ /* ifxForOp - returns the icode containing the ifx for operand */ @@ -5311,11 +6238,14 @@ static iCode *ifxForOp ( operand *op, iCode *ic ) /* if this has register type condition and the next instruction is ifx with the same operand and live to of the operand is upto the ifx only then */ - if (ic->next && - ic->next->op == IFX && - IC_COND(ic->next)->key == op->key && - OP_SYMBOL(op)->liveTo <= ic->next->seq ) - return ic->next; + if (ic->next + && ic->next->op == IFX + && IC_COND(ic->next)->key == op->key + && OP_SYMBOL(op)->liveTo <= ic->next->seq + ) { + DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__); + return ic->next; + } if (ic->next && ic->next->op == IFX && @@ -5338,6 +6268,35 @@ static iCode *ifxForOp ( operand *op, iCode *ic ) ic->next->seq); } +#if 0 + /* the code below is completely untested + * it just allows ulong2fs.c compile -- VR */ + + ic = ic->next; + fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n", + __FILE__, __FUNCTION__, __LINE__); + + /* if this has register type condition and + the next instruction is ifx with the same operand + and live to of the operand is upto the ifx only then */ + if (ic->next && + ic->next->op == IFX && + IC_COND(ic->next)->key == op->key && + OP_SYMBOL(op)->liveTo <= ic->next->seq ) + return ic->next; + + if (ic->next && + ic->next->op == IFX && + IC_COND(ic->next)->key == op->key) { + DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__); + return ic->next; + } + + fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n", + __FILE__, __FUNCTION__, __LINE__); + +// return ic->next->next; /* this just might work */ /* FIXME FIXME */ +#endif return NULL; } @@ -5423,9 +6382,9 @@ static void genOrOp (iCode *ic) tlbl = newiTempLabel(NULL); pic16_toBoolean(left); emitSKPZ; - pic16_emitcode("goto","%05d_DS_",tlbl->key+100+labelOffset); + pic16_emitcode("goto","%05d_DS_",tlbl->key+100+pic16_labelOffset); pic16_toBoolean(right); - pic16_emitcode("","%05d_DS_:",tlbl->key+100+labelOffset); + pic16_emitcode("","%05d_DS_:",tlbl->key+100+pic16_labelOffset); pic16_outBitAcc(result); } @@ -5617,8 +6576,25 @@ static void genAnd (iCode *ic, iCode *ifx) pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key)); } */ + DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__); + size = AOP_SIZE(left); + + { + int bp = posbit, ofs=0; + + while(bp > 7) { + bp -= 8; + ofs++; + } + + pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), + pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER)); + + } +/* pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0)); +*/ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key)); ifx->generated = 1; @@ -5628,10 +6604,36 @@ static void genAnd (iCode *ic, iCode *ifx) } else { symbol *tlbl = newiTempLabel(NULL); int sizel = AOP_SIZE(left); + if(size) - pic16_emitcode("setb","c"); - while(sizel--){ - if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L){ + emitSETC; + + while(sizel--) { + if((bytelit = ((lit >> (offset*8)) & 0x0FFL)) != 0x0L) { + + /* patch provided by Aaron Colwell */ + if((posbit = isLiteralBit(bytelit)) != 0) { + pic16_emitpcode(((rIfx.condition) ? POC_BTFSS : POC_BTFSC ), + pic16_newpCodeOpBit(pic16_aopGet(AOP(left), offset,FALSE,FALSE), + (posbit-1),0, PO_GPR_REGISTER)); + + pic16_emitpcode(POC_BRA, pic16_popGetLabel(tlbl->key)); + } else { + if (bytelit == 0xff) { + /* Aaron had a MOVF instruction here, changed to MOVFW cause + * a peephole could optimize it out -- VR */ + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset)); + } else { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), offset)); + pic16_emitpcode(POC_ANDLW, pic16_popGetLit(bytelit)); + } + + pic16_emitpcode(((rIfx.condition) ? POC_BZ : POC_BNZ), + pic16_popGetLabel(tlbl->key)); + } + +#if 0 + /* old code, left here for reference -- VR 09/2004 */ MOVA( pic16_aopGet(AOP(left),offset,FALSE,FALSE)); // byte == 2^n ? if((posbit = isLiteralBit(bytelit)) != 0) @@ -5641,22 +6643,27 @@ static void genAnd (iCode *ic, iCode *ifx) pic16_emitcode("anl","a,%s", pic16_aopGet(AOP(right),offset,FALSE,TRUE)); pic16_emitcode("jnz","%05d_DS_",tlbl->key+100); - } + } +#endif } offset++; } // bit = left & literal - if(size){ - pic16_emitcode("clr","c"); - pic16_emitcode("","%05d_DS_:",tlbl->key+100); + if(size) { + emitCLRC; + pic16_emitpLabel(tlbl->key); } // if(left & literal) - else{ - if(ifx) - jmpTrueOrFalse(ifx, tlbl); - goto release ; + else { + if(ifx) { + pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->key)); + pic16_emitpLabel(tlbl->key); + ifx->generated = 1; + } + goto release; } } + pic16_outBitC(result); goto release ; } @@ -5682,7 +6689,7 @@ static void genAnd (iCode *ic, iCode *ifx) if(p>=0) { /* only one bit is set in the literal, so use a bcf instruction */ // pic16_emitcode("bcf","%s,%d",pic16_aopGet(AOP(left),offset,FALSE,TRUE),p); - pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0)); + pic16_emitpcode(POC_BCF,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER)); } else { pic16_emitcode("movlw","0x%x", (lit & 0xff)); @@ -5986,7 +6993,7 @@ static void genOr (iCode *ic, iCode *ifx) if(p>=0) { /* only one bit is set in the literal, so use a bsf instruction */ pic16_emitpcode(POC_BSF, - pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0)); + pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offset,FALSE,FALSE),p,0, PO_GPR_REGISTER)); } else { if(know_W != (lit & 0xff)) pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff)); @@ -6338,29 +7345,31 @@ static void genInline (iCode *ic) char *buffer, *bp, *bp1; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + _G.inLine += (!options.asmpeep); buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); strcpy(buffer,IC_INLINE(ic)); +// fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer); + /* emit each line as a code */ while (*bp) { if (*bp == '\n') { *bp++ = '\0'; - + if(*bp1) -#if 0 - pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); -#else - pic16_addpCode2pBlock(pb, pic16_AssembleLine(bp1, 1)); -#endif + pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process bp1 = bp; } else { if (*bp == ':') { bp++; *bp = '\0'; bp++; - pic16_emitcode(bp1,""); + + /* print label, use this special format with NULL directive + * to denote that the argument should not be indented with tab */ + pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process bp1 = bp; } else bp++; @@ -6368,14 +7377,12 @@ static void genInline (iCode *ic) } if ((bp1 != bp) && *bp1) -#if 0 - pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); -#else - pic16_addpCode2pBlock(pb, pic16_AssembleLine(bp1, 1)); -#endif + pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process + - Safe_free(buffer); - _G.inLine -= (!options.asmpeep); + Safe_free(buffer); + + _G.inLine -= (!options.asmpeep); } /*-----------------------------------------------------------------*/ @@ -6468,6 +7475,10 @@ static void genRLC (iCode *ic) pic16_freeAsmop(result,NULL,ic,TRUE); } + +/* gpasm can get the highest order bit with HIGH/UPPER + * so the following probably is not needed -- VR */ + /*-----------------------------------------------------------------*/ /* genGetHbit - generates code get highest order bit */ /*-----------------------------------------------------------------*/ @@ -6542,78 +7553,83 @@ static void AccRol (int shCount) /*-----------------------------------------------------------------*/ static void AccLsh (int shCount) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - switch(shCount){ - case 0 : + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + switch(shCount){ + case 0 : return; - break; - case 1 : - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 2 : - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 3 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 4 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 5 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 6 : - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 7 : - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - } - pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount])); + break; + case 1 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 2 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 3 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 4 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 5 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 6 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 7 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + } + pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount])); } /*-----------------------------------------------------------------*/ /* AccRsh - right shift accumulator by known count */ /*-----------------------------------------------------------------*/ -static void AccRsh (int shCount) +static void AccRsh (int shCount, int andmask) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - switch(shCount){ - case 0 : - return; - break; - case 1 : - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 2 : - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 3 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 4 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 5 : - pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 6 : - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - case 7 : - pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); - break; - } - pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount])); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + switch(shCount){ + case 0 : + return; break; + case 1 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); +// andmask = 0; /* no need */ + break; + case 2 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); +// andmask = 0; /* no need */ + break; + case 3 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 4 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 5 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 6 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 7 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + } + + if(andmask) + pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount])); + else + DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__); } #if 0 @@ -6697,7 +7713,7 @@ static void shiftR1Left2ResultSigned (operand *left, int offl, pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr)); pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xe0)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr)); @@ -6706,7 +7722,7 @@ static void shiftR1Left2ResultSigned (operand *left, int offl, case 4: pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl)); pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf0)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr)); break; @@ -6719,7 +7735,7 @@ static void shiftR1Left2ResultSigned (operand *left, int offl, } pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(result),offr)); pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),3,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xf8)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr)); break; @@ -6727,29 +7743,29 @@ static void shiftR1Left2ResultSigned (operand *left, int offl, case 6: if(same) { pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xfe)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_IORLW, pic16_popGetLit(0x01)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr)); } else { pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0)); - pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0)); + pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),6,0, PO_GPR_REGISTER)); + pic16_emitpcode(POC_BCF, pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr,FALSE,FALSE),0,0, PO_GPR_REGISTER)); } break; case 7: if(same) { pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x00)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr)); } else { pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),offl,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offr)); } @@ -7168,7 +8184,7 @@ static void shiftR2Left2Result (operand *left, int offl, if(sign) { pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xf0 + (shCount-4)*8 )); pic16_emitpcode(POC_BTFSC, - pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0)); + pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),7-shCount,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16)); } @@ -7186,7 +8202,7 @@ static void shiftR2Left2Result (operand *left, int offl, pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03)); if(sign) { pic16_emitpcode(POC_BTFSC, - pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0)); + pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),1,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc)); } pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16)); @@ -7204,7 +8220,7 @@ static void shiftR2Left2Result (operand *left, int offl, pic16_emitpcode(POC_ANDLW,pic16_popGetLit(0x03)); if(sign) { pic16_emitpcode(POC_BTFSC, - pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0)); + pic16_newpCodeOpBit(pic16_aopGet(AOP(result),offr+MSB16,FALSE,FALSE),0,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc)); } pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+MSB16)); @@ -7254,7 +8270,7 @@ static void shiftRLeftOrResult (operand *left, int offl, pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl)); /* shift right accumulator */ - AccRsh(shCount); + AccRsh(shCount, 1); /* or with result */ /* back to result */ pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr)); @@ -7595,15 +8611,15 @@ static void genLeftShift (iCode *ic) if(optimized_for_speed) { pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),0)); pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xf0)); - pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0)); + pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),2,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0)); + pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0)); pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),0)); pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xfe)); pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),1,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0)); } else { @@ -7729,7 +8745,7 @@ static void genrshTwo (operand *result,operand *left, pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16)); if(sign) { - pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),LSB,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16)); } } @@ -7898,14 +8914,14 @@ static void genRightShiftLiteral (operand *left, if(res_size == 1) { pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),LSB)); if(sign) { - pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),LSB)); } } else { if(sign) { pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(left),lsize-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff)); while(res_size--) pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),res_size)); @@ -8198,59 +9214,74 @@ release: pic16_freeAsmop(result,NULL,ic,TRUE); } + +void pic16_loadFSR0(operand *op) +{ + pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0))); +} + /*-----------------------------------------------------------------*/ /* genUnpackBits - generates code for unpacking bits */ /*-----------------------------------------------------------------*/ -static void genUnpackBits (operand *result, char *rname, int ptype) +static void genUnpackBits (operand *result, operand *left, char *rname, int ptype) { int shCnt ; int rlen = 0 ; sym_link *etype; int offset = 0 ; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - etype = getSpec(operandType(result)); - - /* read the first byte */ - switch (ptype) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + etype = getSpec(operandType(result)); - case POINTER: - case IPOINTER: - pic16_emitcode("mov","a,@%s",rname); - break; - - case PPOINTER: - pic16_emitcode("movx","a,@%s",rname); - break; + /* the following call to pic16_loadFSR0 is temporary until + * optimization to handle single bit assignments is added + * to the function. Until then use the old safe way! -- VR */ + pic16_loadFSR0( left ); + + /* read the first byte */ + switch (ptype) { + case POINTER: + case IPOINTER: + case PPOINTER: + case FPOINTER: + case GPOINTER: + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); + break; + case CPOINTER: + pic16_emitcode("clr","a"); + pic16_emitcode("movc","a","@a+dptr"); + break; + } - case FPOINTER: - pic16_emitcode("movx","a,@dptr"); - break; - case CPOINTER: - pic16_emitcode("clr","a"); - pic16_emitcode("movc","a","@a+dptr"); - break; + /* if we have bitdisplacement then it fits */ + /* into this byte completely or if length is */ + /* less than a byte */ + if ((shCnt = SPEC_BSTR(etype)) || + (SPEC_BLEN(etype) <= 8)) { - case GPOINTER: - pic16_emitcode("lcall","__gptrget"); - break; - } + /* shift right acc */ + AccRsh(shCnt, 0); - /* if we have bitdisplacement then it fits */ - /* into this byte completely or if length is */ - /* less than a byte */ - if ((shCnt = SPEC_BSTR(etype)) || - (SPEC_BLEN(etype) <= 8)) { + pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ])); - /* shift right acc */ - AccRsh(shCnt); +/* VR -- normally I would use the following, but since we use the hack, + * to avoid the masking from AccRsh, why not mask it right now? */ - pic16_emitcode("anl","a,#0x%02x", - ((unsigned char) -1)>>(8 - SPEC_BLEN(etype))); - pic16_aopPut(AOP(result),"a",offset); - return ; - } +/* + pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype)))); +*/ + + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + return ; + } + + + + fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n"); + fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); + exit(-1); /* bit field did not fit in a byte */ rlen = SPEC_BLEN(etype) - 8; @@ -8304,42 +9335,86 @@ static void genUnpackBits (operand *result, char *rname, int ptype) return ; } -#if 0 -/*-----------------------------------------------------------------*/ -/* genDataPointerGet - generates code when ptr offset is known */ -/*-----------------------------------------------------------------*/ -static void genDataPointerGet (operand *left, - operand *result, - iCode *ic) + +static void genDataPointerGet(operand *left, + operand *result, + iCode *ic) { - int size , offset = 0; + int size, offset = 0, leoffset=0 ; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_aopOp(result, ic, FALSE); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + size = AOP_SIZE(result); +// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size); - /* optimization - most of the time, left and result are the same - * address, but different types. for the pic code, we could omit - * the following - */ +#if 0 + /* The following tests may save a redudant movff instruction when + * accessing unions */ + + /* if they are the same */ + if (operandsEqu (left, result)) { + DEBUGpic16_emitcode("; ***", "left and result operands are equ/same"); + goto release; + } +#endif - pic16_aopOp(result,ic,TRUE); +#if 0 + /* if they are the same registers */ + if (pic16_sameRegs(AOP(left),AOP(result))) { + DEBUGpic16_emitcode("; ***", "left and result registers are same"); + goto release; + } +#endif - DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); +#if 1 + if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE), + pic16_aopGet(AOP(left), 0, TRUE, FALSE))) { + DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving"); + goto release; + } +#endif - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0)); - size = AOP_SIZE(result); +#if 0 + if ( AOP_TYPE(left) == AOP_PCODE) { + fprintf(stderr,"genDataPointerGet %s, %d\n", + AOP(left)->aopu.pcop->name, + (AOP(left)->aopu.pcop->type == PO_DIR)? + PCOR(AOP(left)->aopu.pcop)->instance: + PCOI(AOP(left)->aopu.pcop)->offset); + } +#endif - while (size--) { - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - offset++; - } + if(AOP(left)->aopu.pcop->type == PO_DIR) + leoffset=PCOR(AOP(left)->aopu.pcop)->instance; - pic16_freeAsmop(left,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); + DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); + + while (size--) { + DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset); + + if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE + || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) { + mov2w(AOP(left), offset); // patch 8 + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popGet(AOP(left), offset), //patch 8 + pic16_popGet(AOP(result), offset))); + } + + offset++; + leoffset++; + } + +release: + pic16_freeAsmop(result,NULL,ic,TRUE); } -#endif + + + /*-----------------------------------------------------------------*/ /* genNearPointerGet - pic16_emitcode for near pointer fetch */ /*-----------------------------------------------------------------*/ @@ -8349,68 +9424,91 @@ static void genNearPointerGet (operand *left, { asmop *aop = NULL; //regs *preg = NULL ; - char *rname ; sym_link *rtype, *retype; sym_link *ltype = operandType(left); - //char buffer[80]; - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - rtype = operandType(result); - retype= getSpec(rtype); - - pic16_aopOp(left,ic,FALSE); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + rtype = operandType(result); + retype= getSpec(rtype); - /* if left is rematerialisable and - result is not bit variable type and - the left is pointer to data space i.e - lower 128 bytes of space */ - if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD && - !IS_BITVAR(retype) && - DCL_TYPE(ltype) == POINTER) { - //genDataPointerGet (left,result,ic); - return ; - } + pic16_aopOp(left,ic,FALSE); + +// pic16_DumpOp("(left)",left); +// pic16_DumpOp("(result)",result); + + /* if left is rematerialisable and + * result is not bit variable type and + * the left is pointer to data space i.e + * lower 128 bytes of space */ + if (AOP_TYPE(left) == AOP_PCODE + && !IS_BITFIELD(retype) + && DCL_TYPE(ltype) == POINTER) { + + genDataPointerGet (left,result,ic); + pic16_freeAsmop(left, NULL, ic, TRUE); + return ; + } - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(left))) { - /* otherwise get a free pointer register */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); -/* - aop = newAsmop(0); - preg = getFreePtr(ic,&aop,FALSE); - pic16_emitcode("mov","%s,%s", - preg->name, - pic16_aopGet(AOP(left),0,FALSE,TRUE)); - rname = preg->name ; -*/ - rname ="BAD"; - } else - rname = pic16_aopGet(AOP(left),0,FALSE,FALSE); + * then don't need anything more */ + if (!AOP_INPREG(AOP(left))) { + /* otherwise get a free pointer register */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + /* VR -- the whole concept is to load FSR0 with the address of the symbol */ + if( (AOP_TYPE(left) == AOP_PCODE) + && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE) + || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10 + { + if(!IS_BITFIELD(retype)) + pic16_loadFSR0( left ); // patch 10 + } else { + // set up FSR0 with address from left + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10 + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10 + } + } +// else +// rname = pic16_aopGet(AOP(left),0,FALSE,FALSE); - pic16_aopOp (result,ic,FALSE); + pic16_aopOp (result,ic,FALSE); /* if bitfield then unpack the bits */ if (IS_BITFIELD(retype)) - genUnpackBits (result,rname,POINTER); + genUnpackBits (result, left, NULL, POINTER); else { /* we have can just get the values */ int size = AOP_SIZE(result); - int offset = 0 ; + int offset = 0; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0)); + + /* fsr0 is loaded already -- VR */ +// pic16_loadFSR0( left ); + +// pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0)); +// pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0)); while(size--) { - pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0)); - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++)); + + if(size) { + pic16_emitpcode(POC_MOVFF, + pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), + pic16_popGet(AOP(result), offset++))); + } else { + pic16_emitpcode(POC_MOVFF, + pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), + pic16_popGet(AOP(result), offset++))); + } + } +#if 0 +// pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0)); +// pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++)); if(size) pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0)); - } +#endif /* while (size--) { if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) { @@ -8444,9 +9542,9 @@ static void genNearPointerGet (operand *left, !OP_SYMBOL(left)->remat && ( OP_SYMBOL(left)->liveTo > ic->seq || ic->depth )) { - int size = AOP_SIZE(result) - 1; - while (size--) - pic16_emitcode("dec","%s",rname); +// int size = AOP_SIZE(result) - 1; +// while (size--) +// pic16_emitcode("dec","%s",rname); } } @@ -8493,7 +9591,7 @@ static void genPagedPointerGet (operand *left, /* if bitfield then unpack the bits */ if (IS_BITFIELD(retype)) - genUnpackBits (result,rname,PPOINTER); + genUnpackBits (result,left,rname,PPOINTER); else { /* we have can just get the values */ int size = AOP_SIZE(result); @@ -8571,7 +9669,7 @@ static void genFarPointerGet (operand *left, /* if bit then unpack */ if (IS_BITFIELD(retype)) - genUnpackBits(result,"dptr",FPOINTER); + genUnpackBits(result,left,"dptr",FPOINTER); else { size = AOP_SIZE(result); offset = 0 ; @@ -8621,7 +9719,7 @@ static void genCodePointerGet (operand *left, /* if bit then unpack */ if (IS_BITFIELD(retype)) - genUnpackBits(result,"dptr",CPOINTER); + genUnpackBits(result,left,"dptr",CPOINTER); else { size = AOP_SIZE(result); offset = 0 ; @@ -8644,8 +9742,8 @@ static void genCodePointerGet (operand *left, static void genGenPointerGet (operand *left, operand *result, iCode *ic) { - int size, offset, lit; - sym_link *retype = getSpec(operandType(result)); + int size, offset, lit; + sym_link *retype = getSpec(operandType(result)); DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(left,ic,FALSE); @@ -8659,6 +9757,9 @@ static void genGenPointerGet (operand *left, lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit); // load FSR0 from immediate pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit))); + +// pic16_loadFSR0( left ); + offset = 0; while(size--) { if(size) { @@ -8691,7 +9792,7 @@ static void genGenPointerGet (operand *left, /* if bit then unpack */ if (IS_BITFIELD(retype)) - genUnpackBits(result,"BAD",GPOINTER); + genUnpackBits(result,left,"BAD",GPOINTER); release: pic16_freeAsmop(left,NULL,ic,TRUE); @@ -8706,19 +9807,21 @@ static void genConstPointerGet (operand *left, operand *result, iCode *ic) { //sym_link *retype = getSpec(operandType(result)); - symbol *albl = newiTempLabel(NULL); - symbol *blbl = newiTempLabel(NULL); - PIC_OPCODE poc; + // symbol *albl = newiTempLabel(NULL); // patch 15 + // symbol *blbl = newiTempLabel(NULL); // + // PIC_OPCODE poc; // patch 15 + int size; + int offset = 0; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(left,ic,FALSE); - pic16_aopOp(result,ic,FALSE); - + pic16_aopOp(result,ic,TRUE); + size = AOP_SIZE(result); DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__); - +#if 0 // patch 15 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key)); pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key)); pic16_emitpLabel(albl->key); @@ -8734,12 +9837,42 @@ static void genConstPointerGet (operand *left, pic16_emitpLabel(blbl->key); pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0)); +#endif // patch 15 + // set up table pointer + if( (AOP_TYPE(left) == AOP_PCODE) + && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE) + || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ...... + { + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl)); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh)); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru)); + } + else + { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru))); + } + + + while(size--) + { + pic16_emitpcodeNULLop(POC_TBLRD_POSTINC); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset))); + offset++; + } + pic16_freeAsmop(left,NULL,ic,TRUE); pic16_freeAsmop(result,NULL,ic,TRUE); } + + /*-----------------------------------------------------------------*/ /* genPointerGet - generate code for pointer get */ /*-----------------------------------------------------------------*/ @@ -8826,6 +9959,11 @@ static void genPointerGet (iCode *ic) #endif genGenPointerGet (left,result,ic); break; + + default: + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "genPointerGet: illegal pointer type"); + } } @@ -8833,75 +9971,93 @@ static void genPointerGet (iCode *ic) /*-----------------------------------------------------------------*/ /* genPackBits - generates code for packed bit storage */ /*-----------------------------------------------------------------*/ -static void genPackBits (sym_link *etype , +static void genPackBits (sym_link *etype , operand *result, operand *right , char *rname, int p_type) { - int shCount = 0 ; - int offset = 0 ; - int rLen = 0 ; - int blen, bstr ; - char *l ; - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - blen = SPEC_BLEN(etype); - bstr = SPEC_BSTR(etype); - - l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE); - MOVA(l); - - /* if the bit lenth is less than or */ - /* it exactly fits a byte then */ - if (SPEC_BLEN(etype) <= 8 ) { - shCount = SPEC_BSTR(etype) ; - - /* shift left acc */ - AccLsh(shCount); - - if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */ + int shCnt = 0 ; + int offset = 0 ; + int rLen = 0 ; + int blen, bstr ; + char *l ; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + blen = SPEC_BLEN(etype); + bstr = SPEC_BSTR(etype); + + if(AOP_TYPE(right) == AOP_LIT) { + if((blen == 1) && (bstr < 8)) { + unsigned long lit; + /* it is a single bit, so use the appropriate bit instructions */ + + DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__); + + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); +// pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); + if((p_type == POINTER) && (result)) { + /* workaround to reduce the extra lfsr instruction */ + if(lit) { + pic16_emitpcode(POC_BSF, + pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); + } else { + pic16_emitpcode(POC_BCF, + pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); + } + } else { - switch (p_type) { - case POINTER: - pic16_emitcode ("mov","b,a"); - pic16_emitcode("mov","a,@%s",rname); - break; - - case FPOINTER: - pic16_emitcode ("mov","b,a"); - pic16_emitcode("movx","a,@dptr"); - break; + if(lit) { + pic16_emitpcode(POC_BSF, + pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); + } else { + pic16_emitpcode(POC_BCF, + pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); + } + } + + return; + } - case GPOINTER: - pic16_emitcode ("push","b"); - pic16_emitcode ("push","acc"); - pic16_emitcode ("lcall","__gptrget"); - pic16_emitcode ("pop","b"); - break; - } + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0)); + offset++; + } else + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++)); + + /* if the bit lenth is less than or */ + /* it exactly fits a byte then */ + if((shCnt=SPEC_BSTR(etype)) + || SPEC_BLEN(etype) <= 8 ) { + + /* shift left acc */ + AccLsh(shCnt); + + /* using PRODL as a temporary register here */ + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl)); + + switch (p_type) { + case FPOINTER: + case POINTER: + case GPOINTER: + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); +// pic16_emitcode ("mov","b,a"); +// pic16_emitcode("mov","a,@%s",rname); + break; + } +#if 1 + pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + (unsigned char)((unsigned char)(0xff << (blen+bstr)) | + (unsigned char)(0xff >> (8-bstr))) )); + pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); +#endif - pic16_emitcode ("anl","a,#0x%02x",(unsigned char) - ((unsigned char)(0xFF << (blen+bstr)) | - (unsigned char)(0xFF >> (8-bstr)) ) ); - pic16_emitcode ("orl","a,b"); - if (p_type == GPOINTER) - pic16_emitcode("pop","b"); - } - } + return; + } - switch (p_type) { - case POINTER: - pic16_emitcode("mov","@%s,a",rname); - break; - case FPOINTER: - pic16_emitcode("movx","@dptr,a"); - break; + fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n"); + fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); + exit(-1); - case GPOINTER: - DEBUGpic16_emitcode(";lcall","__gptrput"); - break; - } /* if we r done */ if ( SPEC_BLEN(etype) <= 8 ) @@ -8910,6 +10066,8 @@ static void genPackBits (sym_link *etype , pic16_emitcode("inc","%s",rname); rLen = SPEC_BLEN(etype) ; + + /* now generate for lengths greater than one byte */ while (1) { @@ -8994,65 +10152,54 @@ static void genDataPointerSet(operand *right, operand *result, iCode *ic) { - int size, offset = 0 ; - char *l, buffer[256]; + int size, offset = 0, resoffset=0 ; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(right,ic,FALSE); - - l = pic16_aopGet(AOP(result),0,FALSE,TRUE); + size = AOP_SIZE(right); -/* + +// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size); + +#if 0 if ( AOP_TYPE(result) == AOP_PCODE) { fprintf(stderr,"genDataPointerSet %s, %d\n", AOP(result)->aopu.pcop->name, + (AOP(result)->aopu.pcop->type == PO_DIR)? + PCOR(AOP(result)->aopu.pcop)->instance: PCOI(AOP(result)->aopu.pcop)->offset); } -*/ - - // tsd, was l+1 - the underline `_' prefix was being stripped - while (size--) { - if (offset) { - sprintf(buffer,"(%s + %d)",l,offset); - fprintf(stderr,"%s:%d: oops %s\n",__FILE__, __LINE__, buffer); - } else - sprintf(buffer,"%s",l); - - if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); - lit = lit >> (8*offset); - if(lit&0xff) { - pic16_emitcode("movlw","%d",lit); - pic16_emitcode("movwf","%s",buffer); - - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff)); - //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); +#endif - } else { - pic16_emitcode("clrf","%s",buffer); - //pic16_emitpcode(POC_CLRF, pic16_popRegFromString(buffer)); - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); - } - }else { - pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s",buffer); + if(AOP(result)->aopu.pcop->type == PO_DIR) + resoffset=PCOR(AOP(result)->aopu.pcop)->instance; - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); - //pic16_emitpcode(POC_MOVWF, pic16_popRegFromString(buffer)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); + while (size--) { + if (AOP_TYPE(right) == AOP_LIT) { + unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); + lit = lit >> (8*offset); + if(lit&0xff) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8 + } else { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8 + } + } else { + mov2w(AOP(right), offset); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8 + } + offset++; + resoffset++; } - offset++; - } - pic16_freeAsmop(right,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); } + + /*-----------------------------------------------------------------*/ -/* genNearPointerSet - pic16_emitcode for near pointer put */ +/* genNearPointerSet - pic16_emitcode for near pointer put */ /*-----------------------------------------------------------------*/ static void genNearPointerSet (operand *right, operand *result, @@ -9062,121 +10209,127 @@ static void genNearPointerSet (operand *right, char *l; sym_link *retype; sym_link *ptype = operandType(result); - + sym_link *resetype; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - retype= getSpec(operandType(right)); - - pic16_aopOp(result,ic,FALSE); - + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + retype= getSpec(operandType(right)); + resetype = getSpec(operandType(result)); + + pic16_aopOp(result,ic,FALSE); - /* if the result is rematerializable & - in data space & not a bit variable */ - //if (AOP_TYPE(result) == AOP_IMMD && - if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD && - DCL_TYPE(ptype) == POINTER && - !IS_BITVAR(retype)) { - genDataPointerSet (right,result,ic); - pic16_freeAsmop(result,NULL,ic,TRUE); - return; - } + /* if the result is rematerializable & + * in data space & not a bit variable */ + + /* and result is not a bit variable */ + if (AOP_TYPE(result) == AOP_PCODE +// && AOP_TYPE(result) == AOP_IMMD + && DCL_TYPE(ptype) == POINTER + && !IS_BITFIELD(retype) + && !IS_BITFIELD(resetype)) { + + genDataPointerSet (right,result,ic); + pic16_freeAsmop(result,NULL,ic,TRUE); + return; + } - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_aopOp(right,ic,FALSE); - DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_aopOp(right,ic,FALSE); + DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(result))) { - /* otherwise get a free pointer register */ - //aop = newAsmop(0); - //preg = getFreePtr(ic,&aop,FALSE); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - //pic16_emitcode("mov","%s,%s", - // preg->name, - // pic16_aopGet(AOP(result),0,FALSE,TRUE)); - //rname = preg->name ; - //pic16_emitcode("movwf","fsr0"); - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0)); - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); - goto release; + /* if the value is already in a pointer register + * then don't need anything more */ + if (!AOP_INPREG(AOP(result))) { + /* otherwise get a free pointer register */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if( (AOP_TYPE(result) == AOP_PCODE) + && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE) + || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10 + { + if(!IS_BITFIELD(resetype)) + pic16_loadFSR0( result ); // patch 10 + } else { + // set up FSR0 with address of result + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10 + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10 + } - }// else + } +// else // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if bitfield then unpack the bits */ - if (IS_BITFIELD(retype)) { - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "The programmer is obviously confused"); -// genPackBits (retype,right,"BAD",POINTER); - exit(1); - } - else { - /* we have can just get the values */ - int size = AOP_SIZE(right); - int offset = 0 ; + /* if bitfield then unpack the bits */ + if (IS_BITFIELD(resetype)) { + genPackBits (resetype, result, right, NULL, POINTER); + } else { + /* we have can just get the values */ + int size = AOP_SIZE(right); + int offset = 0 ; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - while (size--) { - l = pic16_aopGet(AOP(right),offset,FALSE,TRUE); - if (*l == '@' ) { - //MOVA(l); - //pic16_emitcode("mov","@%s,a",rname); - pic16_emitcode("movf","indf0,w ;1"); - } else { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + while (size--) { + l = pic16_aopGet(AOP(right),offset,FALSE,TRUE); + if (*l == '@' ) { + //MOVA(l); + //pic16_emitcode("mov","@%s,a",rname); + pic16_emitcode("movf","indf0,w ;1"); + } else { - if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); - if(lit) { - pic16_emitcode("movlw","%s",l); - pic16_emitcode("movwf","indf0 ;2"); - } else - pic16_emitcode("clrf","indf0"); - }else { - pic16_emitcode("movf","%s,w",l); - pic16_emitcode("movwf","indf0 ;2"); - } - //pic16_emitcode("mov","@%s,%s",rname,l); - } - if (size) - pic16_emitcode("incf","fsr0,f ;3"); - //pic16_emitcode("inc","%s",rname); - offset++; - } - } + if (AOP_TYPE(right) == AOP_LIT) { // patch 10 + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); // + if (size) { // + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); // + } else { // + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); // + } // + } else { // no literal // + if(size) { // + pic16_emitpcode(POC_MOVFF, // + pic16_popGet2p(pic16_popGet(AOP(right),offset), // + pic16_popCopyReg(&pic16_pc_postinc0))); // + } else { // + pic16_emitpcode(POC_MOVFF, // + pic16_popGet2p(pic16_popGet(AOP(right),offset), // + pic16_popCopyReg(&pic16_pc_indf0))); // + } // + } // patch 10 + } + offset++; + } + } - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* now some housekeeping stuff */ - if (aop) { - /* we had to allocate for this iCode */ - pic16_freeAsmop(NULL,aop,ic,TRUE); - } else { - /* we did not allocate which means left - already in a pointer register, then - if size > 0 && this could be used again - we have to point it back to where it - belongs */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (AOP_SIZE(right) > 1 && - !OP_SYMBOL(result)->remat && - ( OP_SYMBOL(result)->liveTo > ic->seq || - ic->depth )) { - int size = AOP_SIZE(right) - 1; - while (size--) - pic16_emitcode("decf","fsr0,f"); - //pic16_emitcode("dec","%s",rname); - } - } + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* now some housekeeping stuff */ + if (aop) { + /* we had to allocate for this iCode */ + pic16_freeAsmop(NULL,aop,ic,TRUE); + } else { + /* we did not allocate which means left + * already in a pointer register, then + * if size > 0 && this could be used again + * we have to point it back to where it + * belongs */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (AOP_SIZE(right) > 1 + && !OP_SYMBOL(result)->remat + && ( OP_SYMBOL(result)->liveTo > ic->seq + || ic->depth )) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* done */ - release: - pic16_freeAsmop(right,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); + int size = AOP_SIZE(right) - 1; + + while (size--) + pic16_emitcode("decf","fsr0,f"); + //pic16_emitcode("dec","%s",rname); + } + } + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* done */ +//release: + pic16_freeAsmop(right,NULL,ic,TRUE); + pic16_freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -9215,7 +10368,7 @@ static void genPagedPointerSet (operand *right, /* if bitfield then unpack the bits */ if (IS_BITFIELD(retype)) - genPackBits (retype,right,rname,PPOINTER); + genPackBits (retype,result,right,rname,PPOINTER); else { /* we have can just get the values */ int size = AOP_SIZE(right); @@ -9293,7 +10446,7 @@ static void genFarPointerSet (operand *right, /* if bit then unpack */ if (IS_BITFIELD(retype)) - genPackBits(retype,right,"dptr",FPOINTER); + genPackBits(retype,result,right,"dptr",FPOINTER); else { size = AOP_SIZE(right); offset = 0 ; @@ -9316,7 +10469,7 @@ static void genFarPointerSet (operand *right, static void genGenPointerSet (operand *right, operand *result, iCode *ic) { - int size, offset, lit; + int i, size, offset, lit; sym_link *retype = getSpec(operandType(right)); DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -9328,7 +10481,6 @@ static void genGenPointerSet (operand *right, DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - /* if the operand is already in dptr then we do nothing else we move the value to dptr */ if (AOP_TYPE(result) != AOP_STR) { @@ -9364,19 +10516,33 @@ static void genGenPointerSet (operand *right, DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - while(size--) { - if(size) { - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0))); - } else { - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0))); + if(AOP_TYPE(right) == AOP_LIT) + { + // copy literal + // note: pic16_popGet handles sign extension + for(i=0;iname, IN_CODESPACE( SPEC_OCLS(sym->etype))); + + if(sym->onStack) { + DEBUGpic16_emitcode("; ", "%s symbol %s on stack", __FUNCTION__, sym->name); + + return; } +// if(pic16_debug_verbose) { +// fprintf(stderr, "%s:%d %s symbol %s , codespace=%d\n", +// __FILE__, __LINE__, __FUNCTION__, sym->name, IN_CODESPACE( SPEC_OCLS(sym->etype))); +// } + /* Assume that what we want the address of is in data space * since there is no stack on the PIC, yet! -- VR */ /* low */ @@ -9624,7 +10762,6 @@ static void genAddrOf (iCode *ic) pic16_freeAsmop(left, NULL, ic, FALSE); } -#endif /* new genAddrOf */ #if 0 /*-----------------------------------------------------------------*/ @@ -9733,20 +10870,89 @@ 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_LIT) { + if(!IS_FLOAT(operandType( right ))) + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + else { + union { + unsigned long lit_int; + float lit_float; + } info; + + /* take care if literal is a float */ + info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit); + lit = info.lit_int; + } + } + +// fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit, +// sizeof(unsigned long int), sizeof(float)); + + if(AOP_TYPE(right) != AOP_LIT + && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))) { + DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__); + fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name); + + // set up table pointer + if( (AOP_TYPE(right) == AOP_PCODE) + && ((AOP(right)->aopu.pcop->type == PO_IMMEDIATE) + || (AOP(right)->aopu.pcop->type == PO_DIR))) + { + fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl)); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh)); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru)); + } else { + fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0), + pic16_popCopyReg(&pic16_pc_tblptrl))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1), + pic16_popCopyReg(&pic16_pc_tblptrh))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2), + pic16_popCopyReg(&pic16_pc_tblptru))); + } + + size = min(AOP_SIZE(right), AOP_SIZE(result)); + while(size--) { + pic16_emitpcodeNULLop(POC_TBLRD_POSTINC); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), + pic16_popGet(AOP(result),offset))); + offset++; + } + + if(AOP_SIZE(result) > AOP_SIZE(right)) { + size = AOP_SIZE(result) - AOP_SIZE(right); + while(size--) { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset)); + offset++; + } + } + goto release; + } + + + +#if 0 /* VR - What is this?! */ if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(aopIdx(AOP(result),0) == 4) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + /* this is a workaround to save value of right into wreg too, + * value of wreg is going to be used later */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); goto release; } else +// assert(0); DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__); } +#endif know_W=-1; while (size--) { @@ -9768,6 +10974,9 @@ static void genAssign (iCode *ic) pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0)); pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0)); } + } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); } else { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -10032,7 +11241,7 @@ static void genCast (iCode *ic) /* we need to or */ if (AOP_TYPE(right) == AOP_REG) { pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),0,FALSE,FALSE),0,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); } pic16_toBoolean(right); @@ -10241,15 +11450,16 @@ static void genCast (iCode *ic) size = AOP_SIZE(right); offset = 0 ; while (size--) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset)); +// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); +// pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); offset++; } /* now depending on the sign of the destination */ size = AOP_SIZE(result) - AOP_SIZE(right); /* if unsigned or not an integral type */ - if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) { + if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) { while (size--) pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++)); } else { @@ -10258,15 +11468,15 @@ static void genCast (iCode *ic) if(size == 1) { /* Save one instruction of casting char to int */ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),offset)); } else { pic16_emitpcode(POC_CLRF,pic16_popCopyReg(&pic16_pc_wreg)); if(offset) - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER)); else - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0)); + pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),offset,FALSE,FALSE),7,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0xff)); @@ -10329,7 +11539,7 @@ static int genDjnz (iCode *ic, iCode *ifx) pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key)); pic16_emitcode("decfsz","%s,f",pic16_aopGet(AOP(IC_RESULT(ic)),0,FALSE,FALSE)); - pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + labelOffset); + pic16_emitcode ("goto","_%05d_DS_",IC_TRUE(ifx)->key+100 + pic16_labelOffset); } /* pic16_emitcode ("sjmp","%05d_DS_",lbl1->key+100); */ @@ -10350,13 +11560,20 @@ static void genReceive (iCode *ic) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (isOperandInFarSpace(IC_RESULT(ic)) && +#if 0 + fprintf(stderr, "%s:%d %s for symbol %s\tonStack: %d\n", __FILE__, __LINE__, __FUNCTION__, + OP_SYMBOL( IC_RESULT(ic) )->rname, OP_SYMBOL( IC_RESULT(ic) )->onStack); +#endif +// pic16_DumpOp(__FUNCTION__, IC_RESULT(ic)); + + if (isOperandInFarSpace(IC_RESULT(ic)) && ( OP_SYMBOL(IC_RESULT(ic))->isspilt || IS_TRUE_SYMOP(IC_RESULT(ic))) ) { int size = getSize(operandType(IC_RESULT(ic))); int offset = pic16_fReturnSizePic - size; + assert( 0 ); while (size--) { pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ? fReturn[pic16_fReturnSizePic - offset - 1] : "acc")); @@ -10378,7 +11595,7 @@ static void genReceive (iCode *ic) _G.accInUse++; pic16_aopOp(IC_RESULT(ic),ic,FALSE); _G.accInUse--; - assignResultValue(IC_RESULT(ic)); + assignResultValue(IC_RESULT(ic), 0); } pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); @@ -10423,33 +11640,16 @@ void genpic16Code (iCode *lic) if (options.debug && currFunc) { if (currFunc) { cdbSymbol(currFunc,cdbFile,FALSE,TRUE); - _G.debugLine = 1; - if (IS_STATIC(currFunc->etype)) { - pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__); - //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name)); - } else { - pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__); - //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name)); - } - _G.debugLine = 0; } } #endif -// dumpiCode(lic); - for (ic = lic ; ic ; ic = ic->next ) { -// fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op); -// DEBUGpic16_emitcode("; VR", ""); DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op); if ( cln != ic->lineno ) { if ( options.debug ) { - _G.debugLine = 1; - pic16_emitcode("",";C$%s$%d$%d$%d ==.", - FileBaseName(ic->filename),ic->lineno, - ic->level,ic->block); - _G.debugLine = 0; + debugFile->writeCLine (ic); } if(!options.noCcodeInAsm) { @@ -10462,8 +11662,10 @@ void genpic16Code (iCode *lic) } if(options.iCodeInAsm) { + char *l; /* insert here code to print iCode as comment */ - pic16_emitcomment("; ic:%d: %s", ic->seq, printILine(ic)); + l = Safe_strdup(printILine(ic)); + pic16_emitpcomment("ic:%d: %s", ic->seq, l); } /* if the result is marked as