X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgen.c;h=159eeb8b559d304db8eb3f5cde1ea12488de16ab;hb=b69c2ce731d39b467f0bac5f532ef5e94a1eff5e;hp=c84e20e5e5349c4133a59ef01d04ec335147156b;hpb=820b7c701814ded6b791cee96570d4f9bb77a85c;p=fw%2Fsdcc diff --git a/src/pic16/gen.c b/src/pic16/gen.c index c84e20e5..159eeb8b 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -6,7 +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) + - 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 @@ -58,9 +58,13 @@ static asmop *newAsmop (short type); 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 void mov2f(asmop *dst, asmop *src, int offset); +static void mov2fp(pCodeOp *dst, asmop *src, int offset); +static pCodeOp *pic16_popRegFromIdx(int rIdx); -static int labelOffset=0; +//static int aopIdx (asmop *aop, int offset); + +int pic16_labelOffset=0; extern int pic16_debug_verbose; static int optimized_for_speed = 0; /* @@ -76,6 +80,7 @@ static int max_key=0; static int GpsuedoStkPtr=0; pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index); + unsigned int pic16aopLiteral (value *val, int offset); const char *pic16_AopType(short type); static iCode *ifxForOp ( operand *op, iCode *ic ); @@ -96,7 +101,7 @@ static bool is_LitAOp(asmop *aop); static char *zero = "#0x00"; static char *one = "#0x01"; -static char *spname = "sp"; +//static char *spname = "sp"; /* @@ -110,8 +115,7 @@ static char *spname = "sp"; */ -char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" }; -//char *fReturn390[] = {"dpl","dph","dpx", "b","a" }; +char *fReturnpic16[] = {"WREG", "PRODL", "PRODH", "FSR0L" }; unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */ static char **fReturn = fReturnpic16; @@ -122,12 +126,20 @@ static char *accUse[] = {"WREG"}; static struct { short r0Pushed; short r1Pushed; + short fsr0Pushed; short accInUse; short inLine; short debugLine; short nRegsSaved; + short ipushRegs; set *sendSet; + set *stackRegSet; int interruptvector; + int usefastretfie; + bitVect *fregsUsed; + int stack_lat; /* stack offset latency */ + int resDirect; + int useWreg; /* flag when WREG is used to pass function parameter */ } _G; /* Resolved ifx structure. This structure stores information @@ -143,7 +155,7 @@ typedef struct resolvedIfx { extern int pic16_ptrRegReq ; extern int pic16_nRegs; extern FILE *codeOutFile; -static void saverbank (int, iCode *,bool); +//static void saverbank (int, iCode *,bool); static lineNode *lineHead = NULL; static lineNode *lineCurr = NULL; @@ -270,7 +282,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) @@ -280,10 +297,16 @@ void pic16_emitpcode(PIC_OPCODE poc, pCodeOp *pcop) pic16_addpCode2pBlock(pb,pic16_newpCode(poc,pcop)); else DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__); - -// fprintf(stderr, "%s\n", pcop->name); } +void pic16_emitpinfo(INFO_TYPE itype, pCodeOp *pcop) +{ + if(pcop) + pic16_addpCode2pBlock(pb, pic16_newpCodeInfo(itype, pcop)); + else + DEBUGpic16_emitcode(";","%s ignoring NULL pcop",__FUNCTION__); +} + void pic16_emitpcodeNULLop(PIC_OPCODE poc) { @@ -352,11 +375,67 @@ pic16_emitDebuggerSymbol (char * debugSym) /*-----------------------------------------------------------------*/ 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__); + } + + if(!fsr0iu && !fsr0ou) { + ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0); + (*aopp)->type = AOP_FSR0; + + fprintf(stderr, "%s:%d returning plain FSR0\n", __FILE__, __LINE__); + + return ((*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR0)); + } + +#if 0 + /* 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); + } +#endif + + /* 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; + +// fprintf(stderr, "%s:%d returning FSR0 after pushing value to stack\n", __FILE__, __LINE__); - //fprintf(stderr, "%s:%d: getting free ptr from ic = %c\n", __FUNCTION__, __LINE__, ic->op); + return (*aopp)->aopu.aop_ptr = pic16_regWithIdx (IDX_FSR0); + } + + 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 */ @@ -374,7 +453,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) /* if no usage of r0 then return it */ if (!r0iu && !r0ou) { ic->rUsed = bitVectSetBit(ic->rUsed,R0_IDX); - (*aopp)->type = AOP_R0; + (*aopp)->type = AOP_R0; return (*aopp)->aopu.aop_ptr = pic16_regWithIdx(R0_IDX); } @@ -430,6 +509,7 @@ endOfWorld : werror(E_INTERNAL_ERROR,__FILE__,__LINE__, "getFreePtr should never reach here"); exit(0); +#endif } /*-----------------------------------------------------------------*/ @@ -498,7 +578,7 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) #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 @@ -524,6 +604,8 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + _G.resDirect = 0; /* clear flag that instructs the result is loaded directly from aopForSym */ + // sym = OP_SYMBOL(op); /* if already has one */ @@ -532,28 +614,73 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) return sym->aop; } +#if 0 /* 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) { - sym->onStack = 0; - SPEC_OCLS( sym->etype ) = data; - space = data; + fprintf(stderr, "%s:%d symbol %s on stack\n", __FILE__, __LINE__, OP_SYMBOL(op)->name); } - +#endif #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) { - + if (sym->onStack || sym->iaccess) { + pCodeOp *pcop[4]; + int i; + 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); + /* acquire a temporary register -- it is saved in function */ + + sym->aop = aop = newAsmop(AOP_STA); + aop->aopu.stk.stk = sym->stack; aop->size = getSize(sym->type); + + DEBUGpic16_emitcode("; +++", "%s:%d", __FILE__, __LINE__); + pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) )); + if((ic->op == '=') && IC_RESULT(ic) && AOP( IC_RESULT(ic) ) + && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG) ) { + + for(i=0;isize;i++) + aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx); + _G.resDirect = 1; /* notify that result will be loaded directly from aopForSym */ + } else + for(i=0;isize;i++) { + aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond( _G.fregsUsed, 0 ); + _G.fregsUsed = bitVectSetBit(_G.fregsUsed, PCOR(pcop[i])->r->rIdx); + } + + +// fprintf(stderr, "%s:%d\t%s\tsym size %d\n", __FILE__, __LINE__, __FUNCTION__, aop->size); + +#if 1 + DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d stack = %d",__LINE__,sym->rname,aop->size, sym->stack); + + if(_G.accInUse) { + pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) ); + } + + for(i=0;isize;i++) { + + /* initialise for stack access via frame pointer */ + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack + i + _G.stack_lat)); + + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg(&pic16_pc_plusw2), pcop[i])); + } + + 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) { @@ -580,9 +707,12 @@ static asmop *aopForSym (iCode *ic, operand *op, 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 @@ -613,6 +743,23 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) aop->size = getSize(sym->type); return aop; } +#endif + +#if 0 + /* special case for a function */ + if (IS_FUNC(sym->type)) { + sym->aop = aop = newAsmop(AOP_PCODE); + //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1); + aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0); + PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space); + PCOI(aop->aopu.pcop)->index = 0; + aop->size = FPTRSIZE; + DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname); + return aop; + } +#endif + + //DEBUGpic16_emitcode(";","%d",__LINE__); /* if in bit space */ @@ -633,22 +780,18 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) return aop; } -#if 0 // patch 14 - /* special case for a function */ - if (IS_FUNC(sym->type)) { - sym->aop = aop = newAsmop(AOP_IMMD); - //_ALLOC_ATOMIC(aop->aopu.aop_immd,strlen(sym->rname)+1); - aop->aopu.aop_immd = Safe_calloc(1,strlen(sym->rname)+1); - strcpy(aop->aopu.aop_immd,sym->rname); - aop->size = FPTRSIZE; - DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname); + + if (IN_FARSPACE(space) && !IN_CODESPACE(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; } -#endif // patch 14 /* only remaining is far space */ - /* in which case DPTR gets the address */ sym->aop = aop = newAsmop(AOP_PCODE); /* change the next if to 1 to revert to good old immediate code */ @@ -672,11 +815,13 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) if(IN_DIRSPACE( space )) aop->size = PTRSIZE; - else if(IN_CODESPACE( space )) + 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 { + else if(sym->onStack) { + aop->size = PTRSIZE; + } else { assert( 0 ); } @@ -695,6 +840,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) static asmop *aopForRemat (operand *op) // x symbol *sym) { symbol *sym = OP_SYMBOL(op); + operand *refop; iCode *ic = NULL, *oldic; asmop *aop = newAsmop(AOP_PCODE); int val = 0; @@ -726,14 +872,15 @@ static asmop *aopForRemat (operand *op) // x symbol *sym) } offset = OP_SYMBOL(IC_LEFT(ic))->offset; + refop = IC_LEFT(ic); 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))) + if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(refop))) || viaimmd) { - DEBUGpic16_emitcode("%s:%d immediate", __FILE__, __LINE__); + DEBUGpic16_emitcode(";", "%s:%d immediate", __FILE__, __LINE__); aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val); @@ -745,7 +892,7 @@ static asmop *aopForRemat (operand *op) // x symbol *sym) PCOI(aop->aopu.pcop)->index = val; } else { - DEBUGpic16_emitcode("%s:%d dir", __FILE__, __LINE__); + 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); @@ -771,6 +918,7 @@ static asmop *aopForRemat (operand *op) // x symbol *sym) return aop; } +#if 0 static int aopIdx (asmop *aop, int offset) { if(!aop) @@ -782,6 +930,8 @@ static int aopIdx (asmop *aop, int offset) return aop->aopu.aop_reg[offset]->rIdx; } +#endif + /*-----------------------------------------------------------------*/ /* regsInCommon - two operands have some registers in common */ /*-----------------------------------------------------------------*/ @@ -841,7 +991,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; @@ -872,6 +1023,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 ; @@ -879,14 +1035,31 @@ bool pic16_sameRegs (asmop *aop1, asmop *aop2 ) if (aop1->size != aop2->size ) return FALSE ; - for (i = 0 ; i < aop1->size ; i++ ) - if (aop1->aopu.aop_reg[i] != - aop2->aopu.aop_reg[i] ) + for (i = 0 ; i < aop1->size ; i++ ) { +// if(aop1->aopu.aop_reg[i]->type != aop2->aopu.aop_reg[i]->type)return FALSE; + +// if(aop1->aopu.aop_reg[i]->type == AOP_REG) + if (strcmp(aop1->aopu.aop_reg[i]->name, aop2->aopu.aop_reg[i]->name )) return FALSE ; + } return TRUE ; } +bool pic16_sameRegsOfs(asmop *aop1, asmop *aop2, int offset) +{ + DEBUGpic16_emitcode(";***", "%s aop1->type = %s\taop2->type = %s (offset = %d)\n", __FUNCTION__, + pic16_AopType(aop1->type), pic16_AopType(aop2->type), offset); + + if(aop1 == aop2)return TRUE; + if(aop1->type != AOP_REG || aop2->type != AOP_REG)return FALSE; + + if(strcmp(aop1->aopu.aop_reg[offset]->name, aop2->aopu.aop_reg[offset]->name))return FALSE; + + return TRUE; +} + + /*-----------------------------------------------------------------*/ /* pic16_aopOp - allocates an asmop for an operand : */ /*-----------------------------------------------------------------*/ @@ -964,8 +1137,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) /* rematerialize it NOW */ if (sym->remat) { - sym->aop = op->aop = aop = - aopForRemat (op); + sym->aop = op->aop = aop = aopForRemat (op); aop->size = getSize(sym->type); //DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd); return; @@ -1011,10 +1183,13 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) /* force a new aop if sizes differ */ sym->usl.spillLoc->aop = NULL; } + +#if 0 DEBUGpic16_emitcode(";","%s %d %s sym->rname = %s, offset %d", __FUNCTION__,__LINE__, sym->usl.spillLoc->rname, sym->rname, sym->usl.spillLoc->offset); +#endif sym->aop = op->aop = aop = newAsmop(AOP_PCODE); //aop->aopu.pcop = pic16_popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset); @@ -1066,8 +1241,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) { @@ -1088,6 +1279,32 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) bitVectUnSetBit(ic->rUsed,R1_IDX); break; + case AOP_STA: + { + int i; + + /* we must store the result on stack */ + if((op == IC_RESULT(ic)) && RESULTONSTA(ic)) { + if(_G.accInUse)pic16_pushpCodeOp( pic16_popCopyReg(&pic16_pc_wreg) ); + for(i=0;isize;i++) { + /* initialise for stack access via frame pointer */ + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(OP_SYMBOL(IC_RESULT(ic))->stack + i + _G.stack_lat)); + + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + aop->aopu.stk.pop[i], pic16_popCopyReg(&pic16_pc_plusw2))); + } + + if(_G.accInUse)pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) ); + } + + if(!_G.resDirect) { + for(i=0;isize;i++) + PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1; + } + _G.resDirect = 0; + } + break; +#if 0 case AOP_STK : { int sz = aop->size; @@ -1132,6 +1349,8 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) _G.r1Pushed--; } } +#endif + } #endif @@ -1165,65 +1384,39 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) /* 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) @@ -1264,10 +1457,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__); + 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"; +// 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)); @@ -1300,53 +1495,119 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) strcpy(rs,s); return rs; + case AOP_STA: + rs = Safe_strdup(PCOR(aop->aopu.stk.pop[offset])->r->name); + 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); } + +/* lock has the following meaning: When allocating temporary registers + * for stack variables storage, the value of the temporary register is + * saved on stack. Its value is restored at the end. This procedure is + * done via calls to pic16_aopOp and pic16_freeAsmop functions. There is + * a possibility that before a call to pic16_aopOp, a temporary register + * is allocated for a while and it is freed after some time, this will + * mess the stack and values will not be restored properly. So use lock=1 + * to allocate temporary registers used internally by the programmer, and + * lock=0 to allocate registers for stack use. lock=1 will emit a warning + * to inform the compiler developer about a possible bug. This is an internal + * feature for developing the compiler -- VR */ + +int _TempReg_lock = 0; /*-----------------------------------------------------------------*/ /* pic16_popGetTempReg - create a new temporary pCodeOp */ /*-----------------------------------------------------------------*/ -pCodeOp *pic16_popGetTempReg(void) +pCodeOp *pic16_popGetTempReg(int lock) { pCodeOp *pcop; symbol *cfunc; -// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); +// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(_TempReg_lock) { + werror(W_POSSBUG2, __FILE__, __LINE__); + } + + _TempReg_lock += lock; + + cfunc = currFunc; + currFunc = NULL; - 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; - 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) ); + } - /* push value on stack */ - pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) ); - } + currFunc = cfunc; + + return pcop; +} + +/*-----------------------------------------------------------------*/ +/* pic16_popGetTempRegCond - create a new temporary pCodeOp, but */ +/* don't save if inside v */ +/*-----------------------------------------------------------------*/ +pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock) +{ + pCodeOp *pcop; + symbol *cfunc; + +// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(_TempReg_lock) { + werror(W_POSSBUG2, __FILE__, __LINE__); + } + + _TempReg_lock += lock; + + cfunc = currFunc; + currFunc = NULL; - currFunc = 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; + + if(!bitVectBitValue(v, PCOR(pcop)->r->rIdx)) { + /* 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) +void pic16_popReleaseTempReg(pCodeOp *pcop, int lock) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { - PCOR(pcop)->r->isFree = 1; - - pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) ); - } + _TempReg_lock -= lock; + + 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 */ @@ -1354,12 +1615,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); } /*-----------------------------------------------------------------*/ @@ -1389,7 +1650,7 @@ pCodeOp *pic16_popCopyReg(pCodeOpReg *pc) /*-----------------------------------------------------------------*/ /* pic16_popGetLit - asm operator to pcode operator conversion */ /*-----------------------------------------------------------------*/ -pCodeOp *pic16_popGetLit(unsigned int lit) +pCodeOp *pic16_popGetLit(int lit) { return pic16_newpCodeOpLit(lit); } @@ -1397,7 +1658,7 @@ pCodeOp *pic16_popGetLit(unsigned int lit) /*-----------------------------------------------------------------*/ /* pic16_popGetLit2 - asm operator to pcode operator conversion */ /*-----------------------------------------------------------------*/ -pCodeOp *pic16_popGetLit2(unsigned int lit, pCodeOp *arg2) +pCodeOp *pic16_popGetLit2(int lit, pCodeOp *arg2) { return pic16_newpCodeOpLit2(lit, arg2); } @@ -1451,16 +1712,19 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING")); PCOR(pcop)->r = pic16_dirregWithName(pcop->name); - if(PCOR(pcop)->r == NULL) { + + /* make sure that register doesn't exist, + * and operand isn't NULL + * and symbol isn't in codespace (codespace symbols are handled elsewhere) */ + if((PCOR(pcop)->r == NULL) + && (op) + && !IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(op)))) { // 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, op); - //fprintf(stderr, "allocating new register -> %s\n", str); + 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 size= %d offset=%d",__LINE__,pcop->name,size,offset); } PCOR(pcop)->instance = offset; @@ -1476,6 +1740,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; @@ -1573,11 +1838,29 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) 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_STA: + /* pCodeOp is already allocated from aopForSym */ + DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset); + pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]); + + return (pcop); + case AOP_ACC: { int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx; @@ -1616,8 +1899,9 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) 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; @@ -1631,7 +1915,7 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) 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); @@ -1685,6 +1969,8 @@ void pic16_aopPut (asmop *aop, char *s, int offset) char *d = buffer ; symbol *lbl ; + return; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (aop->size && offset > ( aop->size - 1)) { @@ -1901,9 +2187,10 @@ void pic16_aopPut (asmop *aop, char *s, int offset) break; default : - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "pic16_aopPut got unsupported aop->type"); - exit(0); + fprintf(stderr, "%s:%d: unknown aop->type = 0x%x\n", __FILE__, __LINE__, aop->type); +// werror(E_INTERNAL_ERROR,__FILE__,__LINE__, +// "pic16_aopPut got unsupported aop->type"); +// exit(0); } } @@ -1913,17 +2200,34 @@ void pic16_aopPut (asmop *aop, char *s, int offset) /*-----------------------------------------------------------------*/ static void mov2w (asmop *aop, int offset) { + DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset); -// if(!aop) -// return; - - DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset); + if(is_LitAOp(aop)) + 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)); +static void mov2f(asmop *dst, asmop *src, int offset) +{ + if(is_LitAOp(src)) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(dst, offset)); + } else { + if(pic16_sameRegsOfs(src, dst, offset))return; + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( pic16_popGet(src, offset), + pic16_popGet(dst, offset))); + } +} +static void mov2fp(pCodeOp *dst, asmop *src, int offset) +{ + if(is_LitAOp(src)) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(src, offset)); + pic16_emitpcode(POC_MOVWF, dst); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(src, offset), dst)); + } } @@ -2327,6 +2631,7 @@ release: pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } +#if 0 /*-----------------------------------------------------------------*/ /* saveRegisters - will look for a call and save the registers */ /*-----------------------------------------------------------------*/ @@ -2428,6 +2733,7 @@ static void unsaveRegisters (iCode *ic) //} } +#endif #if 0 // patch 14 /*-----------------------------------------------------------------*/ @@ -2452,15 +2758,13 @@ static void pushSide(operand * oper, int size) void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src) { -// (AOP(left)->aopu.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))); - } + 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))); + } } @@ -2471,92 +2775,106 @@ void pic16_loadFromReturn(operand *op, int offset, pCodeOp *src) static void assignResultValue(operand * oper, int rescall) { int size = AOP_SIZE(oper); + int offset=0; + + DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14 + DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL); - DEBUGpic16_emitcode ("; ***","%s %d rescall:%d size:%d",__FUNCTION__,__LINE__,rescall,size); // patch 14 - DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL); - - if(rescall) { - /* assign result from a call/pcall function() */ + if(rescall) { + /* assign result from a call/pcall function() */ - /* function results are stored in a special order, - * see top of file with Function return policy, or manual */ + /* 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 <= 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>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>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 { - /* >32-bits, result on stack, and FSR0 points to beginning. - * Fix stack when done */ - - while (size--) { -// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); -// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + if(size>3) { + /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */ + pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14 + } + + } else { + /* >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++; - } + 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++; - } + /* 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 { + int areg = 0; /* matching argument register */ + + areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1; - 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 + /* its called from genReceive (probably) -- VR */ + if(!GpsuedoStkPtr && _G.useWreg) { +// DEBUGpic16_emitcode("; ", "pop %d", GpsuedoStkPtr); - } - } - + /* The last byte in the assignment is in W */ + if(areg <= GpsuedoStkPtr) { + size--; + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), offset /*size*/)); + offset++; + } + } +// GpsuedoStkPtr++; + _G.stack_lat = AOP_SIZE(oper)-1; + + while (size) { + size--; + GpsuedoStkPtr++; + popaopidx(AOP(oper), offset, GpsuedoStkPtr); + offset++; + } + } } /*-----------------------------------------------------------------*/ -/* genIpush - genrate code for pushing this gets a little complex */ +/* genIpush - generate code for pushing this gets a little complex */ /*-----------------------------------------------------------------*/ static void genIpush (iCode *ic) { +// int size, offset=0; DEBUGpic16_emitcode ("; ***","%s %d - WARNING no code generated",__FUNCTION__,__LINE__); + + + if(ic->parmPush) { + pic16_aopOp(IC_LEFT(ic), ic, FALSE ); + + /* send to stack as normal */ + addSet(&_G.sendSet,ic); +// addSetHead(&_G.sendSet,ic); + pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); + } + + #if 0 int size, offset = 0 ; char *l; @@ -2584,29 +2902,6 @@ static void genIpush (iCode *ic) return ; } - /* this is a paramter push: in this case we call - the routine to find the call and save those - registers that need to be saved */ - saveRegisters(ic); - - /* then do the push */ - pic16_aopOp(IC_LEFT(ic),ic,FALSE); - - - // pushSide(IC_LEFT(ic), AOP_SIZE(IC_LEFT(ic))); - size = AOP_SIZE(IC_LEFT(ic)); - - while (size--) { - l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++,FALSE,TRUE); - if (AOP_TYPE(IC_LEFT(ic)) != AOP_REG && - AOP_TYPE(IC_LEFT(ic)) != AOP_DIR && - strcmp(l,"a") ) { - pic16_emitcode("mov","a,%s",l); - pic16_emitcode("push","acc"); - } else - pic16_emitcode("push","%s",l); - } - pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); #endif } @@ -2636,6 +2931,7 @@ static void genIpop (iCode *ic) #endif } +#if 0 /*-----------------------------------------------------------------*/ /* unsaverbank - restores the resgister bank from stack */ /*-----------------------------------------------------------------*/ @@ -2731,7 +3027,7 @@ static void saverbank (int bank, iCode *ic, bool pushPsw) ic->bankSaved = 1; #endif } - +#endif /* 0 */ /*-----------------------------------------------------------------*/ @@ -2739,429 +3035,301 @@ static void saverbank (int bank, iCode *ic, bool pushPsw) /*-----------------------------------------------------------------*/ static void genCall (iCode *ic) { - sym_link *dtype; + sym_link *ftype; int stackParms=0; + int use_wreg=0; + char *fname; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if caller saves & we have not saved then */ - if (!ic->regsSaved) - saveRegisters(ic); + ftype = OP_SYM_TYPE(IC_LEFT(ic)); + /* 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) + /* initialise stackParms for IPUSH pushes */ +// stackParms = psuedoStkPtr; +// fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes); + fname = OP_SYMBOL(IC_LEFT(ic))->rname[0]?OP_SYMBOL(IC_LEFT(ic))->rname:OP_SYMBOL(IC_LEFT(ic))->name; - saverbank(FUNC_REGBANK(dtype),ic,TRUE); +#if 0 + gpsimDebug_StackDump(__FILE__, __LINE__, fname ); +#endif - /* if send set is not empty the assign */ - if (_G.sendSet) { - iCode *sic; + /* if send set is not empty the assign */ + if (_G.sendSet) { + iCode *sic; + int psuedoStkPtr=-1; + int firstTimeThruLoop = 1; - /* 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; +#if 1 + /* reverse sendSet if function is not reentrant */ + if(!IFFUNC_ISREENT(ftype)) + _G.sendSet = reverseSet(_G.sendSet); +#endif - _G.sendSet = reverseSet(_G.sendSet); + /* First figure how many parameters are getting passed */ - /* 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); - } +/* do we really need to know this ? -- VR + 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; +// stackParms = psuedoStkPtr; + stackParms = 0; + use_wreg = 0; + + 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)); + 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; + stackParms += size; - mov2w (AOP(IC_LEFT(sic)), offset); - offset++; - } - pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); - } - _G.sendSet = NULL; - } + while (size--) { + DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, + pic16_AopType(AOP_TYPE(IC_LEFT(sic)))); + DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1); - /* make the call */ - pic16_emitpcode(POC_CALL,pic16_popGetWithString(OP_SYMBOL(IC_LEFT(ic))->rname[0] ? - OP_SYMBOL(IC_LEFT(ic))->rname : - OP_SYMBOL(IC_LEFT(ic))->name)); + 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. */ - 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)) ) { + pushw(); +// --psuedoStkPtr; // sanity check + } + + firstTimeThruLoop=0; - _G.accInUse++; - pic16_aopOp(IC_RESULT(ic),ic,FALSE); - _G.accInUse--; + mov2w (AOP(IC_LEFT(sic)), size); - assignResultValue(IC_RESULT(ic), 1); + offset++; + } + pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); + } - DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, - pic16_AopType(AOP_TYPE(IC_RESULT(ic)))); - - pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE); - } + /* save last parameter to stack if functions has varargs */ + if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw(); + else use_wreg = 1; /* last parameter in WREG */ + + _G.stackRegSet = _G.sendSet; + _G.sendSet = NULL; + } - 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 )); - } - } + /* make the call */ + pic16_emitpcode(POC_CALL,pic16_popGetWithString(fname)); - /* 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); + GpsuedoStkPtr=0; + /* if we need to 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)) ) { - if (ic->parmBytes) { - int i; + _G.accInUse++; + pic16_aopOp(IC_RESULT(ic),ic,FALSE); + _G.accInUse--; - 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); - } + 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 && ic->parmBytes) { + stackParms = ic->parmBytes; + } + + stackParms -= use_wreg; + + if(stackParms>0) { + if(stackParms == 1) { + pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1l)); + } else { + 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 )); + } + } + +#if 0 + gpsimDebug_StackDump(__FILE__, __LINE__, fname); +#endif + + /* 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 register bank was saved then pop them */ - if (ic->bankSaved) - unsaverbank(FUNC_REGBANK(dtype),ic,TRUE); + /* 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); + /* 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 - HJD */ /*-----------------------------------------------------------------*/ - -// new version, created from genCall - static void genPcall (iCode *ic) { - sym_link *dtype; + sym_link *ftype; int stackParms=0; symbol *retlbl = newiTempLabel(NULL); pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key); + int use_wreg=0; - 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); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - // push return address - // push $ on return stack, then replace with retlbl + ftype = OP_SYM_TYPE(IC_LEFT(ic)); + + /* if send set is not empty the assign */ + if (_G.sendSet) { + iCode *sic; + int psuedoStkPtr=-1; + int firstTimeThruLoop = 1; - // Note: retlbl is supplied as dummy operand to PUSH - // This has the nice side effect of keeping the label from being optimized out :o) - pic16_emitpcode(POC_PUSH, pic16_popGetLabel(retlbl->key)); + /* 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 :). */ - 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 */ - // FIXME Disabled writes to PCLATU because of gpsim problems #if 1 - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu))); -#else - fprintf(stderr, -"WARNING: (%s:%d) PCLATU is not written because of gpsim problems\n\ -Correct this as soon as gpsim bug is fixed\n", __FILE__, __LINE__); + /* reverse sendSet if function is not reentrant */ + if(!IFFUNC_ISREENT(ftype)) + _G.sendSet = reverseSet(_G.sendSet); #endif - - 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)); - - /* return address is here: (X) */ - pic16_emitpLabel(retlbl->key); - - 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); + /* First figure how many parameters are getting passed */ +#if 0 + 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); + } +#endif - if (ic->parmBytes) { - int i; +// stackParms = psuedoStkPtr; + stackParms = 0; - 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); - } + for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) { + int size, offset = 0; - /* if register bank was saved then pop them */ - if (ic->bankSaved) - unsaverbank(FUNC_REGBANK(dtype),ic,TRUE); + pic16_aopOp(IC_LEFT(sic),sic,FALSE); + size = AOP_SIZE(IC_LEFT(sic)); + stackParms += size; - /* if we hade saved some registers then unsave them */ - if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype)) - unsaveRegisters (ic); -} + 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. */ -#if 0 // patch 14 -// old version, kept for reference + pushw(); + --psuedoStkPtr; // sanity check + } + + firstTimeThruLoop=0; -/*-----------------------------------------------------------------*/ -/* genPcall - generates a call by pointer statement */ -/*-----------------------------------------------------------------*/ -static void genPcall (iCode *ic) -{ - sym_link *dtype; - symbol *rlbl = newiTempLabel(NULL); + mov2w (AOP(IC_LEFT(sic)), size); + offset++; + } - 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 && - IFFUNC_ISISR(currFunc->type) && - (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype))) - saverbank(FUNC_REGBANK(dtype),ic,TRUE); + pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); + } + if(IFFUNC_HASVARARGS(ftype) || IFFUNC_ISREENT(ftype))pushw(); + else use_wreg = 1; /* last parameter in WREG */ - /* push the return address on to the stack */ - pic16_emitcode("mov","a,#%05d_DS_",(rlbl->key+100)); - pic16_emitcode("push","acc"); - pic16_emitcode("mov","a,#(%05d_DS_ >> 8)",(rlbl->key+100)); - pic16_emitcode("push","acc"); - - if (options.model == MODEL_FLAT24) - { - pic16_emitcode("mov","a,#(%05d_DS_ >> 16)",(rlbl->key+100)); - pic16_emitcode("push","acc"); + _G.stackRegSet = _G.sendSet; + _G.sendSet = NULL; } - /* now push the calling address */ pic16_aopOp(IC_LEFT(ic),ic,FALSE); - pushSide(IC_LEFT(ic), FPTRSIZE); + // push return address + // push $ on return stack, then replace with retlbl - pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); + pic16_emitpcodeNULLop(POC_PUSH); - /* if send set is not empty the assign */ - if (_G.sendSet) { - iCode *sic ; + 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)); - 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--) { - char *l = pic16_aopGet(AOP(IC_LEFT(sic)),offset, - FALSE,FALSE); - if (strcmp(l,fReturn[offset])) - pic16_emitcode("mov","%s,%s", - fReturn[offset], - l); - offset++; - } - pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); - } - _G.sendSet = NULL; - } - pic16_emitcode("ret",""); - pic16_emitcode("","%05d_DS_:",(rlbl->key+100)); + /* return address is here: (X) */ + pic16_emitpLabelFORCE(retlbl->key); + 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); + if ((IS_ITEMP(IC_RESULT(ic)) + && (OP_SYMBOL(IC_RESULT(ic))->nRegs + || OP_SYMBOL(IC_RESULT(ic))->spildir )) + || IS_TRUE_SYMOP(IC_RESULT(ic)) ) { - pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); - } + _G.accInUse++; + pic16_aopOp(IC_RESULT(ic),ic,FALSE); + _G.accInUse--; - /* adjust the stack for parameters if - required */ - 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); + 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 register bank was saved then unsave them */ - if (currFunc && dtype && - (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype))) - unsaverbank(FUNC_REGBANK(dtype),ic,TRUE); - - /* if we hade saved some registers then - unsave them */ - if (ic->regsSaved) - unsaveRegisters (ic); - + stackParms -= use_wreg; + + if(stackParms>0) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms)); + pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l )); + if(STACK_MODEL_LARGE) { + /* this implies that stackParms < 256 !!! -- VR */ + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h )); + } + } } -#endif // patch 14 - /*-----------------------------------------------------------------*/ /* resultRemat - result is rematerializable */ @@ -3218,409 +3386,319 @@ static void genFunction (iCode *ic) symbol *sym; sym_link *ftype; - DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key); - - labelOffset += (max_key+4); - max_key=0; - GpsuedoStkPtr=0; - _G.nRegsSaved = 0; + DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key); - ftype = operandType(IC_LEFT(ic)); - sym = OP_SYMBOL(IC_LEFT(ic)); + 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; + 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; - } - } + { + 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(";-----------------------------------------")); + 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); - pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name)); + apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section")); + pic16_addpBlock( apb ); - pic16_addpCode2pBlock(apb, - pic16_newpCode(POC_GOTO, pic16_popGetWithString( sym->rname ))); + 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; + /* mark the end of this tiny function */ + pic16_addpCode2pBlock(apb,pic16_newpCodeFunction(NULL,NULL)); - abSym = Safe_calloc(1, sizeof(absSym)); - abSym->name = Safe_strdup( asymname ); + { + absSym *abSym; - switch( _G.interruptvector ) { - case 0: abSym->address = 0x000000; break; - case 1: abSym->address = 0x000008; break; - case 2: abSym->address = 0x000018; break; - } + abSym = Safe_calloc(1, sizeof(absSym)); + strcpy(abSym->name, asymname); - addSet(&absSymSet, abSym); - } - } + 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; - /* create the function header */ - pic16_emitcode(";","-----------------------------------------"); - pic16_emitcode(";"," function %s",sym->name); - pic16_emitcode(";","-----------------------------------------"); + addSet(&absSymSet, abSym); + } + } - pic16_emitcode("","%s:",sym->rname); - pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname)); + /* create the function header */ + pic16_emitcode(";","-----------------------------------------"); + 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)) { - pic16_pBlockConvert2Absolute(pb); - break; - } + { + absSym *ab; - } + for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet)) { + if(!strcmp(ab->name, sym->rname)) { + pic16_pBlockConvert2Absolute(pb); + break; + } + } + } - if(IFFUNC_ISNAKED(ftype)) { - DEBUGpic16_emitcode("; ***", "_naked function, no prologue"); - return; - } + 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"); - - /* if this is an interrupt service routine then - * save acc, b, dpl, dph */ - if (IFFUNC_ISISR(sym->type)) { - int i; - /* 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 */ - - pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg )); - pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status )); - pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr )); - } + /* if critical function then turn interrupts off */ + if (IFFUNC_ISCRITICAL(ftype)) { + //pic16_emitcode("clr","ea"); + } + + _G.fregsUsed = sym->regsUsed; - 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 )); + /* if this is an interrupt service routine then + * save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */ + if (IFFUNC_ISISR(sym->type)) { + _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 )); + } -// pic16_pBlockConvert2ISR(pb); + /* 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)) { -// fprintf(stderr, "%s:%d function %s uses register %s\n", -// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, -// pic16_regWithIdx(i)->name); - - pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); - _G.nRegsSaved++; - } - } - } - } else { - /* emit code to setup stack frame if user enabled, - * and function is not main() */ + } + + /* emit code to setup stack frame if user enabled, + * and function is not main() */ -// fprintf(stderr, "function name: %s\n", sym->name); - 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)); - if(STACK_MODEL_LARGE) - pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0)); - } - } + //fprintf(stderr, "function name: %s\n", sym->name); + if(strcmp(sym->name, "main")) { + if(1 /*!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)); + if(STACK_MODEL_LARGE) + pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0)); + } + } - /* if callee-save to be used for this function - * then save the registers being used in this function */ -// if (IFFUNC_CALLEESAVES(sym->type)) - { - int i; + if ((IFFUNC_ISREENT(sym->type) || options.stackAuto) + && sym->stack) { -// fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size); + if (sym->stack > 127)werror(W_STACK_OVERFLOW, sym->name); -// pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1); + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack)); + pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_fsr1l)); + emitSKPNC; + pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h)); + } + + if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type)) + _G.useWreg = 0; + else _G.useWreg = 1; - /* 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 callee-save to be used for this function + * then save the registers being used in this function */ +// if (IFFUNC_CALLEESAVES(sym->type)) + { + int i; -// fprintf(stderr, "%s:%d function %s uses register %s\n", -// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, -// pic16_regWithIdx(i)->name); + /* if any registers used */ + if (sym->regsUsed) { + /* save the registers used */ + DEBUGpic16_emitcode("; **", "Saving used registers in stack"); + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN)); + for ( i = 0 ; i < sym->regsUsed->size ; i++) { + if (bitVectBitValue(sym->regsUsed,i)) { + 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; + } + } + } + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END)); + } + } + + DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack); +// fprintf(stderr, "Function '%s' uses %d bytes of stack\n", sym->name, sym->stack); +} - 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 0 - if (IFFUNC_ISREENT(sym->type) || options.stackAuto) { - - if (options.useXstack) { - pic16_emitcode("mov","r0,%s",spname); - pic16_emitcode("mov","a,_bp"); - pic16_emitcode("movx","@r0,a"); - pic16_emitcode("inc","%s",spname); - } else { - /* set up the stack */ - pic16_emitcode ("push","_bp"); /* save the callers stack */ - } - pic16_emitcode ("mov","_bp,%s",spname); - } -#endif - DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack); - - /* adjust the stack for the function */ - if (sym->stack) { - int i = sym->stack; - - if (i > 127 ) - werror(W_STACK_OVERFLOW,sym->name); - - if (i > 3 && sym->recvSize < 4) { - pic16_emitcode ("mov","a,sp"); - pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff)); - pic16_emitcode ("mov","sp,a"); - } else - while(i--) - pic16_emitcode("inc","sp"); - } - - if (sym->xstack) { - DEBUGpic16_emitcode("; ", "%s", __FUNCTION__); - - pic16_emitcode ("mov","a,_spx"); - pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff)); - pic16_emitcode ("mov","_spx,a"); - } - -} - -/*-----------------------------------------------------------------*/ -/* genEndFunction - generates epilogue for functions */ -/*-----------------------------------------------------------------*/ -static void genEndFunction (iCode *ic) -{ - symbol *sym = OP_SYMBOL(IC_LEFT(ic)); +/*-----------------------------------------------------------------*/ +/* genEndFunction - generates epilogue for functions */ +/*-----------------------------------------------------------------*/ +static void genEndFunction (iCode *ic) +{ + symbol *sym = OP_SYMBOL(IC_LEFT(ic)); DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(IFFUNC_ISNAKED(sym->type)) { - DEBUGpic16_emitcode("; ***", "_naked function, no epilogue"); - return; + DEBUGpic16_emitcode("; ***", "_naked function, no epilogue"); + return; } -#if 0 - if (IFFUNC_ISREENT(sym->type) || options.stackAuto) - { - pic16_emitcode ("mov","%s,_bp",spname); - } -#endif + _G.stack_lat = 0; - /* if use external stack but some variables were - added to the local stack then decrement the - local stack */ - if (options.useXstack && sym->stack) { - pic16_emitcode("mov","a,sp"); - pic16_emitcode("add","a,#0x%02x",((char)-sym->stack) & 0xff); - pic16_emitcode("mov","sp,a"); + /* add code for ISCRITICAL */ + if(IFFUNC_ISCRITICAL(sym->type)) { + /* if critical function, turn on interrupts */ + + /* TODO: add code here -- VR */ } - - -#if 0 - if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) { - if (options.useXstack) { - pic16_emitcode("mov","r0,%s",spname); - pic16_emitcode("movx","a,@r0"); - pic16_emitcode("mov","_bp,a"); - pic16_emitcode("dec","%s",spname); - } - else - { - pic16_emitcode ("pop","_bp"); - } + + if ((IFFUNC_ISREENT(sym->type) || options.stackAuto) + && sym->stack) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack)); + pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(&pic16_pc_fsr1l)); + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h)); } -#endif - if (IFFUNC_ISISR(sym->type)) { - /* now we need to restore the registers */ - /* if any registers used */ - if (sym->regsUsed) { - int i; + /* now we need to restore the registers */ + /* if any registers used */ + if (sym->regsUsed) { + int i; - /* restore registers used */ - DEBUGpic16_emitcode("; **", "Restoring used registers from stack"); - for ( i = sym->regsUsed->size; i >= 0; i--) { - if (bitVectBitValue(sym->regsUsed,i)) { + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN)); + /* restore registers used */ + DEBUGpic16_emitcode("; **", "Restoring used registers from stack"); + for ( i = sym->regsUsed->size; i >= 0; i--) { + if (bitVectBitValue(sym->regsUsed,i)) { + pic16_poppCodeOp( pic16_popRegFromIdx(i) ); + _G.nRegsSaved--; + } + } + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END)); -// 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) ); + if(strcmp(sym->name, "main")) { + if(1/*!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_preinc1, &pic16_pc_fsr2l, 0)); + } + } -// pic16_emitpcode(POC_MOVFF, pic16_popCombine2( -// &pic16_pc_preinc1, -// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0)); + _G.useWreg = 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 )); - } - - _G.interruptvector = 0; /* sanity check */ + if (IFFUNC_ISISR(sym->type)) { + 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 )); -// pic16_pBlockConvert2ISR(pb); + 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 )); + } + _G.interruptvector = 0; /* sanity check */ - /* if debug then send end of function */ -/* if (options.debug && currFunc) */ - if (currFunc) { - debugFile->writeEndFunction (currFunc, ic, 1); - } - - pic16_emitpcodeNULLop(POC_RETFIE); - } else { - if (IFFUNC_ISCRITICAL(sym->type)) - pic16_emitcode("setb","ea"); + /* 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); -// pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1); + pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL)); + + _G.usefastretfie = 0; + return; + } - /* 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)) { - -// 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)); + if (IFFUNC_ISCRITICAL(sym->type)) { + pic16_emitcode("setb","ea"); + } - _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) { + debugFile->writeEndFunction (currFunc, ic, 1); + } - /* 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(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_preinc1, &pic16_pc_fsr2l, 0)); - } - } - - pic16_emitcode ("return",""); - pic16_emitpcodeNULLop(POC_RETURN); - - /* Mark the end of a function */ - pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL)); - } + 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 { - pic16_emitpcode(POC_MOVFF, pic16_popGet2p( - pic16_popGet(AOP(op), offset), dest)); - } + if(is_LitOp(op)) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); + 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)); + } } /*-----------------------------------------------------------------*/ @@ -3742,7 +3820,7 @@ jumpret: && IC_LABEL(ic->next) == returnLabel)) { pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key)); - pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset); + pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset); } } @@ -3759,7 +3837,7 @@ static void genLabel (iCode *ic) 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)); } /*-----------------------------------------------------------------*/ @@ -3769,7 +3847,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); } @@ -4022,9 +4100,9 @@ static void genDivOneByte (operand *left, /* unsigned is easy */ - pct1 = pic16_popGetTempReg(); - pct2 = pic16_popGetTempReg(); - pct3 = pic16_popGetTempReg(); + pct1 = pic16_popGetTempReg(1); + pct2 = pic16_popGetTempReg(1); + pct3 = pic16_popGetTempReg(1); label1 = newiTempLabel(NULL); label2 = newiTempLabel(NULL); @@ -4074,9 +4152,9 @@ static void genDivOneByte (operand *left, if(AOP_TYPE(result) != AOP_ACC) pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); - pic16_popReleaseTempReg( pct3 ); - pic16_popReleaseTempReg( pct2 ); - pic16_popReleaseTempReg( pct1 ); + pic16_popReleaseTempReg( pct3, 1); + pic16_popReleaseTempReg( pct2, 1); + pic16_popReleaseTempReg( pct1, 1); return ; } @@ -4336,11 +4414,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 { @@ -4351,11 +4429,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); } @@ -4393,7 +4471,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 { @@ -4412,7 +4490,7 @@ 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); } @@ -4477,9 +4555,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 @@ -4493,9 +4571,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)); @@ -4534,6 +4612,7 @@ static int genChkZeroes(operand *op, int lit, int size) /*-----------------------------------------------------------------*/ /* genCmp :- greater or less than comparison */ /*-----------------------------------------------------------------*/ +#if 1 static void genCmp (operand *left,operand *right, operand *result, iCode *ifx, int sign) { @@ -4591,7 +4670,7 @@ static void genCmp (operand *left,operand *right, #if 0 fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n", - __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+labelOffset, lbl->key+100+labelOffset); + __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset); #endif #ifndef _swapp @@ -4673,7 +4752,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 @@ -4743,7 +4822,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)); @@ -4754,7 +4833,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 @@ -4800,52 +4879,519 @@ static void genCmp (operand *left,operand *right, } - /* sign is out of the way. So now do an unsigned compare */ - DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit); + /* sign is out of the way. So now do an unsigned compare */ + DEBUGpic16_emitcode(";right lit","line = %d unsigned compare to 0x%x",__LINE__,lit); + + + /* General case - compare to an unsigned literal on the right.*/ + + i = (lit >> (size*8)) & 0xff; + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i)); + pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); + while(size--) { + i = (lit >> (size*8)) & 0xff; + + if(i) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i)); + emitSKPNZ; + pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); + } else { + /* this byte of the lit is zero, + *if it's not the last then OR in the variable */ + if(size) + pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size)); + } + } + + + pic16_emitpLabel(lbl->key); +// pic16_emitpLabel(truelbl->key); + //if(emitFinalCheck) + genSkipc(&rFalseIfx); + if(sign) + pic16_emitpLabel(truelbl->key); + + if(ifx) ifx->generated = 1; + return; + + + } +#endif // _swapp + + if(AOP_TYPE(left) == AOP_LIT) { + //symbol *lbl = newiTempLabel(NULL); + + //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit)); + + + DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign); + + /* Special cases */ + if((lit == 0) && (sign == 0)){ + + size--; + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); + while(size) + pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size)); + + genSkipz2(&rFalseIfx,0); + if(ifx) ifx->generated = 1; + return; + } + + if(size==1) { + /* Special cases */ + lit &= 0xff; + if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) { + /* degenerate compare can never be true */ + if(rFalseIfx.condition == 0) + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key)); + + if(ifx) ifx->generated = 1; + return; + } + + if(sign) { + /* signed comparisons to a literal byte */ + + int lp1 = (lit+1) & 0xff; + + DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit); + switch (lp1) { + case 0: + rFalseIfx.condition ^= 1; + genSkipCond(&rFalseIfx,right,0,7); + break; + case 0x7f: + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f)); + genSkipz2(&rFalseIfx,1); + break; + default: + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80)); + rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); + break; + } + } else { + /* unsigned comparisons to a literal byte */ + + switch(lit & 0xff ) { + case 0: + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); + genSkipz2(&rFalseIfx,0); + break; + case 0x7f: + rFalseIfx.condition ^= 1; + genSkipCond(&rFalseIfx,right,0,7); + break; + + default: + pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff)); + pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0)); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + rFalseIfx.condition ^= 1; + if (AOP_TYPE(result) == AOP_CRY) + genSkipc(&rFalseIfx); + else { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0)); + } + break; + } + } + + if(ifx) ifx->generated = 1; + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + goto check_carry; + return; + + } else { + + /* Size is greater than 1 */ + + if(sign) { + int lp1 = lit+1; + + size--; + + if(lp1 == 0) { + /* this means lit = 0xffffffff, or -1 */ + + + DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__); + rFalseIfx.condition ^= 1; + genSkipCond(&rFalseIfx,right,size,7); + if(ifx) ifx->generated = 1; + + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + goto check_carry; + + return; + } + + if(lit == 0) { + int s = size; + + if(rFalseIfx.condition) { + 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)); + } + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); + while(size--) + pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); + + + emitSKPZ; + if(rFalseIfx.condition) { + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); + pic16_emitpLabel(truelbl->key); + }else { + rFalseIfx.condition ^= 1; + genSkipCond(&rFalseIfx,right,s,7); + } + + if(ifx) ifx->generated = 1; + + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + goto check_carry; + + return; + } + + if((size == 1) && (0 == (lp1&0xff))) { + /* lower byte of signed word is zero */ + DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit); + i = ((lp1 >> 8) & 0xff) ^0x80; + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i)); + rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); + + + if(ifx) ifx->generated = 1; + + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + goto check_carry; + + return; + } + + if(lit & (0x80 << (size*8))) { + /* Lit is less than zero */ + DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit); + //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, PO_GPR_REGISTER)); + //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); + + if(rFalseIfx.condition) + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); + else + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); + + + } else { + /* Lit is greater than or equal to zero */ + DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit); + //rFalseIfx.condition ^= 1; + //genSkipCond(&rFalseIfx,right,size,7); + //rFalseIfx.condition ^= 1; + + //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, PO_GPR_REGISTER)); + if(rFalseIfx.condition) + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); + else + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); + + } + + + pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff)); + pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); + + while(size--) { + + pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff)); + emitSKPNZ; + pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); + } + rFalseIfx.condition ^= 1; + //rFalseIfx.condition = 1; + genSkipc(&rFalseIfx); + + pic16_emitpLabel(truelbl->key); + + if(ifx) ifx->generated = 1; + + + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + goto check_carry; + + return; + // end of if (sign) + } else { + + /* compare word or long to an unsigned literal on the right.*/ + + + size--; + if(lit < 0xff) { + DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit); + switch (lit) { + case 0: + break; /* handled above */ +/* + case 0xff: + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); + while(size--) + pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); + genSkipz2(&rFalseIfx,0); + break; +*/ + default: + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); + while(--size) + pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); + + emitSKPZ; + if(rFalseIfx.condition) + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); + else + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); + + + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1)); + pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0)); + + rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); + } + + pic16_emitpLabel(truelbl->key); + + if(ifx) ifx->generated = 1; + + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + goto check_carry; + + return; + } + + + lit++; + DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit); + i = (lit >> (size*8)) & 0xff; + + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i)); + pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); + + while(size--) { + i = (lit >> (size*8)) & 0xff; + + if(i) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i)); + emitSKPNZ; + 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(size) + pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); + } + } + + + pic16_emitpLabel(lbl->key); + + rFalseIfx.condition ^= 1; + + genSkipc(&rFalseIfx); + } + + if(sign) + pic16_emitpLabel(truelbl->key); + if(ifx) ifx->generated = 1; + + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + goto check_carry; + + return; + } + } + /* Compare two variables */ + + DEBUGpic16_emitcode(";sign","%d",sign); + + size--; + if(sign) { + /* Sigh. thus sucks... */ + if(size) { + pCodeOp *pctemp; + + pctemp = pic16_popGetTempReg(1); + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size)); + pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr)); + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80)); + pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr)); + pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size)); + pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr)); + pic16_popReleaseTempReg(pctemp, 1); + } else { + /* Signed char comparison */ + /* Special thanks to Nikolai Golovchenko for this snippet */ + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */ + pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + genSkipc(&rFalseIfx); + + if(ifx) ifx->generated = 1; + + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + goto check_carry; + + return; + } + + } else { + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); + pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); + } + + + /* The rest of the bytes of a multi-byte compare */ + while (size) { + + emitSKPZ; + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key)); + size--; + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); + pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); + + + } + + pic16_emitpLabel(lbl->key); + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || + (AOP_TYPE(result) == AOP_REG)) { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0)); + } else { + genSkipc(&rFalseIfx); + } + //genSkipc(&rFalseIfx); + if(ifx) ifx->generated = 1; + + + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + goto check_carry; + + return; + + } + +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__); + /* if the result is used in the next + ifx conditional branch then generate + code a little differently */ + if (ifx ) + genIfxJump (ifx,"c"); + else + pic16_outBitC(result); + /* leave the result in acc */ + } + +} + +#else /* old version of genCmp() */ + +/* new version of genCmp -- VR 20041012 */ +static void genCmp (operand *left,operand *right, + operand *result, iCode *ifx, int sign) +{ + int size; //, offset = 0 ; + unsigned long lit = 0L,i = 0; + resolvedIfx rFalseIfx; + int willCheckCarry=0; + // resolvedIfx rTrueIfx; + symbol *truelbl; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + /* General concept: + * subtract right from left if at the end the carry flag is set then we + * know that left is greater than right */ + + resolveIfx(&rFalseIfx,ifx); + truelbl = newiTempLabel(NULL); + size = max(AOP_SIZE(left),AOP_SIZE(right)); - /* General case - compare to an unsigned literal on the right.*/ + DEBUGpic16_pic16_AopType(__LINE__,left,right,result); - i = (lit >> (size*8)) & 0xff; - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); - while(size--) { - i = (lit >> (size*8)) & 0xff; + /* POC_CPFSGT compare f, wreg, skip if f greater than wreg + * POC_CPFSLT compare f, wreg, skip if f less then wreg */ + - if(i) { - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i)); - emitSKPNZ; - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); - } else { - /* this byte of the lit is zero, - *if it's not the last then OR in the variable */ - if(size) - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),size)); - } - } + /* if literal is on the right then swap with left */ + if ((AOP_TYPE(right) == AOP_LIT)) { + operand *tmp = right ; + unsigned long mask = (0x100 << (8*(size-1))) - 1; + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - pic16_emitpLabel(lbl->key); -// pic16_emitpLabel(truelbl->key); - //if(emitFinalCheck) - genSkipc(&rFalseIfx); - if(sign) - pic16_emitpLabel(truelbl->key); +// lit = (lit - 1) & mask; + right = left; + left = tmp; + rFalseIfx.condition ^= 1; + } else + if ((AOP_TYPE(left) == AOP_LIT)) { + /* float compares are handled by support functions */ + lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit); + } - if(ifx) ifx->generated = 1; - return; + //if(IC_TRUE(ifx) == NULL) + /* if left & right are bit variables */ + if (AOP_TYPE(left) == AOP_CRY && + AOP_TYPE(right) == AOP_CRY ) { + pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); + pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir); - } -#endif // _swapp + } else { + symbol *lbl = newiTempLabel(NULL); if(AOP_TYPE(left) == AOP_LIT) { - //symbol *lbl = newiTempLabel(NULL); + DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign); - //EXPERIMENTAL lit = (unsigned long)(floatFromVal(AOP(left)->aopu.aop_lit)); - - - DEBUGpic16_emitcode(";left lit","lit = 0x%x,sign=%d",lit,sign); + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + willCheckCarry = 1; + else willCheckCarry = 0; /* Special cases */ if((lit == 0) && (sign == 0)){ @@ -4877,7 +5423,7 @@ static void genCmp (operand *left,operand *right, int lp1 = (lit+1) & 0xff; - DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x",__LINE__,lit); + DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d",__LINE__,lit, rFalseIfx.condition); switch (lp1) { case 0: rFalseIfx.condition ^= 1; @@ -4889,11 +5435,27 @@ static void genCmp (operand *left,operand *right, genSkipz2(&rFalseIfx,1); break; default: - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit )); + + if(rFalseIfx.condition) + pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0)); + else + pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0)); + + if(willCheckCarry) { + if(!rFalseIfx.condition) { emitCLRC; emitSETC; } + else { emitSETC; emitCLRC; } + + } else { + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); + } + +/* pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80)); rFalseIfx.condition ^= 1; genSkipc(&rFalseIfx); +*/ break; } } else { @@ -4953,7 +5515,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)); } @@ -4996,7 +5558,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) @@ -5015,7 +5577,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 @@ -5131,12 +5693,16 @@ static void genCmp (operand *left,operand *right, if(sign) { /* Sigh. thus sucks... */ if(size) { + pCodeOp *pctemp; + + pctemp = pic16_popGetTempReg(1); 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, 1); } else { /* Signed char comparison */ /* Special thanks to Nikolai Golovchenko for this snippet */ @@ -5195,7 +5761,8 @@ check_carry: if ((AOP_TYPE(result) != AOP_CRY) && AOP_SIZE(result)) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); -// pic16_emitpLabel( rFalseIfx.lbl->key ); + + if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key ); pic16_outBitC(result); } else { @@ -5211,6 +5778,9 @@ check_carry: } } +#endif + + /*-----------------------------------------------------------------*/ /* genCmpGt :- greater than comparison */ @@ -5790,7 +6360,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 */ @@ -5907,11 +6477,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 { @@ -5931,7 +6501,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; @@ -5939,7 +6509,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; @@ -5947,13 +6517,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); } } } @@ -6194,9 +6764,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); } @@ -6400,7 +6970,7 @@ static void genAnd (iCode *ic, iCode *ifx) } pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), - pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0)); + pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER)); } /* @@ -6416,10 +6986,37 @@ 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)); +// pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx.lbl->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) @@ -6429,22 +7026,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 ; } @@ -6470,7 +7072,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)); @@ -6774,7 +7376,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)); @@ -7380,12 +7982,10 @@ static void AccRsh (int shCount, int andmask) 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)); @@ -7444,6 +8044,7 @@ static void AccSRsh (int shCount) } } #endif + /*-----------------------------------------------------------------*/ /* shiftR1Left2Result - shift right one byte from left to result */ /*-----------------------------------------------------------------*/ @@ -7490,11 +8091,11 @@ static void shiftR1Left2ResultSigned (operand *left, int offl, pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr)); } - pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr)); + pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(result),offr)); + //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)); @@ -7503,7 +8104,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; @@ -7516,7 +8117,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; @@ -7524,29 +8125,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)); } @@ -7606,8 +8207,8 @@ static void shiftR1Left2Result (operand *left, int offl, pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr)); } - pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr)); + pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(result),offr)); + //pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(result),offr)); pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x1f)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr)); break; @@ -7620,19 +8221,19 @@ static void shiftR1Left2Result (operand *left, int offl, case 5: pic16_emitpcode(POC_SWAPFW, pic16_popGet(AOP(left),offl)); - pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0f)); + pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0e)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr)); - emitCLRC; - pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),offr)); + //emitCLRC; + pic16_emitpcode(POC_RRNCF, pic16_popGet(AOP(result),offr)); break; case 6: - pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),offl)); - pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x80)); + pic16_emitpcode(POC_RLNCFW, pic16_popGet(AOP(left),offl)); + pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x81)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr)); + //pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr)); + pic16_emitpcode(POC_RLNCF, pic16_popGet(AOP(result),offr)); break; case 7: @@ -7846,7 +8447,7 @@ static void shiftL2Left2Result (operand *left, int offl, pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16)); pic16_emitpcode(POC_SWAPFW,pic16_popGet(AOP(left),offl)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0xF0)); + pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x0F)); pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr)); pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16)); @@ -7965,7 +8566,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)); } @@ -7983,7 +8584,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,FALSE,FALSE),0,0, PO_GPR_REGISTER)); pic16_emitpcode(POC_IORLW,pic16_popGetLit(0xfc)); } pic16_emitpcode(POC_XORFW,pic16_popGet(AOP(result),offr+MSB16)); @@ -8001,7 +8602,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)); @@ -8119,7 +8720,7 @@ static void shiftLLong (operand *left, operand *result, int offr ) pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr)); } - if (size >= LSB+offr ){ + if (size > LSB+offr ){ if (same) { pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr)); } else { @@ -8128,7 +8729,7 @@ static void shiftLLong (operand *left, operand *result, int offr ) } } - if(size >= MSB16+offr){ + if(size > MSB16+offr){ if (same) { pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr)); } else { @@ -8137,7 +8738,7 @@ static void shiftLLong (operand *left, operand *result, int offr ) } } - if(size >= MSB24+offr){ + if(size > MSB24+offr){ if (same) { pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr)); } else { @@ -8299,34 +8900,220 @@ static void genLeftShiftLiteral (operand *left, pic16_freeAsmop(result,NULL,ic,TRUE); } -/*-----------------------------------------------------------------* - * genMultiAsm - repeat assembly instruction for size of register. - * if endian == 1, then the high byte (i.e base address + size of - * register) is used first else the low byte is used first; - *-----------------------------------------------------------------*/ -static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian) -{ +/*-----------------------------------------------------------------* + * genMultiAsm - repeat assembly instruction for size of register. + * if endian == 1, then the high byte (i.e base address + size of + * register) is used first else the low byte is used first; + *-----------------------------------------------------------------*/ +static void genMultiAsm( PIC_OPCODE poc, operand *reg, int size, int endian) +{ + + int offset = 0; + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(!reg) + return; + + if(!endian) { + endian = 1; + } else { + endian = -1; + offset = size-1; + } + + while(size--) { + pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset)); + offset += endian; + } + +} +/*-----------------------------------------------------------------*/ +/* genLeftShift - generates code for left shifting */ +/*-----------------------------------------------------------------*/ +static void genLeftShift (iCode *ic) +{ + operand *left,*right, *result; + int size, offset; +// char *l; + symbol *tlbl , *tlbl1; + pCodeOp *pctemp; + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + right = IC_RIGHT(ic); + left = IC_LEFT(ic); + result = IC_RESULT(ic); + + pic16_aopOp(right,ic,FALSE); + + /* if the shift count is known then do it + as efficiently as possible */ + if (AOP_TYPE(right) == AOP_LIT) { + genLeftShiftLiteral (left,right,result,ic); + return ; + } + + /* shift count is unknown then we have to form + * a loop. Get the loop count in WREG : Note: we take + * only the lower order byte since shifting + * more than 32 bits make no sense anyway, ( the + * largest size of an object can be only 32 bits ) */ + + pic16_aopOp(left,ic,FALSE); + pic16_aopOp(result,ic,FALSE); + + /* now move the left to the result if they are not the + * same, and if size > 1, + * and if right is not same to result (!!!) -- VR */ + if (!pic16_sameRegs(AOP(left),AOP(result)) + && (AOP_SIZE(result) > 1)) { + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + size = AOP_SIZE(result); + offset=0; + while (size--) { + +#if 0 + l = pic16_aopGet(AOP(left),offset,FALSE,TRUE); + if (*l == '@' && (IS_AOP_PREG(result))) { + + pic16_emitcode("mov","a,%s",l); + pic16_aopPut(AOP(result),"a",offset); + } else +#endif + { + /* we don't know if left is a literal or a register, take care -- VR */ + mov2f(AOP(result), AOP(left), offset); + } + offset++; + } + } + + size = AOP_SIZE(result); + + /* if it is only one byte then */ + if (size == 1) { + 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, 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, 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, PO_GPR_REGISTER)); + pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0)); + } else { + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + tlbl = newiTempLabel(NULL); + +#if 1 + /* this is already done, why change it? */ + if (!pic16_sameRegs(AOP(left),AOP(result))) { + mov2f(AOP(result), AOP(left), 0); + } +#endif + + pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_RRCF, pic16_popGet(AOP(result),0)); + pic16_emitpLabel(tlbl->key); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1)); + emitSKPC; + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key)); + } + goto release ; + } + + if (pic16_sameRegs(AOP(left),AOP(result))) { + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + tlbl = newiTempLabel(NULL); + pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0)); + genMultiAsm(POC_RRCF, result, size,1); + pic16_emitpLabel(tlbl->key); + genMultiAsm(POC_RLCF, result, size,0); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(1)); + emitSKPC; + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key)); + goto release; + } + + //tlbl = newiTempLabel(NULL); + //offset = 0 ; + //tlbl1 = newiTempLabel(NULL); + + //reAdjustPreg(AOP(result)); + + //pic16_emitcode("sjmp","%05d_DS_",tlbl1->key+100); + //pic16_emitcode("","%05d_DS_:",tlbl->key+100); + //l = pic16_aopGet(AOP(result),offset,FALSE,FALSE); + //MOVA(l); + //pic16_emitcode("add","a,acc"); + //pic16_aopPut(AOP(result),"a",offset++); + //while (--size) { + // l = pic16_aopGet(AOP(result),offset,FALSE,FALSE); + // MOVA(l); + // pic16_emitcode("rlc","a"); + // pic16_aopPut(AOP(result),"a",offset++); + //} + //reAdjustPreg(AOP(result)); + + //pic16_emitcode("","%05d_DS_:",tlbl1->key+100); + //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100); + + + tlbl = newiTempLabel(NULL); + tlbl1= newiTempLabel(NULL); + + size = AOP_SIZE(result); + offset = 1; + + pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */ + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); + + /* offset should be 0, 1 or 3 */ + + pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1)); + emitSKPNZ; + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key)); + + pic16_emitpcode(POC_MOVWF, pctemp); - int offset = 0; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_emitpLabel(tlbl->key); - if(!reg) - return; + emitCLRC; + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0)); + while(--size) + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++)); - if(!endian) { - endian = 1; - } else { - endian = -1; - offset = size-1; - } + pic16_emitpcode(POC_DECFSZ, pctemp); + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key)); + pic16_emitpLabel(tlbl1->key); - while(size--) { - pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset)); - offset += endian; - } + pic16_popReleaseTempReg(pctemp,1); + + release: + pic16_freeAsmop (right,NULL,ic,TRUE); + pic16_freeAsmop(left,NULL,ic,TRUE); + pic16_freeAsmop(result,NULL,ic,TRUE); } + + + +#if 0 +#error old code (left here for reference) /*-----------------------------------------------------------------*/ /* genLeftShift - generates code for left shifting */ /*-----------------------------------------------------------------*/ @@ -8368,6 +9155,8 @@ static void genLeftShift (iCode *ic) if (!pic16_sameRegs(AOP(left),AOP(result)) && AOP_SIZE(result) > 1) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + size = AOP_SIZE(result); offset=0; while (size--) { @@ -8377,9 +9166,9 @@ static void genLeftShift (iCode *ic) pic16_emitcode("mov","a,%s",l); pic16_aopPut(AOP(result),"a",offset); } else { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - //pic16_aopPut(AOP(result),l,offset); + + /* we don't know if left is a literal or a register, take care -- VR */ + mov2f(AOP(result), AOP(left), offset); } offset++; } @@ -8392,22 +9181,26 @@ 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 { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + tlbl = newiTempLabel(NULL); if (!pic16_sameRegs(AOP(left),AOP(result))) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); + mov2f(AOP(result), AOP(left), 0); + +// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0)); +// pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); } pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0)); @@ -8423,6 +9216,8 @@ static void genLeftShift (iCode *ic) if (pic16_sameRegs(AOP(left),AOP(result))) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + tlbl = newiTempLabel(NULL); pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(right),0)); genMultiAsm(POC_RRCF, result, size,1); @@ -8464,7 +9259,7 @@ static void genLeftShift (iCode *ic) size = AOP_SIZE(result); offset = 1; - pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */ + pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); @@ -8488,7 +9283,7 @@ static void genLeftShift (iCode *ic) pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key)); pic16_emitpLabel(tlbl1->key); - pic16_popReleaseTempReg(pctemp); + pic16_popReleaseTempReg(pctemp,1); release: @@ -8496,6 +9291,7 @@ static void genLeftShift (iCode *ic) pic16_freeAsmop(left,NULL,ic,TRUE); pic16_freeAsmop(result,NULL,ic,TRUE); } +#endif /*-----------------------------------------------------------------*/ /* genrshOne - right shift a one byte quantity by known count */ @@ -8526,7 +9322,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)); } } @@ -8695,14 +9491,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)); @@ -8810,7 +9606,7 @@ static void genSignedRightShift (iCode *ic) size = AOP_SIZE(result); offset = size - 1; - pctemp = pic16_popGetTempReg(); /* grab a temporary working register. */ + pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */ pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); @@ -8835,7 +9631,7 @@ static void genSignedRightShift (iCode *ic) pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key)); pic16_emitpLabel(tlbl1->key); - pic16_popReleaseTempReg(pctemp); + pic16_popReleaseTempReg(pctemp,1); #if 0 size = AOP_SIZE(result); offset = size - 1; @@ -8995,10 +9791,16 @@ 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 ; @@ -9008,6 +9810,11 @@ static void genUnpackBits (operand *result, char *rname, int ptype) DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); etype = getSpec(operandType(result)); + /* 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: @@ -9183,10 +9990,6 @@ release: pic16_freeAsmop(result,NULL,ic,TRUE); } -void pic16_loadFSR0(operand *op) -{ - pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0))); -} /*-----------------------------------------------------------------*/ @@ -9236,7 +10039,8 @@ static void genNearPointerGet (operand *left, && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE) || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10 { - pic16_loadFSR0( left ); // 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 @@ -9250,7 +10054,7 @@ static void genNearPointerGet (operand *left, /* if bitfield then unpack the bits */ if (IS_BITFIELD(retype)) - genUnpackBits (result, NULL, POINTER); + genUnpackBits (result, left, NULL, POINTER); else { /* we have can just get the values */ int size = AOP_SIZE(result); @@ -9268,11 +10072,11 @@ static void genNearPointerGet (operand *left, if(size) { pic16_emitpcode(POC_MOVFF, - pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), + pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result), offset++))); } else { pic16_emitpcode(POC_MOVFF, - pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), + pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result), offset++))); } } @@ -9364,7 +10168,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); @@ -9442,7 +10246,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 ; @@ -9492,7 +10296,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 ; @@ -9509,6 +10313,7 @@ static void genCodePointerGet (operand *left, pic16_freeAsmop(result,NULL,ic,TRUE); } #endif +#if 0 /*-----------------------------------------------------------------*/ /* genGenPointerGet - gget value from generic pointer space */ /*-----------------------------------------------------------------*/ @@ -9565,13 +10370,96 @@ 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); pic16_freeAsmop(result,NULL,ic,TRUE); } +#endif + +extern set *externs; + +/*-----------------------------------------------------------------*/ +/* genGenPointerGet - gget value from generic pointer space */ +/*-----------------------------------------------------------------*/ +static void genGenPointerGet (operand *left, + operand *result, iCode *ic) +{ + int size, offset, lit; + sym_link *retype = getSpec(operandType(result)); + char fgptrget[32]; + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_aopOp(left,ic,FALSE); + pic16_aopOp(result,ic,FALSE); + size = AOP_SIZE(result); + + DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); + + if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!) + + lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit); + // load FSR0 from immediate + pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit))); + + werror(W_POSSBUG2, __FILE__, __LINE__); + + offset = 0; + while(size--) { + if(size) { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), pic16_popGet(AOP(result),offset))); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), pic16_popGet(AOP(result),offset))); + } + offset++; + } + + goto release; + + } else { /* we need to get it byte by byte */ + + /* set up WREG:PRODL:FSR0L with address from left */ + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_prodl))); + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 2)); + + switch( size ) { + case 1: strcpy(fgptrget, "__gptrget1"); break; + case 2: strcpy(fgptrget, "__gptrget2"); break; + case 3: strcpy(fgptrget, "__gptrget3"); break; + case 4: strcpy(fgptrget, "__gptrget4"); break; + default: + werror(W_POSSBUG2, __FILE__, __LINE__); + abort(); + } + + pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrget )); + + assignResultValue(result, 1); + + { + symbol *sym; + + sym = newSymbol( fgptrget, 0 ); + strcpy(sym->rname, fgptrget); + checkAddSym(&externs, sym); + +// fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget); + } + + goto release; + } + + /* if bit then unpack */ + if (IS_BITFIELD(retype)) + genUnpackBits(result,left,"BAD",GPOINTER); + +release: + pic16_freeAsmop(left,NULL,ic,TRUE); + pic16_freeAsmop(result,NULL,ic,TRUE); +} /*-----------------------------------------------------------------*/ /* genConstPointerGet - get value from const generic pointer space */ @@ -9600,7 +10488,7 @@ static void genConstPointerGet (operand *left, pic16_emitpLabel(albl->key); poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW); - + /* this performs a goto to the specified address -- Why not to use pointer? -- VR */ pic16_emitpcode(poc,pic16_popGet(AOP(left),1)); pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pclath)); @@ -9639,11 +10527,13 @@ static void genConstPointerGet (operand *left, pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset))); offset++; } - // .... patch 15 + pic16_freeAsmop(left,NULL,ic,TRUE); pic16_freeAsmop(result,NULL,ic,TRUE); } + + /*-----------------------------------------------------------------*/ /* genPointerGet - generate code for pointer get */ /*-----------------------------------------------------------------*/ @@ -9730,6 +10620,11 @@ static void genPointerGet (iCode *ic) #endif genGenPointerGet (left,result,ic); break; + + default: + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "genPointerGet: illegal pointer type"); + } } @@ -9737,7 +10632,7 @@ 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) { @@ -9760,12 +10655,24 @@ static void genPackBits (sym_link *etype , lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); // pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); - if(lit) { - pic16_emitpcode(POC_BSF, - pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); + 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 { - pic16_emitpcode(POC_BCF, - pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); + + 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; @@ -9930,19 +10837,32 @@ static void genDataPointerSet(operand *right, 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 - } + unsigned int lit; + + if(!IS_FLOAT(operandType( right ))) + lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->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(IC_RIGHT(ic))->aopu.aop_lit); + lit = info.lit_int; + } + + 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++; } @@ -10000,6 +10920,7 @@ static void genNearPointerSet (operand *right, && ((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 @@ -10015,7 +10936,7 @@ static void genNearPointerSet (operand *right, /* if bitfield then unpack the bits */ if (IS_BITFIELD(resetype)) { - genPackBits (resetype, right, NULL, POINTER); + genPackBits (resetype, result, right, NULL, POINTER); } else { /* we have can just get the values */ int size = AOP_SIZE(right); @@ -10121,7 +11042,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); @@ -10199,7 +11120,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 ; @@ -10219,6 +11140,7 @@ static void genFarPointerSet (operand *right, /*-----------------------------------------------------------------*/ /* genGenPointerSet - set value from generic pointer space */ /*-----------------------------------------------------------------*/ +#if 0 static void genGenPointerSet (operand *right, operand *result, iCode *ic) { @@ -10306,7 +11228,7 @@ static void genGenPointerSet (operand *right, /* if bit then unpack */ if (IS_BITFIELD(retype)) - genPackBits(retype,right,"dptr",GPOINTER); + genPackBits(retype,result,right,"dptr",GPOINTER); else { size = AOP_SIZE(right); offset = 0 ; @@ -10340,6 +11262,81 @@ static void genGenPointerSet (operand *right, pic16_freeAsmop(right,NULL,ic,TRUE); pic16_freeAsmop(result,NULL,ic,TRUE); } +#endif + +static void genGenPointerSet (operand *right, + operand *result, iCode *ic) +{ + int size; + sym_link *retype = getSpec(operandType(right)); + char fgptrput[32]; + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + pic16_aopOp(result,ic,FALSE); + pic16_aopOp(right,ic,FALSE); + size = AOP_SIZE(right); + + DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); + + + /* if bit then unpack */ + if (IS_BITFIELD(retype)) { +// pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit))); + genPackBits(retype,result,right,"dptr",GPOINTER); + goto release; + } + + size = AOP_SIZE(right); + + DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size); + + + + /* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */ + + /* value of right+0 is placed on stack, which will be retrieved + * by the support function this restoring the stack. The important + * thing is that there is no need to manually restore stack pointer + * here */ + mov2fp(pic16_popCopyReg(&pic16_pc_postdec1), AOP(right), 0); + if(size>1)mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), 1); + if(size>2)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(right), 2); + if(size>3)mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(right), 3); + + /* load address to write to in WREG:FSR0H:FSR0L */ + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 0), + pic16_popCopyReg(&pic16_pc_fsr0l))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result), 1), + pic16_popCopyReg(&pic16_pc_prodl))); + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2)); + + + /* put code here */ + switch (size) { + case 1: strcpy(fgptrput, "__gptrput1"); break; + case 2: strcpy(fgptrput, "__gptrput2"); break; + case 3: strcpy(fgptrput, "__gptrput3"); break; + case 4: strcpy(fgptrput, "__gptrput4"); break; + default: + werror(W_POSSBUG2, __FILE__, __LINE__); + abort(); + } + + pic16_emitpcode(POC_CALL, pic16_popGetWithString( fgptrput )); + + { + symbol *sym; + + sym = newSymbol( fgptrput, 0 ); + strcpy(sym->rname, fgptrput); + checkAddSym(&externs, sym); + } + +release: + pic16_freeAsmop(right,NULL,ic,TRUE); + pic16_freeAsmop(result,NULL,ic,TRUE); +} /*-----------------------------------------------------------------*/ /* genPointerSet - stores the value into a pointer location */ @@ -10460,52 +11457,72 @@ static void genAddrOf (iCode *ic) symbol *sym; // = OP_SYMBOL(IC_LEFT(ic)); pCodeOp *pcop0, *pcop1, *pcop2; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE); - pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); + pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); - sym = OP_SYMBOL( left ); + sym = OP_SYMBOL( IC_LEFT(ic) ); + + if(sym->onStack) { + /* get address of symbol on stack */ + DEBUGpic16_emitcode("; ", "%s symbol %s on stack", __FUNCTION__, sym->name); +#if 0 + fprintf(stderr, "%s:%d symbol %s on stack offset %d\n", __FILE__, __LINE__, + OP_SYMBOL(left)->name, OP_SYMBOL(left)->stack); +#endif - size = AOP_SIZE(IC_RESULT(ic)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg(&pic16_pc_fsr2l), + pic16_popGet(AOP(result), 0))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg(&pic16_pc_fsr2h), + pic16_popGet(AOP(result), 1))); + + pic16_emitpcode(POC_MOVLW, pic16_popGetLit( OP_SYMBOL( IC_LEFT(ic))->stack ) /*+ _G.stack_lat*/); + pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result), 0)); + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 1)); + goto release; + } + // 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 */ - pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype)))); + pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE); + size = AOP_SIZE(IC_RESULT(ic)); - /* high */ - pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype)))); - - /* upper */ - pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype)))); - - if (size == 3) { - pic16_emitpcode(POC_MOVLW, pcop0); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); - pic16_emitpcode(POC_MOVLW, pcop1); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1)); - pic16_emitpcode(POC_MOVLW, pcop2); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2)); - } else - if (size == 2) { - pic16_emitpcode(POC_MOVLW, pcop0); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_MOVLW, pcop1); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1)); - } else { - pic16_emitpcode(POC_MOVLW, pcop0); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); - } + /* Assume that what we want the address of is in data space + * since there is no stack on the PIC, yet! -- VR */ + + pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype)))); + pcop1 = PCOP(pic16_newpCodeOpImmd(sym->rname, 1, 0, IN_CODESPACE( SPEC_OCLS(sym->etype)))); + pcop2 = PCOP(pic16_newpCodeOpImmd(sym->rname, 2, 0, IN_CODESPACE( SPEC_OCLS(sym->etype)))); + + if (size == 3) { + pic16_emitpcode(POC_MOVLW, pcop0); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + pic16_emitpcode(POC_MOVLW, pcop1); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 1)); + pic16_emitpcode(POC_MOVLW, pcop2); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 2)); + } else + if (size == 2) { + pic16_emitpcode(POC_MOVLW, pcop0); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_MOVLW, pcop1); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1)); + } else { + pic16_emitpcode(POC_MOVLW, pcop0); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); + } - pic16_freeAsmop(result,NULL,ic,TRUE); - pic16_freeAsmop(left, NULL, ic, FALSE); + pic16_freeAsmop(left, NULL, ic, FALSE); +release: + pic16_freeAsmop(result,NULL,ic,TRUE); } @@ -10556,8 +11573,11 @@ static void genAssign (iCode *ic) if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic))) return ; - pic16_aopOp(right,ic,FALSE); + /* reversed order operands are aopOp'ed so that result operand + * is effective in case right is a stack symbol. This maneauver + * allows to use the _G.resDirect flag later */ pic16_aopOp(result,ic,TRUE); + pic16_aopOp(right,ic,FALSE); DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); @@ -10636,14 +11656,20 @@ static void genAssign (iCode *ic) // sizeof(unsigned long int), sizeof(float)); if(AOP_TYPE(right) != AOP_LIT - && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))) { + && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype)) + && !IS_FUNC(OP_SYM_TYPE(right)) + ) { 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))) +// || (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)); @@ -10651,6 +11677,7 @@ static void genAssign (iCode *ic) 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), @@ -10679,12 +11706,15 @@ static void genAssign (iCode *ic) +#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__); - assert(0); + + /* 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; @@ -10692,10 +11722,11 @@ static void genAssign (iCode *ic) // assert(0); DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__); } +#endif know_W=-1; while (size--) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d size %d",__FUNCTION__,__LINE__, size); if(AOP_TYPE(right) == AOP_LIT) { if(lit&0xff) { if(know_W != (lit&0xff)) @@ -10717,32 +11748,15 @@ static void genAssign (iCode *ic) 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__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); -#if 1 - /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It - normally should work, but mind that the W register live range - is not checked, so if the code generator assumes that the W - is already loaded after such a pair, wrong code will be generated. - - Checking the live range is the next step. - This is experimental code yet and has not been fully tested yet. - USE WITH CARE. Revert to old code by setting 0 to the condition above. - Vangelis Rokas 030603 (vrokas@otenet.gr) */ - - pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset)); -#else - /* This is the old code, which is assumed(?!) that works fine(!?) */ - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); -#endif + if(!_G.resDirect) /* use this aopForSym feature */ + pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset)); } offset++; } - - + release: pic16_freeAsmop (right,NULL,ic,FALSE); pic16_freeAsmop (result,NULL,ic,TRUE); @@ -10980,7 +11994,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); @@ -11118,16 +12132,20 @@ static void genCast (iCode *ic) offset = 0 ; while (size--) { if(offset < AOP_SIZE(right)) { - DEBUGpic16_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode("; ***","%s %d - pointer cast3 ptype = 0x%x",__FUNCTION__,__LINE__, p_type); + mov2f(AOP(result), AOP(right), offset); +/* 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 { + pic16_aopPut(AOP(result), pic16_aopGet(AOP(right),offset,FALSE,FALSE), offset); } +*/ } else pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),offset)); offset++; @@ -11136,21 +12154,28 @@ static void genCast (iCode *ic) switch (p_type) { case IPOINTER: case POINTER: - pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1)); + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), GPTRSIZE - 1)); +// pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),GPTRSIZE - 1)); break; + + case CPOINTER: + pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1)); + break; + case FPOINTER: pic16_emitcode(";BUG!? ","%d",__LINE__); l = one; break; - case CPOINTER: - pic16_emitcode(";BUG!? ","%d",__LINE__); - l = "#0x02"; - break; case PPOINTER: pic16_emitcode(";BUG!? ","%d",__LINE__); l = "#0x03"; break; - + + case GPOINTER: + pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1)); + break; + default: /* this should never happen */ werror(E_INTERNAL_ERROR,__FILE__,__LINE__, @@ -11189,8 +12214,7 @@ 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)); + mov2f(AOP(result), AOP(right), offset); offset++; } @@ -11206,15 +12230,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)); @@ -11277,14 +12301,9 @@ 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); */ -/* pic16_emitcode ("","%05d_DS_:",lbl->key+100); */ -/* pic16_emitcode ("ljmp","%05d_DS_",IC_TRUE(ifx)->key+100); */ -/* pic16_emitcode ("","%05d_DS_:",lbl1->key+100); */ - pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); ifx->generated = 1; @@ -11296,40 +12315,47 @@ static int genDjnz (iCode *ic, iCode *ifx) /*-----------------------------------------------------------------*/ static void genReceive (iCode *ic) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (isOperandInFarSpace(IC_RESULT(ic)) && - ( OP_SYMBOL(IC_RESULT(ic))->isspilt || - IS_TRUE_SYMOP(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)); - int size = getSize(operandType(IC_RESULT(ic))); - int offset = pic16_fReturnSizePic - size; + if (isOperandInFarSpace(IC_RESULT(ic)) + && ( OP_SYMBOL(IC_RESULT(ic))->isspilt + || IS_TRUE_SYMOP(IC_RESULT(ic))) ) { - while (size--) { - pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ? - fReturn[pic16_fReturnSizePic - offset - 1] : "acc")); - offset++; - } + int size = getSize(operandType(IC_RESULT(ic))); + int offset = pic16_fReturnSizePic - size; - DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__); + assert( 0 ); + while (size--) { + pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ? + fReturn[pic16_fReturnSizePic - offset - 1] : "acc")); + offset++; + } - pic16_aopOp(IC_RESULT(ic),ic,FALSE); - size = AOP_SIZE(IC_RESULT(ic)); - offset = 0; - while (size--) { - pic16_emitcode ("pop","acc"); - pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++); - } - } else { - DEBUGpic16_emitcode ("; ***","2 %s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__); - _G.accInUse++; - pic16_aopOp(IC_RESULT(ic),ic,FALSE); - _G.accInUse--; - assignResultValue(IC_RESULT(ic), 0); - } + pic16_aopOp(IC_RESULT(ic),ic,FALSE); + size = AOP_SIZE(IC_RESULT(ic)); + offset = 0; + while (size--) { + pic16_emitcode ("pop","acc"); + pic16_aopPut (AOP(IC_RESULT(ic)),"a",offset++); + } + } else { + DEBUGpic16_emitcode ("; ***","2 %s %d argreg = %d",__FUNCTION__,__LINE__, SPEC_ARGREG(OP_SYM_ETYPE(IC_RESULT(ic)) )); + + _G.accInUse++; + pic16_aopOp(IC_RESULT(ic),ic,FALSE); + _G.accInUse--; + assignResultValue(IC_RESULT(ic), 0); + } - pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); + pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -11587,6 +12613,8 @@ void genpic16Code (iCode *lic) case SEND: addSet(&_G.sendSet,ic); + /* create a reversed list of SEND iCodes */ +// addSetHead(&_G.sendSet, ic); break; case DUMMY_READ_VOLATILE: @@ -11605,7 +12633,7 @@ void genpic16Code (iCode *lic) peepHole (&lineHead); } /* now do the actual printing */ - printLine (lineHead,codeOutFile); + printLine (lineHead, codeOutFile); #ifdef PCODE_DEBUG DFPRINTF((stderr,"printing pBlock\n\n"));