X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgen.c;h=0a15d8cfcfa4677b287643dc951553b40947dcb6;hb=9182d601aa287fff2b037d607180a06bcf0b281b;hp=7646de4f02c0bcd0fc4a5d959a6580a29a87c1e3;hpb=cc2423da79ce6f6eedb517fd5a14290e355e3529;p=fw%2Fsdcc diff --git a/src/pic16/gen.c b/src/pic16/gen.c index 7646de4f..0a15d8cf 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -6,7 +6,7 @@ Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a) PIC port - Scott Dattalo scott@dattalo.com (2000) PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002) - - Vangelis Rokas vrokas@otenet.gr (2003,2004) + - Vangelis Rokas vrokas@otenet.gr (2003,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 @@ -153,7 +153,6 @@ static struct { short ipushRegs; set *sendSet; set *stackRegSet; - int interruptvector; int usefastretfie; bitVect *fregsUsed; int stack_lat; /* stack offset latency */ @@ -648,11 +647,29 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) } #endif + +#if 0 + if(sym->iaccess) { + if(space->paged) { + fprintf(stderr, "%s:%d symbol %s points to paged data\n", __FILE__, __LINE__, sym->name); + + sym->aop = aop = newAsmop (AOP_PAGED); + 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; + } + assert( 0 ); + } +#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 || sym->iaccess) { + if (sym->onStack) // || sym->iaccess) + { pCodeOp *pcop[4]; int i; @@ -704,7 +721,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) } // if pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/)); pic16_emitpcode(POC_MOVFF, pic16_popGet2p( - pic16_popCopyReg(&pic16_pc_plusw2), pcop[i])); + pic16_popCopyReg( pic16_frame_plusw ), pcop[i])); } } @@ -780,7 +797,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) } #endif -#if 0 +#if 1 /* special case for a function */ if (IS_FUNC(sym->type)) { sym->aop = aop = newAsmop(AOP_PCODE); @@ -852,11 +869,15 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) 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(IC_LEFT(ic) && AOP(IC_LEFT(ic))) aop->size = AOP_SIZE( IC_LEFT(ic) ); + else if(IC_RIGHT(ic) && AOP(IC_RIGHT(ic))) aop->size = AOP_SIZE( IC_RIGHT(ic) ); else if(sym->onStack) { aop->size = PTRSIZE; } else { + if(SPEC_SCLS(sym->etype) == S_PDATA) { + fprintf(stderr, "%s: %d symbol in PDATA space\n", __FILE__, __LINE__); + aop->size = FPTRSIZE; + } else assert( 0 ); } @@ -1069,10 +1090,12 @@ bool pic16_sameRegs (asmop *aop1, asmop *aop2 ) aop2->type != AOP_REG ) return FALSE ; + /* This is a bit too restrictive if one is a subset of the other... if (aop1->size != aop2->size ) return FALSE ; + */ - for (i = 0 ; i < aop1->size ; i++ ) { + for (i = 0 ; i < min(aop1->size, aop2->size) ; i++ ) { // if(aop1->aopu.aop_reg[i]->type != aop2->aopu.aop_reg[i]->type)return FALSE; // if(aop1->aopu.aop_reg[i]->type == AOP_REG) @@ -1170,6 +1193,7 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) b) has a spill location */ if (sym->isspilt || sym->nRegs == 0) { +// debugf2("%s:%d symbol %s\tisspilt: %d\tnRegs: %d\n", sym->isspilt, sym->nRegs); DEBUGpic16_emitcode(";","%d",__LINE__); /* rematerialize it NOW */ if (sym->remat) { @@ -1230,9 +1254,16 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) 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 = pic16_popRegFromString(sym->usl.spillLoc->rname, - getSize(sym->type), - sym->usl.spillLoc->offset, op); + if (sym->usl.spillLoc && sym->usl.spillLoc->rname) { + aop->aopu.pcop = pic16_popRegFromString(sym->usl.spillLoc->rname, + getSize(sym->type), + sym->usl.spillLoc->offset, op); + } else { + fprintf (stderr, "%s:%d called for a spillLocation -- assigning WREG instead --- CHECK!\n", __FUNCTION__, __LINE__); + DEBUGpic16_emitcode (";","%s:%d called for a spillLocation -- assigning WREG instead --- CHECK", __FUNCTION__, __LINE__); + assert (getSize(sym->type) <= 1); + aop->aopu.pcop = pic16_popCopyReg (&pic16_pc_wreg);//pic16_popRegFromString("_WREG", getSize(sym->type), 0, op); + } aop->size = getSize(sym->type); return; @@ -1335,7 +1366,7 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) /* initialise for stack access via frame pointer */ pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/)); pic16_emitpcode(POC_MOVFF, pic16_popGet2p( - aop->aopu.stk.pop[i], pic16_popCopyReg(&pic16_pc_plusw2))); + aop->aopu.stk.pop[i], pic16_popCopyReg(pic16_frame_plusw))); } if(_G.accInUse)pic16_poppCodeOp( pic16_popCopyReg(&pic16_pc_wreg) ); @@ -1543,6 +1574,21 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) strcpy(rs,s); return rs; +#if 0 + case AOP_PAGED: + DEBUGpic16_emitcode(";","oops AOP_PAGED did this %s\n",s); + if (offset) { + sprintf(s,"(%s + %d)", + aop->aopu.aop_dir, + offset); + } else + sprintf(s,"%s",aop->aopu.aop_dir); + DEBUGpic16_emitcode(";","oops AOP_PAGED did this %s\n",s); + rs = Safe_calloc(1,strlen(s)+1); + strcpy(rs,s); + return rs; +#endif + case AOP_STA: rs = Safe_strdup(PCOR(aop->aopu.stk.pop[offset])->r->name); return (rs); @@ -1941,6 +1987,12 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__); return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL); +#if 0 + case AOP_PAGED: + DEBUGpic16_emitcode(";","%d\tAOP_DIR", __LINE__); + return pic16_popRegFromString(aop->aopu.aop_dir, aop->size, offset, NULL); +#endif + case AOP_REG: { int rIdx; @@ -1998,16 +2050,14 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) __LINE__, ((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 + switch( aop->aopu.pcop->type ) { + case PO_DIR: PCOR(pcop)->instance += offset; break; + case PO_IMMEDIATE: PCOI(pcop)->offset = offset; break; + case PO_WREG: assert (offset==0); break; + default: + fprintf (stderr, "%s: unhandled aop->aopu.pcop->type %d\n", __FUNCTION__, aop->aopu.pcop->type); + assert( 0 ); /* should never reach here */; + } return pcop; } @@ -2304,7 +2354,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_pc_postdec1))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec ))); //&pic16_pc_postdec1))); if(pic16_options.gstack) pic16_testStackOverflow(); @@ -2313,7 +2363,7 @@ void pic16_pushpCodeOp(pCodeOp *pcop) /* pop pcop from stack */ void pic16_poppCodeOp(pCodeOp *pcop) { - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_preinc1), pcop)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg( pic16_stack_preinc ), pcop)); if(pic16_options.gstack) pic16_testStackOverflow(); } @@ -2325,7 +2375,7 @@ void pic16_poppCodeOp(pCodeOp *pcop) void pushw(void) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); //&pic16_pc_postdec1)); if(pic16_options.gstack) pic16_testStackOverflow(); } @@ -2340,13 +2390,12 @@ void pushaop(asmop *aop, int offset) if(is_LitAOp(aop)) { pic16_emitpcode(POC_MOVLW, pic16_popGet(aop, offset)); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postdec1)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); //&pic16_pc_postdec1)); } else { pic16_emitpcode(POC_MOVFF, - pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg(&pic16_pc_postdec1))); + pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec ))); //&pic16_pc_postdec1))); } -// pic16_emitpcode(POC_MOVFF, pic16_popCombine2(PCOR(pic16_popGet(aop, offset)), &pic16_pc_postdec1, 0)); if(pic16_options.gstack) pic16_testStackOverflow(); } @@ -2357,7 +2406,7 @@ void pushaop(asmop *aop, int offset) 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)); + pic16_emitpcode(POC_MOVFF, pic16_popCombine2(pic16_stack_preinc, PCOR(pic16_popGet(aop, offset)), 0)); if(pic16_options.gstack) pic16_testStackOverflow(); } @@ -2371,7 +2420,7 @@ void popaopidx(asmop *aop, int offset, int index) 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)); + pic16_emitpcode(POC_MOVFF, pic16_popCombine2(pic16_frame_plusw, PCOR(pic16_popGet(aop, offset)), 0)); if(pic16_options.gstack) pic16_testStackOverflow(); } @@ -2685,6 +2734,8 @@ static void genUminus (iCode *ic) { int size, i; sym_link *optype, *rtype; + symbol *label; + int needLabel=0; FENTRY; @@ -2713,21 +2764,33 @@ static void genUminus (iCode *ic) /* otherwise subtract from zero by taking the 2's complement */ size = AOP_SIZE(IC_LEFT(ic)); - - for(i=0; i 0; i--) { + pic16_emitpcode (POC_COMF, pic16_popGet (AOP(IC_LEFT(ic)), i)); + } // for + pic16_emitpcode (POC_NEGF, pic16_popGet (AOP(IC_LEFT(ic)), 0)); + for (i=1; i < size; i++) { + if (i == size - 1) { emitSKPNZ; } else { pic16_emitpcode (POC_BNZ, pic16_popGetLabel (label->key)); needLabel++; } + pic16_emitpcode (POC_INCF, pic16_popGet (AOP(IC_LEFT(ic)), i)); + } // for + } else { + for (i=size-1; i >= 0; i--) { + pic16_emitpcode (POC_COMFW, pic16_popGet (AOP(IC_LEFT(ic)), i)); + pic16_emitpcode (POC_MOVWF, pic16_popGet (AOP(IC_RESULT(ic)), i)); + } // for + if (size > 1) { + for (i=0; i < size-2; i++) { + pic16_emitpcode (POC_INCF, pic16_popGet (AOP(IC_RESULT(ic)),i)); + pic16_emitpcode (POC_BNZ, pic16_popGetLabel (label->key)); needLabel++; + } // for + pic16_emitpcode (POC_INFSNZ, pic16_popGet (AOP(IC_RESULT(ic)), size-2)); + } // if + pic16_emitpcode (POC_INCF, pic16_popGet(AOP(IC_RESULT(ic)), size-1)); } + if (needLabel) + pic16_emitpLabel (label->key); release: /* release the aops */ @@ -2925,10 +2988,10 @@ static void assignResultValue(operand * oper, int rescall) /* fix stack */ pic16_emitpcode(POC_MOVLW, pic16_popGetLit( AOP_SIZE(oper) )); - pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l )); + pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo )); //&pic16_pc_fsr1l )); if(STACK_MODEL_LARGE) { emitSKPNC; - pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h )); + pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi )); //&pic16_pc_fsr1h )); } } } else { @@ -3177,7 +3240,7 @@ static void genCall (iCode *ic) // stackParms = psuedoStkPtr; // fprintf(stderr, "%s:%d ic parmBytes = %d\n", __FILE__, __LINE__, ic->parmBytes); fname = OP_SYMBOL(IC_LEFT(ic))->rname[0]?OP_SYMBOL(IC_LEFT(ic))->rname:OP_SYMBOL(IC_LEFT(ic))->name; - inwparam = inWparamList(OP_SYMBOL(IC_LEFT(ic))->name); + inwparam = (inWparamList(OP_SYMBOL(IC_LEFT(ic))->name)) || (FUNC_ISWPARAM(OP_SYM_TYPE(IC_LEFT(ic)))); #if 0 gpsimDebug_StackDump(__FILE__, __LINE__, fname ); @@ -3293,14 +3356,14 @@ static void genCall (iCode *ic) if(stackParms>0) { if(stackParms == 1) { - pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1l)); + pic16_emitpcode(POC_INCF, pic16_popCopyReg(pic16_stackpnt_lo )); //&pic16_pc_fsr1l)); } else { pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms)); - pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l )); + pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo )); //&pic16_pc_fsr1l )); } if(STACK_MODEL_LARGE) { emitSKPNC; - pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h )); + pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi )); //&pic16_pc_fsr1h )); } } @@ -3381,6 +3444,11 @@ static void genPcall (iCode *ic) // push return address // push $ on return stack, then replace with retlbl + /* Thanks to Thorsten Klose for pointing out that the following + * snippet should be interrupt safe */ + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_intcon), pic16_popCopyReg(&pic16_pc_postdec1))); + pic16_emitpcode(POC_BCF, pic16_popCopyGPR2Bit(pic16_popCopyReg(&pic16_pc_intcon), 7)); + pic16_emitpcodeNULLop(POC_PUSH); pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 0, 0)); @@ -3390,6 +3458,11 @@ static void genPcall (iCode *ic) pic16_emitpcode(POC_MOVLW, pic16_popGetImmd(pcop_lbl->name, 2, 0)); pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_tosu)); + + /* restore interrupt control register */ + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_preinc1)); + 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))); @@ -3427,11 +3500,10 @@ static void genPcall (iCode *ic) if(stackParms>0) { pic16_emitpcode(POC_MOVLW, pic16_popGetLit(stackParms)); - pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( &pic16_pc_fsr1l )); + pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo )); if(STACK_MODEL_LARGE) { - /* this implies that stackParms < 256 !!! -- VR */ emitSKPNC; - pic16_emitpcode(POC_INCF, pic16_popCopyReg( &pic16_pc_fsr1h )); + pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi )); } } } @@ -3509,6 +3581,10 @@ static void genFunction (iCode *ic) char asymname[128]; pBlock *apb; + +// debugf("interrupt number: %hhi\n", FUNC_INTNO(sym->type)); + +#if 0 { int i, found=-1; @@ -3524,12 +3600,16 @@ static void genFunction (iCode *ic) if(found == -1) { fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n", __FILE__, __LINE__, sym->name); - assert( 0 ); +// assert( 0 ); } _G.interruptvector = found; } +#endif - sprintf(asymname, "ivec_%d_%s", _G.interruptvector, sym->name); + if(FUNC_INTNO(sym->type) == 256) + sprintf(asymname, "ivec_%s", sym->name); + else + sprintf(asymname, "ivec_0x%x_%s", FUNC_INTNO(sym->type), sym->name); asym = newSymbol(asymname, 0); apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section")); @@ -3548,14 +3628,18 @@ static void genFunction (iCode *ic) abSym = Safe_calloc(1, sizeof(absSym)); strcpy(abSym->name, asymname); - switch( _G.interruptvector ) { + switch( FUNC_INTNO(sym->type) ) { case 0: abSym->address = 0x000000; break; case 1: abSym->address = 0x000008; break; case 2: abSym->address = 0x000018; break; + + default: + abSym->address = -1; break; } /* relocate interrupt vectors if needed */ - abSym->address += pic16_options.ivt_loc; + if(abSym->address != -1) + abSym->address += pic16_options.ivt_loc; addSet(&absSymSet, abSym); } @@ -3600,7 +3684,7 @@ static void genFunction (iCode *ic) _G.usefastretfie = 1; /* use shadow registers by default */ /* an ISR should save: WREG, STATUS, BSR, PRODL, PRODH, FSR0L, FSR0H */ - if(!(_G.interruptvector == 1)) { + if(!FUNC_ISSHADOWREGS(sym->type)) { /* do not save WREG,STATUS,BSR for high priority interrupts * because they are stored in the hardware shadow registers already */ _G.usefastretfie = 0; @@ -3628,12 +3712,12 @@ static void genFunction (iCode *ic) if(1 /*!options.ommitFramePtr || sym->regsUsed*/) { /* setup the stack frame */ if(STACK_MODEL_LARGE) - pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_fsr2h)); - pic16_pushpCodeOp(pic16_popCopyReg(&pic16_pc_fsr2l)); -// 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)); + pic16_pushpCodeOp(pic16_popCopyReg(pic16_framepnt_hi)); + pic16_pushpCodeOp(pic16_popCopyReg(pic16_framepnt_lo)); + + pic16_emitpcode(POC_MOVFF, pic16_popCombine2( pic16_stackpnt_lo, pic16_framepnt_lo, 0)); if(STACK_MODEL_LARGE) - pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_fsr1h, &pic16_pc_fsr2h, 0)); + pic16_emitpcode(POC_MOVFF, pic16_popCombine2( pic16_stackpnt_hi, pic16_framepnt_hi, 0)); } } @@ -3643,12 +3727,12 @@ static void genFunction (iCode *ic) if (sym->stack > 127)werror(W_STACK_OVERFLOW, sym->name); pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack)); - pic16_emitpcode(POC_SUBWF, pic16_popCopyReg(&pic16_pc_fsr1l)); + pic16_emitpcode(POC_SUBWF, pic16_popCopyReg( pic16_stackpnt_lo )); //&pic16_pc_fsr1l)); emitSKPC; - pic16_emitpcode(POC_DECF, pic16_popCopyReg(&pic16_pc_fsr1h)); + pic16_emitpcode(POC_DECF, pic16_popCopyReg( pic16_stackpnt_hi )); //&pic16_pc_fsr1h)); } - if(inWparamList(sym->name)) { + if(inWparamList(sym->name) || FUNC_ISWPARAM(sym->type)) { if(IFFUNC_HASVARARGS(sym->type) || IFFUNC_ISREENT(sym->type)) _G.useWreg = 0; else @@ -3733,17 +3817,17 @@ static void genEndFunction (iCode *ic) if ((IFFUNC_ISREENT(sym->type) || options.stackAuto) && sym->stack) { if (sym->stack == 1) { - pic16_emitpcode(POC_INFSNZ, pic16_popCopyReg(&pic16_pc_fsr1l)); - pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h)); + pic16_emitpcode(POC_INFSNZ, pic16_popCopyReg( pic16_stackpnt_lo )); + pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi )); } else { // we have to add more than one... - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_postinc1)); // this holds a return value! + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postinc )); // this holds a return value! pic16_emitpcode(POC_MOVLW, pic16_popGetLit(sym->stack-1)); - pic16_emitpcode(POC_ADDWF, pic16_popCopyReg(&pic16_pc_fsr1l)); + pic16_emitpcode(POC_ADDWF, pic16_popCopyReg( pic16_stackpnt_lo )); emitSKPNC; - pic16_emitpcode(POC_INCF, pic16_popCopyReg(&pic16_pc_fsr1h)); + pic16_emitpcode(POC_INCF, pic16_popCopyReg( pic16_stackpnt_hi )); pic16_emitpcode(POC_COMF, pic16_popCopyReg(&pic16_pc_wreg)); // WREG = -(WREG+1)! - pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_plusw1)); // this holds a retrun value! + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(pic16_stack_plusw)); // this holds a retrun value! } } @@ -3751,10 +3835,8 @@ static void genEndFunction (iCode *ic) if(1/*!options.ommitFramePtr ||*/ /*sym->regsUsed*/) { /* restore stack frame */ if(STACK_MODEL_LARGE) - pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr2h )); -// pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2h, 0)); - pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_fsr2l )); -// pic16_emitpcode(POC_MOVFF, pic16_popCombine2( &pic16_pc_preinc1, &pic16_pc_fsr2l, 0)); + pic16_poppCodeOp( pic16_popCopyReg( pic16_framepnt_hi )); + pic16_poppCodeOp( pic16_popCopyReg( pic16_framepnt_lo )); } } @@ -3766,14 +3848,14 @@ static void genEndFunction (iCode *ic) pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodh )); pic16_poppCodeOp( pic16_popCopyReg( &pic16_pc_prodl )); - if(!(_G.interruptvector == 1)) { + if(!FUNC_ISSHADOWREGS(sym->type)) { /* 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 */ +// _G.interruptvector = 0; /* sanity check */ /* if debug then send end of function */ @@ -3815,8 +3897,25 @@ static void genEndFunction (iCode *ic) void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest) { - if(is_LitOp(op)) { - unsigned long lit = (unsigned long)floatFromVal(AOP(op)->aopu.aop_lit); + unsigned long lit=1; + + // this fails for is_LitOp(op) (if op is an AOP_PCODE) + if(AOP_TYPE(op) == AOP_LIT) { + if(!IS_FLOAT(operandType( op ))) { + lit = (unsigned long)floatFromVal(AOP(op)->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(op)->aopu.aop_lit); + lit = info.lit_int; + } + } + + if (is_LitOp(op)) { if(lit == 0) { pic16_emitpcode(POC_CLRF, dest); } else { @@ -3889,13 +3988,13 @@ static void genRet (iCode *ic) /* setup FSR0 */ pic16_emitpcode(POC_MOVFF, pic16_popGet2p( - pic16_popCopyReg(&pic16_pc_fsr1l), pic16_popCopyReg(&pic16_pc_fsr0l))); + pic16_popCopyReg( pic16_stackpnt_lo ), 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))); + pic16_popCopyReg( pic16_stackpnt_hi ), pic16_popCopyReg(&pic16_pc_fsr0h))); } else { - pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_fsr1h ) ); + pic16_emitpcode(POC_CLRF, pic16_popCopyReg( pic16_stackpnt_hi )); } } @@ -4577,6 +4676,33 @@ static void genIfxJump (iCode *ic, char *jval) ic->generated = 1; } +static void genIfxpCOpJump (iCode *ic, pCodeOp *jop) +{ + FENTRY; + + /* if true label then we jump if condition + supplied is true */ + if ( IC_TRUE(ic) ) { + DEBUGpic16_emitcode ("; ***","%d - assuming is in bit space",__LINE__); + pic16_emitpcode(POC_BTFSC, jop); + + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_TRUE(ic)->key)); + pic16_emitcode(" goto","_%05d_DS_",IC_TRUE(ic)->key+100 + pic16_labelOffset); + + } else { + /* false label is present */ + DEBUGpic16_emitcode ("; ***","%d - assuming is in bit space",__LINE__); + pic16_emitpcode(POC_BTFSS, jop); + + pic16_emitpcode(POC_GOTO,pic16_popGetLabel(IC_FALSE(ic)->key)); + pic16_emitcode(" goto","_%05d_DS_",IC_FALSE(ic)->key+100 + pic16_labelOffset); + } + + + /* mark the icode as generated */ + ic->generated = 1; +} + #if 0 // not needed ATM @@ -4748,7 +4874,9 @@ static int genChkZeroes(operand *op, int lit, int size) } #endif +#if !defined(__BORLANDC__) && !defined(_MSC_VER) #define DEBUGpc(fmt,...) DEBUGpic16_emitcode("; =:=", "%s:%s:%d: " fmt, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__) +#endif #define isAOP_LIT(x) (AOP_TYPE(x) == AOP_LIT) #define isAOP_REGlike(x) (AOP_TYPE(x) == AOP_REG || AOP_TYPE(x) == AOP_DIR || AOP_TYPE(x) == AOP_PCODE || AOP_TYPE(x) == AOP_STA) @@ -4831,7 +4959,9 @@ static void genCmp (operand *left,operand *right, * make sure that left is register (or the like) * *************************************************/ if (!isAOP_REGlike(left)) { + #if !defined(__BORLANDC__) && !defined(_MSC_VER) DEBUGpc ("swapping arguments (AOP_TYPEs %d/%d)", AOP_TYPE(left), AOP_TYPE(right)); + #endif assert (isAOP_LIT(left)); assert (isAOP_REGlike(right)); // swap left and right @@ -4867,7 +4997,9 @@ static void genCmp (operand *left,operand *right, if (isAOP_LIT(right)) { if (!sign) { // unsigned comparison to a literal + #if !defined(__BORLANDC__) && !defined(_MSC_VER) DEBUGpc ("unsigned compare: left %s lit(0x%X=%lu), size=%d", performedLt ? "<" : ">=", lit, lit, size+1); + #endif if (lit == 0) { // unsigned left < 0? always false if (performedLt) emitCLRC; else emitSETC; @@ -4875,7 +5007,9 @@ static void genCmp (operand *left,operand *right, } } else { // signed comparison to a literal + #if !defined(__BORLANDC__) && !defined(_MSC_VER) DEBUGpc ("signed compare: left %s lit(0x%X=%ld), size=%d, mask=%x", performedLt ? "<" : ">=", lit, lit, size+1, mask); + #endif if ((lit & mask) == ((0x80 << (size*8)) & mask)) { // signed left < 0x80000000? always false if (performedLt) emitCLRC; else emitSETC; @@ -10985,10 +11119,54 @@ static void genNearPointerGet (operand *left, } DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_aopOp (result,ic,FALSE); + + DEBUGpic16_pic16_AopType(__LINE__, left, NULL, result); + +#if 1 + if(IS_BITFIELD( retype ) + && (SPEC_BLEN(operandType(result))==1) + ) { + iCode *nextic; + pCodeOp *jop; + int bitstrt, bytestrt; + + /* if this is bitfield of size 1, see if we are checking the value + * of a single bit in an if-statement, + * if yes, then don't generate usual code, but execute the + * genIfx directly -- VR */ + + nextic = ic->next; + + /* CHECK: if next iCode is IFX + * and current result operand is nextic's conditional operand + * and current result operand live ranges ends at nextic's key number + */ + if((nextic->op == IFX) + && (result == IC_COND(nextic)) + && (OP_LIVETO(result) == nextic->seq) + ) { + /* everything is ok then */ + /* find a way to optimize the genIfx iCode */ + + bytestrt = SPEC_BSTR(operandType(result))/8; + bitstrt = SPEC_BSTR(operandType(result))%8; + + jop = pic16_popCopyGPR2Bit(pic16_popGet(AOP(left), 0), bitstrt); + + genIfxpCOpJump(nextic, jop); + + pic16_freeAsmop(left, NULL, ic, TRUE); + pic16_freeAsmop(result, NULL, ic, TRUE); + return; + } + } +#endif + /* if the value is already in a pointer register * then don't need anything more */ - if (!AOP_INPREG(AOP(left))) { + if (1 || !AOP_INPREG(AOP(left))) { // AOP_INPREG(AOP(left)) is not always correct... /* otherwise get a free pointer register */ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -11005,12 +11183,6 @@ static void genNearPointerGet (operand *left, } } } -// else -// rname = pic16_aopGet(AOP(left),0,FALSE,FALSE); - - pic16_aopOp (result,ic,FALSE); - - DEBUGpic16_pic16_AopType(__LINE__, left, NULL, result); /* if bitfield then unpack the bits */ if (IS_BITFIELD(retype)) @@ -11216,6 +11388,7 @@ static void genFarPointerGet (operand *left, pic16_freeAsmop(result,NULL,ic,TRUE); } + #if 0 /*-----------------------------------------------------------------*/ /* genCodePointerGet - get value from code space */ @@ -11268,6 +11441,7 @@ static void genCodePointerGet (operand *left, pic16_freeAsmop(result,NULL,ic,TRUE); } #endif + #if 0 /*-----------------------------------------------------------------*/ /* genGenPointerGet - gget value from generic pointer space */ @@ -11436,29 +11610,11 @@ static void genConstPointerGet (operand *left, 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)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_pcl)); - - 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 ...... + || (AOP(left)->aopu.pcop->type == PO_DIR))) { pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(left),0)); pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl)); @@ -11466,25 +11622,20 @@ static void genConstPointerGet (operand *left, 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))); - } - + } 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++; - } + 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); - } @@ -11493,9 +11644,9 @@ static void genConstPointerGet (operand *left, /*-----------------------------------------------------------------*/ static void genPointerGet (iCode *ic) { - operand *left, *result ; - sym_link *type, *etype; - int p_type; + operand *left, *result ; + sym_link *type, *etype; + int p_type; FENTRY; @@ -11516,57 +11667,56 @@ static void genPointerGet (iCode *ic) /* if left is of type of pointer then it is simple */ if (IS_PTR(type) && !IS_FUNC(type->next)) - p_type = DCL_TYPE(type); + p_type = DCL_TYPE(type); else { - /* we have to go by the storage class */ - p_type = PTR_TYPE(SPEC_OCLS(etype)); + /* we have to go by the storage class */ + p_type = PTR_TYPE(SPEC_OCLS(etype)); - DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__); + DEBUGpic16_emitcode ("; ***","%d - resolve pointer by storage class",__LINE__); - if (SPEC_OCLS(etype)->codesp ) { - DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__); - //p_type = CPOINTER ; - } - else - if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) - DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__); - /*p_type = FPOINTER ;*/ - else - if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) - DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__); -/* p_type = PPOINTER; */ - else - if (SPEC_OCLS(etype) == idata ) - DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__); -/* p_type = IPOINTER; */ - else - DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__); -/* p_type = POINTER ; */ + if (SPEC_OCLS(etype)->codesp ) { + DEBUGpic16_emitcode ("; ***","%d - cpointer",__LINE__); + //p_type = CPOINTER ; + } else + if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged) { + DEBUGpic16_emitcode ("; ***","%d - fpointer",__LINE__); + /*p_type = FPOINTER ;*/ + } else + if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged) { + DEBUGpic16_emitcode ("; ***","%d - ppointer",__LINE__); + /* p_type = PPOINTER; */ + } else + if (SPEC_OCLS(etype) == idata ) { + DEBUGpic16_emitcode ("; ***","%d - ipointer",__LINE__); + /* p_type = IPOINTER; */ + } else { + DEBUGpic16_emitcode ("; ***","%d - pointer",__LINE__); + /* p_type = POINTER ; */ + } } /* now that we have the pointer type we assign the pointer values */ switch (p_type) { - - case POINTER: - case IPOINTER: + case POINTER: + case IPOINTER: genNearPointerGet (left,result,ic); break; - case PPOINTER: + case PPOINTER: genPagedPointerGet(left,result,ic); break; - case FPOINTER: + case FPOINTER: genFarPointerGet (left,result,ic); break; - case CPOINTER: + case CPOINTER: genConstPointerGet (left,result,ic); //pic16_emitcodePointerGet (left,result,ic); break; - case GPOINTER: + case GPOINTER: #if 0 if (IS_PTR_CONST(type)) genConstPointerGet (left,result,ic); @@ -11580,7 +11730,6 @@ static void genPointerGet (iCode *ic) "genPointerGet: illegal pointer type"); } - } /*-----------------------------------------------------------------*/ @@ -11668,39 +11817,106 @@ static void genPackBits (sym_link *etype , operand *result, } else pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), offset++)); - /* if the bit lenth is less than or */ + /* 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; - pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1)); + if (blen != 8 || bstr != 0) { + // we need to combine the value with the old value + pic16_emitpcode(POC_ANDLW, pic16_popGetLit((1U << blen)-1)); - /* shift left acc */ - AccLsh(shCnt); + /* shift left acc */ + AccLsh(shCnt); - /* using PRODL as a temporary register here */ - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodl)); + /* using PRODH as a temporary register here */ + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_prodh)); - switch (p_type) { + /* get old value */ + switch (p_type) { case FPOINTER: case POINTER: pic16_loadFSR0( result ); + fsr0_setup = 1; pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); // pic16_emitcode ("mov","b,a"); // pic16_emitcode("mov","a,@%s",rname); break; case GPOINTER: - werror(W_POSSBUG2, __FILE__, __LINE__); + if (AOP(result)->aopu.aop_reg[2]) { + // prepare call to __gptrget1, this is actually genGenPointerGet(result, WREG, ?ic?) + pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); + pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl))); + pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2)); + pic16_emitpcode (POC_CALL, pic16_popGetWithString ("__gptrget1")); + { + symbol *sym; + sym = newSymbol( "__gptrget1", 0 ); + strcpy(sym->rname, "__gptrget1"); + checkAddSym(&externs, sym); + } + } else { + // data pointer (just 2 byte given) + pic16_loadFSR0( result ); + fsr0_setup = 1; + pic16_emitpcode(POC_MOVFW, pic16_popCopyReg(&pic16_pc_indf0)); + } + + // warnings will be emitted below + //pic16_emitpcomment ("; =?= genPackBits, GPOINTER..."); + //werror(W_POSSBUG2, __FILE__, __LINE__); break; - } + default: + assert (0 && "invalid pointer type specified"); + break; + } #if 1 - pic16_emitpcode(POC_ANDLW, pic16_popGetLit( + 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)); + pic16_emitpcode(POC_IORFW, pic16_popCopyReg(&pic16_pc_prodh)); + } // if (blen != 8 || bstr != 0) + + /* write new value back */ + switch (p_type) { + case FPOINTER: + case POINTER: + if (!fsr0_setup) pic16_loadFSR0( result ); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); + break; + + case GPOINTER: + if (AOP(result)->aopu.aop_reg[2]) { + // prepare call to __gptrset1, this is actually genGenPointerSet(WREG, result, ?ic?) + pic16_emitpcode (POC_MOVWF, pic16_popCopyReg (pic16_stack_postdec/*pic16_pc_postdec1*/)); + pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),0), pic16_popCopyReg(&pic16_pc_fsr0l))); + pic16_emitpcode (POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(result),1), pic16_popCopyReg(&pic16_pc_prodl))); + pic16_emitpcode (POC_MOVFW, pic16_popGet(AOP(result),2)); + pic16_emitpcode (POC_CALL, pic16_popGetWithString ("__gptrput1")); + { + symbol *sym; + sym = newSymbol( "__gptrput1", 0 ); + strcpy(sym->rname, "__gptrput1"); + checkAddSym(&externs, sym); + } + } else { + // data pointer (just 2 byte given) + if (!fsr0_setup) pic16_loadFSR0( result ); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg(&pic16_pc_indf0)); + } + + // this should work in all cases (as soon as gptrget/gptrput work on EEPROM and PROGRAM MEMORY) + //pic16_emitpcomment ("; =?= genPackBits, GPOINTER access"); + werror(W_POSSBUG2, __FILE__, __LINE__); + break; + + default: + assert (0 && "invalid pointer type specified"); + break; + } #endif return; @@ -11904,7 +12120,7 @@ static void genNearPointerSet (operand *right, /* if the value is already in a pointer register * then don't need anything more */ - if (!AOP_INPREG(AOP(result))) { + if (1 || !AOP_INPREG(AOP(result))) { // AOP_INPREG(AOP(result)) is not always correct... /* otherwise get a free pointer register */ DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -11948,24 +12164,24 @@ static void genNearPointerSet (operand *right, 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 + 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++; } @@ -12381,27 +12597,26 @@ static void genPointerSet (iCode *ic) /* now that we have the pointer type we assign the pointer values */ switch (p_type) { + case POINTER: + case IPOINTER: + genNearPointerSet (right,result,ic); + break; - case POINTER: - case IPOINTER: - genNearPointerSet (right,result,ic); - break; - - case PPOINTER: - genPagedPointerSet (right,result,ic); - break; - - case FPOINTER: - genFarPointerSet (right,result,ic); + case PPOINTER: + genPagedPointerSet (right,result,ic); break; - case GPOINTER: - genGenPointerSet (right,result,ic); - break; + case FPOINTER: + genFarPointerSet (right,result,ic); + break; + + case GPOINTER: + genGenPointerSet (right,result,ic); + break; - default: - werror (E_INTERNAL_ERROR, __FILE__, __LINE__, - "genPointerSet: illegal pointer type"); + default: + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "genPointerSet: illegal pointer type"); } } @@ -12478,10 +12693,10 @@ static void genAddrOf (iCode *ic) } // 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_pc_fsr2l)); + 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_pc_fsr2h)); + pic16_emitpcode(POC_ADDFWC, pic16_popCopyReg(pic16_framepnt_hi)); pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 1)); } @@ -12496,10 +12711,6 @@ static void genAddrOf (iCode *ic) pic16_aopOp((left=IC_LEFT(ic)), ic, FALSE); size = AOP_SIZE(IC_RESULT(ic)); - - /* 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)))); @@ -12693,7 +12904,7 @@ static void genAssign (iCode *ic) pic16_popCopyReg(&pic16_pc_tblptru))); } - size = min(AOP_SIZE(right), AOP_SIZE(result)); + size = min(getSize(OP_SYM_ETYPE(right)), AOP_SIZE(result)); while(size--) { pic16_emitpcodeNULLop(POC_TBLRD_POSTINC); pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), @@ -12701,8 +12912,9 @@ static void genAssign (iCode *ic) offset++; } - if(AOP_SIZE(result) > AOP_SIZE(right)) { - size = AOP_SIZE(result) - AOP_SIZE(right); + size = getSize(OP_SYM_ETYPE(right)); + if(AOP_SIZE(result) > size) { + size = AOP_SIZE(result) - size; while(size--) { pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset)); offset++; @@ -13237,7 +13449,13 @@ static void genCast (iCode *ic) break; case GPOINTER: - pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1)); + 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)); + } else { + pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), GPTRSIZE-1)); + } break; default: @@ -13433,10 +13651,26 @@ static void genReceive (iCode *ic) static void genDummyRead (iCode * ic) { - pic16_emitcode ("; genDummyRead",""); - pic16_emitcode ("; not implemented",""); + operand *op; + int i; - ic = ic; + op = IC_RIGHT(ic); + if (op && IS_SYMOP(op)) { + if (IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(op)))) { + fprintf (stderr, "%s: volatile symbols in codespace?!? -- might go wrong...\n", __FUNCTION__); + return; + } + pic16_aopOp (op, ic, FALSE); + for (i=0; i < AOP_SIZE(op); i++) { + // may need to protect this from the peepholer -- this is not nice but works... + pic16_addpCode2pBlock(pb,pic16_newpCodeAsmDir(";", "VOLATILE READ - BEGIN")); + pic16_mov2w (AOP(op),i); + pic16_addpCode2pBlock(pb,pic16_newpCodeAsmDir(";", "VOLATILE READ - END")); + } // for i + pic16_freeAsmop (op, NULL, ic, TRUE); + } else if (op) { + fprintf (stderr, "%s: not implemented for non-symbols (volatile operand might not be read)\n", __FUNCTION__); + } // if } /*-----------------------------------------------------------------*/ @@ -13472,7 +13706,7 @@ void genpic16Code (iCode *lic) for (ic = lic ; ic ; ic = ic->next ) { - DEBUGpic16_emitcode(";ic ", "\t%c 0x%x",ic->op, ic->op); + DEBUGpic16_emitcode(";ic ", "\t%c 0x%x\t(%s)",ic->op, ic->op, pic16_decodeOp(ic->op)); if ( cln != ic->lineno ) { if ( options.debug ) { debugFile->writeCLine (ic);