X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgen.c;h=aa811c3e1cc039aa21da410bf4178ab86e0f4ddc;hb=4fa52c899d3553b51d56db35d035f17b7e22e66b;hp=1435ca23a65d27bd2b987d661c0c4d5530d3323f;hpb=059d9df1631fa63c0ad1d6db6db5c9bfa01b16fb;p=fw%2Fsdcc diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 1435ca23..aa811c3e 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -7,7 +7,7 @@ PIC port - Scott Dattalo scott@dattalo.com (2000) PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002) - Vangelis Rokas vrokas@otenet.gr (2003,2004,2005) - Bug Fixes - Raphael Neider rneider@web.de (2004,2005) + Bug Fixes - Raphael Neider (2004,2005) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -59,6 +59,21 @@ * more reliable and (sigh) slighly slower. */ #define USE_SIMPLE_GENCMP 1 +/* The PIC port(s) do not need to distinguish between POINTER and FPOINTER. */ +#define PIC_IS_DATA_PTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x)) +#define PIC_IS_FARPTR(x) (IS_DATA_PTR(x) || IS_FARPTR(x)) +#define PIC_IS_TAGGED(x) (IS_GENPTR(x) || IS_CODEPTR(x)) +#define IS_DIRECT(op) ((AOP_TYPE(op) == AOP_PCODE) && (AOP(op)->aopu.pcop->type == PO_DIR)) + +/* If you change these, you also have to update the library files + * device/lib/pic16/libsdcc/gptr{get,put}{1,2,3,4}.c */ +#define GPTR_TAG_DATA 0x80 +#define GPTR_TAG_EEPROM 0x40 +#define GPTR_TAG_CODE 0x00 /* must be 0 becaue of UPPER(sym)==0 */ + +/* Wrapper to execute `code' at most once. */ +#define PERFORM_ONCE(id,code) do { static char id = 0; if (!id) { id = 1; code } } while (0) + 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 *); @@ -234,7 +249,7 @@ void pic16_emitpcomment (char *fmt, ...) { va_list ap; char lb[INITIAL_INLINEASM]; - unsigned char *lbp = lb; + unsigned char *lbp = (unsigned char *)lb; va_start(ap,fmt); @@ -260,7 +275,7 @@ void DEBUGpic16_emitcode (char *inst,char *fmt, ...) { va_list ap; char lb[INITIAL_INLINEASM]; - unsigned char *lbp = lb; + unsigned char *lbp = (unsigned char *)lb; if(!pic16_debug_verbose) return; @@ -395,7 +410,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) 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); + //fprintf(stderr, "%s:%s:%d: getting free ptr from ic = %c result: %d\n", __FILE__, __FUNCTION__, __LINE__, ic->op, result); fsr2iu = bitVectBitValue(ic->rUsed, IDX_FSR2); @@ -413,7 +428,7 @@ static regs *getFreePtr (iCode *ic, asmop **aopp, bool result) ic->rUsed = bitVectSetBit(ic->rUsed, IDX_FSR0); (*aopp)->type = AOP_FSR0; - fprintf(stderr, "%s:%d returning plain FSR0\n", __FILE__, __LINE__); + //fprintf(stderr, "%s:%d returning plain FSR0\n", __FILE__, __LINE__); return ((*aopp)->aopu.aop_ptr = pic16_regWithIdx(IDX_FSR0)); } @@ -714,7 +729,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) for(i=0;isize;i++) { /* initialise for stack access via frame pointer */ - // operands on stack are accessible via "FSR2 + index" with index + // operands on stack are accessible via "{FRAME POINTER} + index" with index // starting at 2 for arguments and growing from 0 downwards for // local variables (index == 0 is not assigned so we add one here) { @@ -836,14 +851,21 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) } /* if it is in direct space */ if (IN_DIRSPACE(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(!strcmp(sym->rname, "_WREG")) { + sym->aop = aop = newAsmop (AOP_ACC); + aop->size = getSize(sym->type); /* should always be 1 */ + assert(aop->size == 1); + DEBUGpic16_emitcode(";","%d sym->rname (AOP_ACC) = %s, size = %d",__LINE__,sym->rname,aop->size); + return (aop); + } else { + sym->aop = aop = newAsmop (AOP_DIR); + aop->aopu.aop_dir = sym->rname ; + aop->size = getSize(sym->type); + DEBUGpic16_emitcode(";","%d sym->rname (AOP_DIR) = %s, size = %d",__LINE__,sym->rname,aop->size); + pic16_allocDirReg( IC_LEFT(ic) ); + return (aop); + } + } if (IN_FARSPACE(space) && !IN_CODESPACE(space)) { sym->aop = aop = newAsmop (AOP_DIR); @@ -905,7 +927,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) /*-----------------------------------------------------------------*/ /* aopForRemat - rematerialzes an object */ /*-----------------------------------------------------------------*/ -static asmop *aopForRemat (operand *op) // x symbol *sym) +static asmop *aopForRemat (operand *op, bool result) // x symbol *sym) { symbol *sym = OP_SYMBOL(op); operand *refop; @@ -923,6 +945,7 @@ static asmop *aopForRemat (operand *op) // x symbol *sym) DEBUGpic16_emitcode(";","%s %d IS_OP_POINTER",__FUNCTION__,__LINE__); } +// if(!result) /* fixme-vr */ for (;;) { oldic = ic; @@ -1210,7 +1233,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) /* rematerialize it NOW */ if (sym->remat) { - sym->aop = op->aop = aop = aopForRemat (op); + sym->aop = op->aop = aop = aopForRemat (op, result); // aop->size = getSize(sym->type); // DEBUGpic16_emitcode(";"," %d: size %d, %s\n",__LINE__,aop->size,aop->aopu.aop_immd); return; @@ -1539,13 +1562,9 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) return rs; case AOP_REG: - //if (dname) - // return aop->aopu.aop_reg[offset]->dname; - //else - return aop->aopu.aop_reg[offset]->name; + return aop->aopu.aop_reg[offset]->name; case AOP_CRY: - //pic16_emitcode(";","%d",__LINE__); return aop->aopu.aop_dir; case AOP_ACC: @@ -1557,7 +1576,7 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) return (rs); case AOP_LIT: - sprintf(s,"0X%02x", pic16aopLiteral (aop->aopu.aop_lit,offset)); + sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset)); rs = Safe_calloc(1,strlen(s)+1); strcpy(rs,s); return rs; @@ -1570,7 +1589,7 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) // return "acc"; if(!strcmp(aop->aopu.aop_str[offset], "WREG")) { aop->type = AOP_ACC; - return Safe_strdup("WREG"); + return Safe_strdup("_WREG"); } DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]); @@ -1647,7 +1666,7 @@ int _TempReg_lock = 0; /*-----------------------------------------------------------------*/ pCodeOp *pic16_popGetTempReg(int lock) { - pCodeOp *pcop; + pCodeOp *pcop=NULL; symbol *cfunc; // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -1660,6 +1679,34 @@ pCodeOp *pic16_popGetTempReg(int lock) cfunc = currFunc; currFunc = NULL; +#if 0 + { + regs *rr; + int i; + + /* this code might seem better but it does the *same* job with + * the old code, it all depends on ralloc.c to get a free/unused + * register */ + + i=0; + while(i < pic16_nRegs) { + rr = pic16_typeRegWithIdx(i, REG_GPR, 0); + fprintf(stderr, "%s:%d checking for TempReg Idx=%d rr=%p\n", __FILE__, __LINE__, i, rr); + if((!rr || (rr && rr->isFree)) + && !bitVectBitValue(cfunc->regsUsed, i)) { + pcop = pic16_newpCodeOpReg( i ); + PCOR(pcop)->r->wasUsed = 1; + PCOR(pcop)->r->isFree = 0; + break; + } + i++; + } + + if(pcop) { + pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) ); + } + } +#else pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP); if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { PCOR(pcop)->r->wasUsed=1; @@ -1668,6 +1715,7 @@ pCodeOp *pic16_popGetTempReg(int lock) /* push value on stack */ pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) ); } +#endif currFunc = cfunc; @@ -1774,7 +1822,7 @@ void pic16_popReleaseTempReg(pCodeOp *pcop, int lock) /*-----------------------------------------------------------------*/ /* pic16_popGetLabel - create a new pCodeOp of type PO_LABEL */ /*-----------------------------------------------------------------*/ -pCodeOp *pic16_popGetLabel(unsigned int key) +pCodeOp *pic16_popGetLabel(int key) { DEBUGpic16_emitcode ("; ***","%s key=%d, label offset %d",__FUNCTION__,key, pic16_labelOffset); @@ -1821,6 +1869,12 @@ pCodeOp *pic16_popGetLit(int lit) return pic16_newpCodeOpLit(lit); } +/* Allow for 12 bit literals (LFSR x, ). */ +pCodeOp *pic16_popGetLit12(int lit) +{ + return pic16_newpCodeOpLit12(lit); +} + /*-----------------------------------------------------------------*/ /* pic16_popGetLit2 - asm operator to pcode operator conversion */ /*-----------------------------------------------------------------*/ @@ -1878,6 +1932,7 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand //pcop->name = Safe_strdup( ( (str) ? str : "BAD STRING")); PCOR(pcop)->r = pic16_dirregWithName(pcop->name); +// PCOR(pcop)->r->wasUsed = 1; /* make sure that register doesn't exist, * and operand isn't NULL @@ -1889,7 +1944,7 @@ static pCodeOp *pic16_popRegFromString(char *str, int size, int offset, operand // __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); + //fprintf(stderr, "%s:%d: WARNING: need to allocate new register by name -> %s\n", __FILE__, __LINE__, str); } PCOR(pcop)->instance = offset; @@ -1902,11 +1957,14 @@ static pCodeOp *pic16_popRegFromIdx(int rIdx) pCodeOp *pcop; // DEBUGpic16_emitcode ("; ***","%s,%d\trIdx=0x%x", __FUNCTION__,__LINE__,rIdx); - +// fprintf(stderr, "%s:%d rIdx = 0x%0x\n", __FUNCTION__, __LINE__, rIdx); + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); PCOR(pcop)->rIdx = rIdx; PCOR(pcop)->r = pic16_regWithIdx(rIdx); - + if(!PCOR(pcop)->r) + PCOR(pcop)->r = pic16_allocWithIdx(rIdx); + PCOR(pcop)->r->isFree = 0; PCOR(pcop)->r->wasUsed = 1; @@ -1979,13 +2037,13 @@ pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc) /*-----------------------------------------------------------------*/ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) { - //char *s = buffer ; - char *rs; +// char *s = buffer ; +// char *rs; pCodeOp *pcop; - FENTRY2; - /* offset is greater than - size then zero */ + FENTRY2; + /* offset is greater than + * size then zero */ // if (offset > (aop->size - 1) && // aop->type != AOP_LIT) @@ -1993,69 +2051,65 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) /* depending on type */ switch (aop->type) { - - case AOP_R0: - case AOP_R1: - case AOP_DPTR: - case AOP_DPTR2: - 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; + case AOP_R0: + case AOP_R1: + case AOP_DPTR: + case AOP_DPTR2: + DEBUGpic16_emitcode(";8051 legacy","%d type = %s",__LINE__,pic16_AopType(aop->type)); + fprintf(stderr, ";8051 legacy %d type = %s\n",__LINE__,pic16_AopType(aop->type)); + assert( 0 ); + return NULL; + + case AOP_FSR0: + case AOP_FSR2: + pcop = Safe_calloc(1, sizeof(pCodeOpReg)); + PCOR(pcop)->rIdx = aop->aopu.aop_ptr->rIdx+2; /* access PLUSW register */ + PCOR(pcop)->r = pic16_regWithIdx( PCOR(pcop)->rIdx ); + PCOR(pcop)->r->wasUsed = 1; + PCOR(pcop)->r->isFree = 0; - PCOR(pcop)->instance = offset; - pcop->type = PCOR(pcop)->r->pc_type; - return (pcop); - - case AOP_IMMD: - DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__); - return pic16_popGetImmd(aop->aopu.aop_immd,offset,0); - - case AOP_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); + PCOR(pcop)->instance = offset; + pcop->type = PCOR(pcop)->r->pc_type; + return (pcop); + + case AOP_IMMD: + DEBUGpic16_emitcode(";","%d\tAOP_IMMD",__LINE__); + return pic16_popGetImmd(aop->aopu.aop_immd,offset,0); + + case AOP_STA: + /* pCodeOp is already allocated from aopForSym */ + DEBUGpic16_emitcode(";---", "%d getting stack + offset %d\n", __LINE__, offset); + pcop = pic16_pCodeOpCopy(aop->aopu.stk.pop[offset]); + return (pcop); - case AOP_ACC: - { - int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx; + case AOP_ACC: + { + int rIdx = IDX_WREG; //aop->aopu.aop_reg[offset]->rIdx; - fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]); + fprintf(stderr, "%s:%d returning register AOP_ACC %s\n", __FILE__, __LINE__, aop->aopu.aop_str[offset]); - DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__); + DEBUGpic16_emitcode(";","%d\tAOP_ACC", __LINE__); - pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); - PCOR(pcop)->rIdx = rIdx; - PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx); - PCOR(pcop)->r->wasUsed=1; - PCOR(pcop)->r->isFree=0; + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = pic16_typeRegWithIdx(rIdx, REG_SFR, 1); // pic16_regWithIdx(rIdx); + PCOR(pcop)->r->wasUsed=1; + PCOR(pcop)->r->isFree=0; - PCOR(pcop)->instance = offset; - pcop->type = PCOR(pcop)->r->pc_type; -// rs = aop->aopu.aop_reg[offset]->name; -// DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs); - return pcop; + PCOR(pcop)->instance = offset; + pcop->type = PCOR(pcop)->r->pc_type; +// DEBUGpic16_emitcode(";","%d register idx = %d name =%s",__LINE__,rIdx,rs); + return pcop; // return pic16_popRegFromString(aop->aopu.aop_str[offset], aop->size, offset); // return pic16_newpCodeOpRegFromStr(aop->aopu.aop_str[offset]); // assert( 0 ); - } + } case AOP_DIR: - DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__); + DEBUGpic16_emitcode(";","%d\tAOP_DIR (name = %s)", __LINE__, aop->aopu.aop_dir); return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL); #if 0 @@ -2075,7 +2129,7 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); // pcop->type = PO_GPR_REGISTER; PCOR(pcop)->rIdx = rIdx; - PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx); + PCOR(pcop)->r = pic16_allocWithIdx( rIdx ); //pic16_regWithIdx(rIdx); PCOR(pcop)->r->wasUsed=1; PCOR(pcop)->r->isFree=0; @@ -2083,8 +2137,8 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) pcop->type = PCOR(pcop)->r->pc_type; DEBUGpic16_emitcode(";*+*", "%d\tAOP_REG type = %s", __LINE__, dumpPicOptype(pcop->type)); - rs = aop->aopu.aop_reg[offset]->name; - DEBUGpic16_emitcode(";","%d register idx = %d name = %s",__LINE__,rIdx,rs); +// rs = aop->aopu.aop_reg[offset]->name; +// DEBUGpic16_emitcode(";","%d register idx = %d name = %s",__LINE__,rIdx,rs); return pcop; } @@ -2397,6 +2451,20 @@ void pic16_mov2f(asmop *dst, asmop *src, int offset) } } +static void pic16_movLit2f(pCodeOp *pc, int lit) +{ + if (0 == (lit & 0x00ff)) + { + pic16_emitpcode (POC_CLRF, pc); + } else if (0xff == (lit & 0x00ff)) + { + pic16_emitpcode (POC_SETF, pc); + } else { + pic16_emitpcode (POC_MOVLW, pic16_popGetLit (lit & 0x00ff)); + if (pc->type != PO_WREG) pic16_emitpcode (POC_MOVWF, pc); + } +} + static void mov2fp(pCodeOp *dst, asmop *src, int offset) { if(is_LitAOp(src)) { @@ -2417,7 +2485,7 @@ void pic16_testStackOverflow(void) symbol *sym; sym = newSymbol( GSTACK_TEST_NAME , 0 ); - sprintf(sym->rname, "%s%s", port->fun_prefix, GSTACK_TEST_NAME); + sprintf(sym->rname, "%s", /*port->fun_prefix,*/ GSTACK_TEST_NAME); // strcpy(sym->rname, GSTACK_TEST_NAME); checkAddSym(&externs, sym); } @@ -2428,7 +2496,7 @@ void pic16_testStackOverflow(void) void pic16_pushpCodeOp(pCodeOp *pcop) { // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec ))); //&pic16_pc_postdec1))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec ))); if(pic16_options.gstack) pic16_testStackOverflow(); @@ -2462,6 +2530,8 @@ void pushaop(asmop *aop, int offset) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(_G.resDirect)return; + if(is_LitAOp(aop)) { pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset)); pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); @@ -3283,8 +3353,8 @@ static void genCall (iCode *ic) DEBUGpic16_emitcode("; ", "push %d", psuedoStkPtr-1); // pushaop(AOP(IC_LEFT(sic)), size); - pic16_mov2w (AOP(IC_LEFT(sic)), size); - + pic16_mov2w( AOP(IC_LEFT(sic)), size ); + if(!_G.resDirect) pushw(); } @@ -3373,14 +3443,13 @@ static void genCall (iCode *ic) /*-----------------------------------------------------------------*/ static void genPcall (iCode *ic) { - sym_link *ftype, *fntype; + sym_link *fntype; int stackParms=0; symbol *retlbl = newiTempLabel(NULL); pCodeOp *pcop_lbl = pic16_popGetLabel(retlbl->key); FENTRY; - ftype = OP_SYM_TYPE(IC_LEFT(ic)); fntype = operandType( IC_LEFT(ic) )->next; /* if send set is not empty the assign */ @@ -3444,11 +3513,11 @@ static void genPcall (iCode *ic) pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_intcon)); /* 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))); + mov2fp(pic16_popCopyReg(&pic16_pc_pclatu), AOP(IC_LEFT(ic)), 2); + mov2fp(pic16_popCopyReg(&pic16_pc_pclath), AOP(IC_LEFT(ic)), 1); // note: MOVFF to PCL not allowed - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_mov2w(AOP(IC_LEFT(ic)), 0); pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_pcl)); @@ -3716,27 +3785,46 @@ static void genFunction (iCode *ic) /* if callee-save to be used for this function * then save the registers being used in this function */ // if (IFFUNC_CALLEESAVES(sym->type)) - { + if(strcmp(sym->name, "main")) { int i; /* if any registers used */ if (sym->regsUsed) { - /* save the registers used */ - DEBUGpic16_emitcode("; **", "Saving used registers in stack"); - pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN)); - for ( i = 0 ; i < sym->regsUsed->size ; i++) { - if (bitVectBitValue(sym->regsUsed,i)) { - pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); - _G.nRegsSaved++; - - if(!pic16_regWithIdx(i)->wasUsed) { - fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0d\n", - __FILE__, __LINE__, pic16_regWithIdx(i)->name); - pic16_regWithIdx(i)->wasUsed = 1; + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN)); + + if(!xinst) { + /* 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 local register w/rIdx = %d is used in function\n", __FUNCTION__, __LINE__, i); +#endif + pic16_pushpCodeOp( pic16_popRegFromIdx(i) ); + _G.nRegsSaved++; + + if(!pic16_regWithIdx(i)->wasUsed) { + fprintf(stderr, "%s:%d register %s is used in function but was wasUsed = 0\n", + __FILE__, __LINE__, pic16_regWithIdx(i)->name); + pic16_regWithIdx(i)->wasUsed = 1; + } + } + } + } else { + + /* xinst */ + DEBUGpic16_emitcode("; **", "Allocate a space in stack to be used as temporary registers"); + for(i=0;iregsUsed->size;i++) { + if(bitVectBitValue(sym->regsUsed, i)) { + _G.nRegsSaved++; } } + +// pic16_emitpcode(POC_ADDFSR, pic16_popGetLit2(2, pic16_popGetLit(_G.nRegsSaved))); } + pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_END)); + } } @@ -3782,7 +3870,7 @@ static void genEndFunction (iCode *ic) } } - if (sym->regsUsed) { + if (strcmp(sym->name, "main") && sym->regsUsed) { int i; pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN)); @@ -3909,12 +3997,7 @@ void pic16_storeForReturn(iCode *ic, /*operand *op,*/ int offset, pCodeOp *dest) } if(is_LitOp(op)) { - if(/*(OP_LIVETO(op) <= ic->seq) &&*/ (lit == 0)) { - pic16_emitpcode(POC_CLRF, dest); - } else { - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(op), offset)); - if(dest->type != PO_WREG)pic16_emitpcode(POC_MOVWF, dest); - } + pic16_movLit2f(dest, lit); } else { if(dest->type == PO_WREG && (offset == 0)) { pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset)); @@ -5028,6 +5111,7 @@ static void genCmp (operand *left,operand *right, pic16_emitpcode (POC_ADDLW, pic16_popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF)); } // if } else { + /* using PRODL as a temporary register here */ pCodeOp *pctemp = pic16_popCopyReg(&pic16_pc_prodl); //pCodeOp *pctemp = pic16_popGetTempReg(1); pic16_mov2w (AOP(left), size); @@ -5982,6 +6066,7 @@ static void genCmp (operand *left, operand *right, /* signed compare */ DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__); + /* using PRODL:PRODH as a temporary register here */ pct = pic16_popCopyReg(&pic16_pc_prodl); pct2 = pic16_popCopyReg(&pic16_pc_prodh); tlbl = newiTempLabel( NULL ); @@ -7796,13 +7881,13 @@ static void genOr (iCode *ic, iCode *ifx) } else { if (AOP_TYPE(left) == AOP_ACC) { pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset)); - pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); +// pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); } else { pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset)); - pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE)); +// pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); +// pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE)); } } @@ -7843,21 +7928,21 @@ static void genOr (iCode *ic, iCode *ifx) pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - pic16_emitcode("movf","%s,w", - pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s", - pic16_aopGet(AOP(result),offset,FALSE,FALSE)); +// pic16_emitcode("movf","%s,w", +// pic16_aopGet(AOP(left),offset,FALSE,FALSE)); +// pic16_emitcode("movwf","%s", +// pic16_aopGet(AOP(result),offset,FALSE,FALSE)); break; default: pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t)); pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - pic16_emitcode("movlw","0x%x",t); - pic16_emitcode("iorwf","%s,w", - pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s", - pic16_aopGet(AOP(result),offset,FALSE,FALSE)); +// pic16_emitcode("movlw","0x%x",t); +// pic16_emitcode("iorwf","%s,w", +// pic16_aopGet(AOP(left),offset,FALSE,FALSE)); +// pic16_emitcode("movwf","%s", +// pic16_aopGet(AOP(result),offset,FALSE,FALSE)); } continue; @@ -7867,17 +7952,17 @@ static void genOr (iCode *ic, iCode *ifx) // and better if result is SFR if (AOP_TYPE(left) == AOP_ACC) { pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset)); - pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); +// pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); } else { pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset)); - pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode("iorwf","%s,w", - pic16_aopGet(AOP(left),offset,FALSE,FALSE)); +// pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); +// pic16_emitcode("iorwf","%s,w", +// pic16_aopGet(AOP(left),offset,FALSE,FALSE)); } pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE)); +// pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE)); } } @@ -8408,7 +8493,7 @@ static void AccRol (int shCount) /*-----------------------------------------------------------------*/ /* AccLsh - left shift accumulator by known count */ /*-----------------------------------------------------------------*/ -static void AccLsh (int shCount) +static void AccLsh (int shCount, int doMask) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); switch(shCount){ @@ -8441,8 +8526,10 @@ static void AccLsh (int shCount) pic16_emitpcode(POC_RRNCFW,pic16_popCopyReg(&pic16_pc_wreg)); break; } - - pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount])); + if (doMask) { + /* no masking is required in genPackBits */ + pic16_emitpcode(POC_ANDLW,pic16_popGetLit(SLMask[shCount])); + } } /*-----------------------------------------------------------------*/ @@ -8739,7 +8826,7 @@ static void shiftL1Left2Result (operand *left, int offl, // l = pic16_aopGet(AOP(left),offl,FALSE,FALSE); // MOVA(l); /* shift left accumulator */ - //AccLsh(shCount); // don't comment out just yet... + //AccLsh(shCount, 1); // don't comment out just yet... // pic16_aopPut(AOP(result),"a",offr); switch(shCount) { @@ -9110,7 +9197,7 @@ static void shiftLLeftOrResult (operand *left, int offl, pic16_emitpcode(POC_MOVFW,pic16_popGet(AOP(left),offl)); /* shift left accumulator */ - AccLsh(shCount); + AccLsh(shCount, 1); /* or with result */ /* back to result */ pic16_emitpcode(POC_IORWF,pic16_popGet(AOP(result),offr)); @@ -9328,7 +9415,7 @@ void pic16_genLeftShiftLiteral (operand *left, operand *result, iCode *ic) { - int shCount = (int) abs(floatFromVal (AOP(right)->aopu.aop_lit)); + int shCount = abs((int)floatFromVal (AOP(right)->aopu.aop_lit)); int size; FENTRY; @@ -9933,7 +10020,7 @@ static void genRightShiftLiteral (operand *left, iCode *ic, int sign) { - int shCount = (int) abs(floatFromVal (AOP(right)->aopu.aop_lit)); + int shCount = abs((int)floatFromVal (AOP(right)->aopu.aop_lit)); int lsize,res_size; pic16_freeAsmop(right,NULL,ic,TRUE); @@ -10430,10 +10517,21 @@ static void genRightShift (iCode *ic) { /* load FSR0 with address of/from op according to is_LitOp() or if lit is 1 */ void pic16_loadFSR0(operand *op, int lit) { - if(OP_SYMBOL(op)->remat || is_LitOp( op )) { - pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0))); + if((IS_SYMOP(op) && OP_SYMBOL(op)->remat) || is_LitOp( op )) { + if (AOP_TYPE(op) == AOP_LIT) { + /* handle 12 bit integers correctly */ + unsigned int val = (unsigned int)floatFromVal(AOP(op)->aopu.aop_lit); + if ((val & 0x0fff) != val) { + fprintf (stderr, "WARNING: Accessing memory at 0x%x truncated to 0x%x.\n", + val, (val & 0x0fff) ); + val &= 0x0fff; + } + pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGetLit12(val))); + } else { + pic16_emitpcode(POC_LFSR, pic16_popGetLit2(0, pic16_popGet(AOP(op), 0))); + } } else { - assert (!OP_SYMBOL(op)->remat); + assert (!IS_SYMOP(op) || !OP_SYMBOL(op)->remat); // set up FSR0 with address of result pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op),0), pic16_popCopyReg(&pic16_pc_fsr0l))); pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op),1), pic16_popCopyReg(&pic16_pc_fsr0h))); @@ -10447,6 +10545,17 @@ void pic16_loadFSR0(operand *op, int lit) /*----------------------------------------------------------------*/ static void pic16_derefPtr (operand *ptr, int p_type, int doWrite, int *fsr0_setup) { + if (!IS_PTR(operandType(ptr))) + { + if (doWrite) pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(ptr), 0)); + else pic16_mov2w (AOP(ptr), 0); + return; + } + + //assert (IS_DECL(operandType(ptr)) && (p_type == DCL_TYPE(operandType(ptr)))); + /* We might determine pointer type right here: */ + p_type = DCL_TYPE(operandType(ptr)); + switch (p_type) { case FPOINTER: case POINTER: @@ -10465,9 +10574,9 @@ static void pic16_derefPtr (operand *ptr, int p_type, int doWrite, int *fsr0_set if (AOP(ptr)->aopu.aop_reg[2]) { if (doWrite) pic16_emitpcode (POC_MOVWF, pic16_popCopyReg(pic16_stack_postdec)); // prepare call to __gptrget1, this is actually genGenPointerGet(result, WREG, ?ic?) - pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(ptr),0), pic16_popCopyReg(&pic16_pc_fsr0l))); - pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(ptr),1), pic16_popCopyReg(&pic16_pc_prodl))); - pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(ptr),2)); + mov2fp(pic16_popCopyReg(&pic16_pc_fsr0l), AOP(ptr), 0); + mov2fp(pic16_popCopyReg(&pic16_pc_prodl), AOP(ptr), 1); + pic16_mov2w(AOP(ptr), 2); pic16_callGenericPointerRW(doWrite, 1); } else { // data pointer (just 2 byte given) @@ -10498,91 +10607,109 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp sym_link *etype, *letype; int blen=0, bstr=0; int lbstr; + int same; + pCodeOp *op; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - etype = getSpec(operandType(result)); - letype = getSpec(operandType(left)); - -// if(IS_BITFIELD(etype)) { - blen = SPEC_BLEN(etype); - bstr = SPEC_BSTR(etype); -// } + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + etype = getSpec(operandType(result)); + letype = getSpec(operandType(left)); - lbstr = SPEC_BSTR( letype ); + // if(IS_BITFIELD(etype)) { + blen = SPEC_BLEN(etype); + bstr = SPEC_BSTR(etype); + // } -#if 1 - if((blen == 1) && (bstr < 8)) { - /* it is a single bit, so use the appropriate bit instructions */ - DEBUGpic16_emitcode (";","%s %d optimize bit read",__FUNCTION__,__LINE__); + lbstr = SPEC_BSTR( letype ); - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); - - // distinguish (p->bitfield) and p.bitfield, remat seems to work... - if(!IS_PTR(operandType(left))/* && OP_SYMBOL(left)->remat && (ptype == POINTER)*/) { - /* workaround to reduce the extra lfsr instruction */ - pic16_emitpcode(POC_BTFSC, - pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr)); - } else { - pic16_loadFSR0 (left, 0); - pic16_emitpcode(POC_BTFSC, - pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); - } - - pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg)); + DEBUGpic16_emitcode ("; ***","%s %d - reading %s bitfield int %s destination",__FUNCTION__,__LINE__, + SPEC_USIGN(OP_SYM_ETYPE(left)) ? "an unsigned" : "a signed", SPEC_USIGN(OP_SYM_TYPE(result)) ? "an unsigned" : "a signed"); - pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0 )); - return; +#if 1 + if((blen == 1) && (bstr < 8) + && (!IS_PTR(operandType(left)) || IS_DIRECT(left) || PIC_IS_DATA_PTR(operandType(left)))) { + /* it is a single bit, so use the appropriate bit instructions */ + DEBUGpic16_emitcode (";","%s %d optimize bit read",__FUNCTION__,__LINE__); + + same = pic16_sameRegs(AOP(left),AOP(result)); + op = (same ? pic16_popCopyReg(&pic16_pc_wreg) : pic16_popGet (AOP(result),0)); + pic16_emitpcode(POC_CLRF, op); + + if(!IS_PTR(operandType(left)) || IS_DIRECT(left)) { + /* workaround to reduce the extra lfsr instruction */ + pic16_emitpcode(POC_BTFSC, + pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bstr)); + } else { + assert (PIC_IS_DATA_PTR (operandType(left))); + pic16_loadFSR0 (left, 0); + pic16_emitpcode(POC_BTFSC, + pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); } -#endif - - /* 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 */ - - if (!IS_PTR(operandType(left)) /*OP_SYMBOL(left)->remat*/) { - // access symbol directly - pic16_mov2w (AOP(left), 0); + if (SPEC_USIGN(OP_SYM_ETYPE(left))) { + /* unsigned bitfields result in either 0 or 1 */ + pic16_emitpcode(POC_INCF, op); } else { - pic16_derefPtr (left, ptype, 0, NULL); + /* signed bitfields result in either 0 or -1 */ + pic16_emitpcode(POC_DECF, op); + } + if (same) { + pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0 )); } - /* if we have bitdisplacement then it fits */ - /* into this byte completely or if length is */ - /* less than a byte */ - if ((shCnt = SPEC_BSTR(etype)) || - (SPEC_BLEN(etype) <= 8)) { + pic16_addSign (result, 1, !SPEC_USIGN(OP_SYM_TYPE(result))); + return; + } - /* shift right acc */ - AccRsh(shCnt, 0); +#endif - pic16_emitpcode(POC_ANDLW, pic16_popGetLit( - (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ])); + if (!IS_PTR(operandType(left)) || IS_DIRECT(left)) { + // access symbol directly + pic16_mov2w (AOP(left), 0); + } else { + pic16_derefPtr (left, ptype, 0, NULL); + } -/* 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? */ + /* if we have bitdisplacement then it fits */ + /* into this byte completely or if length is */ + /* less than a byte */ + if ((shCnt = SPEC_BSTR(etype)) || (SPEC_BLEN(etype) <= 8)) { -/* - pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype)))); -*/ + /* shift right acc */ + AccRsh(shCnt, 0); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); - return ; - } + pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + (((unsigned char) -1)>>(8 - SPEC_BLEN(etype))) & SRMask[ shCnt ])); + /* VR -- normally I would use the following, but since we use the hack, + * to avoid the masking from AccRsh, why not mask it right now? */ + /* + pic16_emitpcode(POC_ANDLW, pic16_popGetLit(((unsigned char) -1)>>(8 - SPEC_BLEN(etype)))); + */ + + /* extend signed bitfields to 8 bits */ + if (!SPEC_USIGN(OP_SYM_ETYPE(left)) && (bstr + blen < 8)) + { + assert (blen + bstr > 0); + pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr + blen - 1)); + pic16_emitpcode(POC_IORLW, pic16_popGetLit(0xFF << (bstr + blen))); + } - 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); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), 0)); + pic16_addSign (result, 1, !SPEC_USIGN(OP_SYM_TYPE(result))); 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); + + return ; } -static void genDataPointerGet(operand *left, - operand *result, - iCode *ic) +static void genDataPointerGet(operand *left, operand *result, iCode *ic) { int size, offset = 0, leoffset=0 ; @@ -10595,25 +10722,6 @@ static void genDataPointerGet(operand *left, // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size); -#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 - -#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))) { @@ -10622,17 +10730,6 @@ static void genDataPointerGet(operand *left, } #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; @@ -11098,10 +11195,9 @@ static void genGenPointerGet (operand *left, } else { /* we need to get it byte by byte */ /* set up WREG:PRODL:FSR0L with address from left */ - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),0), pic16_popCopyReg(&pic16_pc_fsr0l))); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(left),1), pic16_popCopyReg(&pic16_pc_prodl))); - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), 2)); - + mov2fp(pic16_popCopyReg(&pic16_pc_fsr0l), AOP(left), 0); + mov2fp(pic16_popCopyReg(&pic16_pc_prodl), AOP(left), 1); + pic16_mov2w(AOP(left), 2); pic16_callGenericPointerRW(0, size); assignResultValue(result, 1); @@ -11148,9 +11244,9 @@ static void genConstPointerGet (operand *left, 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))); + mov2fp(pic16_popCopyReg(&pic16_pc_tblptrl), AOP(left), 0); + mov2fp(pic16_popCopyReg(&pic16_pc_tblptrh), AOP(left), 1); + mov2fp(pic16_popCopyReg(&pic16_pc_tblptru), AOP(left), 2); } while(size--) { @@ -11273,224 +11369,243 @@ static void genPackBits (sym_link *etype , operand *result, int offset = 0 ; int rLen = 0 ; int blen, bstr ; + int shifted_and_masked = 0; + unsigned long lit = (unsigned long)-1; sym_link *retype; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - blen = SPEC_BLEN(etype); - bstr = SPEC_BSTR(etype); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + blen = SPEC_BLEN(etype); + bstr = SPEC_BSTR(etype); - retype = getSpec(operandType(right)); + retype = getSpec(operandType(right)); - 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 */ + if(AOP_TYPE(right) == AOP_LIT) { + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + + if((blen == 1) && (bstr < 8)) { + /* it is a single bit, so use the appropriate bit instructions */ - DEBUGpic16_emitcode (";","%s %d optimize bit assignment",__FUNCTION__,__LINE__); + 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(OP_SYMBOL(result)->remat && (p_type == POINTER) && (result)) { - /* workaround to reduce the extra lfsr instruction */ - if(lit) { - pic16_emitpcode(POC_BSF, - pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); - } else { - pic16_emitpcode(POC_BCF, - pic16_popCopyGPR2Bit(pic16_popGet(AOP(result), 0), bstr)); - } - } else { - pic16_loadFSR0(result, 0); - 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; - } - /* move literal to W */ - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right), 0)); - offset++; - } else - if(IS_BITFIELD(retype) - && (AOP_TYPE(right) == AOP_REG || AOP_TYPE(right) == AOP_DIR) - && (blen == 1)) { - int rblen, rbstr; + if(!IS_PTR(operandType(result)) || IS_DIRECT(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 (PIC_IS_DATA_PTR(operandType(result))) { + pic16_loadFSR0(result, 0); + pic16_emitpcode(lit ? POC_BSF : POC_BCF, + pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_indf0), bstr)); + } else { + /* get old value */ + pic16_derefPtr (result, p_type, 0, NULL); + pic16_emitpcode(lit ? POC_BSF : POC_BCF, + pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr)); + /* write back new value */ + pic16_derefPtr (result, p_type, 1, NULL); + } + } - rblen = SPEC_BLEN( retype ); - rbstr = SPEC_BSTR( retype ); - + return; + } + /* IORLW below is more efficient */ + //pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit & ((1UL << blen) - 1)) << bstr)); + lit = (lit & ((1UL << blen) - 1)) << bstr; + shifted_and_masked = 1; + offset++; + } else + if (IS_DIRECT(result) && !IS_PTR(operandType(result)) + && IS_BITFIELD(retype) + && (AOP_TYPE(right) == AOP_REG || AOP_TYPE(right) == AOP_DIR) + && (blen == 1)) { + int rblen, rbstr; + + rblen = SPEC_BLEN( retype ); + rbstr = SPEC_BSTR( retype ); + + if(IS_BITFIELD(etype)) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 0)); + pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr)); + } else { + pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); + } - if(IS_BITFIELD(etype)) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result), 0)); - pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr)); - } else { - pic16_emitpcode(POC_CLRF, pic16_popCopyReg(&pic16_pc_wreg)); - } - - pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), 0), rbstr)); - - if(IS_BITFIELD(etype)) { - pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr)); - } else { - pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg)); - } + pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), 0), rbstr)); - pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0)); - - return; - } else { - /* move right to W */ - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++)); - } + if(IS_BITFIELD(etype)) { + pic16_emitpcode(POC_BSF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_wreg), bstr)); + } else { + pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_wreg)); + } - /* if the bit length is less than or */ - /* it exactly fits a byte then */ - if((shCnt=SPEC_BSTR(etype)) - || SPEC_BLEN(etype) <= 8 ) { - int fsr0_setup = 0; - - if (blen != 8 || bstr != 0) { - // we need to combine the value with the old value - pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1)); - - DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt, - SPEC_BSTR(etype), SPEC_BLEN(etype)); - - /* shift left acc */ - AccLsh(shCnt); - - /* using PRODH as a temporary register here */ - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh)); - - if (IS_SYMOP(result) && !IS_PTR(operandType (result))/*OP_SYMBOL(result)->remat*/) { - /* access symbol directly */ - pic16_mov2w (AOP(result), 0); - } else { - /* get old value */ - pic16_derefPtr (result, p_type, 0, &fsr0_setup); - } -#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_prodh)); - } // if (blen != 8 || bstr != 0) - - /* write new value back */ - if (IS_SYMOP(result) & !IS_PTR(operandType(result))) { - pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0)); - } else { - pic16_derefPtr (result, p_type, 1, &fsr0_setup); - } -#endif + pic16_emitpcode(POC_MOVWF, pic16_popGet( AOP(result), 0)); - return; - } + return; + } else { + /* move right to W */ + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++)); + } + /* if the bit length is less than or */ + /* it exactly fits a byte then */ + if((shCnt=SPEC_BSTR(etype)) + || SPEC_BLEN(etype) <= 8 ) { + int fsr0_setup = 0; -#if 0 - 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); -#endif + if (blen != 8 || bstr != 0) { + // we need to combine the value with the old value + if(!shifted_and_masked) + { + pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1)); + DEBUGpic16_emitcode(";", "shCnt = %d SPEC_BSTR(etype) = %d:%d", shCnt, + SPEC_BSTR(etype), SPEC_BLEN(etype)); - pic16_loadFSR0(result, 0); // load FSR0 with address of result - rLen = SPEC_BLEN(etype)-8; - - /* now generate for lengths greater than one byte */ - while (1) { - rLen -= 8 ; - if (rLen <= 0 ) { - mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), offset); - break ; - } + /* shift left acc, do NOT mask the result again */ + AccLsh(shCnt, 0); - switch (p_type) { - case POINTER: - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0)); - break; + /* using PRODH as a temporary register here */ + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh)); + } -/* - case FPOINTER: - MOVA(l); - pic16_emitcode("movx","@dptr,a"); - break; + if ((IS_SYMOP(result) && !IS_PTR(operandType (result))) + || IS_DIRECT(result)) { + /* access symbol directly */ + pic16_mov2w (AOP(result), 0); + } else { + /* get old value */ + pic16_derefPtr (result, p_type, 0, &fsr0_setup); + } +#if 1 + pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + (unsigned char)((unsigned char)(0xff << (blen+bstr)) | + (unsigned char)(0xff >> (8-bstr))) )); + if (!shifted_and_masked) { + pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh)); + } else { + /* We have the shifted and masked (literal) right value in `lit' */ + if (lit != 0) + pic16_emitpcode(POC_IORLW, pic16_popGetLit(lit)); + } + } // if (blen != 8 || bstr != 0) - case GPOINTER: - MOVA(l); - DEBUGpic16_emitcode(";lcall","__gptrput"); - break; -*/ - default: - assert(0); - } + /* write new value back */ + if ((IS_SYMOP(result) && !IS_PTR(operandType(result))) + || IS_DIRECT(result)) { + pic16_emitpcode (POC_MOVWF, pic16_popGet(AOP(result),0)); + } else { + pic16_derefPtr (result, p_type, 1, &fsr0_setup); + } +#endif + return; + } - pic16_mov2w(AOP(right), offset++); - } - /* last last was not complete */ - if (rLen) { - /* save the byte & read byte */ - switch (p_type) { - case POINTER: -// pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl)); - pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); - break; +#if 0 + 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); +#endif -/* - 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; -*/ - default: - assert(0); - } - DEBUGpic16_emitcode(";", "rLen = %i", rLen); - pic16_emitpcode(POC_ANDLW, pic16_popGetLit((unsigned char)-1 << -rLen)); - pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh)); -// pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) ); -// pic16_emitcode ("orl","a,b"); - } + pic16_loadFSR0(result, 0); // load FSR0 with address of result + rLen = SPEC_BLEN(etype)-8; -// if (p_type == GPOINTER) -// pic16_emitcode("pop","b"); + /* now generate for lengths greater than one byte */ + while (1) { + rLen -= 8 ; + if (rLen <= 0 ) { + mov2fp(pic16_popCopyReg(&pic16_pc_prodh), AOP(right), offset); + break ; + } switch (p_type) { - case POINTER: - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); -// pic16_emitcode("mov","@%s,a",rname); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc0)); break; -/* - case FPOINTER: - pic16_emitcode("movx","@dptr,a"); + + /* + case FPOINTER: + MOVA(l); + pic16_emitcode("movx","@dptr,a"); + break; + + case GPOINTER: + MOVA(l); + DEBUGpic16_emitcode(";lcall","__gptrput"); + break; + */ + default: + assert(0); + } + + + pic16_mov2w(AOP(right), offset++); + } + + /* last last was not complete */ + if (rLen) { + /* save the byte & read byte */ + switch (p_type) { + case POINTER: + // pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl)); + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); break; - - case GPOINTER: - DEBUGpic16_emitcode(";lcall","__gptrput"); - 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; + */ default: - assert(0); + assert(0); } - -// pic16_freeAsmop(right, NULL, ic, TRUE); + DEBUGpic16_emitcode(";", "rLen = %i", rLen); + pic16_emitpcode(POC_ANDLW, pic16_popGetLit((unsigned char)-1 << -rLen)); + pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh)); + // pic16_emitcode ("anl","a,#0x%02x",((unsigned char)-1 << -rLen) ); + // pic16_emitcode ("orl","a,b"); + } + + // if (p_type == GPOINTER) + // pic16_emitcode("pop","b"); + + switch (p_type) { + + case POINTER: + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); + // pic16_emitcode("mov","@%s,a",rname); + break; + /* + case FPOINTER: + pic16_emitcode("movx","@dptr,a"); + break; + + case GPOINTER: + DEBUGpic16_emitcode(";lcall","__gptrput"); + break; + */ + default: + assert(0); + } + + // pic16_freeAsmop(right, NULL, ic, TRUE); } + /*-----------------------------------------------------------------*/ /* genDataPointerSet - remat pointer to data space */ /*-----------------------------------------------------------------*/ @@ -11498,7 +11613,7 @@ static void genDataPointerSet(operand *right, operand *result, iCode *ic) { - int size, offset = 0, resoffset=0 ; + int size, offset = 0, resoffset=0 ; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(right,ic,FALSE); @@ -11517,33 +11632,27 @@ static void genDataPointerSet(operand *right, } #endif - if(AOP(result)->aopu.pcop->type == PO_DIR) - resoffset=PCOR(AOP(result)->aopu.pcop)->instance; + 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; - - if(!IS_FLOAT(operandType( right ))) - lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); - else { - union { - unsigned long lit_int; - float lit_float; - } info; + while (size--) { + if (AOP_TYPE(right) == AOP_LIT) { + unsigned int lit; + + if(!IS_FLOAT(operandType( right ))) + lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + else { + union { + unsigned long lit_int; + float lit_float; + } info; - /* take care if literal is a float */ - info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); - lit = info.lit_int; - } - + /* take care if literal is a float */ + info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + lit = info.lit_int; + } lit = lit >> (8*offset); - if(lit&0xff) { - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit&0xff)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // pstch 8 - } else { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); // patch 8 - } + pic16_movLit2f(pic16_popGet(AOP(result),offset), lit); } else { pic16_mov2w(AOP(right), offset); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); // patch 8 @@ -11569,89 +11678,90 @@ static void genNearPointerSet (operand *right, sym_link *ptype = operandType(result); sym_link *resetype; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - retype= getSpec(operandType(right)); - resetype = getSpec(operandType(result)); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + retype= getSpec(operandType(right)); + resetype = getSpec(operandType(result)); - pic16_aopOp(result,ic,FALSE); + pic16_aopOp(result,ic,FALSE); - /* if the result is rematerializable & - * in data space & not a bit variable */ + /* 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; - } + /* 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)) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_aopOp(right,ic,FALSE); - DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); + genDataPointerSet (right,result,ic); + pic16_freeAsmop(result,NULL,ic,TRUE); + return; + } - /* 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__); + pic16_aopOp(right,ic,FALSE); + DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - pic16_loadFSR0(result, 0); - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - 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 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__); - /* 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); + pic16_loadFSR0(result, 0); + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + 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++; } + } + + 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 */ @@ -11953,7 +12063,7 @@ static void genGenPointerSet (operand *right, /* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */ /* value of right+0 is placed on stack, which will be retrieved - * by the support function this restoring the stack. The important + * by the support function thus restoring the stack. The important * thing is that there is no need to manually restore stack pointer * here */ pushaop(AOP(right), 0); @@ -12115,18 +12225,20 @@ static void genAddrOf (iCode *ic) // starting at 2 for arguments and growing from 0 downwards for // local variables (index == 0 is not assigned so we add one here) { - int soffs = OP_SYMBOL( IC_LEFT(ic))->stack; - if (soffs <= 0) { - assert (soffs < 0); - soffs++; - } // if - DEBUGpic16_emitcode("*!*", "accessing stack symbol at offset=%d", soffs); - pic16_emitpcode(POC_MOVLW , pic16_popGetLit( soffs & 0x00FF )); - pic16_emitpcode(POC_ADDFW , pic16_popCopyReg(pic16_framepnt_lo)); - pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 0)); - pic16_emitpcode(POC_MOVLW , pic16_popGetLit( (soffs >> 8) & 0x00FF )); - pic16_emitpcode(POC_ADDFWC, pic16_popCopyReg(pic16_framepnt_hi)); - pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 1)); + int soffs = OP_SYMBOL( IC_LEFT(ic))->stack; + + if (soffs <= 0) { + assert (soffs < 0); + soffs++; + } // if + + DEBUGpic16_emitcode("*!*", "accessing stack symbol at offset=%d", soffs); + pic16_emitpcode(POC_MOVLW , pic16_popGetLit( soffs & 0x00FF )); + pic16_emitpcode(POC_ADDFW , pic16_popCopyReg(pic16_framepnt_lo)); + pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 0)); + pic16_emitpcode(POC_MOVLW , pic16_popGetLit( (soffs >> 8) & 0x00FF )); + pic16_emitpcode(POC_ADDFWC, pic16_popCopyReg(pic16_framepnt_hi)); + pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 1)); } goto release; @@ -12203,191 +12315,212 @@ static void genFarFarAssign (operand *result, operand *right, iCode *ic) static void genAssign (iCode *ic) { operand *result, *right; + sym_link *restype, *rtype; int size, offset,know_W; unsigned long lit = 0L; - result = IC_RESULT(ic); - right = IC_RIGHT(ic) ; + result = IC_RESULT(ic); + right = IC_RIGHT(ic) ; - FENTRY; + FENTRY; - /* if they are the same */ - if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic))) - return ; + /* if they are the same */ + if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic))) + return ; - /* reversed order operands are aopOp'ed so that result operand - * is effective in case right is a stack symbol. This maneauver - * allows to use the _G.resDirect flag later */ - pic16_aopOp(result,ic,TRUE); - pic16_aopOp(right,ic,FALSE); + /* reversed order operands are aopOp'ed so that result operand + * is effective in case right is a stack symbol. This maneauver + * allows to use the _G.resDirect flag later */ + pic16_aopOp(result,ic,TRUE); + pic16_aopOp(right,ic,FALSE); - DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); + DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - /* if they are the same registers */ - if (pic16_sameRegs(AOP(right),AOP(result))) - goto release; + /* if they are the same registers */ + if (pic16_sameRegs(AOP(right),AOP(result))) + goto release; - /* 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 */ - if (AOP_TYPE(right) == AOP_LIT) { + /* 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 */ + if (AOP_TYPE(right) == AOP_LIT) { - pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF), - pic16_popGet(AOP(result),0)); + 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; - } + 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; + } + + /* the right is also a bit variable */ + if (AOP_TYPE(right) == AOP_CRY) { + pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); + + goto release ; + } - /* the right is also a bit variable */ - if (AOP_TYPE(right) == AOP_CRY) { + /* we need to or */ pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + pic16_toBoolean(right); + emitSKPZ; pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); - - pic16_emitcode("bcf","(%s >> 3),(%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - pic16_emitcode("btfsc","(%s >> 3),(%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - pic16_emitcode("bsf","(%s >> 3),(%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); + //pic16_aopPut(AOP(result),"a",0); goto release ; } - /* we need to or */ - pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); - pic16_toBoolean(right); - emitSKPZ; - pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); - //pic16_aopPut(AOP(result),"a",0); - goto release ; - } + /* bit variables done */ + /* general case */ + size = AOP_SIZE(result); + offset = 0 ; /* bit variables done */ /* general case */ size = AOP_SIZE(result); + restype = operandType(result); + rtype = operandType(right); offset = 0 ; if(AOP_TYPE(right) == AOP_LIT) { - if(!(IS_FLOAT(operandType( right )) || IS_FIXED(operandType(right)))) - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - else{ - union { - unsigned long lit_int; - float lit_float; - } info; - + if(!(IS_FLOAT(operandType( right )) || IS_FIXED(operandType(right)))) + { + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - if(IS_FIXED16X16(operandType(right))) { - lit = (unsigned long)fixed16x16FromDouble( floatFromVal( AOP(right)->aopu.aop_lit)); - } else { - /* take care if literal is a float */ - info.lit_float = floatFromVal(AOP(right)->aopu.aop_lit); - lit = info.lit_int; - } + /* patch tag for literals that are cast to pointers */ + if (IS_CODEPTR(restype)) { + //fprintf (stderr, "%s:%u: INFO: `(__code*)literal'\n", ic->filename, ic->lineno); + lit = (lit & 0x00ffff) | (GPTR_TAG_CODE << 16); + } else { + if (IS_GENPTR(restype)) + { + if (IS_CODEPTR(rtype)) { + //fprintf (stderr, "%s:%u: INFO: `(generic*)(literal __code*)'\n", ic->filename, ic->lineno); + lit = (lit & 0x00ffff) | (GPTR_TAG_CODE << 16); + } else if (PIC_IS_DATA_PTR(rtype)) { + //fprintf (stderr, "%s:%u: INFO: `(generic*)(literal __data*)'\n", ic->filename, ic->lineno); + lit = (lit & 0x00ffff) | (GPTR_TAG_DATA << 16); + } else if (!IS_PTR(rtype) || IS_GENPTR(rtype)) { + //fprintf (stderr, "%s:%u: INFO: `(generic*)literal' -- accepting specified tag %02x\n", ic->filename, ic->lineno, (unsigned char)(lit >> 16)); + } else if (IS_PTR(rtype)) { + fprintf (stderr, "%s:%u: WARNING: `(generic*)literal' -- assuming __data space\n", ic->filename, ic->lineno); + lit = (lit & 0x00ffff) | (GPTR_TAG_DATA << 16); + } } + } + } else { + union { + unsigned long lit_int; + float lit_float; + } info; + + + if(IS_FIXED16X16(operandType(right))) { + lit = (unsigned long)fixed16x16FromDouble( floatFromVal( AOP(right)->aopu.aop_lit)); + } else { + /* 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_REG) { - DEBUGpic16_emitcode("; ", "%s:%d assign from register\n", __FUNCTION__, __LINE__); - while (size--) { - pic16_emitpcode (POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset++)); - } // while - goto release; - } - - /* when do we have to read the program memory? - * - if right itself is a symbol in code space - * (we don't care what it points to if it's a pointer) - * - AND right is not a function (we would want its address) - */ - if(AOP_TYPE(right) != AOP_LIT - && IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(right))) - && !IS_FUNC(OP_SYM_TYPE(right)) - && !IS_ITEMP(right)) - { - DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__); - fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name); - - // set up table pointer - if(is_LitOp(right)) { -// 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))); - } + if (AOP_TYPE(right) == AOP_REG) { + DEBUGpic16_emitcode("; ", "%s:%d assign from register\n", __FUNCTION__, __LINE__); + while (size--) { + pic16_emitpcode (POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset++)); + } // while + goto release; + } - /* must fetch 3 bytes for pointers (was OP_SYM_ETYPE before) */ - size = min(getSize(OP_SYM_TYPE(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++; - } + /* when do we have to read the program memory? + * - if right itself is a symbol in code space + * (we don't care what it points to if it's a pointer) + * - AND right is not a function (we would want its address) + */ + if(AOP_TYPE(right) != AOP_LIT + && IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(right))) + && !IS_FUNC(OP_SYM_TYPE(right)) + && !IS_ITEMP(right)) { - /* FIXME: for pointers we need to extend differently (according - * to pointer type DATA/CODE/EEPROM/... :*/ - size = getSize(OP_SYM_TYPE(right)); - if(AOP_SIZE(result) > size) { - size = AOP_SIZE(result) - size; - while(size--) { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset)); - offset++; - } - } - goto release; - } + 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(is_LitOp(right)) { +// 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))); + } + /* must fetch 3 bytes for pointers (was OP_SYM_ETYPE before) */ + size = min(getSize(OP_SYM_TYPE(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++; + } + /* FIXME: for pointers we need to extend differently (according + * to pointer type DATA/CODE/EEPROM/... :*/ + size = getSize(OP_SYM_TYPE(right)); + if(AOP_SIZE(result) > size) { + size = AOP_SIZE(result) - size; + 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__); - if(aopIdx(AOP(result),0) == 4) { - - /* this is a workaround to save value of right into wreg too, - * value of wreg is going to be used later */ + /* VR - What is this?! */ + if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) { 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 + + if(aopIdx(AOP(result),0) == 4) { + /* 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 size %d",__FUNCTION__,__LINE__, size); + DEBUGpic16_emitcode ("; ***","%s %d size %d",__FUNCTION__,__LINE__, size); if(AOP_TYPE(right) == AOP_LIT) { if(lit&0xff) { if(know_W != (lit&0xff)) @@ -12412,17 +12545,25 @@ static void genAssign (iCode *ic) } else { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(!_G.resDirect) /* use this aopForSym feature */ - pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset)); + if(!_G.resDirect) { /* use this aopForSym feature */ + if(AOP_TYPE(result) == AOP_ACC) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset)); + } else + if(AOP_TYPE(right) == AOP_ACC) { + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset)); + } + } + } + + offset++; } - - offset++; - } - release: +release: pic16_freeAsmop (right,NULL,ic,FALSE); pic16_freeAsmop (result,NULL,ic,TRUE); -} +} /*-----------------------------------------------------------------*/ /* genJumpTab - generates code for jump table */ @@ -12737,6 +12878,74 @@ static void genCast (iCode *ic) && IS_BITFIELD(getSpec(rtype))) { DEBUGpic16_emitcode("***", "%d casting a bit to another bit", __LINE__); } + + /* port from pic14 to cope with generic pointers */ + if (PIC_IS_TAGGED(restype)) + { + operand *result = IC_RESULT(ic); + //operand *left = IC_LEFT(ic); + operand *right = IC_RIGHT(ic); + int tag = 0xff; + + /* copy common part */ + int max, size = AOP_SIZE(result); + if (size > AOP_SIZE(right)) size = AOP_SIZE(right); + DEBUGpic16_emitcode("; ***","%s %d",__FUNCTION__,__LINE__); + + max = size; + while (size--) + { + pic16_mov2w (AOP(right), size); + pic16_emitpcode(POC_MOVWF, pic16_popGet (AOP(result), size)); + } // while + + /* upcast into generic pointer type? */ + if (IS_GENPTR(restype) + && !PIC_IS_TAGGED(rtype) + && (AOP_SIZE(result) > max)) + { + /* determine appropriate tag for right */ + if (PIC_IS_DATA_PTR(rtype)) + tag = GPTR_TAG_DATA; + else if (IS_CODEPTR(rtype)) + tag = GPTR_TAG_CODE; + else if (PIC_IS_DATA_PTR(ctype)) { + //fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(__data*)(non-pointer)'\n", ic->filename, ic->lineno); + tag = GPTR_TAG_DATA; + } else if (IS_CODEPTR(ctype)) { + //fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(__code*)(non-pointer)'\n", ic->filename, ic->lineno); + tag = GPTR_TAG_CODE; + } else if (IS_PTR(rtype)) { + PERFORM_ONCE(weirdcast, + fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(unknown*)' -- assumimg __data space\n", ic->filename, ic->lineno); + ); + tag = GPTR_TAG_DATA; + } else { + PERFORM_ONCE(weirdcast, + fprintf (stderr, "%s:%u: WARNING: casting `(generic*)(non-pointer)' -- assumimg __data space\n", ic->filename, ic->lineno); + ); + tag = GPTR_TAG_DATA; + } + + assert (AOP_SIZE(result) == 3); + /* zero-extend address... */ + for (size = max; size < AOP_SIZE(result)-1; size++) + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),size)); + /* ...and add tag */ + pic16_movLit2f(pic16_popGet(AOP(result), AOP_SIZE(result)-1), tag); + } else if (IS_CODEPTR(restype) && AOP_SIZE(result) > max) { + //fprintf (stderr, "%s:%u: INFO: code pointer\n", ic->filename, ic->lineno); + for (size = max; size < AOP_SIZE(result)-1; size++) + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), size)); + /* add __code tag */ + pic16_movLit2f (pic16_popGet(AOP(result), AOP_SIZE(result)-1), GPTR_TAG_CODE); + } else if (AOP_SIZE(result) > max) { + /* extend non-pointers */ + //fprintf (stderr, "%s:%u: zero-extending value cast to pointer\n", ic->filename, ic->lineno); + pic16_addSign(result, max, 0); + } // if + goto release; + } /* if they are the same size : or less */ if (AOP_SIZE(result) <= AOP_SIZE(right)) { @@ -12873,19 +13082,14 @@ static void genCast (iCode *ic) switch (p_type) { case IPOINTER: case POINTER: - 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)); + case FPOINTER: + pic16_movLit2f(pic16_popGet(AOP(result), GPTRSIZE-1), GPTR_TAG_DATA); 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 PPOINTER: pic16_emitcode(";BUG!? ","%d",__LINE__); l = "#0x03"; @@ -12893,9 +13097,8 @@ static void genCast (iCode *ic) case GPOINTER: if (GPTRSIZE > AOP_SIZE(right)) { - // assume data pointer... THIS MIGHT BE WRONG! - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), GPTRSIZE - 1)); + // assume __data pointer... THIS MIGHT BE WRONG! + pic16_movLit2f(pic16_popGet(AOP(result), GPTRSIZE-1), GPTR_TAG_DATA); } else { pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1)); } @@ -13174,7 +13377,7 @@ void genpic16Code (iCode *lic) 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