X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgen.c;h=9a09ef0b891063c594ff9914f17864e1f7aa82ab;hb=8332acb8ebcdd1490779c012db097c74c71d039e;hp=0245249bbcc8d7651f5090e97a67ca8cd24908df;hpb=002b45e47d2e16535faf6ac10a84ebcb0e9091fc;p=fw%2Fsdcc diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 0245249b..9a09ef0b 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -6,6 +6,7 @@ Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a) PIC port - Scott Dattalo scott@dattalo.com (2000) PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002) + - Vangelis Rokas vrokas@otenet.gr (2003,2004) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -42,26 +43,32 @@ #include "ralloc.h" #include "pcode.h" #include "gen.h" - +#include "genutils.h" +#include "device.h" +#include "main.h" extern void pic16_genUMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); extern void pic16_genSMult8X8_16 (operand *, operand *,operand *,pCodeOpReg *); void pic16_genMult8X8_8 (operand *, operand *,operand *); -pCode *pic16_AssembleLine(char *line); +void pic16_genMult16X16_16(operand *, operand *, operand *); +void pic16_genMult32X32_32(operand *, operand *, operand *); +pCode *pic16_AssembleLine(char *line, int peeps); extern void pic16_printpBlock(FILE *of, pBlock *pb); static asmop *newAsmop (short type); -static pCodeOp *popRegFromString(char *str, int size, int offset); +static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op); +extern pCode *pic16_newpCodeAsmDir(char *asdir, char *argfmt, ...); static void mov2w (asmop *aop, int offset); -static int aopIdx (asmop *aop, int offset); +static void mov2f(asmop *dst, asmop *src, int offset); +static void mov2fp(pCodeOp *dst, asmop *src, int offset); +//static int aopIdx (asmop *aop, int offset); -static int labelOffset=0; +int pic16_labelOffset=0; extern int pic16_debug_verbose; static int optimized_for_speed = 0; /* hack hack */ -int options_no_movff = 1; /* max_key keeps track of the largest label number used in a function. This is then used to adjust the label offset @@ -71,10 +78,19 @@ static int max_key=0; static int GpsuedoStkPtr=0; pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index); +pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst); + unsigned int pic16aopLiteral (value *val, int offset); const char *pic16_AopType(short type); static iCode *ifxForOp ( operand *op, iCode *ic ); +void pic16_pushpCodeOp(pCodeOp *pcop); +void pic16_poppCodeOp(pCodeOp *pcop); + +static bool is_LitOp(operand *op); +static bool is_LitAOp(asmop *aop); + + #define BYTEofLONG(l,b) ( (l>> (b<<3)) & 0xff) /* this is the down and dirty file with all kinds of @@ -84,25 +100,43 @@ static iCode *ifxForOp ( operand *op, iCode *ic ); static char *zero = "#0x00"; static char *one = "#0x01"; -static char *spname = "sp"; +//static char *spname = "sp"; + + +/* + * Function return value policy (MSB-->LSB): + * 8 bits -> WREG + * 16 bits -> PRODL:WREG + * 24 bits -> PRODH:PRODL:WREG + * 32 bits -> FSR0L:PRODH:PRODL:WREG + * >32 bits -> on stack, and FSR0 points to the beginning + * + */ + -char *fReturnpic16[] = {"temp1","temp2","temp3","temp4" }; -//char *fReturn390[] = {"dpl","dph","dpx", "b","a" }; +char *fReturnpic16[] = {"WREG", "PRODL", "PRODH", "FSR0L" }; unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */ static char **fReturn = fReturnpic16; -static char *accUse[] = {"a","b"}; +static char *accUse[] = {"WREG"}; //static short rbank = -1; static struct { short r0Pushed; short r1Pushed; + short fsr0Pushed; short accInUse; short inLine; short debugLine; short nRegsSaved; + short ipushRegs; set *sendSet; + set *stackRegSet; + int interruptvector; + int usefastretfie; + bitVect *fregsUsed; + int stack_lat; /* stack offset latency */ } _G; /* Resolved ifx structure. This structure stores information @@ -118,7 +152,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; @@ -157,7 +191,6 @@ static int my_powof2 (unsigned long num) void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operand *result) { - DEBUGpic16_emitcode ("; ","line = %d result %s=%s, left %s=%s, right %s=%s, size = %d", line_no, ((result) ? pic16_AopType(AOP_TYPE(result)) : "-"), @@ -167,7 +200,6 @@ void DEBUGpic16_pic16_AopType(int line_no, operand *left, operand *right, operan ((right) ? pic16_AopType(AOP_TYPE(right)) : "-"), ((right) ? pic16_aopGet(AOP(right),0,FALSE,FALSE) : "-"), ((result) ? AOP_SIZE(result) : 0)); - } void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, operand *result) @@ -184,6 +216,32 @@ void DEBUGpic16_pic16_AopTypeSign(int line_no, operand *left, operand *right, op } +void pic16_emitpcomment (char *fmt, ...) +{ + va_list ap; + char lb[INITIAL_INLINEASM]; + char *lbp = lb; + + va_start(ap,fmt); + + lb[0] = ';'; + vsprintf(lb+1,fmt,ap); + + while (isspace(*lbp)) lbp++; + + if (lbp && *lbp) + lineCurr = (lineCurr ? + connectLine(lineCurr,newLineNode(lb)) : + (lineHead = newLineNode(lb))); + lineCurr->isInline = _G.inLine; + lineCurr->isDebug = _G.debugLine; + + pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb)); + va_end(ap); + +// fprintf(stderr, "%s\n", lb); +} + void DEBUGpic16_emitcode (char *inst,char *fmt, ...) { va_list ap; @@ -219,10 +277,14 @@ void DEBUGpic16_emitcode (char *inst,char *fmt, ...) // fprintf(stderr, "%s\n", lb); } - 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) @@ -243,6 +305,10 @@ void pic16_emitpcodeNULLop(PIC_OPCODE poc) } + +#if 1 +#define pic16_emitcode DEBUGpic16_emitcode +#else /*-----------------------------------------------------------------*/ /* pic16_emitcode - writes the code into a file : for now it is simple */ /*-----------------------------------------------------------------*/ @@ -274,11 +340,25 @@ void pic16_emitcode (char *inst,char *fmt, ...) // VR fprintf(stderr, "lb = <%s>\n", lbp); - if(pic16_debug_verbose) - pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb)); +// if(pic16_debug_verbose) +// pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(lb)); va_end(ap); } +#endif + + +/*-----------------------------------------------------------------*/ +/* pic16_emitDebuggerSymbol - associate the current code location */ +/* with a debugger symbol */ +/*-----------------------------------------------------------------*/ +void +pic16_emitDebuggerSymbol (char * debugSym) +{ + _G.debugLine = 1; + pic16_emitcode (";", "%s ==.", debugSym); + _G.debugLine = 0; +} /*-----------------------------------------------------------------*/ @@ -286,11 +366,67 @@ void pic16_emitcode (char *inst,char *fmt, ...) /*-----------------------------------------------------------------*/ 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 */ @@ -308,7 +444,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); } @@ -364,6 +500,7 @@ endOfWorld : werror(E_INTERNAL_ERROR,__FILE__,__LINE__, "getFreePtr should never reach here"); exit(0); +#endif } /*-----------------------------------------------------------------*/ @@ -398,20 +535,24 @@ static void genSetDPTR(int n) /*-----------------------------------------------------------------*/ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) { + + DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + if(!resIfx) return; - // DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); resIfx->condition = 1; /* assume that the ifx is true */ resIfx->generated = 0; /* indicate that the ifx has not been used */ if(!ifx) { resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */ -/* + +#if 1 DEBUGpic16_emitcode("; ***","%s %d null ifx creating new label key =%d", __FUNCTION__,__LINE__,resIfx->lbl->key); -*/ +#endif + } else { if(IC_TRUE(ifx)) { resIfx->lbl = IC_TRUE(ifx); @@ -419,17 +560,19 @@ static void resolveIfx(resolvedIfx *resIfx, iCode *ifx) resIfx->lbl = IC_FALSE(ifx); resIfx->condition = 0; } -/* + +#if 1 if(IC_TRUE(ifx)) DEBUGpic16_emitcode("; ***","ifx true is non-null"); if(IC_FALSE(ifx)) DEBUGpic16_emitcode("; ***","ifx false is non-null"); -*/ +#endif } - // DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,labelOffset); + DEBUGpic16_emitcode("; ***","%s lbl->key=%d, (lab offset=%d)",__FUNCTION__,resIfx->lbl->key,pic16_labelOffset); } +#if 0 /*-----------------------------------------------------------------*/ /* pointerCode - returns the code for a pointer type */ /*-----------------------------------------------------------------*/ @@ -439,30 +582,83 @@ static int pointerCode (sym_link *etype) return PTR_TYPE(SPEC_OCLS(etype)); } +#endif /*-----------------------------------------------------------------*/ /* aopForSym - for a true symbol */ /*-----------------------------------------------------------------*/ -static asmop *aopForSym (iCode *ic,symbol *sym,bool result) +static asmop *aopForSym (iCode *ic, operand *op, bool result) { + symbol *sym=OP_SYMBOL(op); asmop *aop; memmap *space= SPEC_OCLS(sym->etype); DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + +// sym = OP_SYMBOL(op); + /* if already has one */ if (sym->aop) { DEBUGpic16_emitcode("; ***", "already has sym %s %d", __FUNCTION__, __LINE__); return sym->aop; } +#if 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) { + 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) { - sym->aop = aop = newAsmop(0); - aop->aopu.aop_ptr = getFreePtr(ic,&aop,result); + 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); + + /* 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); + 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) { @@ -489,8 +685,12 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) } else aop->aopu.aop_stk = sym->stack; return aop; +#endif + } - +#endif + +#if 0 if (sym->onStack && options.stack10bit) { /* It's on the 10 bit stack, which is located in @@ -521,14 +721,14 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) aop->size = getSize(sym->type); return aop; } - +#endif //DEBUGpic16_emitcode(";","%d",__LINE__); /* if in bit space */ if (IN_BITSPACE(space)) { sym->aop = aop = newAsmop (AOP_CRY); aop->aopu.aop_dir = sym->rname ; aop->size = getSize(sym->type); - //DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); + DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); return aop; } /* if it is in direct space */ @@ -537,9 +737,20 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) aop->aopu.aop_dir = sym->rname ; aop->size = getSize(sym->type); DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); + pic16_allocDirReg( IC_LEFT(ic) ); + return aop; + } + + if (IN_FARSPACE(space)) { + sym->aop = aop = newAsmop (AOP_DIR); + aop->aopu.aop_dir = sym->rname ; + aop->size = getSize(sym->type); + DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); + pic16_allocDirReg( IC_LEFT(ic) ); return aop; } +#if 0 // patch 14 /* special case for a function */ if (IS_FUNC(sym->type)) { sym->aop = aop = newAsmop(AOP_IMMD); @@ -550,30 +761,45 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname); return aop; } +#endif // patch 14 /* only remaining is far space */ /* in which case DPTR gets the address */ sym->aop = aop = newAsmop(AOP_PCODE); - aop->aopu.pcop = pic16_popGetImmd(sym->rname,0,0); - PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space); - PCOI(aop->aopu.pcop)->index = 0; +/* change the next if to 1 to revert to good old immediate code */ + if(IN_CODESPACE(space)) { + aop->aopu.pcop = pic16_popGetImmd(sym->rname, 0, 0); + PCOI(aop->aopu.pcop)->_const = IN_CODESPACE(space); + PCOI(aop->aopu.pcop)->index = 0; + } else { + /* try to allocate via direct register */ + aop->aopu.pcop = pic16_popRegFromString(sym->rname, getSize(sym->type), sym->offset, op); // Patch 8 +// aop->size = getSize( sym->type ); + } - DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", - __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const); + DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", + __LINE__,sym->rname, 0, PCOI(aop->aopu.pcop)->_const); - pic16_allocDirReg (IC_LEFT(ic)); +#if 0 + if(!pic16_allocDirReg (IC_LEFT(ic))) + return NULL; +#endif - aop->size = FPTRSIZE; -/* - DEBUGpic16_emitcode(";","%d size = %d, name =%s",__LINE__,aop->size,sym->rname); - sym->aop = aop = newAsmop(AOP_DPTR); - pic16_emitcode ("mov","dptr,#%s", sym->rname); - aop->size = getSize(sym->type); + if(IN_DIRSPACE( space )) + aop->size = PTRSIZE; + else if(IN_CODESPACE( space ) || IN_FARSPACE( space )) + aop->size = FPTRSIZE; + else if(IC_LEFT(ic)) aop->size = AOP_SIZE( IC_LEFT(ic) ); + else if(IC_RIGHT(ic)) aop->size = AOP_SIZE( IC_RIGHT(ic) ); + else if(sym->onStack) { + aop->size = PTRSIZE; + } else { + assert( 0 ); + } DEBUGpic16_emitcode(";","%d size = %d",__LINE__,aop->size); -*/ /* if it is in code space */ if (IN_CODESPACE(space)) @@ -588,44 +814,83 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) static asmop *aopForRemat (operand *op) // x symbol *sym) { symbol *sym = OP_SYMBOL(op); - iCode *ic = NULL; + iCode *ic = NULL, *oldic; asmop *aop = newAsmop(AOP_PCODE); int val = 0; int offset = 0; + int viaimmd=0; - ic = sym->rematiCode; - DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__); - if(IS_OP_POINTER(op)) { - DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__); - } - for (;;) { - if (ic->op == '+') { - val += (int) operandLitValue(IC_RIGHT(ic)); - } else if (ic->op == '-') { - val -= (int) operandLitValue(IC_RIGHT(ic)); - } else - break; + ic = sym->rematiCode; + + DEBUGpic16_emitcode(";","%s %d",__FUNCTION__,__LINE__); - ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; - } + if(IS_OP_POINTER(op)) { + DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__); + } + + for (;;) { + oldic = ic; + +// pic16_emitpcomment("ic: %s\n", printILine(ic)); + + if (ic->op == '+') { + val += (int) operandLitValue(IC_RIGHT(ic)); + } else if (ic->op == '-') { + val -= (int) operandLitValue(IC_RIGHT(ic)); + } else + break; + + ic = OP_SYMBOL(IC_LEFT(ic))->rematiCode; + } + + offset = OP_SYMBOL(IC_LEFT(ic))->offset; + + if(!op->isaddr)viaimmd++; else viaimmd=0; + +/* set the following if to 1 to revert to good old immediate code */ + if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op))) + || viaimmd) { + + DEBUGpic16_emitcode("%s:%d immediate", __FILE__, __LINE__); + + aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname, 0, val); + +#if 0 + PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op)); +#else + PCOI(aop->aopu.pcop)->_const = IS_CODEPTR(operandType(op)); +#endif + + PCOI(aop->aopu.pcop)->index = val; + } else { + DEBUGpic16_emitcode("%s:%d dir", __FILE__, __LINE__); + + aop->aopu.pcop = pic16_popRegFromString(OP_SYMBOL(IC_LEFT(ic))->rname, + getSize( OP_SYMBOL( IC_LEFT(ic))->type), val, op); +// aop->size = AOP_SIZE( IC_LEFT(ic) ); + } + - offset = OP_SYMBOL(IC_LEFT(ic))->offset; - aop->aopu.pcop = pic16_popGetImmd(OP_SYMBOL(IC_LEFT(ic))->rname,0,val); - PCOI(aop->aopu.pcop)->_const = IS_PTR_CONST(operandType(op)); - PCOI(aop->aopu.pcop)->index = val; + DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", + __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname, +#if 0 + val, IS_PTR_CONST(operandType(op))); +#else + val, IS_CODEPTR(operandType(op))); +#endif - DEBUGpic16_emitcode(";","%d: rname %s, val %d, const = %d", - __LINE__,OP_SYMBOL(IC_LEFT(ic))->rname, - val, IS_PTR_CONST(operandType(op))); +// DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic)))); - // DEBUGpic16_emitcode(";","aop type %s",pic16_AopType(AOP_TYPE(IC_LEFT(ic)))); + pic16_allocDirReg (IC_LEFT(ic)); - pic16_allocDirReg (IC_LEFT(ic)); + if(IN_CODESPACE( SPEC_OCLS( OP_SYM_ETYPE(op)) )) + aop->code = 1; return aop; } +#if 0 static int aopIdx (asmop *aop, int offset) { if(!aop) @@ -637,6 +902,8 @@ static int aopIdx (asmop *aop, int offset) return aop->aopu.aop_reg[offset]->rIdx; } +#endif + /*-----------------------------------------------------------------*/ /* regsInCommon - two operands have some registers in common */ /*-----------------------------------------------------------------*/ @@ -696,7 +963,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; @@ -727,9 +995,16 @@ 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 0 if (aop1->type != AOP_REG || aop2->type != AOP_REG ) return FALSE ; +#endif if (aop1->size != aop2->size ) return FALSE ; @@ -754,7 +1029,8 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) if (!op) return ; - DEBUGpic16_emitcode(";","%d",__LINE__); +// DEBUGpic16_emitcode(";","%s %d",__FUNCTION__, __LINE__); + /* if this a literal */ if (IS_OP_LITERAL(op)) { op->aop = aop = newAsmop(AOP_LIT); @@ -765,7 +1041,11 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) { sym_link *type = operandType(op); +#if 0 if(IS_PTR_CONST(type)) +#else + if(IS_CODEPTR(type)) +#endif DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__); } @@ -783,7 +1063,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) /* if this is a true symbol */ if (IS_TRUE_SYMOP(op)) { DEBUGpic16_emitcode(";","%d - true symop",__LINE__); - op->aop = aopForSym(ic,OP_SYMBOL(op),result); + op->aop = aopForSym(ic, op, result); return ; } @@ -821,16 +1101,22 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) return; } +#if 1 if (sym->accuse) { int i; aop = op->aop = sym->aop = newAsmop(AOP_ACC); aop->size = getSize(sym->type); - for ( i = 0 ; i < 2 ; i++ ) - aop->aopu.aop_str[i] = accUse[i]; + for ( i = 0 ; i < 1 ; i++ ) { + aop->aopu.aop_str[i] = accUse[i]; +// aop->aopu.pcop = pic16_popRegFromString("WREG", aop->size, sym->usl.spillLoc->offset); + } + fprintf(stderr, "%s:%d allocating AOP_ACC for sym= %s\n", __FILE__, __LINE__, sym->name); DEBUGpic16_emitcode(";","%d size=%d",__LINE__,aop->size); return; } +#endif +#if 1 if (sym->ruonly ) { /* sym->aop = op->aop = aop = newAsmop(AOP_PCODE); @@ -849,22 +1135,25 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) DEBUGpic16_emitcode(";","%d",__LINE__); return; } - +#endif /* else spill location */ if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) { /* force a new aop if sizes differ */ 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); - aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname, + aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname, getSize(sym->type), - sym->usl.spillLoc->offset); + sym->usl.spillLoc->offset, op); aop->size = getSize(sym->type); return; @@ -872,7 +1161,11 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) { sym_link *type = operandType(op); +#if 0 if(IS_PTR_CONST(type)) +#else + if(IS_CODEPTR(type)) +#endif DEBUGpic16_emitcode(";","%d aop type is const pointer",__LINE__); } @@ -906,8 +1199,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) { @@ -928,6 +1237,20 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) bitVectUnSetBit(ic->rUsed,R1_IDX); break; + case AOP_STA: + { + int i; + + for(i=0;isize;i++) +#if 1 + PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1; +#else + pic16_popReleaseTempReg( aop->aopu.stk.pop[i], 0 ); + bitVectUnSetBit(_G.fregsUsed, PCOR(aop->aopu.stk.pop[i])->r->rIdx ); +#endif + } + break; +#if 0 case AOP_STK : { int sz = aop->size; @@ -972,6 +1295,8 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) _G.r1Pushed--; } } +#endif + } #endif @@ -997,98 +1322,72 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) char *rs; //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* offset is greater than - size then zero */ + + /* offset is greater than size then zero */ if (offset > (aop->size - 1) && aop->type != AOP_LIT) return zero; /* depending on type */ switch (aop->type) { + + case AOP_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++; + } + + 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_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--; - } + case AOP_IMMD: + if (bit16) + sprintf (s,"%s",aop->aopu.aop_immd); + else + if (offset) + sprintf(s,"(%s >> %d)", + aop->aopu.aop_immd, + offset*8); + else + sprintf(s,"%s", + aop->aopu.aop_immd); + DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s); + rs = Safe_calloc(1,strlen(s)+1); + strcpy(rs,s); + return rs; - 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"); - } - else { - pic16_emitcode("movx","a,@dptr"); - } - - if (aop->type == AOP_DPTR2) - { - genSetDPTR(0); - } - - return (dname ? "acc" : "a"); - - - case AOP_IMMD: - if (bit16) - sprintf (s,"%s",aop->aopu.aop_immd); - else - if (offset) - sprintf(s,"(%s >> %d)", - aop->aopu.aop_immd, - offset*8); - else - sprintf(s,"%s", - aop->aopu.aop_immd); - DEBUGpic16_emitcode(";","%d immd %s",__LINE__,s); - rs = Safe_calloc(1,strlen(s)+1); - strcpy(rs,s); - return rs; - - case AOP_DIR: - if (offset) { - sprintf(s,"(%s + %d)", - aop->aopu.aop_dir, - offset); - DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s); - } else - sprintf(s,"%s",aop->aopu.aop_dir); + case AOP_DIR: + if (offset) { + sprintf(s,"(%s + %d)", + aop->aopu.aop_dir, + offset); + DEBUGpic16_emitcode(";","oops AOP_DIR did this %s\n",s); + } else + sprintf(s,"%s",aop->aopu.aop_dir); rs = Safe_calloc(1,strlen(s)+1); strcpy(rs,s); return rs; @@ -1104,8 +1403,12 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) return aop->aopu.aop_dir; case AOP_ACC: - DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d",__LINE__); - return "AOP_accumulator_bug"; + DEBUGpic16_emitcode(";Warning -pic port ignoring get(AOP_ACC)","%d\toffset: %d",__LINE__, offset); +// fprintf(stderr, "%s:%d Warning -pic port ignoring get(AOP_ACC)\n",__FILE__, __LINE__); +// assert( 0 ); +// return aop->aopu.aop_str[offset]; //->"AOP_accumulator_bug"; + rs = Safe_strdup("WREG"); + return (rs); case AOP_LIT: sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset)); @@ -1138,40 +1441,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__); + if(_TempReg_lock) { + werror(W_POSSBUG2, __FILE__, __LINE__); + } + + _TempReg_lock += lock; + + cfunc = currFunc; + currFunc = NULL; + + pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP); + if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { + PCOR(pcop)->r->wasUsed=1; + PCOR(pcop)->r->isFree=0; + + /* push value on stack */ + pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) ); + } + + currFunc = cfunc; + + return pcop; +} + +/*-----------------------------------------------------------------*/ +/* pic16_popGetTempRegCond - create a new temporary pCodeOp, but */ +/* don't save if inside v */ +/*-----------------------------------------------------------------*/ +pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock) +{ pCodeOp *pcop; + symbol *cfunc; - pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP); - if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { - PCOR(pcop)->r->wasUsed=1; - PCOR(pcop)->r->isFree=0; - } +// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(_TempReg_lock) { + werror(W_POSSBUG2, __FILE__, __LINE__); + } + + _TempReg_lock += lock; + + 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; + + 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__); - if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) - PCOR(pcop)->r->isFree = 1; + _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 */ @@ -1179,12 +1561,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); } /*-----------------------------------------------------------------*/ @@ -1206,26 +1588,33 @@ pCodeOp *pic16_popCopyReg(pCodeOpReg *pc) pcor->rIdx = pc->rIdx; pcor->r->wasUsed=1; - //DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx); +// DEBUGpic16_emitcode ("; ***","%s , copying %s, rIdx=%d",__FUNCTION__,pc->pcop.name,pc->rIdx); return PCOP(pcor); } + /*-----------------------------------------------------------------*/ -/* pic16_popGet - asm operator to pcode operator conversion */ +/* pic16_popGetLit - asm operator to pcode operator conversion */ /*-----------------------------------------------------------------*/ -pCodeOp *pic16_popGetLit(unsigned int lit) +pCodeOp *pic16_popGetLit(int lit) { - return pic16_newpCodeOpLit(lit); } +/*-----------------------------------------------------------------*/ +/* pic16_popGetLit2 - asm operator to pcode operator conversion */ +/*-----------------------------------------------------------------*/ +pCodeOp *pic16_popGetLit2(int lit, pCodeOp *arg2) +{ + return pic16_newpCodeOpLit2(lit, arg2); +} + /*-----------------------------------------------------------------*/ -/* pic16_popGetImmd - asm operator to pcode immediate conversion */ +/* pic16_popGetImmd - asm operator to pcode immediate conversion */ /*-----------------------------------------------------------------*/ pCodeOp *pic16_popGetImmd(char *name, unsigned int offset, int index) { - return pic16_newpCodeOpImmd(name, offset,index, 0); } @@ -1249,16 +1638,16 @@ pCodeOp *pic16_popGetWithString(char *str) } /*-----------------------------------------------------------------*/ -/* popRegFromString - */ +/* pic16_popRegFromString - */ /*-----------------------------------------------------------------*/ -static pCodeOp *popRegFromString(char *str, int size, int offset) +static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand *op) { pCodeOp *pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); pcop->type = PO_DIR; - DEBUGpic16_emitcode(";","%d %s %s",__LINE__, __FUNCTION__, str); -// fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size); + DEBUGpic16_emitcode(";","%d %s %s %d/%d",__LINE__, __FUNCTION__, str, size, offset); // patch 14 + // fprintf(stderr, "%s:%d: register name = %s pos = %d/%d\n", __FUNCTION__, __LINE__, str, offset, size); if(!str) str = "BAD_STRING"; @@ -1269,37 +1658,37 @@ static pCodeOp *popRegFromString(char *str, int size, int offset) //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING")); PCOR(pcop)->r = pic16_dirregWithName(pcop->name); - if(PCOR(pcop)->r == NULL) { - //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size); - PCOR(pcop)->r = pic16_allocRegByName (pcop->name,size); - //fprintf(stderr, "allocating new register -> %s\n", str); + /* make sure that register doesn't exist, + * and operand isn't NULL */ + if((PCOR(pcop)->r == NULL) + && (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, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str); - DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset); - } else { - DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset); } PCOR(pcop)->instance = offset; return pcop; } -static pCodeOp *popRegFromIdx(int rIdx) +static pCodeOp *pic16_popRegFromIdx(int rIdx) { pCodeOp *pcop; - DEBUGpic16_emitcode ("; ***","%s,%d , rIdx=0x%x", - __FUNCTION__,__LINE__,rIdx); - - pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); +// DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx); - PCOR(pcop)->rIdx = rIdx; - PCOR(pcop)->r = pic16_regWithIdx(rIdx); - PCOR(pcop)->r->isFree = 0; - PCOR(pcop)->r->wasUsed = 1; + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = pic16_regWithIdx(rIdx); - pcop->type = PCOR(pcop)->r->pc_type; + PCOR(pcop)->r->isFree = 0; + PCOR(pcop)->r->wasUsed = 1; + pcop->type = PCOR(pcop)->r->pc_type; return pcop; } @@ -1314,6 +1703,10 @@ pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset) pCodeOp *temp; pcop2 = (pCodeOpReg2 *)pic16_popGet(aop_src, offset); + + /* comment the following check, so errors to throw up */ +// if(!pcop2)return NULL; + temp = pic16_popGet(aop_dst, offset); pcop2->pcop2 = temp; @@ -1321,23 +1714,60 @@ pCodeOp *pic16_popGet2(asmop *aop_src, asmop *aop_dst, int offset) } + +/*--------------------------------------------------------------------------------.-*/ +/* pic16_popGet2p - a variant of pic16_popGet to handle two memory operand commands */ +/* VR 030601 , adapted by Hans Dorn */ +/*--------------------------------------------------------------------------------.-*/ +pCodeOp *pic16_popGet2p(pCodeOp *src, pCodeOp *dst) +{ + pCodeOpReg2 *pcop2; + + pcop2 = (pCodeOpReg2 *)src; + pcop2->pcop2 = dst; + + return PCOP(pcop2); +} + + + +/*---------------------------------------------------------------------------------*/ +/* pic16_popCombine2 - combine two pCodeOpReg variables into one for use with */ +/* movff instruction */ +/*---------------------------------------------------------------------------------*/ +pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc) +{ + pCodeOpReg2 *pcop2; + + if(!noalloc) { + pcop2 = (pCodeOpReg2 *)pic16_popCopyReg(src); + pcop2->pcop2 = pic16_popCopyReg(dst); + } else { + /* the pCodeOp may be already allocated */ + pcop2 = (pCodeOpReg2 *)(src); + pcop2->pcop2 = (pCodeOp *)(dst); + } + + return PCOP(pcop2); +} + + /*-----------------------------------------------------------------*/ /* pic16_popGet - asm operator to pcode operator conversion */ /*-----------------------------------------------------------------*/ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) { //char *s = buffer ; - //char *rs; - - pCodeOp *pcop; + char *rs; + pCodeOp *pcop; //DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* offset is greater than size then zero */ - if (offset > (aop->size - 1) && - aop->type != AOP_LIT) - return NULL; //zero; +// if (offset > (aop->size - 1) && +// aop->type != AOP_LIT) +// return NULL; //zero; /* depending on type */ switch (aop->type) { @@ -1346,76 +1776,103 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) case AOP_R1: case AOP_DPTR: case AOP_DPTR2: - case AOP_ACC: DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type)); + fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type)); + assert( 0 ); return NULL; - + + + case AOP_FSR0: + case AOP_FSR2: + pcop = Safe_calloc(1, sizeof(pCodeOpReg)); + PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */ + PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx ); + PCOR(pcop)->r->wasUsed = 1; + PCOR(pcop)->r->isFree = 0; + + PCOR(pcop)->instance = offset; + pcop->type = PCOR(pcop)->r->pc_type; + return (pcop); + case AOP_IMMD: - DEBUGpic16_emitcode(";","%d",__LINE__); + DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__); return pic16_popGetImmd(aop->aopu.aop_immd,offset,0); - case AOP_DIR: - return popRegFromString(aop->aopu.aop_dir, aop->size, offset); + 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; -#if 0 + fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]); + + DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__); + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); - pcop->type = PO_DIR; + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx); + PCOR(pcop)->r->wasUsed=1; + PCOR(pcop)->r->isFree=0; - /* - if (offset) - sprintf(s,"(%s + %d)", - aop->aopu.aop_dir, - offset); - else - sprintf(s,"%s",aop->aopu.aop_dir); - pcop->name = Safe_calloc(1,strlen(s)+1); - strcpy(pcop->name,s); - */ - pcop->name = Safe_calloc(1,strlen(aop->aopu.aop_dir)+1); - strcpy(pcop->name,aop->aopu.aop_dir); - PCOR(pcop)->r = pic16_dirregWithName(aop->aopu.aop_dir); - if(PCOR(pcop)->r == NULL) { - //fprintf(stderr,"%d - couldn't find %s in allocated registers, size =%d\n",__LINE__,aop->aopu.aop_dir,aop->size); - PCOR(pcop)->r = pic16_allocRegByName (aop->aopu.aop_dir,aop->size); - DEBUGpic16_emitcode(";","%d %s offset=%d - had to alloc by reg name",__LINE__,pcop->name,offset); - } else { - DEBUGpic16_emitcode(";","%d %s offset=%d",__LINE__,pcop->name,offset); - } PCOR(pcop)->instance = offset; - + pcop->type = PCOR(pcop)->r->pc_type; +// rs = aop->aopu.aop_reg[offset]->name; +// DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs); return pcop; -#endif + + +// return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset); +// return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]); + +// assert( 0 ); + } + + case AOP_DIR: + DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__); + return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL); case AOP_REG: { int rIdx = aop->aopu.aop_reg[offset]->rIdx; + DEBUGpic16_emitcode(";","%d\tAOP_REG", __LINE__); + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); +// pcop->type = PO_GPR_REGISTER; PCOR(pcop)->rIdx = rIdx; - PCOR(pcop)->r = pic16_regWithIdx(rIdx); + PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx); PCOR(pcop)->r->wasUsed=1; PCOR(pcop)->r->isFree=0; PCOR(pcop)->instance = offset; pcop->type = PCOR(pcop)->r->pc_type; - //rs = aop->aopu.aop_reg[offset]->name; - //DEBUGpic16_emitcode(";","%d regiser idx = %d name =%s",__LINE__,rIdx,rs); + rs = aop->aopu.aop_reg[offset]->name; + DEBUGpic16_emitcode(";","%d regiser idx = %d name = %s",__LINE__,rIdx,rs); return pcop; } case AOP_CRY: - pcop = pic16_newpCodeOpBit(aop->aopu.aop_dir,-1,1); + DEBUGpic16_emitcode(";","%d\tAOP_CRY", __LINE__); + + 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); return pcop; case AOP_LIT: + DEBUGpic16_emitcode(";","%d\tAOP_LIT", __LINE__); return pic16_newpCodeOpLit(pic16aopLiteral (aop->aopu.aop_lit,offset)); case AOP_STR: - DEBUGpic16_emitcode(";","%d %s",__LINE__,aop->aopu.aop_str[offset]); + DEBUGpic16_emitcode(";","%d AOP_STR %s",__LINE__,aop->aopu.aop_str[offset]); return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]); + /* pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); PCOR(pcop)->r = pic16_allocRegByName(aop->aopu.aop_str[offset]); @@ -1427,11 +1884,20 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) */ case AOP_PCODE: - DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s",pic16_pCodeOpType(aop->aopu.pcop), + DEBUGpic16_emitcode(";","pic16_popGet AOP_PCODE (%s) %d %s offset %d",pic16_pCodeOpType(aop->aopu.pcop), __LINE__, - ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name")); + ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"), offset); pcop = pic16_pCodeOpCopy(aop->aopu.pcop); +#if 1 + switch( aop->aopu.pcop->type ) { + case PO_DIR: PCOR(pcop)->instance += offset; break; // patch 8 + case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break; + default: + assert( 0 ); /* should never reach here */; + } +#else PCOI(pcop)->offset = offset; +#endif return pcop; } @@ -1447,6 +1913,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)) { @@ -1663,9 +2131,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); } } @@ -1675,18 +2144,88 @@ void pic16_aopPut (asmop *aop, char *s, int offset) /*-----------------------------------------------------------------*/ static void mov2w (asmop *aop, int offset) { - - if(!aop) - return; - DEBUGpic16_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset); - if ( aop->type == AOP_PCODE || - aop->type == AOP_LIT ) + 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 { + 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)); + } +} + + +/* push pcop into stack */ +void pic16_pushpCodeOp(pCodeOp *pcop) +{ +// DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_postdec1))); +} + +/* pop pcop from stack */ +void pic16_poppCodeOp(pCodeOp *pcop) +{ + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop)); +} + + +/*-----------------------------------------------------------------*/ +/* pushw - pushes wreg to stack */ +/*-----------------------------------------------------------------*/ +void pushw(void) +{ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1)); +} + +/*-----------------------------------------------------------------*/ +/* pushaop - pushes aop to stack */ +/*-----------------------------------------------------------------*/ +void pushaop(asmop *aop, int offset) +{ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0)); +} + +/*-----------------------------------------------------------------*/ +/* popaop - pops aop from stack */ +/*-----------------------------------------------------------------*/ +void popaop(asmop *aop, int offset) +{ + DEBUGpic16_emitcode("; ***", "%s %d", __FUNCTION__, __LINE__); + pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_preinc1, PCOR(pic16_popGet(aop, offset)), 0)); +} + +void popaopidx(asmop *aop, int offset, int index) +{ + int ofs=1; + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(STACK_MODEL_LARGE)ofs++; + + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(index + ofs)); + pic16_emitpcode(POC_MOVFF, pic16_popCombine2(&pic16_pc_plusw2, PCOR(pic16_popGet(aop, offset)), 0)); } /*-----------------------------------------------------------------*/ @@ -1801,19 +2340,31 @@ void pic16_outAcc(operand *result) } /*-----------------------------------------------------------------*/ -/* pic16_outBitC - output a bit C */ +/* pic16_outBitC - output a bit C */ +/* Move to result the value of Carry flag -- VR */ /*-----------------------------------------------------------------*/ void pic16_outBitC(operand *result) { + int i; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if the result is bit */ - if (AOP_TYPE(result) == AOP_CRY) + if (AOP_TYPE(result) == AOP_CRY) { + fprintf(stderr, "%s:%d: pic16 port warning: unsupported case\n", __FILE__, __LINE__); pic16_aopPut(AOP(result),"c",0); - else { + } else { + + i = AOP_SIZE(result); + while(i--) { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), i)); + } + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result), 0)); + +/* pic16_emitcode("clr","a ; %d", __LINE__); pic16_emitcode("rlc","a"); pic16_outAcc(result); +*/ } } @@ -1836,10 +2387,11 @@ void pic16_toBoolean(operand *oper) } +#if !defined(GEN_Not) /*-----------------------------------------------------------------*/ /* genNot - generate code for ! operation */ /*-----------------------------------------------------------------*/ -static void genNot (iCode *ic) +static void pic16_genNot (iCode *ic) { symbol *tlbl; int size; @@ -1882,12 +2434,14 @@ static void genNot (iCode *ic) pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1)); pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } +#endif +#if !defined(GEN_Cpl) /*-----------------------------------------------------------------*/ /* genCpl - generate code for complement */ /*-----------------------------------------------------------------*/ -static void genCpl (iCode *ic) +static void pic16_genCpl (iCode *ic) { int offset = 0; int size ; @@ -1933,6 +2487,7 @@ release: pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1)); pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } +#endif /*-----------------------------------------------------------------*/ /* genUminusFloat - unary minus for floating points */ @@ -1969,57 +2524,57 @@ static void genUminus (iCode *ic) int size, i; sym_link *optype, *rtype; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + /* assign asmops */ + pic16_aopOp(IC_LEFT(ic),ic,FALSE); + pic16_aopOp(IC_RESULT(ic),ic,TRUE); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* assign asmops */ - pic16_aopOp(IC_LEFT(ic),ic,FALSE); - pic16_aopOp(IC_RESULT(ic),ic,TRUE); - - /* if both in bit space then special - case */ - if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY && - AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { - - pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0)); - pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0)); - pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0)); + /* if both in bit space then special case */ + if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY + && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { - goto release; - } + pic16_emitpcode(POC_BCF, pic16_popGet(AOP(IC_RESULT(ic)),0)); + pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_emitpcode(POC_BSF, pic16_popGet(AOP(IC_RESULT(ic)),0)); + + goto release; + } - optype = operandType(IC_LEFT(ic)); - rtype = operandType(IC_RESULT(ic)); + optype = operandType(IC_LEFT(ic)); + rtype = operandType(IC_RESULT(ic)); - /* if float then do float stuff */ - if (IS_FLOAT(optype)) { - genUminusFloat(IC_LEFT(ic),IC_RESULT(ic)); - goto release; - } + /* if float then do float stuff */ + if (IS_FLOAT(optype)) { + genUminusFloat(IC_LEFT(ic),IC_RESULT(ic)); + goto release; + } - /* otherwise subtract from zero by taking the 2's complement */ - size = AOP_SIZE(IC_LEFT(ic)); + /* otherwise subtract from zero by taking the 2's complement */ + size = AOP_SIZE(IC_LEFT(ic)); - for(i=0; iaopu.pcop->type == PO_IMMEDIATE) { + pic16_emitpcode(POC_MOVFW, src); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(op), offset)); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + src, pic16_popGet(AOP(op), offset))); + } +} + /*-----------------------------------------------------------------*/ -/* assignResultValue - */ +/* assignResultValue - assign results to oper, rescall==1 is */ +/* called from genCall() or genPCall() */ /*-----------------------------------------------------------------*/ -static void assignResultValue(operand * oper) +static void assignResultValue(operand * oper, int rescall) { int size = AOP_SIZE(oper); + 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",__FUNCTION__,__LINE__); - - DEBUGpic16_pic16_AopType(__LINE__,oper,NULL,NULL); + 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 */ - if(!GpsuedoStkPtr) { - /* The last byte in the assignment is in W */ - size--; - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size)); - GpsuedoStkPtr++; - } + if(size <= 4) { + /* 8-bits, result in WREG */ + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper), 0)); + + if(size>1) { + /* 16-bits, result in PRODL:WREG */ + pic16_loadFromReturn(oper, 1, pic16_popCopyReg(&pic16_pc_prodl)); + } + + if(size>2) { + /* 24-bits, result in PRODH:PRODL:WREG */ + pic16_loadFromReturn(oper, 2, pic16_popCopyReg(&pic16_pc_prodh)); // patch 14 + } + + if(size>3) { + /* 32-bits, result in FSR0L:PRODH:PRODL:WREG */ + pic16_loadFromReturn(oper, 3, pic16_popCopyReg(&pic16_pc_fsr0l)); // patch14 + } + + } else { + /* >32-bits, result on stack, and FSR0 points to beginning. + * Fix stack when done */ + /* FIXME FIXME */ + while (size--) { +// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); +// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + + popaopidx(AOP(oper), size, GpsuedoStkPtr); + GpsuedoStkPtr++; + } + + /* fix stack */ + pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) )); + pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l )); + if(STACK_MODEL_LARGE) { + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h )); + } + } + } else { + int areg = 0; /* matching argument register */ + + areg = SPEC_ARGREG( OP_SYM_ETYPE( oper ) ) - 1; + /* its called from genReceive (probably) */ + if(!GpsuedoStkPtr) { +// 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--) { - pic16_emitpcode(POC_MOVFW,popRegFromIdx(GpsuedoStkPtr-1 + pic16_Gstack_base_addr)); - GpsuedoStkPtr++; - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(oper),size)); - } + while (size) { +// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); +// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + if(areg <= GpsuedoStkPtr) { + size--; + popaopidx(AOP(oper), offset, GpsuedoStkPtr); + offset++; + } + GpsuedoStkPtr++; + } + } } @@ -2175,8 +2804,21 @@ static void assignResultValue(operand * oper) /*-----------------------------------------------------------------*/ 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; @@ -2204,29 +2846,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 } @@ -2256,6 +2875,7 @@ static void genIpop (iCode *ic) #endif } +#if 0 /*-----------------------------------------------------------------*/ /* unsaverbank - restores the resgister bank from stack */ /*-----------------------------------------------------------------*/ @@ -2351,248 +2971,298 @@ static void saverbank (int bank, iCode *ic, bool pushPsw) ic->bankSaved = 1; #endif } +#endif /* 0 */ + /*-----------------------------------------------------------------*/ /* genCall - generates a call statement */ /*-----------------------------------------------------------------*/ static void genCall (iCode *ic) { - sym_link *dtype; + sym_link *ftype; + int stackParms=0; + int use_wreg=0; + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + ftype = OP_SYM_TYPE(IC_LEFT(ic)); + /* if caller saves & we have not saved then */ +// if (!ic->regsSaved) +// saveRegisters(ic); - /* if caller saves & we have not saved then */ - if (!ic->regsSaved) - saveRegisters(ic); + /* initialise stackParms for IPUSH pushes */ +// stackParms = psuedoStkPtr; +// fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes); - /* 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) + /* if send set is not empty the assign */ + if (_G.sendSet) { + iCode *sic; + int psuedoStkPtr=-1; + int firstTimeThruLoop = 1; - 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; +#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)) { +/* 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); + } +*/ - pic16_aopOp(IC_LEFT(sic),sic,FALSE); - psuedoStkPtr += AOP_SIZE(IC_LEFT(sic)); - pic16_freeAsmop (IC_LEFT(sic),NULL,sic,FALSE); - } +// stackParms = psuedoStkPtr; + stackParms = 0; - for (sic = setFirstItem(_G.sendSet) ; sic ; - sic = setNextItem(_G.sendSet)) { - int size, offset = 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)))); + stackParms += size; - 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. */ - pic16_emitpcode(POC_MOVWF,popRegFromIdx(--psuedoStkPtr + pic16_Gstack_base_addr)); + while (size--) { + DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, + pic16_AopType(AOP_TYPE(IC_LEFT(sic)))); + DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1); - } - firstTimeThruLoop=0; + 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 (strcmp(l,fReturn[offset])) { - mov2w (AOP(IC_LEFT(sic)), offset); -/* - if ( ((AOP(IC_LEFT(sic))->type) == AOP_PCODE) || - ((AOP(IC_LEFT(sic))->type) == AOP_LIT) ) - pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(sic)),offset)); - else - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(IC_LEFT(sic)),offset)); -*/ - //} - offset++; + pushw(); +// --psuedoStkPtr; // sanity check + } + + firstTimeThruLoop=0; + + mov2w (AOP(IC_LEFT(sic)), size); + + offset++; + } + pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); + } + + /* save last parameter to stack if functions has varargs */ + if(IFFUNC_HASVARARGS(ftype)) + pushw(); + else + use_wreg = 1; /* last parameter in WREG */ + + _G.stackRegSet = _G.sendSet; + _G.sendSet = NULL; } - pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); - } - _G.sendSet = NULL; - } - /* 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)); - - 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--; + /* 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)); - assignResultValue(IC_RESULT(ic)); + 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)) ) { - DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, - pic16_AopType(AOP_TYPE(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 pop them */ - if (ic->bankSaved) - unsaverbank(FUNC_REGBANK(dtype),ic,TRUE); + if(!stackParms && ic->parmBytes) { + stackParms = ic->parmBytes; + } + + 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) { + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h )); + } + } - /* if we hade saved some registers then unsave them */ - if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype)) - unsaveRegisters (ic); + /* 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 we hade saved some registers then unsave them */ + if (ic->regsSaved && !IFFUNC_CALLEESAVES(dtype)) + unsaveRegisters (ic); +#endif } + + /*-----------------------------------------------------------------*/ /* genPcall - generates a call by pointer statement */ +/* new version, created from genCall - HJD */ /*-----------------------------------------------------------------*/ static void genPcall (iCode *ic) { - sym_link *dtype; - symbol *rlbl = newiTempLabel(NULL); + 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__); + 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; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if caller saves & we have not saved then */ - if (!ic->regsSaved) - saveRegisters(ic); + /* 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 :). */ - /* 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); +#if 1 + /* reverse sendSet if function is not reentrant */ + if(!IFFUNC_ISREENT(ftype)) + _G.sendSet = reverseSet(_G.sendSet); +#endif - /* 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"); - } + /* 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 - /* now push the calling address */ - pic16_aopOp(IC_LEFT(ic),ic,FALSE); +// stackParms = psuedoStkPtr; + stackParms = 0; - pushSide(IC_LEFT(ic), FPTRSIZE); + for (sic = setFirstItem(_G.sendSet) ; sic ; sic = setNextItem(_G.sendSet)) { + int size, offset = 0; - pic16_freeAsmop(IC_LEFT(ic),NULL,ic,TRUE); + pic16_aopOp(IC_LEFT(sic),sic,FALSE); + size = AOP_SIZE(IC_LEFT(sic)); + stackParms += size; - /* if send set is not empty the assign */ - if (_G.sendSet) { - iCode *sic ; + while (size--) { + DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, + pic16_AopType(AOP_TYPE(IC_LEFT(sic)))); + DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1); - 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; - } + 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. */ - pic16_emitcode("ret",""); - pic16_emitcode("","%05d_DS_:",(rlbl->key+100)); + pushw(); + --psuedoStkPtr; // sanity check + } + + firstTimeThruLoop=0; + mov2w (AOP(IC_LEFT(sic)), size); - /* 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)) ) { + offset++; + } - _G.accInUse++; - pic16_aopOp(IC_RESULT(ic),ic,FALSE); - _G.accInUse--; - - assignResultValue(IC_RESULT(ic)); - pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); - } + pic16_freeAsmop (IC_LEFT(sic),NULL,sic,TRUE); + } - /* 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); + if(IFFUNC_HASVARARGS(ftype)) + pushw(); + else + use_wreg = 1; /* last parameter in WREG */ + _G.stackRegSet = _G.sendSet; + _G.sendSet = NULL; } - /* if register bank was saved then unsave them */ - if (currFunc && dtype && - (FUNC_REGBANK(currFunc->type) != FUNC_REGBANK(dtype))) - unsaverbank(FUNC_REGBANK(dtype),ic,TRUE); + pic16_aopOp(IC_LEFT(ic),ic,FALSE); - /* if we hade saved some registers then - unsave them */ - if (ic->regsSaved) - unsaveRegisters (ic); + // push return address + // push $ on return stack, then replace with retlbl + + pic16_emitpcodeNULLop(POC_PUSH); + + pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosl)); + pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 1, 0)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosh)); + pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu)); + + /* make the call by writing the pointer into pc */ + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),2), pic16_popCopyReg(&pic16_pc_pclatu))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)),1), pic16_popCopyReg(&pic16_pc_pclath))); + + // note: MOVFF to PCL not allowed + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl)); + + + /* 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); + + DEBUGpic16_emitcode ("; ","%d left %s",__LINE__, + pic16_AopType(AOP_TYPE(IC_RESULT(ic)))); + + pic16_freeAsmop(IC_RESULT(ic),NULL, ic,TRUE); + } + 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 )); + } + } } /*-----------------------------------------------------------------*/ @@ -2647,189 +3317,272 @@ static bool inExcludeList(char *s) /*-----------------------------------------------------------------*/ static void genFunction (iCode *ic) { - symbol *sym; - sym_link *ftype; + symbol *sym; + sym_link *ftype; + + DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,pic16_labelOffset,max_key); + + pic16_labelOffset += (max_key+4); + max_key=0; + GpsuedoStkPtr=0; + _G.nRegsSaved = 0; + + ftype = operandType(IC_LEFT(ic)); + sym = OP_SYMBOL(IC_LEFT(ic)); + + if(IFFUNC_ISISR(sym->type /*ftype*/)) { + /* create an absolute section at the interrupt vector: + * that is 0x0008 for interrupt 1 (high), 0x0018 interrupt 2 (low) */ + symbol *asym; + char asymname[128]; + pBlock *apb; + + { + int i, found=-1; + + sym = OP_SYMBOL( IC_LEFT(ic)); + for(i=0;i<=2;i++) { + if(interrupts[i]->name + && !STRCASECMP(interrupts[i]->name, sym->name)) { + found = i; + break; + } + } + + if(found == -1) { + fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n", + __FILE__, __LINE__, sym->name); + assert( 0 ); + } + _G.interruptvector = found; + } - DEBUGpic16_emitcode ("; ***","%s %d curr label offset=%dprevious max_key=%d ",__FUNCTION__,__LINE__,labelOffset,max_key); + sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name); + asym = newSymbol(asymname, 0); - labelOffset += (max_key+4); - max_key=0; - GpsuedoStkPtr=0; - _G.nRegsSaved = 0; - /* create the function header */ - pic16_emitcode(";","-----------------------------------------"); - pic16_emitcode(";"," function %s",(sym = OP_SYMBOL(IC_LEFT(ic)))->name); - pic16_emitcode(";","-----------------------------------------"); + apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section")); + pic16_addpBlock( apb ); - pic16_emitcode("","%s:",sym->rname); - pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,sym->rname)); + pic16_addpCode2pBlock(apb, + pic16_newpCodeCharP(";-----------------------------------------")); - ftype = operandType(IC_LEFT(ic)); - /* if critical function then turn interrupts off */ - if (IFFUNC_ISCRITICAL(ftype)) - pic16_emitcode("clr","ea"); + pic16_addpCode2pBlock(apb, pic16_newpCodeFunction(moduleName, asym->name)); - /* here we need to generate the equates for the - register bank if required */ -#if 0 - if (FUNC_REGBANK(ftype) != rbank) { - int i ; - - rbank = FUNC_REGBANK(ftype); - for ( i = 0 ; i < pic16_nRegs ; i++ ) { - if (strcmp(regspic16[i].base,"0") == 0) - pic16_emitcode("","%s = 0x%02x", - regspic16[i].dname, - 8*rbank+regspic16[i].offset); - else - pic16_emitcode ("","%s = %s + 0x%02x", - regspic16[i].dname, - regspic16[i].base, - 8*rbank+regspic16[i].offset); - } - } -#endif + 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)); - /* if this is an interrupt service routine then - save acc, b, dpl, dph */ - if (IFFUNC_ISISR(sym->type)) { + { + absSym *abSym; + + abSym = Safe_calloc(1, sizeof(absSym)); + abSym->name = Safe_strdup( asymname ); + + switch( _G.interruptvector ) { + case 0: abSym->address = 0x000000; break; + case 1: abSym->address = 0x000008; break; + case 2: abSym->address = 0x000018; break; + } + + /* relocate interrupt vectors if needed */ + abSym->address += pic16_options.ivt_loc; + + addSet(&absSymSet, abSym); + } + } + + + /* create the function header */ + pic16_emitcode(";","-----------------------------------------"); + pic16_emitcode(";"," function %s",sym->name); + pic16_emitcode(";","-----------------------------------------"); + + pic16_emitcode("","%s:",sym->rname); + pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(moduleName,sym->rname)); -#if 0 - pic16_addpCode2pBlock(pb,pic16_newpCode(POC_BRA,pic16_newpCodeOp("END_OF_INTERRUPT+2",PO_STR))); - - /* what is the reason of having these 3 NOPS? VR - 030701 */ - pic16_emitpcodeNULLop(POC_NOP); - pic16_emitpcodeNULLop(POC_NOP); - pic16_emitpcodeNULLop(POC_NOP); -#endif - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_wsave)); - pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_status)); - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_ssave)); - - pic16_pBlockConvert2ISR(pb); -#if 0 - if (!inExcludeList("acc")) - pic16_emitcode ("push","acc"); - if (!inExcludeList("b")) - pic16_emitcode ("push","b"); - if (!inExcludeList("dpl")) - pic16_emitcode ("push","dpl"); - if (!inExcludeList("dph")) - pic16_emitcode ("push","dph"); - if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) { - pic16_emitcode ("push", "dpx"); - /* Make sure we're using standard DPTR */ - pic16_emitcode ("push", "dps"); - pic16_emitcode ("mov", "dps, #0x00"); - if (options.stack10bit) - { - /* This ISR could conceivably use DPTR2. Better save it. */ - pic16_emitcode ("push", "dpl1"); - pic16_emitcode ("push", "dph1"); - pic16_emitcode ("push", "dpx1"); - } + absSym *ab; + + for(ab = setFirstItem(absSymSet); ab; ab = setNextItem(absSymSet)) + if(!strcmp(ab->name, sym->name)) { + pic16_pBlockConvert2Absolute(pb); + break; + } + } - /* if this isr has no bank i.e. is going to - run with bank 0 , then we need to save more - registers :-) */ - if (!FUNC_REGBANK(sym->type)) { - /* if this function does not call any other - function then we can be economical and - save only those registers that are used */ - if (! IFFUNC_HASFCALL(sym->type)) { - int i; + if(IFFUNC_ISNAKED(ftype)) { + DEBUGpic16_emitcode("; ***", "_naked function, no prologue"); + return; + } + + /* if critical function then turn interrupts off */ + if (IFFUNC_ISCRITICAL(ftype)) { + //pic16_emitcode("clr","ea"); + } + + _G.fregsUsed = sym->regsUsed; + + /* if this is an interrupt service routine then + * save acc, b, dpl, dph */ + if (IFFUNC_ISISR(sym->type)) { + int i; + + _G.usefastretfie = 1; /* use shadow registers by default */ + /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */ + if(!(_G.interruptvector == 1)) { + + /* do not save WREG,STATUS,BSR for high priority interrupts + * because they are stored in the hardware shadow registers already */ + _G.usefastretfie = 0; + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_wreg )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_status )); + pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_bsr )); + } + + + /* 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 */ - for ( i = 0 ; i < sym->regsUsed->size ; i++) { - if (bitVectBitValue(sym->regsUsed,i) || - (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - pic16_emitcode("push","junk");//"%s",pic16_regWithIdx(i)->dname); - } - } - - } else { - /* this function has a function call cannot - determines register usage so we will have the - entire bank */ - saverbank(0,ic,FALSE); - } - } + /* save the registers used */ + DEBUGpic16_emitcode("; **", "Saving used registers in stack"); + for ( i = 0 ; i < sym->regsUsed->size ; i++) { + if (bitVectBitValue(sym->regsUsed,i)) { +#if 0 + fprintf(stderr, "%s:%d function %s uses register %s\n", + __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, + pic16_regWithIdx(i)->name); #endif - } else { - /* 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 any registers used */ - if (sym->regsUsed) { - /* save the registers used */ - for ( i = 0 ; i < sym->regsUsed->size ; i++) { - if (bitVectBitValue(sym->regsUsed,i) || - (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) { - //pic16_emitcode("push","%s",pic16_regWithIdx(i)->dname); - _G.nRegsSaved++; - } + + pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); + _G.nRegsSaved++; + + if(!pic16_regWithIdx(i)->wasUsed) { + fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n", + __FILE__, __LINE__, pic16_regWithIdx(i)->name); + + pic16_regWithIdx(i)->wasUsed = 1; + } + } + } + } + } else { + /* 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*/1) { + /* 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)); + } } - } - } - } - /* set the register bank to the desired value */ - if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) { - pic16_emitcode("push","psw"); - pic16_emitcode("mov","psw,#0x%02x",(FUNC_REGBANK(sym->type) << 3)&0x00ff); - } + /* 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) { +// fprintf(stderr, "%s:%d function sym->regsUsed= %d\n", __FILE__, __LINE__, sym->regsUsed->size); - 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); - } +// pic16_emitpcomment("entry regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1); - /* adjust the stack for the function */ - if (sym->stack) { + /* 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)) { - int i = sym->stack; - if (i > 256 ) - werror(W_STACK_OVERFLOW,sym->name); +#if 0 + fprintf(stderr, "%s:%d function %s uses register %s (wasUsed: %d, %p)\n", + __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, + pic16_regWithIdx(i)->name, + pic16_regWithIdx(i)->wasUsed, + pic16_regWithIdx(i)); +#endif - if (i > 3 && sym->recvSize < 4) { + pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); - pic16_emitcode ("mov","a,sp"); - pic16_emitcode ("add","a,#0x%02x",((char)sym->stack & 0xff)); - pic16_emitcode ("mov","sp,a"); - +// pic16_emitpcode(POC_MOVFF, pic16_popCombine2( +// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), +// &pic16_pc_postdec1, 0)); + + _G.nRegsSaved++; + + if(!pic16_regWithIdx(i)->wasUsed) { + fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n", + __FILE__, __LINE__, pic16_regWithIdx(i)->name); + + pic16_regWithIdx(i)->wasUsed = 1; + } + + } + } + } + } + } + + + +#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); } - else - while(i--) - pic16_emitcode("inc","sp"); - } +#endif + DEBUGpic16_emitcode("; ", "need to adjust stack = %d", sym->stack); - if (sym->xstack) { + /* adjust the stack for the function */ + if (sym->stack) { + int i = sym->stack; - pic16_emitcode ("mov","a,_spx"); - pic16_emitcode ("add","a,#0x%02x",((char)sym->xstack & 0xff)); - pic16_emitcode ("mov","_spx,a"); - } + 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"); + } + } /*-----------------------------------------------------------------*/ @@ -2841,10 +3594,27 @@ static void genEndFunction (iCode *ic) DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(IFFUNC_ISNAKED(sym->type)) { + DEBUGpic16_emitcode("; ***", "_naked function, no epilogue"); + return; + } + + _G.stack_lat = 0; + + /* 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) { pic16_emitcode ("mov","%s,_bp",spname); } +#endif /* if use external stack but some variables were added to the local stack then decrement the @@ -2856,6 +3626,7 @@ static void genEndFunction (iCode *ic) } +#if 0 if ((IFFUNC_ISREENT(sym->type) || options.stackAuto)) { if (options.useXstack) { pic16_emitcode("mov","r0,%s",spname); @@ -2868,135 +3639,140 @@ static void genEndFunction (iCode *ic) pic16_emitcode ("pop","_bp"); } } +#endif - /* restore the register bank */ - if (FUNC_REGBANK(sym->type) || FUNC_ISISR(sym->type)) - pic16_emitcode ("pop","psw"); - - if (IFFUNC_ISISR(sym->type)) { - - /* now we need to restore the registers */ - /* if this isr has no bank i.e. is going to - run with bank 0 , then we need to save more - registers :-) */ - if (!FUNC_REGBANK(sym->type)) { - - /* if this function does not call any other - function then we can be economical and - save only those registers that are used */ - if (! IFFUNC_HASFCALL(sym->type)) { - int i; - + if (IFFUNC_ISISR(sym->type)) { + /* now we need to restore the registers */ /* if any registers used */ if (sym->regsUsed) { - /* save the registers used */ - for ( i = sym->regsUsed->size ; i >= 0 ; i--) { - if (bitVectBitValue(sym->regsUsed,i) || - (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname); - } - } - - } else { - /* this function has a function call cannot - determines register usage so we will have the - entire bank */ - unsaverbank(0,ic,FALSE); - } - } -#if 0 - if (options.model == MODEL_FLAT24 && !inExcludeList("dpx")) - { - if (options.stack10bit) - { - pic16_emitcode ("pop", "dpx1"); - pic16_emitcode ("pop", "dph1"); - pic16_emitcode ("pop", "dpl1"); - } - pic16_emitcode ("pop", "dps"); - pic16_emitcode ("pop", "dpx"); - } - if (!inExcludeList("dph")) - pic16_emitcode ("pop","dph"); - if (!inExcludeList("dpl")) - pic16_emitcode ("pop","dpl"); - if (!inExcludeList("b")) - pic16_emitcode ("pop","b"); - if (!inExcludeList("acc")) - pic16_emitcode ("pop","acc"); - - if (IFFUNC_ISCRITICAL(sym->type)) - pic16_emitcode("setb","ea"); -#endif + int i; - /* if debug then send end of function */ -/* if (options.debug && currFunc) { */ - if (currFunc) { - _G.debugLine = 1; - pic16_emitcode(";","C$%s$%d$%d$%d ==.", - FileBaseName(ic->filename),currFunc->lastLine, - ic->level,ic->block); - if (IS_STATIC(currFunc->etype)) - pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); - else - pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name); - _G.debugLine = 0; - } + /* restore registers used */ + DEBUGpic16_emitcode("; **", "Restoring used registers from stack"); + for ( i = sym->regsUsed->size; i >= 0; i--) { + if (bitVectBitValue(sym->regsUsed,i)) { + +// fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n", +// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, +// pic16_regWithIdx(i)->name); + + pic16_poppCodeOp( pic16_popRegFromIdx(i) ); + +// pic16_emitpcode(POC_MOVFF, pic16_popCombine2( +// &pic16_pc_preinc1, +// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0)); + + } + } + } -// pic16_emitcode ("reti",""); + 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 */ - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_status)); - pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_ssave)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_status)); - pic16_emitpcode(POC_SWAPF, pic16_popCopyReg(&pic16_pc_wsave)); - pic16_emitpcode(POC_SWAPFW, pic16_popCopyReg(&pic16_pc_wsave)); +// pic16_pBlockConvert2ISR(pb); -#if 0 - pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("END_OF_INTERRUPT",-1)); -#endif - pic16_emitpcodeNULLop(POC_RETFIE); + /* if debug then send end of function */ +/* if (options.debug && currFunc) */ + if (currFunc) { + debugFile->writeEndFunction (currFunc, ic, 1); + } + + if(_G.usefastretfie) + pic16_emitpcode(POC_RETFIE, pic16_newpCodeOpLit(1)); + else + pic16_emitpcodeNULLop(POC_RETFIE); + _G.usefastretfie = 0; + } else { + if (IFFUNC_ISCRITICAL(sym->type)) + pic16_emitcode("setb","ea"); + - } - else { - if (IFFUNC_ISCRITICAL(sym->type)) - pic16_emitcode("setb","ea"); +// pic16_emitpcomment("exit regsUsed: %d\n", sym->regsUsed?sym->regsUsed->size:-1); + + /* if any registers used */ + if (sym->regsUsed) { + int i; + /* save the registers used */ + DEBUGpic16_emitcode("; **", "Restoring used registers from stack"); + for ( i = sym->regsUsed->size; i >= 0; i--) { + if (bitVectBitValue(sym->regsUsed,i)) { - if (IFFUNC_CALLEESAVES(sym->type)) { - int i; - - /* if any registers used */ - if (sym->regsUsed) { - /* save the registers used */ - for ( i = sym->regsUsed->size ; i >= 0 ; i--) { - if (bitVectBitValue(sym->regsUsed,i) || - (pic16_ptrRegReq && (i == R0_IDX || i == R1_IDX)) ) - pic16_emitcode("pop","junk");//"%s",pic16_regWithIdx(i)->dname); +// fprintf(stderr, "%s:%d function %s uses register %s (restoring)\n", +// __FILE__, __LINE__, OP_SYMBOL(IC_LEFT(ic))->name, +// pic16_regWithIdx(i)->name); + + pic16_poppCodeOp( pic16_popRegFromIdx(i) ); + +// pic16_emitpcode(POC_MOVFF, pic16_popCombine2( +// &pic16_pc_preinc1, +// PCOR(pic16_popCopyReg( PCOR(pic16_popRegFromIdx(i)))), 0)); + + _G.nRegsSaved--; + } + } + } + +// pic16_emitpcomment("%s: _G.nRegsSaved upon exit from function: %d\n", __FUNCTION__, _G.nRegsSaved); + /* if debug then send end of function */ + if (currFunc) { + debugFile->writeEndFunction (currFunc, ic, 1); } - } - - } - /* if debug then send end of function */ - if (currFunc) { - _G.debugLine = 1; - pic16_emitcode(";","C$%s$%d$%d$%d ==.", - FileBaseName(ic->filename),currFunc->lastLine, - ic->level,ic->block); - if (IS_STATIC(currFunc->etype)) - pic16_emitcode(";","XF%s$%s$0$0 ==.",moduleName,currFunc->name); - else - pic16_emitcode(";","XG$%s$0$0 ==.",currFunc->name); - _G.debugLine = 0; + /* 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_emitpcodeNULLop(POC_RETURN); + + /* Mark the end of a function */ + pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL)); } - pic16_emitcode ("return",""); - pic16_emitpcodeNULLop(POC_RETURN); +} - /* Mark the end of a function */ - pic16_addpCode2pBlock(pb,pic16_newpCodeFunction(NULL,NULL)); - } +void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest) +{ + + if(is_LitOp(op)) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); // patch 12 + + if(dest->type != PO_WREG) + pic16_emitpcode(POC_MOVWF, dest); + } else { + if(dest->type == PO_WREG && (offset == 0)) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset)); + return; + } + + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popGet(AOP(op), offset), dest)); + } } /*-----------------------------------------------------------------*/ @@ -3004,66 +3780,122 @@ static void genEndFunction (iCode *ic) /*-----------------------------------------------------------------*/ static void genRet (iCode *ic) { - int size,offset = 0 , pushed = 0; - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if we have no return value then - just generate the "ret" */ - if (!IC_LEFT(ic)) - goto jumpret; - - /* we have something to return then - move the return value into place */ - pic16_aopOp(IC_LEFT(ic),ic,FALSE); - size = AOP_SIZE(IC_LEFT(ic)); + int size; + operand *left; + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* if we have no return value then + * just generate the "ret" */ + + if (!IC_LEFT(ic)) + goto jumpret; - while (size--) { - char *l ; - if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) { - /* #NOCHANGE */ - l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, - FALSE,TRUE); - pic16_emitcode("push","%s",l); - pushed++; - } else { - l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, - FALSE,FALSE); - if (strcmp(fReturn[offset],l)) { - if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) || - ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) { - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); - }else { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); + /* we have something to return then + * move the return value into place */ + pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE); + size = AOP_SIZE(IC_LEFT(ic)); + + if(size <= 4) { + if(size>3) { + pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l)); +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l))); + } + if(size>2) { + pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh)); +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh))); + } + if(size>1) { + pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl)); +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl))); + } + +// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12 + + pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12 +// pic16_emitpcode(POC_MOVFF, +// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg))); + + } else { + /* >32-bits, setup stack and FSR0 */ + while (size--) { +// DEBUGpic16_emitcode("; ", "POC_MOVLW %d", GpsuedoStkPtr); +// DEBUGpic16_emitcode("; ", "POC_MOVFW PLUSW2"); + + pic16_pushpCodeOp( pic16_popGet( AOP( IC_LEFT(ic) ), size) ); + +// popaopidx(AOP(oper), size, GpseudoStkPtr); + GpsuedoStkPtr++; + } + + /* setup FSR0 */ + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l))); + + if(STACK_MODEL_LARGE) { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg(&pic16_pc_fsr1h), pic16_popCopyReg(&pic16_pc_fsr0h))); + } else { + pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) ); + } } - if(size) { - pic16_emitpcode(POC_MOVWF,popRegFromIdx(offset + pic16_Gstack_base_addr)); + +#if 0 + /* old code, left here for reference -- VR */ + while (size--) { + char *l ; + + if (AOP_TYPE(IC_LEFT(ic)) == AOP_DPTR) { + /* #NOCHANGE */ + l = pic16_aopGet(AOP(IC_LEFT(ic)),offset++, FALSE,TRUE); + pic16_emitpcomment("push %s",l); + pushed++; + } else { + DEBUGpic16_emitcode(";", "%d", __LINE__); + l = pic16_aopGet(AOP(IC_LEFT(ic)),offset, FALSE,FALSE); + DEBUGpic16_emitcode(";", "%d l= %s", __LINE__, l); + + if (strcmp(fReturn[offset],l)) { + if( ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) + || ((AOP(IC_LEFT(ic))->type) == AOP_LIT) ) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); + } else { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); + } + + if(size) { + pic16_emitpcode(POC_MOVWF, pic16_popRegFromIdx(offset + pic16_Gstack_base_addr)); + } + offset++; + } + } + } + + if (pushed) { + while(pushed) { + pushed--; + if (strcmp(fReturn[pushed],"a")) + pic16_emitcode("pop",fReturn[pushed]); + else + pic16_emitcode("pop","acc"); + } } - offset++; - } - } - } +#endif - if (pushed) { - while(pushed) { - pushed--; - if (strcmp(fReturn[pushed],"a")) - pic16_emitcode("pop",fReturn[pushed]); - else - pic16_emitcode("pop","acc"); - } - } - pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE); + + pic16_freeAsmop (IC_LEFT(ic),NULL,ic,TRUE); - jumpret: - /* generate a jump to the return label - if the next is not the return statement */ - if (!(ic->next && ic->next->op == LABEL && - IC_LABEL(ic->next) == returnLabel)) { +jumpret: + /* generate a jump to the return label + * if the next is not the return statement */ + if (!(ic->next && ic->next->op == LABEL + && IC_LABEL(ic->next) == returnLabel)) { - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key)); - pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset); - } - + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(returnLabel->key)); + pic16_emitcode("goto","_%05d_DS_",returnLabel->key+100 + pic16_labelOffset); + } } /*-----------------------------------------------------------------*/ @@ -3071,13 +3903,15 @@ static void genRet (iCode *ic) /*-----------------------------------------------------------------*/ static void genLabel (iCode *ic) { + + /* special case never generate */ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if (IC_LABEL(ic) == entryLabel) return ; pic16_emitpLabel(IC_LABEL(ic)->key); - pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + labelOffset)); + pic16_emitcode("","_%05d_DS_:",(IC_LABEL(ic)->key+100 + pic16_labelOffset)); } /*-----------------------------------------------------------------*/ @@ -3087,7 +3921,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); } @@ -3117,10 +3951,6 @@ static void genMultOneByte (operand *left, operand *right, operand *result) { - sym_link *opetype = operandType(result); - - // symbol *lbl ; - int size,offset; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); DEBUGpic16_pic16_AopType(__LINE__,left,right,result); @@ -3134,129 +3964,159 @@ static void genMultOneByte (operand *left, left = t; } - size = AOP_SIZE(result); - if(size == 1) { - - if (AOP_TYPE(right) == AOP_LIT){ - pic16_emitcode("multiply ","lit val:%s by variable %s and store in %s", - pic16_aopGet(AOP(right),0,FALSE,FALSE), - pic16_aopGet(AOP(left),0,FALSE,FALSE), - pic16_aopGet(AOP(result),0,FALSE,FALSE)); - pic16_emitcode("call","genMultLit"); - } else { - pic16_emitcode("multiply ","variable :%s by variable %s and store in %s", - pic16_aopGet(AOP(right),0,FALSE,FALSE), - pic16_aopGet(AOP(left),0,FALSE,FALSE), - pic16_aopGet(AOP(result),0,FALSE,FALSE)); - pic16_emitcode("call","pic16_genMult8X8_8"); - - } - pic16_genMult8X8_8 (left, right,result); + /* size is already checked in genMult == 1 */ +// size = AOP_SIZE(result); + if (AOP_TYPE(right) == AOP_LIT){ + pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); + } else { + pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); + } + + pic16_genMult8X8_8 (left, right,result); +} - /* signed or unsigned */ - //pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE)); - //l = pic16_aopGet(AOP(left),0,FALSE,FALSE); - //MOVA(l); - //pic16_emitcode("mul","ab"); - /* if result size = 1, mul signed = mul unsigned */ - //pic16_aopPut(AOP(result),"a",0); +/*-----------------------------------------------------------------*/ +/* genMultOneWord : 16 bit multiplication */ +/*-----------------------------------------------------------------*/ +static void genMultOneWord (operand *left, + operand *right, + operand *result) +{ - } else { // (size > 1) + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result); + + /* (if two literals, the value is computed before) + * if one literal, literal on the right */ + if (AOP_TYPE(left) == AOP_LIT){ + operand *t = right; + right = left; + left = t; + } - pic16_emitcode("multiply (size>1) ","variable :%s by variable %s and store in %s", - pic16_aopGet(AOP(right),0,FALSE,FALSE), - pic16_aopGet(AOP(left),0,FALSE,FALSE), - pic16_aopGet(AOP(result),0,FALSE,FALSE)); + /* size is checked already == 2 */ +// size = AOP_SIZE(result); - if (SPEC_USIGN(opetype)){ - pic16_emitcode("multiply ","unsigned result. size = %d",AOP_SIZE(result)); - pic16_genUMult8X8_16 (left, right, result, NULL); + if (AOP_TYPE(right) == AOP_LIT) { + pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); + } else { + pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); + } + + pic16_genMult16X16_16(left, right,result); +} - if (size > 2) { - /* for filling the MSBs */ - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),2)); - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),3)); - } - } - else{ - pic16_emitcode("multiply ","signed result. size = %d",AOP_SIZE(result)); +/*-----------------------------------------------------------------*/ +/* genMultOneLong : 32 bit multiplication */ +/*-----------------------------------------------------------------*/ +static void genMultOneLong (operand *left, + operand *right, + operand *result) +{ - pic16_emitcode("mov","a,b"); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + DEBUGpic16_pic16_AopTypeSign(__LINE__,left,right,result); + + /* (if two literals, the value is computed before) + * if one literal, literal on the right */ + if (AOP_TYPE(left) == AOP_LIT){ + operand *t = right; + right = left; + left = t; + } - /* adjust the MSB if left or right neg */ + /* size is checked already == 4 */ +// size = AOP_SIZE(result); - /* if one literal */ - if (AOP_TYPE(right) == AOP_LIT){ - pic16_emitcode("multiply ","right is a lit"); - /* AND literal negative */ - if((int) floatFromVal (AOP(right)->aopu.aop_lit) < 0){ - /* adjust MSB (c==0 after mul) */ - pic16_emitcode("subb","a,%s", pic16_aopGet(AOP(left),0,FALSE,FALSE)); + if (AOP_TYPE(right) == AOP_LIT) { + pic16_emitpcomment("multiply lit val:%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); + } else { + pic16_emitpcomment("multiply variable :%s by variable %s and store in %s", + pic16_aopGet(AOP(right),0,FALSE,FALSE), + pic16_aopGet(AOP(left),0,FALSE,FALSE), + pic16_aopGet(AOP(result),0,FALSE,FALSE)); } - } - else{ - pic16_genSMult8X8_16 (left, right, result, NULL); - } + + pic16_genMult32X32_32(left, right,result); +} - if(size > 2){ - pic16_emitcode("multiply ","size is greater than 2, so propogate sign"); - /* get the sign */ - pic16_emitcode("rlc","a"); - pic16_emitcode("subb","a,acc"); - } - } - size -= 2; - offset = 2; - if (size > 0) - while (size--) - pic16_emitcode("multiply ","size is way greater than 2, so propogate sign"); - //pic16_aopPut(AOP(result),"a",offset++); - } -} /*-----------------------------------------------------------------*/ /* genMult - generates code for multiplication */ /*-----------------------------------------------------------------*/ static void genMult (iCode *ic) { - operand *left = IC_LEFT(ic); - operand *right = IC_RIGHT(ic); - operand *result= IC_RESULT(ic); - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* assign the amsops */ - pic16_aopOp (left,ic,FALSE); - pic16_aopOp (right,ic,FALSE); - pic16_aopOp (result,ic,TRUE); + operand *left = IC_LEFT(ic); + operand *right = IC_RIGHT(ic); + operand *result= IC_RESULT(ic); - DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* assign the amsops */ + pic16_aopOp (left,ic,FALSE); + pic16_aopOp (right,ic,FALSE); + pic16_aopOp (result,ic,TRUE); + + DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + + /* special cases first * + * both are bits */ + if (AOP_TYPE(left) == AOP_CRY + && AOP_TYPE(right)== AOP_CRY) { + genMultbits(left,right,result); + goto release ; + } - /* special cases first */ - /* both are bits */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right)== AOP_CRY) { - genMultbits(left,right,result); - goto release ; - } + /* if both are of size == 1 */ + if(AOP_SIZE(left) == 1 + && AOP_SIZE(right) == 1) { + genMultOneByte(left,right,result); + goto release ; + } - /* if both are of size == 1 */ - if (AOP_SIZE(left) == 1 && - AOP_SIZE(right) == 1 ) { - genMultOneByte(left,right,result); - goto release ; - } + /* if both are of size == 2 */ + if(AOP_SIZE(left) == 2 + && AOP_SIZE(right) == 2) { + genMultOneWord(left, right, result); + goto release; + } + + /* if both are of size == 4 */ + if(AOP_SIZE(left) == 4 + && AOP_SIZE(right) == 4) { + genMultOneLong(left, right, result); + goto release; + } + + pic16_emitcode("multiply ","sizes are greater than 4 ... need to insert proper algor."); - pic16_emitcode("multiply ","sizes are greater than 2... need to insert proper algor."); - /* should have been converted to function call */ - //assert(0) ; + fprintf(stderr, "operand sizes result: %d left: %d right: %d\n", AOP_SIZE(result), AOP_SIZE(left), AOP_SIZE(right)); + /* should have been converted to function call */ + assert(0) ; release : - pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); - pic16_freeAsmop(result,NULL,ic,TRUE); + pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -3293,19 +4153,83 @@ static void genDivOneByte (operand *left, symbol *lbl ; int size,offset; + /* result = divident / divisor + * - divident may be a register or a literal, + * - divisor may be a register or a literal, + * so there are 3 cases (literal / literal is optimized + * by the front-end) to handle. + * In addition we must handle signed and unsigned, which + * result in 6 final different cases -- VR */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); size = AOP_SIZE(result) - 1; offset = 1; /* signed or unsigned */ if (SPEC_USIGN(opetype)) { + pCodeOp *pct1, /* count */ + *pct2, /* reste */ + *pct3; /* temp */ + symbol *label1, *label2, *label3;; + + /* unsigned is easy */ - pic16_emitcode("mov","b,%s", pic16_aopGet(AOP(right),0,FALSE,FALSE)); - l = pic16_aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - pic16_emitcode("div","ab"); - pic16_aopPut(AOP(result),"a",0); - while (size--) - pic16_aopPut(AOP(result),zero,offset++); + + pct1 = pic16_popGetTempReg(1); + pct2 = pic16_popGetTempReg(1); + pct3 = pic16_popGetTempReg(1); + + label1 = newiTempLabel(NULL); + label2 = newiTempLabel(NULL); + label3 = newiTempLabel(NULL); + + /* the following algorithm is extracted from divuint.c */ + + pic16_emitpcode(POC_MOVLW, pic16_popGetLit( 8 )); + pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct1 )); + + pic16_emitpcode(POC_CLRF, pic16_pCodeOpCopy( pct2 )); + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 0)); + + pic16_emitpLabel(label1->key); + + emitCLRC; + pic16_emitpcode(POC_RLCF, pic16_pCodeOpCopy( pct2 )); + + + emitCLRC; + pic16_emitpcode(POC_RLCF, pic16_popCopyReg( &pic16_pc_wreg )); + + + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy( pct2 )); + + pic16_emitpcode(POC_MOVWF, pic16_pCodeOpCopy( pct3 )); + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), 0)); + + pic16_emitpcode(POC_CPFSLT, pic16_pCodeOpCopy(pct2)); + pic16_emitpcode(POC_BRA, pic16_popGetLabel(label3->key)); + pic16_emitpcode(POC_BRA, pic16_popGetLabel(label2->key)); + + pic16_emitpLabel( label3->key ); + pic16_emitpcode(POC_SUBWF, pic16_pCodeOpCopy(pct2)); + pic16_emitpcode(POC_INCF, pic16_pCodeOpCopy(pct3)); + + + + pic16_emitpLabel(label2->key); + pic16_emitpcode(POC_MOVFW, pic16_pCodeOpCopy(pct3)); + pic16_emitpcode(POC_DECFSZ, pic16_pCodeOpCopy(pct1)); + pic16_emitpcode(POC_BRA, pic16_popGetLabel( label1->key )); + + /* result is in wreg */ + if(AOP_TYPE(result) != AOP_ACC) + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + + pic16_popReleaseTempReg( pct3, 1); + pic16_popReleaseTempReg( pct2, 1); + pic16_popReleaseTempReg( pct1, 1); + return ; } @@ -3374,6 +4298,12 @@ static void genDiv (iCode *ic) operand *right = IC_RIGHT(ic); operand *result= IC_RESULT(ic); + + /* Division is a very lengthy algorithm, so it is better + * to call support routines than inlining algorithm. + * Division functions written here just in case someone + * wants to inline and not use the support libraries -- VR */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* assign the amsops */ pic16_aopOp (left,ic,FALSE); @@ -3558,11 +4488,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 { @@ -3573,11 +4503,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); } @@ -3586,11 +4516,15 @@ static void genIfxJump (iCode *ic, char *jval) ic->generated = 1; } +#if 0 +// not needed ATM + /*-----------------------------------------------------------------*/ /* genSkip */ /*-----------------------------------------------------------------*/ static void genSkip(iCode *ifx,int status_bit) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(!ifx) return; @@ -3611,7 +4545,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 { @@ -3630,17 +4564,20 @@ static void genSkip(iCode *ifx,int status_bit) break; } pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key)); - pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset); + // pic16_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+pic16_labelOffset); } } +#endif /*-----------------------------------------------------------------*/ /* genSkipc */ /*-----------------------------------------------------------------*/ static void genSkipc(resolvedIfx *rifx) { + DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx); + if(!rifx) return; @@ -3649,7 +4586,7 @@ static void genSkipc(resolvedIfx *rifx) else emitSKPNC; - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rifx->lbl->key)); + pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rifx->lbl->key)); rifx->generated = 1; } @@ -3658,6 +4595,8 @@ static void genSkipc(resolvedIfx *rifx) /*-----------------------------------------------------------------*/ static void genSkipz2(resolvedIfx *rifx, int invert_condition) { + DEBUGpic16_emitcode ("; ***","%s %d rifx= %p",__FUNCTION__,__LINE__, rifx); + if(!rifx) return; @@ -3670,6 +4609,7 @@ static void genSkipz2(resolvedIfx *rifx, int invert_condition) rifx->generated = 1; } +#if 0 /*-----------------------------------------------------------------*/ /* genSkipz */ /*-----------------------------------------------------------------*/ @@ -3689,11 +4629,13 @@ 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 + /*-----------------------------------------------------------------*/ /* genSkipCond */ /*-----------------------------------------------------------------*/ @@ -3703,9 +4645,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)); @@ -3797,16 +4739,19 @@ static void genCmp (operand *left,operand *right, end the carry flag is set then we know that left is greater than right */ - // { - symbol *lbl = newiTempLabel(NULL); +#if 0 + fprintf(stderr, "%s:%s:%d truelbl: %d\tlbl: %d\n", + __FILE__, __FUNCTION__, __LINE__, truelbl->key+100+pic16_labelOffset, lbl->key+100+pic16_labelOffset); +#endif + #ifndef _swapp if(AOP_TYPE(right) == AOP_LIT) { //lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - DEBUGpic16_emitcode(";right lit","lit = 0x%x,sign=%d",lit,sign); + DEBUGpic16_emitcode(";right lit","%d lit = 0x%x,sign=%d",__LINE__, lit,sign); /* special cases */ @@ -3880,7 +4825,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 @@ -3950,7 +4895,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)); @@ -3961,7 +4906,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 @@ -4033,6 +4978,7 @@ static void genCmp (operand *left,operand *right, pic16_emitpLabel(lbl->key); +// pic16_emitpLabel(truelbl->key); //if(emitFinalCheck) genSkipc(&rFalseIfx); if(sign) @@ -4131,7 +5077,8 @@ static void genCmp (operand *left,operand *right, } if(ifx) ifx->generated = 1; - //goto check_carry; + if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) + goto check_carry; return; } else { @@ -4158,7 +5105,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)); } @@ -4201,7 +5148,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) @@ -4220,7 +5167,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 @@ -4308,7 +5255,7 @@ static void genCmp (operand *left,operand *right, pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); } else { /* this byte of the lit is zero, - *if it's not the last then OR in the variable */ + * if it's not the last then OR in the variable */ if(size) pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); } @@ -4318,6 +5265,7 @@ static void genCmp (operand *left,operand *right, pic16_emitpLabel(lbl->key); rFalseIfx.condition ^= 1; + genSkipc(&rFalseIfx); } @@ -4335,12 +5283,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, 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, 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, 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 */ @@ -4395,9 +5347,13 @@ static void genCmp (operand *left,operand *right, } - // check_carry: - if (AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) { +check_carry: + if ((AOP_TYPE(result) != AOP_CRY) + && AOP_SIZE(result)) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key ); + pic16_outBitC(result); } else { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -4472,6 +5428,10 @@ static void genCmpLt (iCode *ic, iCode *ifx) pic16_freeAsmop(result,NULL,ic,TRUE); } +#if 0 +// not needed ATM +// FIXME reenable literal optimisation when the pic16 port is stable + /*-----------------------------------------------------------------*/ /* genc16bit2lit - compare a 16 bit value to a literal */ /*-----------------------------------------------------------------*/ @@ -4522,7 +5482,10 @@ static void genc16bit2lit(operand *op, int lit, int offset) } } +#endif +#if 0 +// not needed ATM /*-----------------------------------------------------------------*/ /* gencjneshort - compare and jump if not equal */ /*-----------------------------------------------------------------*/ @@ -4533,15 +5496,18 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) int res_offset = 0; /* the result may be a different size then left or right */ int res_size = AOP_SIZE(result); resolvedIfx rIfx; - symbol *lbl; + symbol *lbl, *lbl_done; unsigned long lit = 0L; + int preserve_result = 0; /* don't touch result before we are done, if left/right == result */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); DEBUGpic16_pic16_AopType(__LINE__,left,right,result); if(result) DEBUGpic16_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__); resolveIfx(&rIfx,ifx); lbl = newiTempLabel(NULL); + lbl_done = newiTempLabel(NULL); /* if the left side is a literal or @@ -4556,16 +5522,28 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) if(AOP_TYPE(right) == AOP_LIT) lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + if ( regsInCommon(left, result) || regsInCommon(right, result) ) + preserve_result = 1; + + if(result && !preserve_result) + { + int i; + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + } + + /* if the right side is a literal then anything goes */ if (AOP_TYPE(right) == AOP_LIT && AOP_TYPE(left) != AOP_DIR ) { switch(size) { case 2: genc16bit2lit(left, lit, 0); - emitSKPNZ; + emitSKPZ; pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); break; default: + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); while (size--) { if(lit & 0xff) { pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset)); @@ -4574,7 +5552,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) pic16_emitpcode(POC_MOVF,pic16_popGet(AOP(left),offset)); } - emitSKPNZ; + emitSKPZ; pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); offset++; if(res_offset < res_size-1) @@ -4595,7 +5573,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) int lbl_key = lbl->key; if(result) { - pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset)); + // pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),res_offset)); //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset)); }else { DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__); @@ -4603,7 +5581,7 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) __FUNCTION__,__LINE__); return; } - + /* switch(size) { */ /* case 2: */ /* genc16bit2lit(left, lit, 0); */ @@ -4627,8 +5605,8 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) break; case 1: pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset)); - //pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); + //pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset)); + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl->key)); emit_skip=0; break; case 0xff: @@ -4704,17 +5682,38 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) } } - pic16_emitpcode(POC_INCF,pic16_popGet(AOP(result),res_offset)); + if(result && preserve_result) + { + int i; + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + } + + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); + + if(result && preserve_result) + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(lbl_done->key)); + if(!rIfx.condition) pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key)); pic16_emitpLabel(lbl->key); + if(result && preserve_result) + { + int i; + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + + pic16_emitpLabel(lbl_done->key); + } + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(ifx) ifx->generated = 1; } +#endif #if 0 /*-----------------------------------------------------------------*/ @@ -4739,6 +5738,143 @@ static void gencjne(operand *left, operand *right, iCode *ifx) } #endif + +/*-----------------------------------------------------------------*/ +/* is_LitOp - check if operand has to be treated as literal */ +/*-----------------------------------------------------------------*/ +static bool is_LitOp(operand *op) +{ + return (AOP_TYPE(op) == AOP_LIT) + || ( (AOP_TYPE(op) == AOP_PCODE) + && ( (AOP(op)->aopu.pcop->type == PO_LITERAL) + || (AOP(op)->aopu.pcop->type == PO_IMMEDIATE) )); +} + +/*-----------------------------------------------------------------*/ +/* is_LitAOp - check if operand has to be treated as literal */ +/*-----------------------------------------------------------------*/ +static bool is_LitAOp(asmop *aop) +{ + return (aop->type == AOP_LIT) + || ( (aop->type == AOP_PCODE) + && ( (aop->aopu.pcop->type == PO_LITERAL) + || (aop->aopu.pcop->type == PO_IMMEDIATE) )); +} + + + +/*-----------------------------------------------------------------*/ +/* genCmpEq - generates code for equal to */ +/*-----------------------------------------------------------------*/ +static void genCmpEq (iCode *ic, iCode *ifx) +{ + operand *left, *right, *result; + symbol *falselbl = newiTempLabel(NULL); + symbol *donelbl = newiTempLabel(NULL); + + int preserve_result = 0; + int generate_result = 0; + int i=0; + + pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE); + pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE); + pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + + if( (AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(left) == AOP_CRY) ) + { + DEBUGpic16_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__); + fprintf(stderr, "%s %d error - left/right CRY operands not supported\n",__FUNCTION__,__LINE__); + goto release; + } + + if (is_LitOp(left) || (AOP_TYPE(right) == AOP_ACC)) + { + operand *tmp = right ; + right = left; + left = tmp; + } + + if ( regsInCommon(left, result) || regsInCommon(right, result) ) + preserve_result = 1; + + if(result && AOP_SIZE(result)) + generate_result = 1; + + if(generate_result && !preserve_result) + { + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + } + + for(i=0; i < AOP_SIZE(left); i++) + { + if(AOP_TYPE(left) != AOP_ACC) + { + if(is_LitOp(left)) + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left), i)); + else + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), i)); + } + if(is_LitOp(right)) + pic16_emitpcode(POC_XORLW, pic16_popGet(AOP(right), i)); + else + pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right), i)); + + pic16_emitpcode(POC_BNZ,pic16_popGetLabel(falselbl->key)); + } + + // result == true + + if(generate_result && preserve_result) + { + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + } + + if(generate_result) + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result), 0)); // result = true + + if(generate_result && preserve_result) + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key)); + + if(ifx && IC_TRUE(ifx)) + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key)); + + if(ifx && IC_FALSE(ifx)) + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(donelbl->key)); + + pic16_emitpLabel(falselbl->key); + + // result == false + + if(ifx && IC_FALSE(ifx)) + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key)); + + if(generate_result && preserve_result) + { + for(i = 0; i < AOP_SIZE(result); i++) + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),i)); + } + + pic16_emitpLabel(donelbl->key); + + if(ifx) + ifx->generated = 1; + +release: + pic16_freeAsmop(left,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); + pic16_freeAsmop(result,NULL,ic,TRUE); + +} + + +#if 0 +// old version kept for reference + /*-----------------------------------------------------------------*/ /* genCmpEq - generates code for equal to */ /*-----------------------------------------------------------------*/ @@ -4747,6 +5883,8 @@ static void genCmpEq (iCode *ic, iCode *ifx) operand *left, *right, *result; unsigned long lit = 0L; int size,offset=0; + symbol *falselbl = newiTempLabel(NULL); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -4776,9 +5914,11 @@ static void genCmpEq (iCode *ic, iCode *ifx) if(ifx && !AOP_SIZE(result)){ symbol *tlbl; + DEBUGpic16_emitcode ("; ***","%s %d CASE 1",__FUNCTION__,__LINE__); /* if they are both bit variables */ if (AOP_TYPE(left) == AOP_CRY && ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) { + DEBUGpic16_emitcode ("; ***","%s %d CASE 11",__FUNCTION__,__LINE__); if(AOP_TYPE(right) == AOP_LIT){ unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); if(lit == 0L){ @@ -4807,98 +5947,104 @@ 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 */ - resolvedIfx rIfx; + { + /* left and right are both bit variables, result is carry */ + resolvedIfx rIfx; - resolveIfx(&rIfx,ifx); - - pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0)); - genSkipz2(&rIfx,0); - } + resolveIfx(&rIfx,ifx); + + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_ANDFW,pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_BTFSC,pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_ANDLW,pic16_popGet(AOP(left),0)); + genSkipz2(&rIfx,0); + } } else { - /* They're not both bit variables. Is the right a literal? */ - if(AOP_TYPE(right) == AOP_LIT) { - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - - switch(size) { - - case 1: - switch(lit & 0xff) { - case 1: - if ( IC_TRUE(ifx) ) { - pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset)); - emitSKPNZ; - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key)); - } else { - pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key)); - } - break; - case 0xff: - if ( IC_TRUE(ifx) ) { - pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset)); - emitSKPNZ; - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key)); - } else { - pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key)); - } - break; - default: - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset)); - if(lit) - pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff)); - genSkip(ifx,'z'); - } - + DEBUGpic16_emitcode ("; ***","%s %d CASE 12",__FUNCTION__,__LINE__); - /* end of size == 1 */ - break; + /* They're not both bit variables. Is the right a literal? */ + if(AOP_TYPE(right) == AOP_LIT) { + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + + switch(size) { + + case 1: + switch(lit & 0xff) { + case 1: + if ( IC_TRUE(ifx) ) { + pic16_emitpcode(POC_DECFW,pic16_popGet(AOP(left),offset)); + emitSKPNZ; + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key)); + } else { + pic16_emitpcode(POC_DECFSZW,pic16_popGet(AOP(left),offset)); + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key)); + } + break; + case 0xff: + if ( IC_TRUE(ifx) ) { + pic16_emitpcode(POC_INCFW,pic16_popGet(AOP(left),offset)); + emitSKPNZ; + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ifx)->key)); + } else { + pic16_emitpcode(POC_INCFSZW,pic16_popGet(AOP(left),offset)); + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ifx)->key)); + } + break; + default: + pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offset)); + if(lit) + pic16_emitpcode(POC_XORLW,pic16_popGetLit(lit & 0xff)); + genSkip(ifx,'z'); + } // switch lit + + + /* end of size == 1 */ + break; - case 2: - genc16bit2lit(left,lit,offset); - genSkip(ifx,'z'); - break; - /* end of size == 2 */ - - default: - /* size is 4 */ - if(lit==0) { - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1)); - pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2)); - pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3)); - - } else { - - /* search for patterns that can be optimized */ - - genc16bit2lit(left,lit,0); - lit >>= 16; - if(lit) { - genSkipz(ifx,IC_TRUE(ifx) == NULL); - //genSkip(ifx,'z'); - genc16bit2lit(left,lit,2); - } else { - pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2)); - pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3)); - - } - - } - - genSkip(ifx,'z'); - } + case 2: + genc16bit2lit(left,lit,offset); + genSkip(ifx,'z'); + break; + /* end of size == 2 */ + + default: + /* size is 4 */ + if(lit==0) { + pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),1)); + pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2)); + pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3)); + genSkip(ifx,'z'); + } else { + /* search for patterns that can be optimized */ + + genc16bit2lit(left,lit,0); + lit >>= 16; + if(lit) { + if(IC_TRUE(ifx)) + emitSKPZ; // if hi word unequal + else + emitSKPNZ; // if hi word equal + // fail early + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(falselbl->key)); + genc16bit2lit(left,lit,2); + genSkip(ifx,'z'); + } else { + pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),2)); + pic16_emitpcode(POC_IORFW,pic16_popGet(AOP(left),3)); + genSkip(ifx,'z'); + } + } + pic16_emitpLabel(falselbl->key); + break; + + } // switch size - ifx->generated = 1; - goto release ; + ifx->generated = 1; + goto release ; } else if(AOP_TYPE(right) == AOP_CRY ) { @@ -4918,11 +6064,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 { @@ -4938,23 +6084,33 @@ static void genCmpEq (iCode *ic, iCode *ifx) if ( IC_TRUE(ifx) ) { if(size) { emitSKPZ; + + 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; + + DEBUGpic16_emitcode (";","\tIC_TRUE 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; + + 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); } } } @@ -4966,6 +6122,7 @@ static void genCmpEq (iCode *ic, iCode *ifx) /* if they are both bit variables */ if (AOP_TYPE(left) == AOP_CRY && ((AOP_TYPE(right) == AOP_CRY) || (AOP_TYPE(right) == AOP_LIT))) { + DEBUGpic16_emitcode ("; ***","%s %d CASE 2",__FUNCTION__,__LINE__); if(AOP_TYPE(right) == AOP_LIT){ unsigned long lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); if(lit == 0L){ @@ -4998,7 +6155,7 @@ static void genCmpEq (iCode *ic, iCode *ifx) pic16_outBitC(result); } else { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d CASE 3",__FUNCTION__,__LINE__); gencjne(left,right,result,ifx); /* if(ifx) @@ -5035,6 +6192,7 @@ release: pic16_freeAsmop(right,NULL,ic,(RESULTONSTACK(ic) ? FALSE : TRUE)); pic16_freeAsmop(result,NULL,ic,TRUE); } +#endif /*-----------------------------------------------------------------*/ /* ifxForOp - returns the icode containing the ifx for operand */ @@ -5049,11 +6207,14 @@ static iCode *ifxForOp ( operand *op, iCode *ic ) /* if this has register type condition and the next instruction is ifx with the same operand and live to of the operand is upto the ifx only then */ - if (ic->next && - ic->next->op == IFX && - IC_COND(ic->next)->key == op->key && - OP_SYMBOL(op)->liveTo <= ic->next->seq ) - return ic->next; + if (ic->next + && ic->next->op == IFX + && IC_COND(ic->next)->key == op->key + && OP_SYMBOL(op)->liveTo <= ic->next->seq + ) { + DEBUGpic16_emitcode(";", "%d %s", __LINE__, __FUNCTION__); + return ic->next; + } if (ic->next && ic->next->op == IFX && @@ -5076,6 +6237,35 @@ static iCode *ifxForOp ( operand *op, iCode *ic ) ic->next->seq); } +#if 0 + /* the code below is completely untested + * it just allows ulong2fs.c compile -- VR */ + + ic = ic->next; + fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code\n", + __FILE__, __FUNCTION__, __LINE__); + + /* if this has register type condition and + the next instruction is ifx with the same operand + and live to of the operand is upto the ifx only then */ + if (ic->next && + ic->next->op == IFX && + IC_COND(ic->next)->key == op->key && + OP_SYMBOL(op)->liveTo <= ic->next->seq ) + return ic->next; + + if (ic->next && + ic->next->op == IFX && + IC_COND(ic->next)->key == op->key) { + DEBUGpic16_emitcode ("; WARNING ","%d IGNORING liveTo range in %s",__LINE__,__FUNCTION__); + return ic->next; + } + + fprintf(stderr, "WARNING (%s:%s:%d) untested hack might produce wrong code (returning NULL)\n", + __FILE__, __FUNCTION__, __LINE__); + +// return ic->next->next; /* this just might work */ /* FIXME FIXME */ +#endif return NULL; } @@ -5161,9 +6351,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); } @@ -5355,8 +6545,25 @@ static void genAnd (iCode *ic, iCode *ifx) pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key)); } */ + DEBUGpic16_emitcode("***", "%d %s", __LINE__, __FUNCTION__); + size = AOP_SIZE(left); + + { + int bp = posbit, ofs=0; + + while(bp > 7) { + bp -= 8; + ofs++; + } + + pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), + pic16_newpCodeOpBit(pic16_aopGet(AOP(left),ofs,FALSE,FALSE),bp,0, PO_GPR_REGISTER)); + + } +/* pic16_emitpcode(((rIfx.condition) ? POC_BTFSC : POC_BTFSS), pic16_newpCodeOpBit(pic16_aopGet(AOP(left),0,FALSE,FALSE),posbit,0)); +*/ pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rIfx.lbl->key)); ifx->generated = 1; @@ -5366,10 +6573,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) @@ -5379,22 +6613,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 ; } @@ -5420,7 +6659,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)); @@ -5724,7 +6963,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)); @@ -6073,36 +7312,43 @@ static void genXor (iCode *ic, iCode *ifx) /*-----------------------------------------------------------------*/ static void genInline (iCode *ic) { - char *buffer, *bp, *bp1; + char *buffer, *bp, *bp1; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - _G.inLine += (!options.asmpeep); + _G.inLine += (!options.asmpeep); - buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); - strcpy(buffer,IC_INLINE(ic)); + buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); + strcpy(buffer,IC_INLINE(ic)); - /* emit each line as a code */ - while (*bp) { - if (*bp == '\n') { - *bp++ = '\0'; +// fprintf(stderr, "%s:%d inline asm : < %s >\n", __FILE__, __LINE__, buffer); + + /* emit each line as a code */ + while (*bp) { + if (*bp == '\n') { + *bp++ = '\0'; + + if(*bp1) + pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process + bp1 = bp; + } else { + if (*bp == ':') { + bp++; + *bp = '\0'; + bp++; + + /* print label, use this special format with NULL directive + * to denote that the argument should not be indented with tab */ + pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(NULL, bp1)); // inline directly, no process + bp1 = bp; + } else + bp++; + } + } + + if ((bp1 != bp) && *bp1) + pic16_addpCode2pBlock(pb, pic16_newpCodeAsmDir(bp1, NULL)); // inline directly, no process - if(*bp1) - pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1)); - bp1 = bp; - } else { - if (*bp == ':') { - bp++; - *bp = '\0'; - bp++; - pic16_emitcode(bp1,""); - bp1 = bp; - } else - bp++; - } - } - if ((bp1 != bp) && *bp1) - pic16_addpCode2pBlock(pb,pic16_AssembleLine(bp1)); Safe_free(buffer); @@ -6117,6 +7363,8 @@ static void genRRC (iCode *ic) operand *left , *result ; int size, offset = 0, same; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* rotate right with carry */ left = IC_LEFT(ic); result=IC_RESULT(ic); @@ -6129,6 +7377,8 @@ static void genRRC (iCode *ic) size = AOP_SIZE(result); + DEBUGpic16_emitcode ("; ***","%s %d size:%d same:%d",__FUNCTION__,__LINE__,size,same); + /* get the lsb and put it into the carry */ pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),size-1)); @@ -6195,6 +7445,10 @@ static void genRLC (iCode *ic) pic16_freeAsmop(result,NULL,ic,TRUE); } + +/* gpasm can get the highest order bit with HIGH/UPPER + * so the following probably is not needed -- VR */ + /*-----------------------------------------------------------------*/ /* genGetHbit - generates code get highest order bit */ /*-----------------------------------------------------------------*/ @@ -6224,6 +7478,7 @@ static void genGetHbit (iCode *ic) pic16_freeAsmop(result,NULL,ic,TRUE); } +#if 0 /*-----------------------------------------------------------------*/ /* AccRol - rotate left accumulator by known count */ /*-----------------------------------------------------------------*/ @@ -6261,46 +7516,88 @@ static void AccRol (int shCount) break; } } +#endif /*-----------------------------------------------------------------*/ /* AccLsh - left shift accumulator by known count */ /*-----------------------------------------------------------------*/ static void AccLsh (int shCount) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(shCount != 0){ - if(shCount == 1) - pic16_emitcode("add","a,acc"); - else - if(shCount == 2) { - pic16_emitcode("add","a,acc"); - pic16_emitcode("add","a,acc"); - } else { - /* rotate left accumulator */ - AccRol(shCount); - /* and kill the lower order bits */ - pic16_emitcode("anl","a,#0x%02x", SLMask[shCount]); - } - } + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + switch(shCount){ + case 0 : + return; + break; + case 1 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 2 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 3 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 4 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 5 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 6 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 7 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + } + + pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount])); } /*-----------------------------------------------------------------*/ /* AccRsh - right shift accumulator by known count */ /*-----------------------------------------------------------------*/ -static void AccRsh (int shCount) +static void AccRsh (int shCount, int andmask) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(shCount != 0){ - if(shCount == 1){ - CLRC; - pic16_emitcode("rrc","a"); - } else { - /* rotate right accumulator */ - AccRol(8 - shCount); - /* and kill the higher order bits */ - pic16_emitcode("anl","a,#0x%02x", SRMask[shCount]); - } - } + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + switch(shCount){ + case 0 : + return; break; + case 1 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 2 : + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 3 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 4 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 5 : + pic16_emitpcode(POC_SWAPFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 6 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + case 7 : + pic16_emitpcode(POC_RLNCFW,pic16_popCopyReg(&pic16_pc_wreg)); + break; + } + + if(andmask) + pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SRMask[shCount])); + else + DEBUGpic16_emitcode("; ***", "%s omitting masking the result", __FUNCTION__); } #if 0 @@ -6334,6 +7631,7 @@ static void AccSRsh (int shCount) } } #endif + /*-----------------------------------------------------------------*/ /* shiftR1Left2Result - shift right one byte from left to result */ /*-----------------------------------------------------------------*/ @@ -6380,11 +7678,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)); @@ -6393,7 +7691,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; @@ -6406,7 +7704,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; @@ -6414,29 +7712,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)); } @@ -6496,8 +7794,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; @@ -6510,19 +7808,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: @@ -6638,11 +7936,23 @@ static void movLeft2Result (operand *left, int offl, static void shiftL2Left2Result (operand *left, int offl, operand *result, int offr, int shCount) { + int same = pic16_sameRegs(AOP(result), AOP(left)); + int i; + DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d offl:%d offr:%d",__FUNCTION__,__LINE__,shCount,same,offl,offr); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (same && (offl != offr)) { // shift bytes + if (offr > offl) { + for(i=1;i>-1;i--) { + pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i)); + pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i)); + } + } else { // just treat as different later on + same = 0; + } + } - if(pic16_sameRegs(AOP(result), AOP(left))) { + if(same) { switch(shCount) { case 0: break; @@ -6655,9 +7965,9 @@ static void shiftL2Left2Result (operand *left, int offl, pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16)); while(--shCount) { - emitCLRC; - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16)); + emitCLRC; + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr)); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16)); } break; @@ -6671,8 +7981,8 @@ static void shiftL2Left2Result (operand *left, int offl, pic16_emitpcode(POC_XORWF, pic16_popGet(AOP(result),offr)); pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offr+MSB16)); if(shCount >=5) { - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16)); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr)); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16)); } break; case 6: @@ -6711,9 +8021,9 @@ static void shiftL2Left2Result (operand *left, int offl, pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offr+MSB16)); while(--shCount) { - emitCLRC; - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16)); + emitCLRC; + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr)); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16)); } break; @@ -6724,14 +8034,14 @@ 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)); if(shCount == 5) { - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16)); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr)); + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offr+MSB16)); } break; case 6: @@ -6766,29 +8076,21 @@ static void shiftR2Left2Result (operand *left, int offl, operand *result, int offr, int shCount, int sign) { - int same=0; - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - same = pic16_sameRegs(AOP(result), AOP(left)); + int same = pic16_sameRegs(AOP(result), AOP(left)); + int i; + DEBUGpic16_emitcode ("; ***","%s %d shCount:%d same:%d sign:%d",__FUNCTION__,__LINE__,shCount,same,sign); - if(same && ((offl + MSB16) == offr)){ - same=1; - /* don't crash result[offr] */ - MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE)); - pic16_emitcode("xch","a,%s", pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } -/* else { - movLeft2Result(left,offl, result, offr); - MOVA(pic16_aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); + if (same && (offl != offr)) { // shift right bytes + if (offr < offl) { + for(i=0;i<2;i++) { + pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offl+i)); + pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offr+i)); + } + } else { // just treat as different later on + same = 0; + } } -*/ - /* a:x >> shCount (x = lsb(result))*/ -/* - if(sign) - AccAXRshS( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount); - else { - AccAXRsh( pic16_aopGet(AOP(result),offr,FALSE,FALSE) , shCount); -*/ + switch(shCount) { case 0: break; @@ -6812,9 +8114,9 @@ static void shiftR2Left2Result (operand *left, int offl, while(--shCount) { if(sign) - pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16)); + pic16_emitpcode(POC_RLCFW,pic16_popGet(AOP(result),offr+MSB16)); else - emitCLRC; + emitCLRC; pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr+MSB16)); pic16_emitpcode(POC_RRCF,pic16_popGet(AOP(result),offr)); } @@ -6851,7 +8153,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)); } @@ -6869,7 +8171,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)); @@ -6887,7 +8189,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)); @@ -6918,13 +8220,13 @@ static void shiftLLeftOrResult (operand *left, int offl, operand *result, int offr, int shCount) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE)); + + pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl)); /* shift left accumulator */ AccLsh(shCount); /* or with result */ - pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE)); /* back to result */ - pic16_aopPut(AOP(result),"a",offr); + pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr)); } /*-----------------------------------------------------------------*/ @@ -6934,13 +8236,13 @@ static void shiftRLeftOrResult (operand *left, int offl, operand *result, int offr, int shCount) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - MOVA(pic16_aopGet(AOP(left),offl,FALSE,FALSE)); + + pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl)); /* shift right accumulator */ - AccRsh(shCount); + AccRsh(shCount, 1); /* or with result */ - pic16_emitcode("orl","a,%s", pic16_aopGet(AOP(result),offr,FALSE,FALSE)); /* back to result */ - pic16_aopPut(AOP(result),"a",offr); + pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr)); } /*-----------------------------------------------------------------*/ @@ -6959,7 +8261,7 @@ static void genlshTwo (operand *result,operand *left, int shCount) { int size; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount); size = pic16_getDataSize(result); /* if shCount >= 8 */ @@ -6986,64 +8288,63 @@ static void genlshTwo (operand *result,operand *left, int shCount) /*-----------------------------------------------------------------*/ /* shiftLLong - shift left one long from left to result */ -/* offl = LSB or MSB16 */ +/* offr = LSB or MSB16 */ /*-----------------------------------------------------------------*/ static void shiftLLong (operand *left, operand *result, int offr ) { - char *l; int size = AOP_SIZE(result); + int same = pic16_sameRegs(AOP(left),AOP(result)); + int i; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(size >= LSB+offr){ - l = pic16_aopGet(AOP(left),LSB,FALSE,FALSE); - MOVA(l); - pic16_emitcode("add","a,acc"); - if (pic16_sameRegs(AOP(left),AOP(result)) && - size >= MSB16+offr && offr != LSB ) - pic16_emitcode("xch","a,%s", - pic16_aopGet(AOP(left),LSB+offr,FALSE,FALSE)); - else - pic16_aopPut(AOP(result),"a",LSB+offr); - } - - if(size >= MSB16+offr){ - if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB16+offr && offr != LSB) ) { - l = pic16_aopGet(AOP(left),MSB16,FALSE,FALSE); - MOVA(l); + DEBUGpic16_emitcode ("; ***","%s %d offr:%d size:%d",__FUNCTION__,__LINE__,offr,size); + + if (same && (offr == MSB16)) { //shift one byte + for(i=size-1;i>=MSB16;i--) { + pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),i-1)); + pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(left),i)); + } + } else { + pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),LSB+offr)); } - pic16_emitcode("rlc","a"); - if (pic16_sameRegs(AOP(left),AOP(result)) && - size >= MSB24+offr && offr != LSB) - pic16_emitcode("xch","a,%s", - pic16_aopGet(AOP(left),MSB16+offr,FALSE,FALSE)); - else - pic16_aopPut(AOP(result),"a",MSB16+offr); + + if (size > LSB+offr ){ + if (same) { + pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(left),LSB+offr)); + } else { + pic16_emitpcode(POC_ADDFW,pic16_popGet(AOP(left),LSB)); + pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),LSB+offr)); + } + } + + if(size > MSB16+offr){ + if (same) { + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB16+offr)); + } else { + pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB16)); + pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB16+offr)); + } } - if(size >= MSB24+offr){ - if (!(pic16_sameRegs(AOP(left),AOP(left)) && size >= MSB24+offr && offr != LSB)) { - l = pic16_aopGet(AOP(left),MSB24,FALSE,FALSE); - MOVA(l); - } - pic16_emitcode("rlc","a"); - if (pic16_sameRegs(AOP(left),AOP(result)) && - size >= MSB32+offr && offr != LSB ) - pic16_emitcode("xch","a,%s", - pic16_aopGet(AOP(left),MSB24+offr,FALSE,FALSE)); - else - pic16_aopPut(AOP(result),"a",MSB24+offr); + if(size > MSB24+offr){ + if (same) { + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB24+offr)); + } else { + pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB24)); + pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB24+offr)); + } } if(size > MSB32+offr){ - if (!(pic16_sameRegs(AOP(result),AOP(left)) && size >= MSB32+offr && offr != LSB)) { - l = pic16_aopGet(AOP(left),MSB32,FALSE,FALSE); - MOVA(l); - } - pic16_emitcode("rlc","a"); - pic16_aopPut(AOP(result),"a",MSB32+offr); + if (same) { + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(left),MSB32+offr)); + } else { + pic16_emitpcode(POC_RLCFW, pic16_popGet(AOP(left),MSB32)); + pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),MSB32+offr)); + } } if(offr != LSB) - pic16_aopPut(AOP(result),zero,LSB); + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB)); + } /*-----------------------------------------------------------------*/ @@ -7065,9 +8366,11 @@ static void genlshFour (operand *result, operand *left, int shCount) shiftL1Left2Result(left, LSB, result, MSB32, shCount); else movLeft2Result(left, LSB, result, MSB32); - pic16_aopPut(AOP(result),zero,LSB); - pic16_aopPut(AOP(result),zero,MSB16); - pic16_aopPut(AOP(result),zero,MSB32); + + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB)); + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16)); + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB24)); + return; } @@ -7082,8 +8385,8 @@ static void genlshFour (operand *result, operand *left, int shCount) movLeft2Result(left, MSB16, result, MSB32); movLeft2Result(left, LSB, result, MSB24); } - pic16_aopPut(AOP(result),zero,MSB16); - pic16_aopPut(AOP(result),zero,LSB); + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB)); + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),MSB16)); return; } @@ -7102,7 +8405,7 @@ static void genlshFour (operand *result, operand *left, int shCount) movLeft2Result(left, MSB24, result, MSB32); movLeft2Result(left, MSB16, result, MSB24); movLeft2Result(left, LSB, result, MSB16); - pic16_aopPut(AOP(result),zero,LSB); + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB)); } else if(shCount == 1) shiftLLong(left, result, MSB16); @@ -7110,107 +8413,294 @@ static void genlshFour (operand *result, operand *left, int shCount) shiftL2Left2Result(left, MSB16, result, MSB24, shCount); shiftL1Left2Result(left, LSB, result, MSB16, shCount); shiftRLeftOrResult(left, LSB, result, MSB24, 8 - shCount); - pic16_aopPut(AOP(result),zero,LSB); + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(result),LSB)); } } } - /* 1 <= shCount <= 7 */ - else if(shCount <= 2){ - shiftLLong(left, result, LSB); - if(shCount == 2) - shiftLLong(result, result, LSB); - } - /* 3 <= shCount <= 7, optimize */ - else{ - shiftL2Left2Result(left, MSB24, result, MSB24, shCount); - shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount); - shiftL2Left2Result(left, LSB, result, LSB, shCount); - } -} + /* 1 <= shCount <= 7 */ + else if(shCount <= 3) + { + shiftLLong(left, result, LSB); + while(--shCount >= 1) + shiftLLong(result, result, LSB); + } + /* 3 <= shCount <= 7, optimize */ + else{ + shiftL2Left2Result(left, MSB24, result, MSB24, shCount); + shiftRLeftOrResult(left, MSB16, result, MSB24, 8 - shCount); + shiftL2Left2Result(left, LSB, result, LSB, shCount); + } +} + +/*-----------------------------------------------------------------*/ +/* genLeftShiftLiteral - left shifting by known count */ +/*-----------------------------------------------------------------*/ +static void genLeftShiftLiteral (operand *left, + operand *right, + operand *result, + iCode *ic) +{ + int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit); + int size; + + DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount); + pic16_freeAsmop(right,NULL,ic,TRUE); + + pic16_aopOp(left,ic,FALSE); + pic16_aopOp(result,ic,FALSE); + + size = getSize(operandType(result)); + +#if VIEW_SIZE + pic16_emitcode("; shift left ","result %d, left %d",size, + AOP_SIZE(left)); +#endif + + /* I suppose that the left size >= result size */ + if(shCount == 0){ + while(size--){ + movLeft2Result(left, size, result, size); + } + } + + else if(shCount >= (size * 8)) + while(size--) + pic16_aopPut(AOP(result),zero,size); + else{ + switch (size) { + case 1: + genlshOne (result,left,shCount); + break; + + case 2: + case 3: + genlshTwo (result,left,shCount); + break; + + case 4: + genlshFour (result,left,shCount); + break; + } + } + pic16_freeAsmop(left,NULL,ic,TRUE); + 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) +{ + + 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 -/*-----------------------------------------------------------------*/ -/* genLeftShiftLiteral - left shifting by known count */ -/*-----------------------------------------------------------------*/ -static void genLeftShiftLiteral (operand *left, - operand *right, - operand *result, - iCode *ic) -{ - int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit); - int size; + 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__); - pic16_freeAsmop(right,NULL,ic,TRUE); + + 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; + } - pic16_aopOp(left,ic,FALSE); - pic16_aopOp(result,ic,FALSE); + //tlbl = newiTempLabel(NULL); + //offset = 0 ; + //tlbl1 = newiTempLabel(NULL); - size = getSize(operandType(result)); + //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)); -#if VIEW_SIZE - pic16_emitcode("; shift left ","result %d, left %d",size, - AOP_SIZE(left)); -#endif + //pic16_emitcode("","%05d_DS_:",tlbl1->key+100); + //pic16_emitcode("djnz","b,%05d_DS_",tlbl->key+100); - /* I suppose that the left size >= result size */ - if(shCount == 0){ - while(size--){ - movLeft2Result(left, size, result, size); - } - } - else if(shCount >= (size * 8)) - while(size--) - pic16_aopPut(AOP(result),zero,size); - else{ - switch (size) { - case 1: - genlshOne (result,left,shCount); - break; + tlbl = newiTempLabel(NULL); + tlbl1= newiTempLabel(NULL); - case 2: - case 3: - genlshTwo (result,left,shCount); - break; + size = AOP_SIZE(result); + offset = 1; - case 4: - genlshFour (result,left,shCount); - break; - } - } - pic16_freeAsmop(left,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); -} + pctemp = pic16_popGetTempReg(1); /* grab a temporary working register. */ -/*-----------------------------------------------------------------* - * 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) -{ + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - int offset = 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)); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_emitpcode(POC_MOVWF, pctemp); - if(!reg) - return; - if(!endian) { - endian = 1; - } else { - endian = -1; - offset = size-1; - } + pic16_emitpLabel(tlbl->key); + + emitCLRC; + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0)); + while(--size) + pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),offset++)); + + pic16_emitpcode(POC_DECFSZ, pctemp); + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(tlbl->key)); + pic16_emitpLabel(tlbl1->key); + + pic16_popReleaseTempReg(pctemp,1); - while(size--) { - pic16_emitpcode(poc, pic16_popGet(AOP(reg),offset)); - offset += endian; - } + 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 */ /*-----------------------------------------------------------------*/ @@ -7252,6 +8742,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--) { @@ -7261,9 +8753,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++; } @@ -7276,22 +8768,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)); @@ -7307,6 +8803,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); @@ -7348,12 +8846,13 @@ 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)); /* offset should be 0, 1 or 3 */ - pic16_emitpcode(POC_ANDLW, pic16_popGetLit(0x07 + ((offset&3) << 3))); + + pic16_emitpcode(POC_ANDLW, pic16_popGetLit((size<<3)-1)); emitSKPNZ; pic16_emitpcode(POC_GOTO, pic16_popGetLabel(tlbl1->key)); @@ -7371,7 +8870,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: @@ -7379,6 +8878,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 */ @@ -7396,7 +8896,7 @@ static void genrshOne (operand *result, operand *left, static void genrshTwo (operand *result,operand *left, int shCount, int sign) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d shCount:%d",__FUNCTION__,__LINE__,shCount); /* if shCount >= 8 */ if (shCount >= 8) { shCount -= 8 ; @@ -7409,7 +8909,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)); } } @@ -7426,31 +8926,58 @@ static void genrshTwo (operand *result,operand *left, static void shiftRLong (operand *left, int offl, operand *result, int sign) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(!sign) - pic16_emitcode("clr","c"); - MOVA(pic16_aopGet(AOP(left),MSB32,FALSE,FALSE)); + int size = AOP_SIZE(result); + int same = pic16_sameRegs(AOP(left),AOP(result)); + int i; + DEBUGpic16_emitcode ("; ***","%s %d offl:%d size:%d",__FUNCTION__,__LINE__,offl,size); + + if (same && (offl == MSB16)) { //shift one byte right + for(i=MSB16;i= 2 shiftR2Left2Result(left, MSB16, result, LSB, shCount, 0); shiftLLeftOrResult(left, MSB32, result, MSB16, 8 - shCount); /* the last shift is signed */ @@ -7524,12 +9051,13 @@ static void genRightShiftLiteral (operand *left, int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit); int lsize,res_size; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_freeAsmop(right,NULL,ic,TRUE); pic16_aopOp(left,ic,FALSE); pic16_aopOp(result,ic,FALSE); + DEBUGpic16_emitcode ("; ***","%s %d shCount:%d result:%d left:%d",__FUNCTION__,__LINE__,shCount,AOP_SIZE(result),AOP_SIZE(left)); + #if VIEW_SIZE pic16_emitcode("; shift right ","result %d, left %d",AOP_SIZE(result), AOP_SIZE(left)); @@ -7550,14 +9078,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)); @@ -7665,7 +9193,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)); @@ -7690,7 +9218,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; @@ -7739,17 +9267,17 @@ static void genSignedRightShift (iCode *ic) static void genRightShift (iCode *ic) { operand *right, *left, *result; - sym_link *retype ; + sym_link *letype ; int size, offset; char *l; symbol *tlbl, *tlbl1 ; /* if signed then we do it the hard way preserve the sign bit moving it inwards */ - retype = getSpec(operandType(IC_RESULT(ic))); + letype = getSpec(operandType(IC_LEFT(ic))); DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (!SPEC_USIGN(retype)) { + if (!SPEC_USIGN(letype)) { genSignedRightShift (ic); return ; } @@ -7850,59 +9378,74 @@ release: pic16_freeAsmop(result,NULL,ic,TRUE); } + +void pic16_loadFSR0(operand *op) +{ + pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0))); +} + /*-----------------------------------------------------------------*/ /* genUnpackBits - generates code for unpacking bits */ /*-----------------------------------------------------------------*/ -static void genUnpackBits (operand *result, char *rname, int ptype) +static void genUnpackBits (operand *result, operand *left, char *rname, int ptype) { int shCnt ; int rlen = 0 ; sym_link *etype; int offset = 0 ; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - etype = getSpec(operandType(result)); + 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: + case IPOINTER: + case PPOINTER: + case FPOINTER: + case GPOINTER: + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); + break; + case CPOINTER: + pic16_emitcode("clr","a"); + pic16_emitcode("movc","a","@a+dptr"); + break; + } + - /* read the first byte */ - switch (ptype) { + /* if we have bitdisplacement then it fits */ + /* into this byte completely or if length is */ + /* less than a byte */ + if ((shCnt = SPEC_BSTR(etype)) || + (SPEC_BLEN(etype) <= 8)) { - case POINTER: - case IPOINTER: - pic16_emitcode("mov","a,@%s",rname); - break; - - case PPOINTER: - pic16_emitcode("movx","a,@%s",rname); - break; - - case FPOINTER: - pic16_emitcode("movx","a,@dptr"); - break; + /* shift right acc */ + AccRsh(shCnt, 0); - case CPOINTER: - pic16_emitcode("clr","a"); - pic16_emitcode("movc","a","@a+dptr"); - break; + pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ])); - case GPOINTER: - pic16_emitcode("lcall","__gptrget"); - break; - } +/* VR -- normally I would use the following, but since we use the hack, + * to avoid the masking from AccRsh, why not mask it right now? */ + +/* + pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype)))); +*/ - /* if we have bitdisplacement then it fits */ - /* into this byte completely or if length is */ - /* less than a byte */ - if ((shCnt = SPEC_BSTR(etype)) || - (SPEC_BLEN(etype) <= 8)) { + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + return ; + } - /* shift right acc */ - AccRsh(shCnt); - pic16_emitcode("anl","a,#0x%02x", - ((unsigned char) -1)>>(8 - SPEC_BLEN(etype))); - pic16_aopPut(AOP(result),"a",offset); - return ; - } + + fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n"); + fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); + exit(-1); /* bit field did not fit in a byte */ rlen = SPEC_BLEN(etype) - 8; @@ -7956,42 +9499,86 @@ static void genUnpackBits (operand *result, char *rname, int ptype) return ; } -#if 0 -/*-----------------------------------------------------------------*/ -/* genDataPointerGet - generates code when ptr offset is known */ -/*-----------------------------------------------------------------*/ -static void genDataPointerGet (operand *left, - operand *result, - iCode *ic) + +static void genDataPointerGet(operand *left, + operand *result, + iCode *ic) { - int size , offset = 0; + int size, offset = 0, leoffset=0 ; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_aopOp(result, ic, FALSE); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + size = AOP_SIZE(result); +// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size); - /* optimization - most of the time, left and result are the same - * address, but different types. for the pic code, we could omit - * the following - */ +#if 0 + /* The following tests may save a redudant movff instruction when + * accessing unions */ + + /* if they are the same */ + if (operandsEqu (left, result)) { + DEBUGpic16_emitcode("; ***", "left and result operands are equ/same"); + goto release; + } +#endif - pic16_aopOp(result,ic,TRUE); +#if 0 + /* if they are the same registers */ + if (pic16_sameRegs(AOP(left),AOP(result))) { + DEBUGpic16_emitcode("; ***", "left and result registers are same"); + goto release; + } +#endif + +#if 1 + if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE), + pic16_aopGet(AOP(left), 0, TRUE, FALSE))) { + DEBUGpic16_emitcode("; ***", "left and result names are same, skipping moving"); + goto release; + } +#endif + + +#if 0 + if ( AOP_TYPE(left) == AOP_PCODE) { + fprintf(stderr,"genDataPointerGet %s, %d\n", + AOP(left)->aopu.pcop->name, + (AOP(left)->aopu.pcop->type == PO_DIR)? + PCOR(AOP(left)->aopu.pcop)->instance: + PCOI(AOP(left)->aopu.pcop)->offset); + } +#endif + + if(AOP(left)->aopu.pcop->type == PO_DIR) + leoffset=PCOR(AOP(left)->aopu.pcop)->instance; + + DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); + + while (size--) { + DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset); + + if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE + || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) { + mov2w(AOP(left), offset); // patch 8 + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popGet(AOP(left), offset), //patch 8 + pic16_popGet(AOP(result), offset))); + } - DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); + offset++; + leoffset++; + } - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),0)); +release: + pic16_freeAsmop(result,NULL,ic,TRUE); +} - size = AOP_SIZE(result); - while (size--) { - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - offset++; - } - pic16_freeAsmop(left,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); -} -#endif /*-----------------------------------------------------------------*/ /* genNearPointerGet - pic16_emitcode for near pointer fetch */ /*-----------------------------------------------------------------*/ @@ -8001,68 +9588,91 @@ static void genNearPointerGet (operand *left, { asmop *aop = NULL; //regs *preg = NULL ; - char *rname ; sym_link *rtype, *retype; sym_link *ltype = operandType(left); - //char buffer[80]; - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - rtype = operandType(result); - retype= getSpec(rtype); - - pic16_aopOp(left,ic,FALSE); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + rtype = operandType(result); + retype= getSpec(rtype); - /* if left is rematerialisable and - result is not bit variable type and - the left is pointer to data space i.e - lower 128 bytes of space */ - if (AOP_TYPE(left) == AOP_PCODE && //AOP_TYPE(left) == AOP_IMMD && - !IS_BITVAR(retype) && - DCL_TYPE(ltype) == POINTER) { - //genDataPointerGet (left,result,ic); - return ; - } + pic16_aopOp(left,ic,FALSE); + +// pic16_DumpOp("(left)",left); +// pic16_DumpOp("(result)",result); + + /* if left is rematerialisable and + * result is not bit variable type and + * the left is pointer to data space i.e + * lower 128 bytes of space */ + if (AOP_TYPE(left) == AOP_PCODE + && !IS_BITFIELD(retype) + && DCL_TYPE(ltype) == POINTER) { + + genDataPointerGet (left,result,ic); + pic16_freeAsmop(left, NULL, ic, TRUE); + return ; + } - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(left))) { - /* otherwise get a free pointer register */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); -/* - aop = newAsmop(0); - preg = getFreePtr(ic,&aop,FALSE); - pic16_emitcode("mov","%s,%s", - preg->name, - pic16_aopGet(AOP(left),0,FALSE,TRUE)); - rname = preg->name ; -*/ - rname ="BAD"; - } else - rname = pic16_aopGet(AOP(left),0,FALSE,FALSE); + * then don't need anything more */ + if (!AOP_INPREG(AOP(left))) { + /* otherwise get a free pointer register */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + /* VR -- the whole concept is to load FSR0 with the address of the symbol */ + if( (AOP_TYPE(left) == AOP_PCODE) + && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE) + || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 10 + { + if(!IS_BITFIELD(retype)) + pic16_loadFSR0( left ); // patch 10 + } else { + // set up FSR0 with address from left + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10 + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10 + } + } +// else +// rname = pic16_aopGet(AOP(left),0,FALSE,FALSE); - pic16_aopOp (result,ic,FALSE); + pic16_aopOp (result,ic,FALSE); /* if bitfield then unpack the bits */ - if (IS_BITVAR(retype)) - genUnpackBits (result,rname,POINTER); + if (IS_BITFIELD(retype)) + genUnpackBits (result, left, NULL, POINTER); else { /* we have can just get the values */ int size = AOP_SIZE(result); - int offset = 0 ; + int offset = 0; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0)); + + /* fsr0 is loaded already -- VR */ +// pic16_loadFSR0( left ); + +// pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0)); +// pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0)); while(size--) { - pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0)); - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++)); + + if(size) { + pic16_emitpcode(POC_MOVFF, + pic16_popGet2p(pic16_popCopyReg(&pic16_pc_postinc0), + pic16_popGet(AOP(result), offset++))); + } else { + pic16_emitpcode(POC_MOVFF, + pic16_popGet2p(pic16_popCopyReg(&pic16_pc_indf0), + pic16_popGet(AOP(result), offset++))); + } + } +#if 0 +// pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_postinc0)); +// pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++)); if(size) pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0)); - } +#endif /* while (size--) { if (IS_AOP_PREG(result) || AOP_TYPE(result) == AOP_STK ) { @@ -8096,9 +9706,9 @@ static void genNearPointerGet (operand *left, !OP_SYMBOL(left)->remat && ( OP_SYMBOL(left)->liveTo > ic->seq || ic->depth )) { - int size = AOP_SIZE(result) - 1; - while (size--) - pic16_emitcode("dec","%s",rname); +// int size = AOP_SIZE(result) - 1; +// while (size--) +// pic16_emitcode("dec","%s",rname); } } @@ -8144,8 +9754,8 @@ static void genPagedPointerGet (operand *left, pic16_aopOp (result,ic,FALSE); /* if bitfield then unpack the bits */ - if (IS_BITVAR(retype)) - genUnpackBits (result,rname,PPOINTER); + if (IS_BITFIELD(retype)) + genUnpackBits (result,left,rname,PPOINTER); else { /* we have can just get the values */ int size = AOP_SIZE(result); @@ -8222,8 +9832,8 @@ static void genFarPointerGet (operand *left, pic16_aopOp(result,ic,FALSE); /* if bit then unpack */ - if (IS_BITVAR(retype)) - genUnpackBits(result,"dptr",FPOINTER); + if (IS_BITFIELD(retype)) + genUnpackBits(result,left,"dptr",FPOINTER); else { size = AOP_SIZE(result); offset = 0 ; @@ -8272,8 +9882,8 @@ static void genCodePointerGet (operand *left, pic16_aopOp(result,ic,FALSE); /* if bit then unpack */ - if (IS_BITVAR(retype)) - genUnpackBits(result,"dptr",CPOINTER); + if (IS_BITFIELD(retype)) + genUnpackBits(result,left,"dptr",CPOINTER); else { size = AOP_SIZE(result); offset = 0 ; @@ -8290,57 +9900,151 @@ static void genCodePointerGet (operand *left, pic16_freeAsmop(result,NULL,ic,TRUE); } #endif +#if 0 /*-----------------------------------------------------------------*/ /* genGenPointerGet - gget value from generic pointer space */ /*-----------------------------------------------------------------*/ static void genGenPointerGet (operand *left, operand *result, iCode *ic) { - int size, offset ; + int size, offset, lit; sym_link *retype = getSpec(operandType(result)); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_aopOp(left,ic,FALSE); - pic16_aopOp(result,ic,FALSE); + 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); - DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); + if (AOP_TYPE(left) == AOP_IMMD) { // do we ever get here? (untested!) - /* if the operand is already in dptr - then we do nothing else we move the value to dptr */ - // if (AOP_TYPE(left) != AOP_STR) { - /* if this is remateriazable */ - if (AOP_TYPE(left) == AOP_IMMD) { - pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(left),0,TRUE,FALSE)); - pic16_emitcode("mov","b,#%d",pointerCode(retype)); - } - else { /* we need to get it byte by byte */ + lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit); + // load FSR0 from immediate + pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit))); + +// pic16_loadFSR0( left ); + + offset = 0; + while(size--) { + if(size) { + 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 FSR0 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_fsr0h))); + + 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; + } + + /* 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); + +} +#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!) - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0)); + lit = (unsigned)floatFromVal(AOP(left)->aopu.aop_lit); + // load FSR0 from immediate + pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit))); - size = AOP_SIZE(result); - offset = 0 ; + werror(W_POSSBUG2, __FILE__, __LINE__); + offset = 0; while(size--) { - pic16_emitpcode(POC_MOVFW,pic16_popCopyReg(&pic16_pc_indf0)); - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),offset++)); - if(size) - pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0)); + 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:FSR0H: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_fsr0h))); + 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; } - //} - /* so dptr know contains the address */ /* if bit then unpack */ - //if (IS_BITVAR(retype)) - // genUnpackBits(result,"dptr",GPOINTER); + if (IS_BITFIELD(retype)) + genUnpackBits(result,left,"BAD",GPOINTER); - release: +release: pic16_freeAsmop(left,NULL,ic,TRUE); pic16_freeAsmop(result,NULL,ic,TRUE); - } /*-----------------------------------------------------------------*/ @@ -8350,25 +10054,28 @@ static void genConstPointerGet (operand *left, operand *result, iCode *ic) { //sym_link *retype = getSpec(operandType(result)); - symbol *albl = newiTempLabel(NULL); - symbol *blbl = newiTempLabel(NULL); - PIC_OPCODE poc; + // symbol *albl = newiTempLabel(NULL); // patch 15 + // symbol *blbl = newiTempLabel(NULL); // + // PIC_OPCODE poc; // patch 15 + int size; + int offset = 0; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(left,ic,FALSE); - pic16_aopOp(result,ic,FALSE); - + pic16_aopOp(result,ic,TRUE); + size = AOP_SIZE(result); DEBUGpic16_pic16_AopType(__LINE__,left,NULL,result); DEBUGpic16_emitcode ("; "," %d getting const pointer",__LINE__); - +#if 0 // patch 15 pic16_emitpcode(POC_CALL,pic16_popGetLabel(albl->key)); pic16_emitpcode(POC_GOTO,pic16_popGetLabel(blbl->key)); pic16_emitpLabel(albl->key); 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)); pic16_emitpcode(poc,pic16_popGet(AOP(left),0)); @@ -8377,12 +10084,42 @@ static void genConstPointerGet (operand *left, pic16_emitpLabel(blbl->key); pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(result),0)); +#endif // patch 15 + + + // set up table pointer + if( (AOP_TYPE(left) == AOP_PCODE) + && ((AOP(left)->aopu.pcop->type == PO_IMMEDIATE) + || (AOP(left)->aopu.pcop->type == PO_DIR))) // patch 15 ...... + { + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl)); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),1)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh)); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),2)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru)); + } + else + { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_tblptrl))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_tblptrh))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),2), pic16_popCopyReg(&pic16_pc_tblptru))); + } + while(size--) + { + pic16_emitpcodeNULLop(POC_TBLRD_POSTINC); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), pic16_popGet(AOP(result),offset))); + offset++; + } + pic16_freeAsmop(left,NULL,ic,TRUE); pic16_freeAsmop(result,NULL,ic,TRUE); } + + /*-----------------------------------------------------------------*/ /* genPointerGet - generate code for pointer get */ /*-----------------------------------------------------------------*/ @@ -8402,7 +10139,11 @@ static void genPointerGet (iCode *ic) type = operandType(left); etype = getSpec(type); +#if 0 if (IS_PTR_CONST(type)) +#else + if (IS_CODEPTR(type)) +#endif DEBUGpic16_emitcode ("; ***","%d - const pointer",__LINE__); /* if left is of type of pointer then it is simple */ @@ -8458,11 +10199,18 @@ static void genPointerGet (iCode *ic) break; case GPOINTER: +#if 0 if (IS_PTR_CONST(type)) genConstPointerGet (left,result,ic); else +#endif genGenPointerGet (left,result,ic); break; + + default: + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "genPointerGet: illegal pointer type"); + } } @@ -8470,75 +10218,93 @@ static void genPointerGet (iCode *ic) /*-----------------------------------------------------------------*/ /* genPackBits - generates code for packed bit storage */ /*-----------------------------------------------------------------*/ -static void genPackBits (sym_link *etype , +static void genPackBits (sym_link *etype , operand *result, operand *right , char *rname, int p_type) { - int shCount = 0 ; - int offset = 0 ; - int rLen = 0 ; - int blen, bstr ; - char *l ; - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - blen = SPEC_BLEN(etype); - bstr = SPEC_BSTR(etype); - - l = pic16_aopGet(AOP(right),offset++,FALSE,FALSE); - MOVA(l); - - /* if the bit lenth is less than or */ - /* it exactly fits a byte then */ - if (SPEC_BLEN(etype) <= 8 ) { - shCount = SPEC_BSTR(etype) ; - - /* shift left acc */ - AccLsh(shCount); - - if (SPEC_BLEN(etype) < 8 ) { /* if smaller than a byte */ + int shCnt = 0 ; + int offset = 0 ; + int rLen = 0 ; + int blen, bstr ; + char *l ; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + blen = SPEC_BLEN(etype); + bstr = SPEC_BSTR(etype); + + if(AOP_TYPE(right) == AOP_LIT) { + if((blen == 1) && (bstr < 8)) { + unsigned long lit; + /* it is a single bit, so use the appropriate bit instructions */ + + DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__); + + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); +// pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); + if((p_type == POINTER) && (result)) { + /* workaround to reduce the extra lfsr instruction */ + if(lit) { + pic16_emitpcode(POC_BSF, + pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); + } else { + pic16_emitpcode(POC_BCF, + pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); + } + } else { + + 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; + } - switch (p_type) { - case POINTER: - pic16_emitcode ("mov","b,a"); - pic16_emitcode("mov","a,@%s",rname); - break; - - case FPOINTER: - pic16_emitcode ("mov","b,a"); - pic16_emitcode("movx","a,@dptr"); - break; - - case GPOINTER: - pic16_emitcode ("push","b"); - pic16_emitcode ("push","acc"); - pic16_emitcode ("lcall","__gptrget"); - pic16_emitcode ("pop","b"); - break; - } + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0)); + offset++; + } else + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++)); + + /* if the bit lenth is less than or */ + /* it exactly fits a byte then */ + if((shCnt=SPEC_BSTR(etype)) + || SPEC_BLEN(etype) <= 8 ) { + + /* shift left acc */ + AccLsh(shCnt); + + /* using PRODL as a temporary register here */ + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl)); + + switch (p_type) { + case FPOINTER: + case POINTER: + case GPOINTER: + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); +// pic16_emitcode ("mov","b,a"); +// pic16_emitcode("mov","a,@%s",rname); + break; + } +#if 1 + pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + (unsigned char)((unsigned char)(0xff << (blen+bstr)) | + (unsigned char)(0xff >> (8-bstr))) )); + pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodl)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); +#endif - pic16_emitcode ("anl","a,#0x%02x",(unsigned char) - ((unsigned char)(0xFF << (blen+bstr)) | - (unsigned char)(0xFF >> (8-bstr)) ) ); - pic16_emitcode ("orl","a,b"); - if (p_type == GPOINTER) - pic16_emitcode("pop","b"); - } - } + return; + } - switch (p_type) { - case POINTER: - pic16_emitcode("mov","@%s,a",rname); - break; - case FPOINTER: - pic16_emitcode("movx","@dptr,a"); - break; + fprintf(stderr, "SDCC pic16 port error: the port currently does not support\n"); + fprintf(stderr, "bitfields of size >=8. Instead of generating wrong code, bailling out...\n"); + exit(-1); - case GPOINTER: - DEBUGpic16_emitcode(";lcall","__gptrput"); - break; - } /* if we r done */ if ( SPEC_BLEN(etype) <= 8 ) @@ -8547,6 +10313,8 @@ static void genPackBits (sym_link *etype , pic16_emitcode("inc","%s",rname); rLen = SPEC_BLEN(etype) ; + + /* now generate for lengths greater than one byte */ while (1) { @@ -8631,65 +10399,54 @@ static void genDataPointerSet(operand *right, operand *result, iCode *ic) { - int size, offset = 0 ; - char *l, buffer[256]; + int size, offset = 0, resoffset=0 ; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(right,ic,FALSE); - - l = pic16_aopGet(AOP(result),0,FALSE,TRUE); + size = AOP_SIZE(right); -/* + +// fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size); + +#if 0 if ( AOP_TYPE(result) == AOP_PCODE) { fprintf(stderr,"genDataPointerSet %s, %d\n", AOP(result)->aopu.pcop->name, + (AOP(result)->aopu.pcop->type == PO_DIR)? + PCOR(AOP(result)->aopu.pcop)->instance: PCOI(AOP(result)->aopu.pcop)->offset); } -*/ - - // tsd, was l+1 - the underline `_' prefix was being stripped - while (size--) { - if (offset) { - sprintf(buffer,"(%s + %d)",l,offset); - fprintf(stderr,"oops %s\n",buffer); - } else - sprintf(buffer,"%s",l); - - if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); - lit = lit >> (8*offset); - if(lit&0xff) { - pic16_emitcode("movlw","%d",lit); - pic16_emitcode("movwf","%s",buffer); - - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff)); - //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); - - } else { - pic16_emitcode("clrf","%s",buffer); - //pic16_emitpcode(POC_CLRF, popRegFromString(buffer)); - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); - } - }else { - pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s",buffer); +#endif - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); - //pic16_emitpcode(POC_MOVWF, popRegFromString(buffer)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); + if(AOP(result)->aopu.pcop->type == PO_DIR) + resoffset=PCOR(AOP(result)->aopu.pcop)->instance; + while (size--) { + if (AOP_TYPE(right) == AOP_LIT) { + unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); + + lit = lit >> (8*offset); + if(lit&0xff) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8 + } else { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8 + } + } else { + mov2w(AOP(right), offset); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8 + } + offset++; + resoffset++; } - offset++; - } - pic16_freeAsmop(right,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); } + + /*-----------------------------------------------------------------*/ -/* genNearPointerSet - pic16_emitcode for near pointer put */ +/* genNearPointerSet - pic16_emitcode for near pointer put */ /*-----------------------------------------------------------------*/ static void genNearPointerSet (operand *right, operand *result, @@ -8699,120 +10456,127 @@ static void genNearPointerSet (operand *right, char *l; sym_link *retype; sym_link *ptype = operandType(result); - + sym_link *resetype; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - retype= getSpec(operandType(right)); - - pic16_aopOp(result,ic,FALSE); - + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + retype= getSpec(operandType(right)); + resetype = getSpec(operandType(result)); + + pic16_aopOp(result,ic,FALSE); - /* if the result is rematerializable & - in data space & not a bit variable */ - //if (AOP_TYPE(result) == AOP_IMMD && - if (AOP_TYPE(result) == AOP_PCODE && //AOP_TYPE(result) == AOP_IMMD && - DCL_TYPE(ptype) == POINTER && - !IS_BITVAR(retype)) { - genDataPointerSet (right,result,ic); - pic16_freeAsmop(result,NULL,ic,TRUE); - return; - } - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_aopOp(right,ic,FALSE); - DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - - /* if the value is already in a pointer register - then don't need anything more */ - if (!AOP_INPREG(AOP(result))) { - /* otherwise get a free pointer register */ - //aop = newAsmop(0); - //preg = getFreePtr(ic,&aop,FALSE); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - //pic16_emitcode("mov","%s,%s", - // preg->name, - // pic16_aopGet(AOP(result),0,FALSE,TRUE)); - //rname = preg->name ; - //pic16_emitcode("movwf","fsr0"); - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_fsr0)); - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); - goto release; + /* if the result is rematerializable & + * in data space & not a bit variable */ + + /* and result is not a bit variable */ + if (AOP_TYPE(result) == AOP_PCODE +// && AOP_TYPE(result) == AOP_IMMD + && DCL_TYPE(ptype) == POINTER + && !IS_BITFIELD(retype) + && !IS_BITFIELD(resetype)) { + + genDataPointerSet (right,result,ic); + pic16_freeAsmop(result,NULL,ic,TRUE); + return; + } - }// else - // rname = pic16_aopGet(AOP(result),0,FALSE,FALSE); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_aopOp(right,ic,FALSE); + DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); + /* if the value is already in a pointer register + * then don't need anything more */ + if (!AOP_INPREG(AOP(result))) { + /* otherwise get a free pointer register */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if( (AOP_TYPE(result) == AOP_PCODE) + && ((AOP(result)->aopu.pcop->type == PO_IMMEDIATE) + || (AOP(result)->aopu.pcop->type == PO_DIR))) // patch 10 + { + if(!IS_BITFIELD(resetype)) + pic16_loadFSR0( result ); // patch 10 + } else { + // set up FSR0 with address of result + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); // patch 10 + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_fsr0h))); // patch 10 + } - /* if bitfield then unpack the bits */ - if (IS_BITVAR(retype)) { - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - "The programmer is obviously confused"); - //genPackBits (retype,right,rname,POINTER); - exit(1); - } - else { - /* we have can just get the values */ - int size = AOP_SIZE(right); - int offset = 0 ; + } +// else +// rname = pic16_aopGet(AOP(result),0,FALSE,FALSE); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - while (size--) { - l = pic16_aopGet(AOP(right),offset,FALSE,TRUE); - if (*l == '@' ) { - //MOVA(l); - //pic16_emitcode("mov","@%s,a",rname); - pic16_emitcode("movf","indf0,w ;1"); - } else { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit); - if(lit) { - pic16_emitcode("movlw","%s",l); - pic16_emitcode("movwf","indf0 ;2"); - } else - pic16_emitcode("clrf","indf0"); - }else { - pic16_emitcode("movf","%s,w",l); - pic16_emitcode("movwf","indf0 ;2"); - } - //pic16_emitcode("mov","@%s,%s",rname,l); - } - if (size) - pic16_emitcode("incf","fsr0,f ;3"); - //pic16_emitcode("inc","%s",rname); - offset++; - } - } + /* if bitfield then unpack the bits */ + if (IS_BITFIELD(resetype)) { + genPackBits (resetype, result, right, NULL, POINTER); + } else { + /* we have can just get the values */ + int size = AOP_SIZE(right); + int offset = 0 ; + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + while (size--) { + l = pic16_aopGet(AOP(right),offset,FALSE,TRUE); + if (*l == '@' ) { + //MOVA(l); + //pic16_emitcode("mov","@%s,a",rname); + pic16_emitcode("movf","indf0,w ;1"); + } else { + + if (AOP_TYPE(right) == AOP_LIT) { // patch 10 + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); // + if (size) { // + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); // + } else { // + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); // + } // + } else { // no literal // + if(size) { // + pic16_emitpcode(POC_MOVFF, // + pic16_popGet2p(pic16_popGet(AOP(right),offset), // + pic16_popCopyReg(&pic16_pc_postinc0))); // + } else { // + pic16_emitpcode(POC_MOVFF, // + pic16_popGet2p(pic16_popGet(AOP(right),offset), // + pic16_popCopyReg(&pic16_pc_indf0))); // + } // + } // patch 10 + } + offset++; + } + } - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* now some housekeeping stuff */ - if (aop) { - /* we had to allocate for this iCode */ - pic16_freeAsmop(NULL,aop,ic,TRUE); - } else { - /* we did not allocate which means left - already in a pointer register, then - if size > 0 && this could be used again - we have to point it back to where it - belongs */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (AOP_SIZE(right) > 1 && - !OP_SYMBOL(result)->remat && - ( OP_SYMBOL(result)->liveTo > ic->seq || - ic->depth )) { - int size = AOP_SIZE(right) - 1; - while (size--) - pic16_emitcode("decf","fsr0,f"); - //pic16_emitcode("dec","%s",rname); - } - } + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* now some housekeeping stuff */ + if (aop) { + /* we had to allocate for this iCode */ + pic16_freeAsmop(NULL,aop,ic,TRUE); + } else { + /* we did not allocate which means left + * already in a pointer register, then + * if size > 0 && this could be used again + * we have to point it back to where it + * belongs */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (AOP_SIZE(right) > 1 + && !OP_SYMBOL(result)->remat + && ( OP_SYMBOL(result)->liveTo > ic->seq + || ic->depth )) { + + int size = AOP_SIZE(right) - 1; + + while (size--) + pic16_emitcode("decf","fsr0,f"); + //pic16_emitcode("dec","%s",rname); + } + } - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* done */ - release: - pic16_freeAsmop(right,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* done */ +//release: + pic16_freeAsmop(right,NULL,ic,TRUE); + pic16_freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -8850,8 +10614,8 @@ static void genPagedPointerSet (operand *right, pic16_aopOp (right,ic,FALSE); /* if bitfield then unpack the bits */ - if (IS_BITVAR(retype)) - genPackBits (retype,right,rname,PPOINTER); + if (IS_BITFIELD(retype)) + genPackBits (retype,result,right,rname,PPOINTER); else { /* we have can just get the values */ int size = AOP_SIZE(right); @@ -8928,8 +10692,8 @@ static void genFarPointerSet (operand *right, pic16_aopOp(right,ic,FALSE); /* if bit then unpack */ - if (IS_BITVAR(retype)) - genPackBits(retype,right,"dptr",FPOINTER); + if (IS_BITFIELD(retype)) + genPackBits(retype,result,right,"dptr",FPOINTER); else { size = AOP_SIZE(right); offset = 0 ; @@ -8949,108 +10713,196 @@ static void genFarPointerSet (operand *right, /*-----------------------------------------------------------------*/ /* genGenPointerSet - set value from generic pointer space */ /*-----------------------------------------------------------------*/ +#if 0 static void genGenPointerSet (operand *right, operand *result, iCode *ic) { - int size, offset ; - sym_link *retype = getSpec(operandType(right)); - - 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 the operand is already in dptr - then we do nothing else we move the value to dptr */ - if (AOP_TYPE(result) != AOP_STR) { - /* if this is remateriazable */ - if (AOP_TYPE(result) == AOP_IMMD) { - pic16_emitcode("mov","dptr,%s",pic16_aopGet(AOP(result),0,TRUE,FALSE)); - pic16_emitcode("mov","b,%s + 1",pic16_aopGet(AOP(result),0,TRUE,FALSE)); - } - else { /* we need to get it byte by byte */ - //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE); - size = AOP_SIZE(right); - offset = 0 ; - - /* hack hack! see if this the FSR. If so don't load W */ - if(AOP_TYPE(right) != AOP_ACC) { + int i, size, offset, lit; + sym_link *retype = getSpec(operandType(right)); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0)); + pic16_aopOp(result,ic,FALSE); + pic16_aopOp(right,ic,FALSE); + size = AOP_SIZE(right); + offset = 0; + + DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); + + /* if the operand is already in dptr + then we do nothing else we move the value to dptr */ + if (AOP_TYPE(result) != AOP_STR) { + /* if this is remateriazable */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + // WARNING: anythig until "else" is untested! + if (AOP_TYPE(result) == AOP_IMMD) { + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + lit = (unsigned)floatFromVal(AOP(result)->aopu.aop_lit); + // load FSR0 from immediate + pic16_emitpcode(POC_LFSR,pic16_popGetLit2(0,pic16_popGetLit(lit))); + offset = 0; + while(size--) { + if(size) { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0))); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0))); + } + offset++; + } + goto release; + } + else { /* we need to get it byte by byte */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + //char *l = pic16_aopGet(AOP(result),0,FALSE,FALSE); + + // set up FSR0 with address of result + 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_fsr0h))); + + /* hack hack! see if this the FSR. If so don't load W */ + if(AOP_TYPE(right) != AOP_ACC) { + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(AOP_TYPE(right) == AOP_LIT) + { + // copy literal + // note: pic16_popGet handles sign extension + for(i=0;i 1) { - pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT)); - pic16_emitpcode(POC_BTFSC,pic16_newpCodeOpBit(pic16_aopGet(AOP(result),1,FALSE,FALSE),0,0)); - pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(PCOP(&pic16_pc_status),PIC_IRP_BIT)); + DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size); + // set up FSR0 with address of result + 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_fsr0h))); + + while (size--) { + if (AOP_TYPE(right) == AOP_LIT) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); + if (size) { + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); + } else { + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); + } + } else { // no literal + if(size) { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_postinc0))); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),offset), pic16_popCopyReg(&pic16_pc_indf0))); + } + } + offset++; + } } - //if(size==2) - //pic16_emitpcode(POC_DECF,pic16_popCopyReg(&pic16_pc_fsr0)); - //if(size==4) { - // pic16_emitpcode(POC_MOVLW,pic16_popGetLit(0xfd)); - // pic16_emitpcode(POC_ADDWF,pic16_popCopyReg(&pic16_pc_fsr0)); - //} + release: + pic16_freeAsmop(right,NULL,ic,TRUE); + pic16_freeAsmop(result,NULL,ic,TRUE); +} +#endif - while(size--) { - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(right),offset++)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); - - if(size) - pic16_emitpcode(POC_INCF,pic16_popCopyReg(&pic16_pc_fsr0)); - } +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__); - goto release; - } + pic16_aopOp(result,ic,FALSE); + pic16_aopOp(right,ic,FALSE); + size = AOP_SIZE(right); - if(aopIdx(AOP(result),0) != 4) { + DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); - goto release; - } - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); + /* 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; - } - } - /* so dptr know contains the address */ - - /* if bit then unpack */ - if (IS_BITVAR(retype)) - genPackBits(retype,right,"dptr",GPOINTER); - else { size = AOP_SIZE(right); - offset = 0 ; - - DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size); - - while (size--) { - pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(result),offset)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_fsr0)); + DEBUGpic16_emitcode ("; ***","%s %d size=%d",__FUNCTION__,__LINE__,size); - if (AOP_TYPE(right) == AOP_LIT) - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); - else - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); + /* load value to write in TBLPTRH:TBLPTRL:PRODH:PRODL */ + mov2fp(pic16_popCopyReg(&pic16_pc_prodl), 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_fsr0h))); + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 2)); + - offset++; + /* put code here */ + switch (size) { + case 1: strcpy(fgptrput, "__gptrput1"); break; + case 2: strcpy(fgptrput, "__gptrput2"); 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); +// fprintf(stderr, "%s:%d adding extern symbol %s in externs\n", __FILE__, __LINE__, fgptrget); } - } - release: - pic16_freeAsmop(right,NULL,ic,TRUE); - pic16_freeAsmop(result,NULL,ic,TRUE); +release: + pic16_freeAsmop(right,NULL,ic,TRUE); + pic16_freeAsmop(result,NULL,ic,TRUE); } /*-----------------------------------------------------------------*/ @@ -9167,36 +11019,80 @@ static void genIfx (iCode *ic, iCode *popIc) /*-----------------------------------------------------------------*/ static void genAddrOf (iCode *ic) { - operand *right, *result, *left; - int size, offset ; - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - - //pic16_aopOp(IC_RESULT(ic),ic,FALSE); + operand *result, *left; + int size; + symbol *sym; // = OP_SYMBOL(IC_LEFT(ic)); + pCodeOp *pcop0, *pcop1, *pcop2; - pic16_aopOp((left=IC_LEFT(ic)),ic,FALSE); - pic16_aopOp((right=IC_RIGHT(ic)),ic,FALSE); - pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - DEBUGpic16_pic16_AopType(__LINE__,left,right,result); + pic16_aopOp((result=IC_RESULT(ic)),ic,TRUE); - size = AOP_SIZE(IC_RESULT(ic)); - offset = 0; + 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 + 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)); - while (size--) { - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(left),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - offset++; - } + 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))); +// } + + pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE); + size = AOP_SIZE(IC_RESULT(ic)); - pic16_freeAsmop(left,NULL,ic,FALSE); - pic16_freeAsmop(result,NULL,ic,TRUE); + /* 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(left, NULL, ic, FALSE); +release: + pic16_freeAsmop(result,NULL,ic,TRUE); } + #if 0 /*-----------------------------------------------------------------*/ /* genFarFarAssign - assignment when both are in far space */ @@ -9304,24 +11200,93 @@ static void genAssign (iCode *ic) /* general case */ size = AOP_SIZE(result); offset = 0 ; - if(AOP_TYPE(right) == AOP_LIT) - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + if(AOP_TYPE(right) == AOP_LIT) { + if(!IS_FLOAT(operandType( right ))) + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + else { + union { + unsigned long lit_int; + float lit_float; + } info; + + /* take care if literal is a float */ + info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit); + lit = info.lit_int; + } + } + +// fprintf(stderr, "%s:%d: assigning value 0x%04lx (%d:%d)\n", __FUNCTION__, __LINE__, lit, +// sizeof(unsigned long int), sizeof(float)); + + if(AOP_TYPE(right) != AOP_LIT + && IN_CODESPACE(SPEC_OCLS(OP_SYMBOL(right)->etype))) { + DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__); + fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name); + + // set up table pointer + if( (AOP_TYPE(right) == AOP_PCODE) + && ((AOP(right)->aopu.pcop->type == PO_IMMEDIATE) + || (AOP(right)->aopu.pcop->type == PO_DIR))) + { + fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl)); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh)); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru)); + } else { + fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0), + pic16_popCopyReg(&pic16_pc_tblptrl))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1), + pic16_popCopyReg(&pic16_pc_tblptrh))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2), + pic16_popCopyReg(&pic16_pc_tblptru))); + } + + size = min(AOP_SIZE(right), AOP_SIZE(result)); + while(size--) { + pic16_emitpcodeNULLop(POC_TBLRD_POSTINC); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), + pic16_popGet(AOP(result),offset))); + offset++; + } + + if(AOP_SIZE(result) > AOP_SIZE(right)) { + size = AOP_SIZE(result) - AOP_SIZE(right); + while(size--) { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset)); + offset++; + } + } + goto release; + } + + + +#if 0 /* VR - What is this?! */ if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(aopIdx(AOP(result),0) == 4) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + /* this is a workaround to save value of right into wreg too, + * value of wreg is going to be used later */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); goto release; } else +// assert(0); DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__); } +#endif know_W=-1; while (size--) { - 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)) @@ -9339,12 +11304,15 @@ static void genAssign (iCode *ic) pic16_emitpcode(POC_BTFSS, pic16_popGet(AOP(right),0)); pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0)); } + } else if ( (AOP_TYPE(right) == AOP_PCODE) && (AOP(right)->aopu.pcop->type == PO_IMMEDIATE) ) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); } else { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); #if 1 /* This is a hack to turn MOVFW/MOVWF pairs to MOVFF command. It - normally should work, but mind that thw W register live range + 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. @@ -9353,7 +11321,6 @@ static void genAssign (iCode *ic) 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(!?) */ @@ -9550,141 +11517,174 @@ release: /*-----------------------------------------------------------------*/ static void genCast (iCode *ic) { - operand *result = IC_RESULT(ic); - sym_link *ctype = operandType(IC_LEFT(ic)); - sym_link *rtype = operandType(IC_RIGHT(ic)); - operand *right = IC_RIGHT(ic); - int size, offset ; - - DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); - /* if they are equivalent then do nothing */ - if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic))) - return ; - - pic16_aopOp(right,ic,FALSE) ; - pic16_aopOp(result,ic,FALSE); - - DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - - /* if the result is a bit */ - if (AOP_TYPE(result) == AOP_CRY) { - /* if the right size is a literal then - we know what the value is */ - DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); - if (AOP_TYPE(right) == AOP_LIT) { - - pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF), - pic16_popGet(AOP(result),0)); + operand *result = IC_RESULT(ic); + sym_link *ctype = operandType(IC_LEFT(ic)); + sym_link *rtype = operandType(IC_RIGHT(ic)); + operand *right = IC_RIGHT(ic); + int size, offset ; - if (((int) operandLitValue(right))) - pic16_emitcode("bsf","(%s >> 3), (%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - else - pic16_emitcode("bcf","(%s >> 3), (%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); + DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + /* if they are equivalent then do nothing */ + if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic))) + return ; - goto release; - } + pic16_aopOp(right,ic,FALSE) ; + pic16_aopOp(result,ic,FALSE); - /* the right is also a bit variable */ - if (AOP_TYPE(right) == AOP_CRY) { + DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - emitCLRC; - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + /* if the result is a bit */ + if (AOP_TYPE(result) == AOP_CRY) { + + /* if the right size is a literal then + * we know what the value is */ + DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + + if (AOP_TYPE(right) == AOP_LIT) { + pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF), + pic16_popGet(AOP(result),0)); + + if (((int) operandLitValue(right))) + pic16_emitcode("bsf","(%s >> 3), (%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + else + pic16_emitcode("bcf","(%s >> 3), (%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + goto release; + } - pic16_emitcode("clrc",""); - pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - pic16_aopPut(AOP(result),"c",0); - goto release ; - } + /* the right is also a bit variable */ + if (AOP_TYPE(right) == AOP_CRY) { + emitCLRC; + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + + pic16_emitcode("clrc",""); + pic16_emitcode("btfsc","(%s >> 3), (%s & 7)", + AOP(right)->aopu.aop_dir, + AOP(right)->aopu.aop_dir); + pic16_aopPut(AOP(result),"c",0); + goto release ; + } - /* 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_BSF, pic16_popGet(AOP(result),0)); + /* 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, PO_GPR_REGISTER)); + pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); + } + pic16_toBoolean(right); + pic16_aopPut(AOP(result),"a",0); + goto release ; } - pic16_toBoolean(right); - pic16_aopPut(AOP(result),"a",0); - goto release ; - } - - if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) { - int offset = 1; - size = AOP_SIZE(result); - DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + if ((AOP_TYPE(right) == AOP_CRY) && (AOP_TYPE(result) == AOP_REG)) { + int offset = 1; - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0)); - - while (size--) - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++)); + size = AOP_SIZE(result); - goto release; - } + DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); - /* if they are the same size : or less */ - if (AOP_SIZE(result) <= AOP_SIZE(right)) { - - /* if they are in the same place */ - if (pic16_sameRegs(AOP(right),AOP(result))) - goto release; + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0)); - DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); - if (IS_PTR_CONST(rtype)) - DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__); - if (IS_PTR_CONST(operandType(IC_RESULT(ic)))) - DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__); + while (size--) + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++)); - if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) { - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1)); - if(AOP_SIZE(result) <2) - fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__); + goto release; + } - } else { + /* if they are the same size : or less */ + if (AOP_SIZE(result) <= AOP_SIZE(right)) { - /* if they in different places then copy */ - size = AOP_SIZE(result); - offset = 0 ; - while (size--) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); + /* if they are in the same place */ + if (pic16_sameRegs(AOP(right),AOP(result))) + goto release; - //pic16_aopPut(AOP(result), - // pic16_aopGet(AOP(right),offset,FALSE,FALSE), - // offset); + DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); +#if 0 + if (IS_PTR_CONST(rtype)) +#else + if (IS_CODEPTR(rtype)) +#endif + DEBUGpic16_emitcode ("; ***","%d - right is const pointer",__LINE__); - offset++; - } - } - goto release; - } +#if 0 + if (IS_PTR_CONST(operandType(IC_RESULT(ic)))) +#else + if (IS_CODEPTR(operandType(IC_RESULT(ic)))) +#endif + DEBUGpic16_emitcode ("; ***","%d - result is const pointer",__LINE__); +#if 0 + if(AOP_TYPE(right) == AOP_IMMD) { + pCodeOp *pcop0, *pcop1, *pcop2; + symbol *sym = OP_SYMBOL( right ); + + size = AOP_SIZE(result); + /* low */ + pcop0 = PCOP(pic16_newpCodeOpImmd(sym->rname, 0, 0, IN_CODESPACE( SPEC_OCLS(sym->etype)))); + /* 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)); + } + } else +#endif + if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),1)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),1)); + if(AOP_SIZE(result) <2) + fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__); + } else { + /* if they in different places then copy */ + size = AOP_SIZE(result); + offset = 0 ; + while (size--) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); + offset++; + } + } + goto release; + } - /* if the result is of type pointer */ - if (IS_PTR(ctype)) { + /* if the result is of type pointer */ + if (IS_PTR(ctype)) { + int p_type; + sym_link *type = operandType(right); + sym_link *etype = getSpec(type); - int p_type; - sym_link *type = operandType(right); - sym_link *etype = getSpec(type); - DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__); + DEBUGpic16_emitcode("; ***","%s %d - pointer cast",__FUNCTION__,__LINE__); - /* pointer to generic pointer */ - if (IS_GENPTR(ctype)) { - char *l = zero; + /* pointer to generic pointer */ + if (IS_GENPTR(ctype)) { + char *l = zero; - if (IS_PTR(type)) - p_type = DCL_TYPE(type); - else { + if (IS_PTR(type)) + p_type = DCL_TYPE(type); + else { /* we have to go by the storage class */ p_type = PTR_TYPE(SPEC_OCLS(etype)); @@ -9709,16 +11709,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++; @@ -9727,21 +11731,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__, @@ -9780,32 +11791,33 @@ static void genCast (iCode *ic) size = AOP_SIZE(right); offset = 0 ; while (size--) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset)); +// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); +// pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); offset++; } /* now depending on the sign of the destination */ size = AOP_SIZE(result) - AOP_SIZE(right); /* if unsigned or not an integral type */ - if (SPEC_USIGN(rtype) || !IS_SPEC(rtype)) { + if (SPEC_USIGN( getSpec(rtype) ) || !IS_SPEC(rtype)) { while (size--) pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset++)); } else { - /* we need to extend the sign :{ */ + /* we need to extend the sign :( */ 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)); @@ -9868,14 +11880,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; @@ -9889,30 +11896,42 @@ static void genReceive (iCode *ic) { 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)); + + if (isOperandInFarSpace(IC_RESULT(ic)) + && ( OP_SYMBOL(IC_RESULT(ic))->isspilt + || IS_TRUE_SYMOP(IC_RESULT(ic))) ) { int size = getSize(operandType(IC_RESULT(ic))); int offset = pic16_fReturnSizePic - size; - 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++); - } - + + assert( 0 ); + while (size--) { + pic16_emitcode ("push","%s", (strcmp(fReturn[pic16_fReturnSizePic - offset - 1],"a") ? + fReturn[pic16_fReturnSizePic - offset - 1] : "acc")); + offset++; + } + + DEBUGpic16_emitcode ("; ***","1 %s %d",__FUNCTION__,__LINE__); + + 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)); + assignResultValue(IC_RESULT(ic), 0); } pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); @@ -9957,46 +11976,34 @@ void genpic16Code (iCode *lic) if (options.debug && currFunc) { if (currFunc) { cdbSymbol(currFunc,cdbFile,FALSE,TRUE); - _G.debugLine = 1; - if (IS_STATIC(currFunc->etype)) { - pic16_emitcode("",";F%s$%s$0$0 %d",moduleName,currFunc->name,__LINE__); - //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(moduleName,currFunc->name)); - } else { - pic16_emitcode("",";G$%s$0$0 %d",currFunc->name,__LINE__); - //pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(NULL,currFunc->name)); - } - _G.debugLine = 0; } } #endif -// dumpiCode(lic); - for (ic = lic ; ic ; ic = ic->next ) { -// fprintf(stderr, "; VR = %c %x\n", ic->op, ic->op); -// DEBUGpic16_emitcode("; VR", ""); DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op); if ( cln != ic->lineno ) { if ( options.debug ) { - _G.debugLine = 1; - pic16_emitcode("",";C$%s$%d$%d$%d ==.", - FileBaseName(ic->filename),ic->lineno, - ic->level,ic->block); - _G.debugLine = 0; + debugFile->writeCLine (ic); + } + + if(!options.noCcodeInAsm) { + pic16_addpCode2pBlock(pb, + pic16_newpCodeCSource(ic->lineno, ic->filename, + printCLine(ic->filename, ic->lineno))); } - /* - pic16_emitcode("#CSRC","%s %d",FileBaseName(ic->filename),ic->lineno); - pic16_emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, - printCLine(ic->filename, ic->lineno)); - */ - pic16_addpCode2pBlock(pb, - pic16_newpCodeCSource(ic->lineno, - ic->filename, - printCLine(ic->filename, ic->lineno))); cln = ic->lineno ; } + + if(options.iCodeInAsm) { + char *l; + /* insert here code to print iCode as comment */ + l = Safe_strdup(printILine(ic)); + pic16_emitpcomment("ic:%d: %s", ic->seq, l); + } + /* if the result is marked as spilt and rematerializable or code for this has already been generated then @@ -10007,11 +12014,11 @@ void genpic16Code (iCode *lic) /* depending on the operation */ switch (ic->op) { case '!' : - genNot(ic); + pic16_genNot(ic); break; case '~' : - genCpl(ic); + pic16_genCpl(ic); break; case UNARYMINUS: @@ -10185,6 +12192,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: @@ -10203,7 +12212,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"));