X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgen.c;h=ee85154ddbb2efa13f528619c5b8d7b8692b51cb;hb=c2194e70f968fe9d82fcb1233c3d7d9e46b286e9;hp=e9b64a7875aa9c027db62037f8c4530d4454c85c;hpb=d10151253d907646b1040f76f9b152f2f9d25835;p=fw%2Fsdcc diff --git a/src/pic16/gen.c b/src/pic16/gen.c index e9b64a78..ee85154d 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; @@ -857,6 +874,10 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) 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 ); } @@ -1172,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) { @@ -1232,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; @@ -1545,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); @@ -1943,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; @@ -2003,7 +2053,9 @@ pCodeOp *pic16_popGet (asmop *aop, int offset) //, bool bit16, bool dname) 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; @@ -3188,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 ); @@ -3392,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)); @@ -3401,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))); @@ -3519,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; @@ -3534,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")); @@ -3558,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); } @@ -3610,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; @@ -3658,7 +3732,7 @@ static void genFunction (iCode *ic) 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 @@ -3774,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 */ @@ -12746,7 +12820,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), @@ -12754,8 +12828,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++; @@ -13492,10 +13567,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 } /*-----------------------------------------------------------------*/