From: vrokas Date: Mon, 14 Mar 2005 01:24:58 +0000 (+0000) Subject: * device/lib/pic16/startup/crt0i.c (_cinit): local variables where X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=5bc044cc26d5c7120689edffd312cb2774fc1c29;p=fw%2Fsdcc * device/lib/pic16/startup/crt0i.c (_cinit): local variables where moved to level 0 and declared as static. Also they are explicit placed in access bank. This was necessery because some times they might cross memory bank boundaries. crt0iz.c is *NOT* updated!!! * src/pic16/device.h: added flag OPTIMIZE_CMP to enable some compare optimizations. Currently only compare to unsigned char is implemented, * src/pic16/gen.c: added fReturnIdx array, * (struct resolvedIfx) is moved to gen.h and made public, * (struct _G): added sregsAlloc and sregsAllocSet fields, * (aopForSym): added an optimization to directly store in stack of the operand of a SEND iCode, * (pic16_aopOp): don't return return registers as strings (AOP_STR) but as registers instead (AOP_REG) using the fReturnIdx array, * (pic16_freeAsmop): remove the freed register from the _G.sregsAlloc field, * (pic16_aopGet): in case AOP_STR, the compare to 'a' is changed to a compare of 'WREG', * (pic16_popGetTempRegCond): changed function prototype, now function takes also a bitVector argument v which holds the current set of registers that are allocated for stack access by aopForSym, registers allocated in aopForSym for accessing stack symbols are not any more part of the functions usedRegs field, * (genCall): some times aopOp is called for a stack variable to be send, aopForSym might perform the push, if this is true make sure that genCall doesn't push the variable twice by testing _G.resDirect, * (genFunction): changed testing for unspecified interrupt number from 256 to INTNO_UNSPEC, * modified selection scheme of frame pointer generation. Previously if function did use local registers a frame pointer was generated, now a frame pointer is generated only if function has arguments (that need PLUSW2 register access), or has stack arguments, or the compiler is not instructed to omit the frame pointer, * (genEndFunction): before restoring local registers that were saved in the function preamble, also restore the registers that *might* have been allocated for stack access, * (genRet): removed some old comments, * (genCmp, the active (RN's) version): added a call to the pic16_genCmp_special function to perform the compare with a more robust and optimized way, * (genInline): a feature has been added in inline code generation, which allows a wildcard variable substitution when writing inline assembly. Code is incomplete and experimental therefore undocumented, * (genCast): changed order of aopOp for result and right to allow aopForSym to directly load the result if possible, * src/pic16/genutils.c (selectCompareOp, pic16_genCmp_special): NEW, perform an optimized compare on some selected special occasions, * src/pic16/genutils.h: declaration of resolvedIfx structure from gen.c, * src/pic16/glue.c (pic16createInterrupVect): make sure we never generate an IVT any more, * src/pic16/main.c (pic16_optionsTable): added command line option --optimize-cmp, * (_pic16_initPaths): when calling C preprocessor define pic18fXXXX macro too, when calling assembler define pic18fXXXX *and* __18Fxxxx macros, * src/pic16/NOTES: Raphael Neider added in list of active developers * src/pic16/pcode.c (OPT_TYPE_STR): added strings jumptable_begin and jumptable_end to prevent bug #, * (pic16_pciADDWFC, ADDFWC, COMF, CLRF): added some missing flags in inCond and outCond fields, * src/pic16/pcoderegs.c (pCodeOptime2pCodes): add a fix for bug #, * src/pic16/ralloc.c (serialRegAssign): explicit set willCS to 0 to turn off register spilling, * (packRegsForOneUse): synced with other ports' versions although it is not used currently, * (pic16_packRegisters): added an optimization while reading structure bitfields, some registers may be saved (malloc code is decreased by 80 bytes) git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3694 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/ChangeLog b/ChangeLog index 808c82c8..99640ebc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,73 @@ +2005-03-12 Vangelis Rokas + + * device/lib/pic16/startup/crt0i.c (_cinit): local variables where + moved to level 0 and declared as static. Also they are explicit + placed in access bank. This was necessery because some times they + might cross memory bank boundaries. crt0iz.c is *NOT* updated!!! + * src/pic16/device.h: added flag OPTIMIZE_CMP to enable some compare + optimizations. Currently only compare to unsigned char is implemented, + * src/pic16/gen.c: added fReturnIdx array, + * (struct resolvedIfx) is moved to gen.h and made public, + * (struct _G): added sregsAlloc and sregsAllocSet fields, + * (aopForSym): added an optimization to directly store in stack of + the operand of a SEND iCode, + * (pic16_aopOp): don't return return registers as strings (AOP_STR) + but as registers instead (AOP_REG) using the fReturnIdx array, + * (pic16_freeAsmop): remove the freed register from the + _G.sregsAlloc field, + * (pic16_aopGet): in case AOP_STR, the compare to 'a' is changed to + a compare of 'WREG', + * (pic16_popGetTempRegCond): changed function prototype, now + function takes also a bitVector argument v which holds the current + set of registers that are allocated for stack access by aopForSym, + registers allocated in aopForSym for accessing stack symbols are not + any more part of the functions usedRegs field, + * (genCall): some times aopOp is called for a stack variable to be + send, aopForSym might perform the push, if this is true make sure + that genCall doesn't push the variable twice by testing _G.resDirect, + * (genFunction): changed testing for unspecified interrupt number + from 256 to INTNO_UNSPEC, + * modified selection scheme of frame pointer generation. Previously + if function did use local registers a frame pointer was generated, + now a frame pointer is generated only if function has arguments + (that need PLUSW2 register access), or has stack arguments, or the + compiler is not instructed to omit the frame pointer, + * (genEndFunction): before restoring local registers that were saved + in the function preamble, also restore the registers that *might* + have been allocated for stack access, + * (genRet): removed some old comments, + * (genCmp, the active (RN's) version): added a call to the + pic16_genCmp_special function to perform the compare with a more + robust and optimized way, + * (genInline): a feature has been added in inline code generation, + which allows a wildcard variable substitution when writing inline + assembly. Code is incomplete and experimental therefore undocumented, + * (genCast): changed order of aopOp for result and right to allow + aopForSym to directly load the result if possible, + * src/pic16/genutils.c (selectCompareOp, pic16_genCmp_special): NEW, + perform an optimized compare on some selected special occasions, + * src/pic16/genutils.h: declaration of resolvedIfx structure from gen.c, + * src/pic16/glue.c (pic16createInterrupVect): make sure we never + generate an IVT any more, + * src/pic16/main.c (pic16_optionsTable): added command line option + --optimize-cmp, + * (_pic16_initPaths): when calling C preprocessor define pic18fXXXX + macro too, when calling assembler define pic18fXXXX *and* __18Fxxxx + macros, + * src/pic16/NOTES: Raphael Neider added in list of active developers + * src/pic16/pcode.c (OPT_TYPE_STR): added strings jumptable_begin and + jumptable_end to prevent bug #, + * (pic16_pciADDWFC, ADDFWC, COMF, CLRF): added some missing flags in + inCond and outCond fields, + * src/pic16/pcoderegs.c (pCodeOptime2pCodes): add a fix for bug #, + * src/pic16/ralloc.c (serialRegAssign): explicit set willCS to 0 to + turn off register spilling, + * (packRegsForOneUse): synced with other ports' versions although it + is not used currently, + * (pic16_packRegisters): added an optimization while reading + structure bitfields, some registers may be saved (malloc code is + decreased by 80 bytes) + 2005-03-12 Vangelis Rokas * src/SDCCcse.c (cseBBlock): inside 'do operand lookup' loop test if diff --git a/device/lib/pic16/startup/crt0i.c b/device/lib/pic16/startup/crt0i.c index 75dd6b48..9459d62c 100644 --- a/device/lib/pic16/startup/crt0i.c +++ b/device/lib/pic16/startup/crt0i.c @@ -86,6 +86,14 @@ extern code struct #define tblrdpostinc tblrd*+ +#pragma udata access _do_cinit_prom, _do_cinit_curr_byte +#pragma udata access _do_cinit_ curr_entry, _do_cinit_data_ptr + +static short long _do_cinit_prom; +static unsigned short _do_cinit_curr_byte; +static unsigned short _do_cinit_curr_entry; +static short long _do_cinit_data_ptr; + /* the variable initialisation routine */ void _do_cinit (void) { @@ -93,10 +101,6 @@ void _do_cinit (void) * we'll make the assumption in the following code that these statics * will be allocated into the same bank. */ - static short long prom; - static unsigned short curr_byte; - static unsigned short curr_entry; - static short long data_ptr; /* TBLPTR = &cinit */ @@ -112,13 +116,13 @@ void _do_cinit (void) /* curr_entry = cinit.num_init */ _asm - movlb __do_cinit_data_ptr_1_1 + movlb __do_cinit_data_ptr tblrdpostinc movf _TABLAT, 0, 0 - movwf __do_cinit_curr_entry_1_1, 1 + movwf __do_cinit_curr_entry, 1 tblrdpostinc movf _TABLAT, 0, 0 - movwf __do_cinit_curr_entry_1_1+1, 1 + movwf __do_cinit_curr_entry+1, 1 _endasm; @@ -126,7 +130,7 @@ void _do_cinit (void) _asm test: bnz done1 - tstfsz __do_cinit_curr_entry_1_1, 1 + tstfsz __do_cinit_curr_entry, 1 bra cont1 done1: @@ -148,17 +152,17 @@ cont1: /* read the source address low */ tblrdpostinc movf _TABLAT, 0, 0 - movwf __do_cinit_prom_1_1, 1 + movwf __do_cinit_prom, 1 /* source address high */ tblrdpostinc movf _TABLAT, 0, 0 - movwf __do_cinit_prom_1_1 + 1, 1 + movwf __do_cinit_prom + 1, 1 /* source address upper */ tblrdpostinc movf _TABLAT, 0, 0 - movwf __do_cinit_prom_1_1 + 2, 1 + movwf __do_cinit_prom + 2, 1 /* skip a byte since it's stored as a 32bit int */ tblrdpostinc @@ -181,10 +185,10 @@ cont1: /* read the destination address directly into FSR0 */ tblrdpostinc movf _TABLAT, 0, 0 - movwf __do_cinit_curr_byte_1_1, 1 + movwf __do_cinit_curr_byte, 1 tblrdpostinc movf _TABLAT, 0, 0 - movwf __do_cinit_curr_byte_1_1+1, 1 + movwf __do_cinit_curr_byte+1, 1 /* skip two bytes since it's stored as a 32bit int */ tblrdpostinc @@ -200,29 +204,29 @@ cont1: /* data_ptr = TBLPTR */ _asm - movff _TBLPTRL, __do_cinit_data_ptr_1_1 - movff _TBLPTRH, __do_cinit_data_ptr_1_1 + 1 - movff _TBLPTRU, __do_cinit_data_ptr_1_1 + 2 + movff _TBLPTRL, __do_cinit_data_ptr + movff _TBLPTRH, __do_cinit_data_ptr + 1 + movff _TBLPTRU, __do_cinit_data_ptr + 2 _endasm; /* now assign the source address to the table pointer */ /* TBLPTR = prom */ _asm - movff __do_cinit_prom_1_1, _TBLPTRL - movff __do_cinit_prom_1_1 + 1, _TBLPTRH - movff __do_cinit_prom_1_1 + 2, _TBLPTRU + movff __do_cinit_prom, _TBLPTRL + movff __do_cinit_prom + 1, _TBLPTRH + movff __do_cinit_prom + 2, _TBLPTRU _endasm; /* do the copy loop */ _asm /* determine if we have any more bytes to copy */ - movlb __do_cinit_curr_byte_1_1 - movf __do_cinit_curr_byte_1_1, 1, 1 + movlb __do_cinit_curr_byte + movf __do_cinit_curr_byte, 1, 1 copy_loop: bnz copy_one_byte // copy_one_byte - movf __do_cinit_curr_byte_1_1 + 1, 1, 1 + movf __do_cinit_curr_byte + 1, 1, 1 bz done_copying copy_one_byte: @@ -231,9 +235,9 @@ copy_one_byte: movwf _POSTINC0, 0 /* decrement byte counter */ - decf __do_cinit_curr_byte_1_1, 1, 1 + decf __do_cinit_curr_byte, 1, 1 bnc copy_loop // copy_loop - decf __do_cinit_curr_byte_1_1 + 1, 1, 1 + decf __do_cinit_curr_byte + 1, 1, 1 bra copy_loop done_copying: @@ -242,14 +246,14 @@ done_copying: /* restore the table pointer for the next entry */ /* TBLPTR = data_ptr */ _asm - movff __do_cinit_data_ptr_1_1, _TBLPTRL - movff __do_cinit_data_ptr_1_1 + 1, _TBLPTRH - movff __do_cinit_data_ptr_1_1 + 2, _TBLPTRU + movff __do_cinit_data_ptr, _TBLPTRL + movff __do_cinit_data_ptr + 1, _TBLPTRH + movff __do_cinit_data_ptr + 2, _TBLPTRU _endasm; /* next entry... */ - curr_entry--; + _do_cinit_curr_entry--; _asm goto test; diff --git a/src/SDCCicode.c b/src/SDCCicode.c index b989c88d..4d0a9f4b 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -233,7 +233,8 @@ printOperand (operand * op, FILE * file) case SYMBOL: #define REGA 1 -#if REGA +//#if REGA /* { */ + if(REGA && !getenv("PRINT_SHORT_OPERANDS")) { fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */ (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name), op->key, @@ -276,28 +277,26 @@ printOperand (operand * op, FILE * file) fprintf (file, "]"); } } -#else - +//#else /* } else { */ + } else { + /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */ fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name)); -#if 0 - - fprintf (file, "[lr%d:%d so:%d]", + if(getenv("PRINT_SHORT_OPERANDS")[0] < '1') + { + fprintf (file, "[lr%d:%d so:%d]", OP_LIVEFROM (op), OP_LIVETO (op), - OP_SYMBOL (op)->stack - ); -#endif - -#if 1 - { - fprintf (file, "{"); - printTypeChain (operandType (op), file); - if (SPIL_LOC (op) && IS_ITEMP (op)) - fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname); - fprintf (file, "}"); + OP_SYMBOL (op)->stack); + } - } -#endif + if(getenv("PRINT_SHORT_OPERANDS")[0] < '2') + { + fprintf (file, "{"); + printTypeChain (operandType (op), file); + if (SPIL_LOC (op) && IS_ITEMP (op)) + fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname); + fprintf (file, "}"); + } /* if assigned to registers */ if (OP_SYMBOL (op)->nRegs) @@ -323,7 +322,8 @@ printOperand (operand * op, FILE * file) fprintf (file, "]"); } } -#endif +//#endif /* } */ + } break; case TYPE: diff --git a/src/pic16/NOTES b/src/pic16/NOTES index 4c6e5b14..35cf9318 100644 --- a/src/pic16/NOTES +++ b/src/pic16/NOTES @@ -1,4 +1,4 @@ -NOTES file for SDCC pic16 port +lNOTES file for SDCC pic16 port $Id$ Current pic16 port status is: Development @@ -11,7 +11,8 @@ For any questions please ask the current port developers. Current developer: -Vangelis Rokas +Vangelis Rokas +Raphael Neider Other people to contact: Scott Dattalo diff --git a/src/pic16/device.h b/src/pic16/device.h index 1bcafdd4..db4acee4 100644 --- a/src/pic16/device.h +++ b/src/pic16/device.h @@ -88,6 +88,7 @@ typedef struct PIC16_device { #define OF_LR_SUPPORT 0x00000001 #define OF_OPTIMIZE_GOTO 0x00000002 +#define OF_OPTIMIZE_CMP 0x00000004 typedef struct { int no_banksel; @@ -113,6 +114,8 @@ typedef struct { extern set *fix_idataSymSet; extern set *rel_idataSymSet; +extern set *asmInlineMap; + typedef struct { unsigned long isize; unsigned long adsize; diff --git a/src/pic16/gen.c b/src/pic16/gen.c index dcc0b93d..41b5a82a 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -1,4 +1,4 @@ -/*------------------------------------------------------------------------- + /*------------------------------------------------------------------------- gen.c - source file for code generation for pic16 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) @@ -135,6 +135,7 @@ static char *one = "#0x01"; char *fReturnpic16[] = {"WREG", "PRODL", "PRODH", "FSR0L" }; +int fReturnIdx[] = {IDX_WREG, IDX_PRODL, IDX_PRODH, IDX_FSR0L }; unsigned pic16_fReturnSizePic = 4; /* shared with ralloc.c */ static char **fReturn = fReturnpic16; @@ -154,22 +155,14 @@ static struct { set *sendSet; set *stackRegSet; int usefastretfie; - bitVect *fregsUsed; + bitVect *fregsUsed; /* registers used in function */ + bitVect *sregsAlloc; + set *sregsAllocSet; /* registers used to store stack variables */ int stack_lat; /* stack offset latency */ int resDirect; int useWreg; /* flag when WREG is used to pass function parameter */ } _G; -/* Resolved ifx structure. This structure stores information - about an iCode ifx that makes it easier to generate code. -*/ -typedef struct resolvedIfx { - symbol *lbl; /* pointer to a label */ - int condition; /* true or false ifx */ - int generated; /* set true when the code associated with the ifx - * is generated */ -} resolvedIfx; - extern int pic16_ptrRegReq ; extern int pic16_nRegs; extern FILE *codeOutFile; @@ -683,19 +676,25 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) aop->size = getSize(sym->type); - DEBUGpic16_emitcode("; +++", "%s:%d", __FILE__, __LINE__); - if((ic->op == '=') && IC_RESULT(ic) && AOP( IC_RESULT(ic) ) - && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG) ) { + DEBUGpic16_emitcode("; +++ ", "%s:%d\top = %s", __FILE__, __LINE__, pic16_decodeOp(ic->op)); + if((ic->op == '=' /*|| ic->op == CAST*/) && IC_RESULT(ic) && AOP( IC_RESULT(ic) ) + && (AOP_TYPE(IC_RESULT(ic)) == AOP_REG)) { pic16_DumpAop("aopForSym", AOP( IC_RESULT(ic) )); for(i=0;isize;i++) aop->aopu.stk.pop[i] = pcop[i] = pic16_popRegFromIdx( AOP(IC_RESULT(ic))->aopu.aop_reg[i]->rIdx); _G.resDirect = 1; /* notify that result will be loaded directly from aopForSym */ } else + if(1 && ic->op == SEND) { + + /* if SEND do the send here */ + _G.resDirect = 1; + } else { for(i=0;isize;i++) { - aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond( _G.fregsUsed, 0 ); - _G.fregsUsed = bitVectSetBit(_G.fregsUsed, PCOR(pcop[i])->r->rIdx); + aop->aopu.stk.pop[i] = pcop[i] = pic16_popGetTempRegCond(_G.fregsUsed, _G.sregsAlloc, 0 ); + _G.sregsAlloc = bitVectSetBit(_G.sregsAlloc, PCOR(pcop[i])->r->rIdx); } + } // fprintf(stderr, "%s:%d\t%s\tsym size %d\n", __FILE__, __LINE__, __FUNCTION__, aop->size); @@ -722,9 +721,17 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) assert (soffs < 0); soffs++; } // if - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/)); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p( - pic16_popCopyReg( pic16_frame_plusw ), pcop[i])); + + if(1 && ic->op == SEND) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + aop->size - i - 1 /*+ _G.stack_lat*/)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg( pic16_frame_plusw ), + pic16_popCopyReg(pic16_stack_postdec ))); + } else { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(soffs + i /*+ _G.stack_lat*/)); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p( + pic16_popCopyReg( pic16_frame_plusw ), pcop[i])); + } } } @@ -1233,10 +1240,10 @@ void pic16_aopOp (operand *op, iCode *ic, bool result) unsigned i; - aop = op->aop = sym->aop = newAsmop(AOP_STR); + aop = op->aop = sym->aop = newAsmop(AOP_REG); aop->size = getSize(sym->type); for ( i = 0 ; i < pic16_fReturnSizePic ; i++ ) - aop->aopu.aop_str[i] = fReturn[i]; + aop->aopu.aop_reg[i] = PCOR(pic16_popRegFromIdx( fReturnIdx[i] ))->r; DEBUGpic16_emitcode(";","%d",__LINE__); return; @@ -1376,8 +1383,13 @@ void pic16_freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop) } if(!_G.resDirect) { - for(i=0;isize;i++) + for(i=0;isize;i++) { PCOR(aop->aopu.stk.pop[i] )->r->isFree = 1; + + if(bitVectBitValue(_G.sregsAlloc, PCOR(aop->aopu.stk.pop[i])->r->rIdx)) + bitVectUnSetBit(_G.sregsAlloc, PCOR(aop->aopu.stk.pop[i])->r->rIdx); + } + } _G.resDirect = 0; } @@ -1550,9 +1562,14 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) case AOP_STR: aop->coff = offset ; - if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && - dname) - return "acc"; + +// if (strcmp(aop->aopu.aop_str[offset],"a") == 0 && +// dname) +// return "acc"; + if(!strcmp(aop->aopu.aop_str[offset], "WREG")) { + aop->type = AOP_ACC; + return Safe_strdup("WREG"); + } DEBUGpic16_emitcode(";","%d - %s",__LINE__, aop->aopu.aop_str[offset]); return aop->aopu.aop_str[offset]; @@ -1656,13 +1673,15 @@ pCodeOp *pic16_popGetTempReg(int lock) } /*-----------------------------------------------------------------*/ -/* pic16_popGetTempRegCond - create a new temporary pCodeOp, but */ -/* don't save if inside v */ +/* pic16_popGetTempRegCond - create a new temporary pCodeOp which */ +/* is not part of f, but don't save if */ +/* inside v */ /*-----------------------------------------------------------------*/ -pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock) +pCodeOp *pic16_popGetTempRegCond(bitVect *f, bitVect *v, int lock) { - pCodeOp *pcop; + pCodeOp *pcop=NULL; symbol *cfunc; + int i; // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -1675,15 +1694,58 @@ pCodeOp *pic16_popGetTempRegCond(bitVect *v, int lock) cfunc = currFunc; currFunc = NULL; - pcop = pic16_newpCodeOp(NULL, PO_GPR_TEMP); - if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { - PCOR(pcop)->r->wasUsed=1; - PCOR(pcop)->r->isFree=0; + i = bitVectFirstBit(f); + while(i < 128) { - if(!bitVectBitValue(v, PCOR(pcop)->r->rIdx)) { - /* push value on stack */ - pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) ); + /* bypass registers that are used by function */ + if(!bitVectBitValue(f, i)) { + + /* bypass registers that are already allocated for stack access */ + if(!bitVectBitValue(v, i)) { + +// debugf("getting register rIdx = %d\n", i); + /* ok, get the operand */ + pcop = pic16_newpCodeOpReg( i ); + + /* should never by NULL */ + assert( pcop != NULL ); + + + /* sanity check */ + if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { + int found=0; + + PCOR(pcop)->r->wasUsed=1; + PCOR(pcop)->r->isFree=0; + + + { + regs *sr; + + for(sr=setFirstItem(_G.sregsAllocSet);sr;sr=setNextItem(_G.sregsAllocSet)) { + + if(sr->rIdx == PCOR(pcop)->r->rIdx) { + /* already used in previous steps, break */ + found=1; + break; + } + } + } + + /* caller takes care of the following */ +// bitVectSetBit(v, i); + + if(!found) { + /* push value on stack */ + pic16_pushpCodeOp( pic16_pCodeOpCopy(pcop) ); + addSet(&_G.sregsAllocSet, PCOR(pcop)->r); + } + + break; + } + } } + i++; } currFunc = cfunc; @@ -1703,6 +1765,7 @@ void pic16_popReleaseTempReg(pCodeOp *pcop, int lock) if(pcop && pcop->type == PO_GPR_TEMP && PCOR(pcop)->r) { PCOR(pcop)->r->isFree = 1; + pic16_poppCodeOp( pic16_pCodeOpCopy(pcop) ); } } @@ -2380,7 +2443,7 @@ void pic16_poppCodeOp(pCodeOp *pcop) void pushw(void) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); //&pic16_pc_postdec1)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); if(pic16_options.gstack) pic16_testStackOverflow(); } @@ -2395,10 +2458,10 @@ 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_stack_postdec )); //&pic16_pc_postdec1)); + pic16_emitpcode(POC_MOVWF, pic16_popCopyReg( pic16_stack_postdec )); } else { pic16_emitpcode(POC_MOVFF, - pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec ))); //&pic16_pc_postdec1))); + pic16_popGet2p(pic16_popGet(aop, offset), pic16_popCopyReg( pic16_stack_postdec ))); } if(pic16_options.gstack) @@ -3311,7 +3374,9 @@ static void genCall (iCode *ic) // pushaop(AOP(IC_LEFT(sic)), size); pic16_mov2w (AOP(IC_LEFT(sic)), size); - pushw(); + + if(!_G.resDirect) + pushw(); } } @@ -3588,34 +3653,16 @@ static void genFunction (iCode *ic) // debugf("interrupt number: %hhi\n", FUNC_INTNO(sym->type)); -#if 0 - { - int i, found=-1; - - sym = OP_SYMBOL( IC_LEFT(ic)); - for(i=0;i<=2;i++) { - if(interrupts[i]->name - && !STRCASECMP(interrupts[i]->name, sym->name)) { - found = i; - break; - } - } - - if(found == -1) { - fprintf(stderr, "PIC16 port: %s:%d: interrupt function but cannot locate symbol (%s)\n", - __FILE__, __LINE__, sym->name); -// assert( 0 ); - } - _G.interruptvector = found; - } -#endif - - if(FUNC_INTNO(sym->type) == 256) + if(FUNC_INTNO(sym->type) == INTNO_UNSPEC) sprintf(asymname, "ivec_%s", sym->name); else sprintf(asymname, "ivec_0x%x_%s", FUNC_INTNO(sym->type), sym->name); asym = newSymbol(asymname, 0); + /* FIXME: when an interrupt is declared as naked, do not emit the special + * wrapper segment at vector address. The user should take care for this + * instead. -- VR */ + apb = pic16_newpCodeChain(NULL, 'A', pic16_newpCodeCharP("; Starting pCode block for absolute section")); pic16_addpBlock( apb ); @@ -3638,6 +3685,7 @@ static void genFunction (iCode *ic) case 2: abSym->address = 0x000018; break; default: + fprintf(stderr, "no interrupt number is given\n"); abSym->address = -1; break; } @@ -3680,7 +3728,10 @@ static void genFunction (iCode *ic) //pic16_emitcode("clr","ea"); } + currFunc = sym; /* update the currFunc symbol */ _G.fregsUsed = sym->regsUsed; + _G.sregsAlloc = newBitVect(128); + /* if this is an interrupt service routine then * save wreg, status, bsr, prodl, prodh, fsr0l, fsr0h */ @@ -3705,15 +3756,19 @@ static void genFunction (iCode *ic) pic16_pushpCodeOp( pic16_popCopyReg( &pic16_pc_fsr0h )); // pic16_pBlockConvert2ISR(pb); - } /* emit code to setup stack frame if user enabled, * and function is not main() */ - //fprintf(stderr, "function name: %s\n", sym->name); +// debugf(stderr, "function name: %s ARGS=%p\n", sym->name, FUNC_ARGS(sym->type)); if(strcmp(sym->name, "main")) { - if(0 || !options.ommitFramePtr || sym->regsUsed) { + if(0 + || !options.ommitFramePtr +// || sym->regsUsed + || IFFUNC_ARGS(sym->type) + || FUNC_HASSTACKPARM(sym->etype) + ) { /* setup the stack frame */ if(STACK_MODEL_LARGE) pic16_pushpCodeOp(pic16_popCopyReg(pic16_framepnt_hi)); @@ -3802,6 +3857,17 @@ static void genEndFunction (iCode *ic) /* now we need to restore the registers */ /* if any registers used */ + + /* first restore registers that might be used for stack access */ + if(_G.sregsAllocSet) { + regs *sr; + + _G.sregsAllocSet = reverseSet( _G.sregsAllocSet ); + for(sr=setFirstItem(_G.sregsAllocSet) ; sr; sr=setNextItem(_G.sregsAllocSet)) { + pic16_poppCodeOp( pic16_popRegFromIdx( sr->rIdx ) ); + } + } + if (sym->regsUsed) { int i; @@ -3815,9 +3881,10 @@ static void genEndFunction (iCode *ic) } } pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_END)); - } + + if ((IFFUNC_ISREENT(sym->type) || options.stackAuto) && sym->stack) { if (sym->stack == 1) { @@ -3836,7 +3903,12 @@ static void genEndFunction (iCode *ic) } if(strcmp(sym->name, "main")) { - if(0 || !options.ommitFramePtr || sym->regsUsed) { + if(0 + || !options.ommitFramePtr +// || sym->regsUsed + || IFFUNC_ARGS(sym->type) + || FUNC_HASSTACKPARM(sym->etype) + ) { /* restore stack frame */ if(STACK_MODEL_LARGE) pic16_poppCodeOp( pic16_popCopyReg( pic16_framepnt_hi )); @@ -3899,36 +3971,39 @@ static void genEndFunction (iCode *ic) } -void pic16_storeForReturn(operand *op, int offset, pCodeOp *dest) +void pic16_storeForReturn(iCode *ic, /*operand *op,*/ int offset, pCodeOp *dest) { 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; + operand *op; + + op = IC_LEFT(ic); + + // 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; + /* 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) { + 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); } - } else { - if(dest->type == PO_WREG && (offset == 0)) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset)); + } else { + if(dest->type == PO_WREG && (offset == 0)) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(op), offset)); return; } pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(op), offset), dest)); @@ -3956,27 +4031,16 @@ static void genRet (iCode *ic) size = AOP_SIZE(IC_LEFT(ic)); if(size <= 4) { - if(size>3) { - pic16_storeForReturn(IC_LEFT(ic), 3, pic16_popCopyReg(&pic16_pc_fsr0l)); -// pic16_emitpcode(POC_MOVFF, -// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 3), pic16_popCopyReg(&pic16_pc_fsr0l))); - } - if(size>2) { - pic16_storeForReturn(IC_LEFT(ic), 2, pic16_popCopyReg(&pic16_pc_prodh)); -// pic16_emitpcode(POC_MOVFF, -// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 2), pic16_popCopyReg(&pic16_pc_prodh))); - } - if(size>1) { - pic16_storeForReturn(IC_LEFT(ic), 1, pic16_popCopyReg(&pic16_pc_prodl)); -// pic16_emitpcode(POC_MOVFF, -// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 1), pic16_popCopyReg(&pic16_pc_prodl))); - } - -// pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(IC_LEFT(ic)), 0)); // patch 12 + if(size>3) + pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 3, pic16_popCopyReg(&pic16_pc_fsr0l)); + + if(size>2) + pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 2, pic16_popCopyReg(&pic16_pc_prodh)); - pic16_storeForReturn(IC_LEFT(ic), 0, pic16_popCopyReg(&pic16_pc_wreg)); // patch 12 -// pic16_emitpcode(POC_MOVFF, -// pic16_popGet2p(pic16_popGet(AOP(IC_LEFT(ic)), 0), pic16_popCopyReg(&pic16_pc_wreg))); + if(size>1) + pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 1, pic16_popCopyReg(&pic16_pc_prodl)); + + pic16_storeForReturn(ic, /*IC_LEFT(ic),*/ 0, pic16_popCopyReg(&pic16_pc_wreg)); } else { /* >32-bits, setup stack and FSR0 */ @@ -4878,11 +4942,6 @@ 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) /*-----------------------------------------------------------------*/ /* mov2w_regOrLit :- move to WREG either the offset's byte from */ @@ -4901,7 +4960,7 @@ void mov2w_regOrLit (asmop *aop, unsigned long lit, int offset) { /* genCmp :- greater or less than comparison */ /*-----------------------------------------------------------------*/ -#if USE_SIMPLE_GENCMP +#if USE_SIMPLE_GENCMP /* { */ /* genCmp performs a left < right comparison, stores * the outcome in result (if != NULL) and generates @@ -4937,6 +4996,10 @@ static void genCmp (operand *left,operand *right, resolveIfx (&rIfx, ifx); + /* handle for special cases */ + if(pic16_genCmp_special(left, right, result, ifx, &rIfx, sign)) + return; + /********************************************************************** * handle bits - bit compares are promoted to int compares seemingly! * **********************************************************************/ @@ -5122,7 +5185,7 @@ correct_result_in_carry: } // if } -#elif 1 +#elif 1 /* } */ /* { */ /* original code */ static void genCmp (operand *left,operand *right, @@ -5845,7 +5908,7 @@ check_carry: } -#else /* old version of genCmp() */ /* } else { */ +#elif 0 /* VR version of genCmp() */ /* } else { */ /* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */ static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx, @@ -5955,10 +6018,6 @@ static void compareAop(resolvedIfx *resIfx, iCode *ifx, symbol *falselbl, } } - - - -#if 1 /* { */ static void genCmp (operand *left, operand *right, operand *result, iCode *ifx, int sign) { @@ -6050,621 +6109,164 @@ static void genCmp (operand *left, operand *right, if(lit < 0) { /* literal is negative: - * a. if carry is set, too, continue compare, - * b. if carry is zero, then continue depending on cmpop ^ condition: - * 1. '<' return true (literal < variable), - * 2. '>' return false (literal > variable) */ -// pic16_emitpcode(POC_BC, pic16_popGetLabel( tlbl1->key )); - pic16_emitpcode(POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7)); - - if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key )); - else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key)); - } -#if 1 - else { - /* lit == 0 */ - pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7)); - - if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key )); - else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key)); - } -#endif - - - pic16_emitpLabel( tlbl1->key ); -#endif /* } */ - - compareAopfirstpass=1; -// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80)); -// pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size)); -// pic16_emitpcode(POC_MOVWF, pct); - -// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80)); - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size))); -// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); - compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl); - - /* generic case */ - while( size-- ) { -// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80)); -// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0)); -// pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size)); -// pic16_emitpcode(POC_MOVWF, pct); - -// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80)); - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x0)); - compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl); -// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); -// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl); - } -// } - - if(ifx)ifx->generated = 1; - - if(AOP_SIZE(result)) { - pic16_emitpLabel(tlbl->key); - pic16_emitpLabel(falselbl->key); - pic16_outBitOp( result, pct2 ); - } else { - pic16_emitpLabel(tlbl->key); - } - } else { - - - /* unsigned compare */ - DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__); - - compareAopfirstpass=1; - while(size--) { - - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size))); - compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL); - - } - - if(ifx)ifx->generated = 1; - - - if(AOP_SIZE(result)) { - pic16_emitpLabel(falselbl->key); - pic16_outBitC( result ); - } - - } - } else { - /* compare registers */ - DEBUGpic16_emitcode ("; ***","%s: %d: compare registers", __FUNCTION__, __LINE__); - - - if(sign) { - pCodeOp *pct, *pct2; - - /* signed compare */ - DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__); - - pct = pic16_popCopyReg(&pic16_pc_prodl); /* first temporary register */ - pct2 = pic16_popCopyReg(&pic16_pc_prodh); /* second temporary register */ - tlbl = newiTempLabel( NULL ); - - compareAopfirstpass=1; - - size--; - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size)); -// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); - pic16_emitpcode(POC_MOVWF, pct); - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size)); -// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); - - /* WREG already holds left + 0x80 */ - compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); - - while( size-- ) { - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size)); -// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); - pic16_emitpcode(POC_MOVWF, pct); - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size)); -// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); - - /* WREG already holds left + 0x80 */ - compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); -// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl); - } - - if(ifx)ifx->generated = 1; - - if(AOP_SIZE(result)) { - pic16_emitpLabel(tlbl->key); - pic16_emitpLabel(falselbl->key); - pic16_outBitOp( result, pct2 ); - } else { - pic16_emitpLabel(tlbl->key); - } - - } else { - /* unsigned compare */ - DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__); - - compareAopfirstpass=1; - while(size--) { - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size)); - compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL); - - } - - if(ifx)ifx->generated = 1; - if(AOP_SIZE(result)) { - - pic16_emitpLabel(falselbl->key); - pic16_outBitC( result ); - } - - } - } -} - -#else /* } else { */ - -/* new version of genCmp -- VR 20041012 */ -static void genCmp (operand *left,operand *right, - operand *result, iCode *ifx, int sign) -{ - int size; //, offset = 0 ; - unsigned long lit = 0L,i = 0; - resolvedIfx rFalseIfx; - int willCheckCarry=0; - // resolvedIfx rTrueIfx; - symbol *truelbl; - - FENTRY; - - /* General concept: - * subtract right from left if at the end the carry flag is set then we - * know that left is greater than right */ - - resolveIfx(&rFalseIfx,ifx); - truelbl = newiTempLabel(NULL); - size = max(AOP_SIZE(left),AOP_SIZE(right)); - - DEBUGpic16_pic16_AopType(__LINE__,left,right,result); - - /* POC_CPFSGT compare f, wreg, skip if f greater than wreg - * POC_CPFSLT compare f, wreg, skip if f less then wreg */ - - - /* if literal is on the right then swap with left */ - if ((AOP_TYPE(right) == AOP_LIT)) { - operand *tmp = right ; - unsigned long mask = (0x100 << (8*(size-1))) - 1; - - lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); - -// lit = (lit - 1) & mask; - right = left; - left = tmp; - rFalseIfx.condition ^= 1; /* reverse compare */ - } else - if ((AOP_TYPE(left) == AOP_LIT)) { - /* float compares are handled by support functions */ - lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit); - } - - - //if(IC_TRUE(ifx) == NULL) - /* if left & right are bit variables */ - if (AOP_TYPE(left) == AOP_CRY && - AOP_TYPE(right) == AOP_CRY ) { - - pic16_emitcode("mov","c,%s",AOP(right)->aopu.aop_dir); - pic16_emitcode("anl","c,/%s",AOP(left)->aopu.aop_dir); - - } else { - symbol *lbl = newiTempLabel(NULL); - - if(AOP_TYPE(left) == AOP_LIT) { - DEBUGpic16_emitcode(";left lit","lit = 0x%x, sign=%d",lit,sign); - - if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) - willCheckCarry = 1; - else willCheckCarry = 0; - - /* Special cases */ - if((lit == 0) && (sign == 0)) { - /* unsigned compare to 0 */ - DEBUGpic16_emitcode("; unsigned compare to 0","lit = 0x%x, sign=%d",lit,sign); - - size--; - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - while(size) - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),--size)); - - genSkipz2(&rFalseIfx,0); - if(ifx)ifx->generated = 1; - return; - } - - if(size==1) { - /* Special cases */ - lit &= 0xff; - if(((lit == 0xff) && !sign) || ((lit==0x7f) && sign)) { - /* degenerate compare can never be true */ - if(rFalseIfx.condition == 0) - pic16_emitpcode(POC_GOTO,pic16_popGetLabel(rFalseIfx.lbl->key)); - - if(ifx) ifx->generated = 1; - return; - } - - if(sign) { - /* signed comparisons to a literal byte */ - DEBUGpic16_emitcode(";signed compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign); - - int lp1 = (lit+1) & 0xff; - - DEBUGpic16_emitcode(";left lit","line = %d lit = 0x%x condition = %d lp1 = %i",__LINE__,lit, rFalseIfx.condition, lp1); - switch (lp1) { - case 0: - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,0,7); - break; - case 0x7f: - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_XORLW, pic16_popGetLit(0x7f)); - genSkipz2(&rFalseIfx,1); - break; - default: - pic16_emitpcode(POC_MOVLW, pic16_popGetLit( lit )); - - if(rFalseIfx.condition) - pic16_emitpcode(POC_CPFSLT, pic16_popGet(AOP(right), 0)); - else - pic16_emitpcode(POC_CPFSGT, pic16_popGet(AOP(right), 0)); - - if(willCheckCarry) { - if(!rFalseIfx.condition) { emitCLRC; emitSETC; } - else { emitSETC; emitCLRC; } - - } else { - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - } - -/* pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(((-(lit+1)) & 0xff) ^ 0x80)); - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); -*/ - break; - } - } else { - /* unsigned comparisons to a literal byte */ - DEBUGpic16_emitcode("; unsigned compare to literal","%d: lit = 0x%x, sign=%d",__LINE__, lit,sign); - - switch(lit & 0xff ) { - /* special cases */ - case 0: - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - genSkipz2(&rFalseIfx,0); - break; - case 0x7f: - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,0,7); - break; - default: - pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lit+1) & 0xff)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0)); - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - rFalseIfx.condition ^= 1; - if (AOP_TYPE(result) == AOP_CRY) - genSkipc(&rFalseIfx); - else { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0)); - } - break; - } - } - - if(ifx) ifx->generated = 1; - if ((AOP_TYPE(result) != AOP_CRY) && (AOP_SIZE(result))) - goto check_carry; - return; - - } else { - - /* Size is greater than 1 */ - - if(sign) { - int lp1 = lit+1; - - size--; - - if(lp1 == 0) { - /* this means lit = 0xffffffff, or -1 */ - - - DEBUGpic16_emitcode(";left lit = -1","line = %d ",__LINE__); - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,size,7); - if(ifx) ifx->generated = 1; - return; - } - - if(lit == 0) { - int s = size; - - if(rFalseIfx.condition) { - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); - } - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - while(size--) - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); - - - emitSKPZ; - if(rFalseIfx.condition) { - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - pic16_emitpLabel(truelbl->key); - }else { - rFalseIfx.condition ^= 1; - genSkipCond(&rFalseIfx,right,s,7); - } - - if(ifx) ifx->generated = 1; - return; - } - - if((size == 1) && (0 == (lp1&0xff))) { - /* lower byte of signed word is zero */ - DEBUGpic16_emitcode(";left lit","line = %d 0x%x+1 low byte is zero",__LINE__,lit); - i = ((lp1 >> 8) & 0xff) ^0x80; - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit( 0x80)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x100-i)); - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); - - - if(ifx) ifx->generated = 1; - return; - } - - if(lit & (0x80 << (size*8))) { - /* Lit is less than zero */ - DEBUGpic16_emitcode(";left lit","line = %d 0x%x is less than 0",__LINE__,lit); - //rFalseIfx.condition ^= 1; - //genSkipCond(&rFalseIfx,left,size,7); - //rFalseIfx.condition ^= 1; - pic16_emitpcode(POC_BTFSS, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); - - if(rFalseIfx.condition) - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - else - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); - - - } else { - /* Lit is greater than or equal to zero */ - DEBUGpic16_emitcode(";left lit","line = %d 0x%x is greater than 0",__LINE__,lit); - //rFalseIfx.condition ^= 1; - //genSkipCond(&rFalseIfx,right,size,7); - //rFalseIfx.condition ^= 1; - - //pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0)); - //pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - - pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(right),size,FALSE,FALSE),7,0, PO_GPR_REGISTER)); - if(rFalseIfx.condition) - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); - else - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - - } - - - pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); - - while(size--) { - - pic16_emitpcode(POC_MOVLW, pic16_popGetLit((lp1 >> (size*8)) & 0xff)); - emitSKPNZ; - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); - } - rFalseIfx.condition ^= 1; - //rFalseIfx.condition = 1; - genSkipc(&rFalseIfx); - - pic16_emitpLabel(truelbl->key); - - if(ifx) ifx->generated = 1; - return; - // end of if (sign) - } else { - - /* compare word or long to an unsigned literal on the right.*/ - - - size--; - if(lit < 0xff) { - DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x < 0xff",__FUNCTION__,__LINE__,lit); - switch (lit) { - case 0: - break; /* handled above */ -/* - case 0xff: - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - while(size--) - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); - genSkipz2(&rFalseIfx,0); - break; -*/ - default: - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - while(--size) - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); - - emitSKPZ; - if(rFalseIfx.condition) - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rFalseIfx.lbl->key)); - else - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(truelbl->key)); - - - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit+1)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),0)); - - rFalseIfx.condition ^= 1; - genSkipc(&rFalseIfx); - } - - pic16_emitpLabel(truelbl->key); - - if(ifx) ifx->generated = 1; - return; - } - + * a. if carry is set, too, continue compare, + * b. if carry is zero, then continue depending on cmpop ^ condition: + * 1. '<' return true (literal < variable), + * 2. '>' return false (literal > variable) */ +// pic16_emitpcode(POC_BC, pic16_popGetLabel( tlbl1->key )); + pic16_emitpcode(POC_BTFSS, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7)); + + if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key )); + else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key)); + } +#if 1 + else { + /* lit == 0 */ + pic16_emitpcode(POC_BTFSC, pic16_popCopyGPR2Bit(pic16_popGet(AOP(right), size), 7)); + + if(!(cmpop ^ rFalseIfx.condition))pic16_emitpcode(POC_GOTO, pic16_popGetLabel( tlbl->key )); + else pic16_emitpcode(POC_GOTO, pic16_popGetLabel( rFalseIfx.lbl->key)); + } +#endif + + + pic16_emitpLabel( tlbl1->key ); +#endif /* } */ - lit++; - DEBUGpic16_emitcode ("; ***","%s %d lit =0x%x",__FUNCTION__,__LINE__,lit); - i = (lit >> (size*8)) & 0xff; + compareAopfirstpass=1; +// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80)); +// pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size)); +// pic16_emitpcode(POC_MOVWF, pct); - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); +// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80)); + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size))); +// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); + compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl); - while(size--) { - i = (lit >> (size*8)) & 0xff; + /* generic case */ + while( size-- ) { +// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80)); +// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x0)); +// pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(right), size)); +// pic16_emitpcode(POC_MOVWF, pct); - if(i) { - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(i)); - emitSKPNZ; - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(right),size)); - } else { - /* this byte of the lit is zero, - * if it's not the last then OR in the variable */ - if(size) - pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),size)); - } - } +// pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x80)); + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size) + 0x0)); + compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, pct2, tlbl); +// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); +// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl); + } +// } + + if(ifx)ifx->generated = 1; + if(AOP_SIZE(result)) { + pic16_emitpLabel(tlbl->key); + pic16_emitpLabel(falselbl->key); + pic16_outBitOp( result, pct2 ); + } else { + pic16_emitpLabel(tlbl->key); + } + } else { - pic16_emitpLabel(lbl->key); - rFalseIfx.condition ^= 1; + /* unsigned compare */ + DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__); + + compareAopfirstpass=1; + while(size--) { + + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(BYTEofLONG(lit, size))); + compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL); - genSkipc(&rFalseIfx); - } + } - if(sign) - pic16_emitpLabel(truelbl->key); - if(ifx) ifx->generated = 1; - return; - } - } - /* Compare two variables */ + if(ifx)ifx->generated = 1; - DEBUGpic16_emitcode(";sign","%d",sign); - size--; - if(sign) { - /* Sigh. thus sucks... */ - if(size) { - pCodeOp *pctemp; - - pctemp = pic16_popGetTempReg(1); - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),size)); - pic16_emitpcode(POC_MOVWF, pctemp); //pic16_pic16_popRegFromIdx(pic16_Gstack_base_addr)); - pic16_emitpcode(POC_MOVLW, pic16_popGetLit(0x80)); - pic16_emitpcode(POC_XORWF, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr)); - pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),size)); - pic16_emitpcode(POC_SUBFW, pctemp); //pic16_popRegFromIdx(pic16_Gstack_base_addr)); - pic16_popReleaseTempReg(pctemp, 1); - } else { - /* Signed char comparison */ - /* Special thanks to Nikolai Golovchenko for this snippet */ - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_RRCFW, pic16_popGet(AOP(left),0)); /* could be any register */ - pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(left),0)); - pic16_emitpcode(POC_XORFW, pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); + if(AOP_SIZE(result)) { + pic16_emitpLabel(falselbl->key); + pic16_outBitC( result ); + } - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - genSkipc(&rFalseIfx); - - if(ifx) ifx->generated = 1; - return; } - } else { - - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); - } + /* compare registers */ + DEBUGpic16_emitcode ("; ***","%s: %d: compare registers", __FUNCTION__, __LINE__); - /* The rest of the bytes of a multi-byte compare */ - while (size) { + if(sign) { + pCodeOp *pct, *pct2; + + /* signed compare */ + DEBUGpic16_emitcode ("; ***","%s: %d: signed compare", __FUNCTION__, __LINE__); - emitSKPZ; - pic16_emitpcode(POC_GOTO, pic16_popGetLabel(lbl->key)); - size--; + pct = pic16_popCopyReg(&pic16_pc_prodl); /* first temporary register */ + pct2 = pic16_popCopyReg(&pic16_pc_prodh); /* second temporary register */ + tlbl = newiTempLabel( NULL ); + + compareAopfirstpass=1; - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),size)); - pic16_emitpcode(POC_SUBFW, pic16_popGet(AOP(left),size)); + size--; + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size)); +// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); + pic16_emitpcode(POC_MOVWF, pct); + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size)); +// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); - } + /* WREG already holds left + 0x80 */ + compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); + + while( size-- ) { + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right), size)); +// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); + pic16_emitpcode(POC_MOVWF, pct); + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size)); +// pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x80)); + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(0x0)); - pic16_emitpLabel(lbl->key); + /* WREG already holds left + 0x80 */ + compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, pct, pct2, tlbl); +// compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 0, pct, pct2, tlbl); + } + + if(ifx)ifx->generated = 1; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if ((AOP_TYPE(result) == AOP_CRY && AOP_SIZE(result)) || - (AOP_TYPE(result) == AOP_REG)) { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_RLCF, pic16_popGet(AOP(result),0)); - } else { - genSkipc(&rFalseIfx); - } - //genSkipc(&rFalseIfx); - if(ifx) ifx->generated = 1; + if(AOP_SIZE(result)) { + pic16_emitpLabel(tlbl->key); + pic16_emitpLabel(falselbl->key); + pic16_outBitOp( result, pct2 ); + } else { + pic16_emitpLabel(tlbl->key); + } - return; + } else { + /* unsigned compare */ + DEBUGpic16_emitcode ("; ***","%s: %d: unsigned compare", __FUNCTION__, __LINE__); - } + compareAopfirstpass=1; + while(size--) { + + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left), size)); + compareAop(&rFalseIfx, ifx, falselbl, right, size, result, sign, 1, NULL, NULL, NULL); -check_carry: - if ((AOP_TYPE(result) != AOP_CRY) - && AOP_SIZE(result)) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + } - if(!ifx)pic16_emitpLabel( rFalseIfx.lbl->key ); + if(ifx)ifx->generated = 1; + if(AOP_SIZE(result)) { - pic16_outBitC(result); - } else { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* if the result is used in the next - ifx conditional branch then generate - code a little differently */ - if (ifx ) - genIfxJump (ifx,"c"); - else - pic16_outBitC(result); - /* leave the result in acc */ - } + pic16_emitpLabel(falselbl->key); + pic16_outBitC( result ); + } + } + } } -#endif /* } */ - #endif /* } */ @@ -8629,6 +8231,7 @@ static void genXor (iCode *ic, iCode *ifx) static void genInline (iCode *ic) { char *buffer, *bp, *bp1; + char *cbuf; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -8636,14 +8239,67 @@ static void genInline (iCode *ic) buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); strcpy(buffer,IC_INLINE(ic)); - + while((bp1=strstr(bp, "\\n"))) { *bp1++ = '\n'; *bp1++ = ' '; bp = bp1; } bp = bp1 = buffer; - + + cbuf = Safe_strdup( buffer ); + + if(asmInlineMap) + { + symbol *sym; + char *s; + int cblen; + + cbuf = Safe_strdup(buffer); + cblen = strlen(buffer)+1; + memset(cbuf, 0, cblen); + + bp = buffer; + bp1 = cbuf; + while(*bp) { + if(*bp != '%')*bp1++ = *bp++; + else { + int i; + + bp++; + i = *bp - '0'; + if(i>elementsInSet(asmInlineMap))break; + + bp++; + s = indexSet(asmInlineMap, i); + DEBUGpc("searching symbol s = `%s'", s); + sym = findSym(SymbolTab, NULL, s); + + if(sym->reqv) { + strcat(bp1, sym->reqv->operand.symOperand->regs[0]->name); + } else { + strcat(bp1, sym->rname); + } + + while(*bp1)bp1++; + } + + if(strlen(bp1) > cblen - 16) { + int i = strlen(cbuf); + cblen += 50; + cbuf = realloc(cbuf, cblen); + memset(cbuf+i, 0, 50); + bp1 = cbuf + i; + } + } + + free(buffer); + buffer = Safe_strdup( cbuf ); + free(cbuf); + + bp = bp1 = buffer; + } + /* emit each line as a code */ while (*bp) { if (*bp == '\n') { @@ -11046,6 +10702,8 @@ static void genDataPointerGet(operand *left, DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(result, ic, TRUE); + FENTRY; + size = AOP_SIZE(result); // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size); @@ -11096,8 +10754,8 @@ static void genDataPointerGet(operand *left, while (size--) { DEBUGpic16_emitcode("; ***", "%s loop offset=%d leoffset=%d", __FUNCTION__, offset, leoffset); - if(AOP(result)->aopu.pcop->type == PO_IMMEDIATE - || AOP(left)->aopu.pcop->type == PO_IMMEDIATE) { +// pic16_DumpOp("(result)",result); + if(is_LitAOp(AOP(result))) { pic16_mov2w(AOP(left), offset); // patch 8 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result), offset)); } else { @@ -12677,8 +12335,8 @@ static void genAddrOf (iCode *ic) /* get address of symbol on stack */ DEBUGpic16_emitcode("; ", "%s symbol %s on stack", __FUNCTION__, sym->name); #if 0 - fprintf(stderr, "%s:%d symbol %s on stack offset %d\n", __FILE__, __LINE__, - OP_SYMBOL(left)->name, OP_SYMBOL(left)->stack); + fprintf(stderr, "%s:%d symbol %s on stack offset %i\n", __FILE__, __LINE__, + OP_SYMBOL(IC_LEFT(ic))->name, OP_SYMBOL(IC_LEFT(ic))->stack); #endif // operands on stack are accessible via "FSR2 + index" with index @@ -13054,9 +12712,10 @@ static void genJumpTab (iCode *ic) pic16_emitpcode(POC_MOVWF , pic16_popCopyReg(&pic16_pc_pcl)); pic16_emitpLabelFORCE(jtab->key); - #endif + pic16_freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE); +// pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_ENTRY_BEGIN)); pic16_emitpinfo (INF_OPTIMIZATION, pic16_newpCodeOpOpt (OPT_JUMPTABLE_BEGIN, "")); /* now generate the jump labels */ @@ -13220,8 +12879,8 @@ static void genCast (iCode *ic) // if (operandsEqu(IC_RESULT(ic),IC_RIGHT(ic))) // return ; - pic16_aopOp(right,ic,FALSE) ; pic16_aopOp(result,ic,FALSE); + pic16_aopOp(right,ic,FALSE) ; DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); @@ -13467,6 +13126,8 @@ static void genCast (iCode *ic) goto release ; } + + assert( 0 ); /* just copy the pointers */ size = AOP_SIZE(result); offset = 0 ; @@ -13494,8 +13155,10 @@ static void genCast (iCode *ic) /* we move to result for the size of source */ size = AOP_SIZE(right); offset = 0 ; + while (size--) { - mov2f(AOP(result), AOP(right), offset); + if(!_G.resDirect) + mov2f(AOP(result), AOP(right), offset); offset++; } diff --git a/src/pic16/gen.h b/src/pic16/gen.h index 73b037d4..bafe4f8c 100644 --- a/src/pic16/gen.h +++ b/src/pic16/gen.h @@ -188,7 +188,7 @@ pCodeOp *pic16_popGetLit2(int lit, pCodeOp *arg2); pCodeOp *popGetWithString(char *str); pCodeOp *pic16_popGet (asmop *aop, int offset);//, bool bit16, bool dname); pCodeOp *pic16_popGetTempReg(int lock); -pCodeOp *pic16_popGetTempRegCond(bitVect *, int lock); +pCodeOp *pic16_popGetTempRegCond(bitVect *, bitVect *, int lock); void pic16_popReleaseTempReg(pCodeOp *pcop, int lock); pCodeOp *pic16_popCombine2(pCodeOpReg *src, pCodeOpReg *dst, int noalloc); diff --git a/src/pic16/genutils.c b/src/pic16/genutils.c index 55e5bbe9..35273afb 100644 --- a/src/pic16/genutils.c +++ b/src/pic16/genutils.c @@ -54,6 +54,7 @@ #include "SDCCpeeph.h" #include "ralloc.h" #include "pcode.h" +#include "device.h" #include "gen.h" #include "genutils.h" @@ -463,3 +464,95 @@ void gpsimDebug_StackDump(char *fname, int line, char *info) gpsimio2_lit('\n'); } + + + +/* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */ +static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx, + operand *result, int offset, int invert_op) +{ + /* add code here */ + + /* check condition, > or < ?? */ + if(rIfx->condition != 0)invert_op ^= 1; + + if(ifx && IC_FALSE(ifx))invert_op ^= 1; + + if(!ifx)invert_op ^= 1; + + DEBUGpic16_emitcode("; +++", "%s:%d %s] rIfx->condition= %d, ifx&&IC_FALSE(ifx)= %d, invert_op = %d", + __FILE__, __LINE__, __FUNCTION__, rIfx->condition, (ifx && IC_FALSE(ifx)), invert_op); + + /* do selection */ + if(!invert_op)return POC_CPFSGT; + else return POC_CPFSLT; +} + +/* return 1 if function handles compare, 0 otherwise */ +/* this functions handles special cases like: + * reg vs. zero + * reg vs. one + */ +int pic16_genCmp_special(operand *left, operand *right, operand *result, + iCode *ifx, resolvedIfx *rIfx, int sign) +{ + int size; + int offs; + symbol *tmplbl; + unsigned long lit; + int op, cmp_op=0; + + FENTRY; + + if(!(pic16_options.opt_flags & OF_OPTIMIZE_CMP))return 0; + + size = max(AOP_SIZE(left), AOP_SIZE(right)); + + if(!isAOP_REGlike(left)) { + operand *dummy; + + dummy = left; + left = right; + right = dummy; + + /* invert comparing operand */ +// cmp_op ^= 1; + rIfx->condition ^= 1; + } + + + if(isAOP_REGlike(left) && isAOP_LIT(right)) { + /* comparing register vs. literal */ + lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit); + + + if(size == 1) { + op = selectCompareOp(rIfx, ifx, result, offs, cmp_op); + + DEBUGpic16_emitcode("%%", "comparing operand %s, condition: %d", (op==POC_CPFSLT?"POC_CPFSLT":"POC_CPFSGT"), rIfx->condition); + + if(!sign) { + /* unsigned compare */ + switch( lit ) { + case 0: + if(ifx && IC_FALSE(ifx)) { + tmplbl = newiTempLabel( NULL ); + pic16_emitpcode(POC_TSTFSZ, pic16_popGet(AOP(left), 0)); + pic16_emitpcode(POC_BRA, pic16_popGetLabel(tmplbl->key)); + pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx->lbl->key)); + pic16_emitpLabel(tmplbl->key); + + ifx->generated = 1; + return 1; + } + break; + } /* switch */ + + } /* if(!sign) */ + + } /* if(size==1) */ + + } /* */ + + return 0; +} diff --git a/src/pic16/genutils.h b/src/pic16/genutils.h index 2c81d09a..2ada0772 100644 --- a/src/pic16/genutils.h +++ b/src/pic16/genutils.h @@ -10,6 +10,24 @@ #include "common.h" +#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) + + +/* Resolved ifx structure. This structure stores information + * about an iCode ifx that makes it easier to generate code. + */ +typedef struct resolvedIfx { + symbol *lbl; /* pointer to a label */ + int condition; /* true or false ifx */ + int generated; /* set true when the code associated with the ifx + * is generated */ +} resolvedIfx; + + /* * The various GEN_xxxxx macros handle which functions * should be included in the gen.c source. We are going to use @@ -38,6 +56,9 @@ void gpsimio2_lit(unsigned char lit); void gpsimDebug_StackDump(char *fname, int line, char *info); +int pic16_genCmp_special(operand *left, operand *right, operand *result, + iCode *ifx, resolvedIfx *rIfx, int sign); + #ifndef debugf #define debugf(frm, rest) _debugf(__FILE__, __LINE__, frm, rest) #endif diff --git a/src/pic16/glue.c b/src/pic16/glue.c index 673e9e8c..af1307ab 100644 --- a/src/pic16/glue.c +++ b/src/pic16/glue.c @@ -1402,7 +1402,7 @@ pic16createInterruptVect (FILE * vFile) return; } #endif - +#if 0 if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) { fprintf (vFile, ";\t.area\t%s\n", CODE_NAME); fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc); @@ -1413,6 +1413,7 @@ pic16createInterruptVect (FILE * vFile) port->genIVT(vFile, interrupts, maxInterrupts); } } +#endif } diff --git a/src/pic16/main.c b/src/pic16/main.c index ac4e22e1..606eea41 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -140,6 +140,8 @@ set *sectNames=NULL; /* list of section listed in pragma directives */ set *sectSyms=NULL; /* list of symbols set in a specific section */ set *wparamList=NULL; +set *asmInlineMap=NULL; + struct { unsigned ignore: 1; unsigned want_libc: 1; @@ -154,190 +156,209 @@ _process_pragma(const char *sz) { static const char *WHITE = " \t\n"; static const char *WHITECOMMA = " \t\n,"; - - char *ptr = strtok((char *)sz, WHITE); + char *ptr = strtok((char *)sz, WHITE); - /* #pragma maxram [maxram] */ - if (startsWith (ptr, "maxram")) { - char *maxRAM = strtok((char *)NULL, WHITE); + /* #pragma maxram [maxram] */ + if (startsWith (ptr, "maxram")) { + char *maxRAM = strtok((char *)NULL, WHITE); - if (maxRAM != (char *)NULL) { - int maxRAMaddress; - value *maxRAMVal; + if (maxRAM != (char *)NULL) { + int maxRAMaddress; + value *maxRAMVal; - maxRAMVal = constVal(maxRAM); - maxRAMaddress = (int)floatFromVal(maxRAMVal); - pic16_setMaxRAM(maxRAMaddress); - } - - return 0; - } - - /* #pragma stack [stack-position] [stack-len] */ - if(startsWith(ptr, "stack")) { - char *stackPosS = strtok((char *)NULL, WHITE); - char *stackLenS = strtok((char *)NULL, WHITE); - value *stackPosVal; - value *stackLenVal; - regs *reg; - symbol *sym; - - stackPosVal = constVal( stackPosS ); - stackPos = (unsigned int)floatFromVal( stackPosVal ); + maxRAMVal = constVal(maxRAM); + maxRAMaddress = (int)floatFromVal(maxRAMVal); + pic16_setMaxRAM(maxRAMaddress); + } - - if(stackLenS) { - stackLenVal = constVal( stackLenS ); - stackLen = (unsigned int)floatFromVal( stackLenVal ); - } + return 0; + } + + /* #pragma stack [stack-position] [stack-len] */ + if(startsWith(ptr, "stack")) { + char *stackPosS = strtok((char *)NULL, WHITE); + char *stackLenS = strtok((char *)NULL, WHITE); + value *stackPosVal; + value *stackLenVal; + regs *reg; + symbol *sym; + + stackPosVal = constVal( stackPosS ); + stackPos = (unsigned int)floatFromVal( stackPosVal ); + + if(stackLenS) { + stackLenVal = constVal( stackLenS ); + stackLen = (unsigned int)floatFromVal( stackLenVal ); + } - if(stackLen < 1) { - stackLen = 64; - fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n", - filename, lineno-1, stackLen, stackLen); + if(stackLen < 1) { + stackLen = 64; + fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n", + filename, lineno-1, stackLen, stackLen); -// fprintf(stderr, "%s:%d setting stack to default size %d\n", __FILE__, __LINE__, stackLen); - } +// fprintf(stderr, "%s:%d setting stack to default size %d\n", __FILE__, __LINE__, stackLen); + } -// fprintf(stderr, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen); - - reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL); - addSet(&pic16_fix_udata, reg); - - reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos + stackLen-1, "_stack_end", 1, 0, NULL); - addSet(&pic16_fix_udata, reg); +// fprintf(stderr, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen); + + reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL); + addSet(&pic16_fix_udata, reg); + + reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos + stackLen-1, "_stack_end", 1, 0, NULL); + addSet(&pic16_fix_udata, reg); + + sym = newSymbol("stack", 0); + sprintf(sym->rname, "_%s", sym->name); + addSet(&publics, sym); + + sym = newSymbol("stack_end", 0); + sprintf(sym->rname, "_%s", sym->name); + addSet(&publics, sym); + + initsfpnt = 1; // force glue() to initialize stack/frame pointers */ - sym = newSymbol("stack", 0); - sprintf(sym->rname, "_%s", sym->name); - addSet(&publics, sym); + return 0; + } + + /* #pragma code [symbol] [location] */ + if(startsWith(ptr, "code")) { + char *symname = strtok((char *)NULL, WHITE); + char *location = strtok((char *)NULL, WHITE); + absSym *absS; + value *addr; + + absS = Safe_calloc(1, sizeof(absSym)); + sprintf(absS->name, "_%s", symname); + + addr = constVal( location ); + absS->address = (unsigned int)floatFromVal( addr ); - sym = newSymbol("stack_end", 0); - sprintf(sym->rname, "_%s", sym->name); - addSet(&publics, sym); - - initsfpnt = 1; // force glue() to initialize stack/frame pointers */ + if((absS->address % 2) != 0) { + absS->address--; + fprintf(stderr, "%s:%d: warning: code memory locations should be word aligned, will locate to 0x%06x instead\n", + filename, lineno-1, absS->address); + } - return 0; - } - - /* #pragma code [symbol] [location] */ - if(startsWith(ptr, "code")) { - char *symname = strtok((char *)NULL, WHITE); - char *location = strtok((char *)NULL, WHITE); - absSym *absS; - value *addr; - - absS = Safe_calloc(1, sizeof(absSym)); - sprintf(absS->name, "_%s", symname); - - addr = constVal( location ); - absS->address = (unsigned int)floatFromVal( addr ); + addSet(&absSymSet, absS); +// fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n", +// __FILE__, __LINE__, symname, absS->address); - if((absS->address % 2) != 0) { - absS->address--; - fprintf(stderr, "%s:%d: warning: code memory locations should be word aligned, will locate to 0x%06x instead\n", - filename, lineno-1, absS->address); - } + return 0; + } - addSet(&absSymSet, absS); -// fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n", -// __FILE__, __LINE__, symname, absS->address); + /* #pragma udata [section-name] [symbol] */ + if(startsWith(ptr, "udata")) { + char *sectname = strtok((char *)NULL, WHITE); + char *symname = strtok((char *)NULL, WHITE); + symbol *nsym; + sectSym *ssym; + sectName *snam; + int found=0; + + while(symname) { + ssym = Safe_calloc(1, sizeof(sectSym)); + ssym->name = Safe_calloc(1, strlen(symname)+2); + sprintf(ssym->name, "_%s", symname); + ssym->reg = NULL; - return 0; - } + addSet(§Syms, ssym); + + nsym = newSymbol(symname, 0); + strcpy(nsym->rname, ssym->name); - /* #pragma udata [section-name] [symbol] */ - if(startsWith(ptr, "udata")) { - char *sectname = strtok((char *)NULL, WHITE); - char *symname = strtok((char *)NULL, WHITE); - symbol *nsym; - sectSym *ssym; - sectName *snam; - int found=0; - - while(symname) { - ssym = Safe_calloc(1, sizeof(sectSym)); - ssym->name = Safe_calloc(1, strlen(symname)+2); - sprintf(ssym->name, "_%s", symname); - ssym->reg = NULL; - - addSet(§Syms, ssym); - - nsym = newSymbol(symname, 0); - strcpy(nsym->rname, ssym->name); #if 0 - checkAddSym(&publics, nsym); + checkAddSym(&publics, nsym); #endif - found = 0; - for(snam=setFirstItem(sectNames);snam;snam=setNextItem(sectNames)) { - if(!strcmp(sectname, snam->name)){ found=1; break; } - } - - if(!found) { - snam = Safe_calloc(1, sizeof(sectName)); - snam->name = Safe_strdup( sectname ); - snam->regsSet = NULL; - - addSet(§Names, snam); - } - - ssym->section = snam; - + found = 0; + for(snam=setFirstItem(sectNames);snam;snam=setNextItem(sectNames)) { + if(!strcmp(sectname, snam->name)){ found=1; break; } + } + + if(!found) { + snam = Safe_calloc(1, sizeof(sectName)); + snam->name = Safe_strdup( sectname ); + snam->regsSet = NULL; + + addSet(§Names, snam); + } + + ssym->section = snam; + #if 0 - fprintf(stderr, "%s:%d placing symbol %s at section %s (%p)\n", __FILE__, __LINE__, - ssym->name, snam->name, snam); + fprintf(stderr, "%s:%d placing symbol %s at section %s (%p)\n", __FILE__, __LINE__, + ssym->name, snam->name, snam); #endif - symname = strtok((char *)NULL, WHITE); - } + symname = strtok((char *)NULL, WHITE); + } - return 0; - } - - /* #pragma wparam function1[, function2[,...]] */ - if(startsWith(ptr, "wparam")) { - char *fname = strtok((char *)NULL, WHITECOMMA); - - while(fname) { - addSet(&wparamList, Safe_strdup(fname)); + return 0; + } + + /* #pragma wparam function1[, function2[,...]] */ + if(startsWith(ptr, "wparam")) { + char *fname = strtok((char *)NULL, WHITECOMMA); + + + while(fname) { + fprintf(stderr, "PIC16 Warning: `%s' wparam pragma is obsolete. use function attribute `wparam' instead.\n", fname); + addSet(&wparamList, Safe_strdup(fname)); -// debugf("passing with WREG to %s\n", fname); - fname = strtok((char *)NULL, WHITECOMMA); - } +// debugf("passing with WREG to %s\n", fname); + fname = strtok((char *)NULL, WHITECOMMA); + } - return 0; - } + return 0; + } - /* #pragma library library_module */ - if(startsWith(ptr, "library")) { - char *lmodule = strtok((char *)NULL, WHITE); + /* #pragma library library_module */ + if(startsWith(ptr, "library")) { + char *lmodule = strtok((char *)NULL, WHITE); - if(lmodule) { - /* lmodule can be: - * c link the C library - * math link the math library - * io link the IO library - * debug link the debug libary - * anything else, will link as-is */ - if(!strcmp(lmodule, "c"))libflags.want_libc = 1; - else if(!strcmp(lmodule, "math"))libflags.want_libm = 1; - else if(!strcmp(lmodule, "io"))libflags.want_libio = 1; - else if(!strcmp(lmodule, "debug"))libflags.want_libdebug = 1; - else if(!strcmp(lmodule, "ignore"))libflags.ignore = 1; - else { - if(!libflags.ignore) { - fprintf(stderr, "link library %s\n", lmodule); - addSetHead(&libFilesSet, lmodule); - } - } - } - - return 0; + if(lmodule) { + /* lmodule can be: + * c link the C library + * math link the math library + * io link the IO library + * debug link the debug libary + * anything else, will link as-is */ + + if(!strcmp(lmodule, "c"))libflags.want_libc = 1; + else if(!strcmp(lmodule, "math"))libflags.want_libm = 1; + else if(!strcmp(lmodule, "io"))libflags.want_libio = 1; + else if(!strcmp(lmodule, "debug"))libflags.want_libdebug = 1; + else if(!strcmp(lmodule, "ignore"))libflags.ignore = 1; + else { + if(!libflags.ignore) { + fprintf(stderr, "link library %s\n", lmodule); + addSetHead(&libFilesSet, lmodule); } - - - + } + } + + return 0; + } + + if(startsWith(ptr, "inline")) { + char *tmp = strtok((char *)NULL, WHITECOMMA); + + while(tmp) { + addSet(&asmInlineMap, Safe_strdup( tmp )); + tmp = strtok((char *)NULL, WHITECOMMA); + } + + { + char *s; + + for(s = setFirstItem(asmInlineMap); s ; s = setNextItem(asmInlineMap)) { + debugf("inline asm: `%s'\n", s); + } + } + + return 0; + } + return 1; } @@ -349,7 +370,7 @@ _process_pragma(const char *sz) #define ALT_ASM "--asm=" #define ALT_LINK "--link=" -#define IVT_LOC "--ivt-loc" +#define IVT_LOC "--ivt-loc=" #define NO_DEFLIBS "--nodefaultlibs" #define MPLAB_COMPAT "--mplab-comp" @@ -359,6 +380,7 @@ _process_pragma(const char *sz) #define OFMSG_LRSUPPORT "--flr-support" #define OPTIMIZE_GOTO "--optimize-goto" +#define OPTIMIZE_CMP "--optimize-cmp" char *alt_asm=NULL; char *alt_link=NULL; @@ -399,8 +421,8 @@ OPTION pic16_optionsTable[]= { { 0, USE_CRT, NULL, "use run-time initialization module"}, { 0, "--no-crt", &pic16_options.no_crt, "do not link any default run-time initialization module"}, { 0, "--gstack", &pic16_options.gstack, "trace stack pointer push/pop to overflow"}, -// { 0, OFMSG_LRSUPPORT, NULL, "use support functions for local register store/restore"}, { 0, OPTIMIZE_GOTO, NULL, "try to use (conditional) BRA instead of GOTO"}, + { 0, OPTIMIZE_CMP, NULL, "try to optimize some compares"}, { 0, NULL, NULL, NULL} }; @@ -462,6 +484,7 @@ _pic16_parseOptions (int *pargc, char **argv, int *i) if(ISOPT(IVT_LOC)) { pic16_options.ivt_loc = getIntArg(IVT_LOC, argv, i, *pargc); + fprintf(stderr, "%s:%d setting interrupt vector addresses 0x%x\n", __FILE__, __LINE__, pic16_options.ivt_loc); return TRUE; } @@ -492,12 +515,16 @@ _pic16_parseOptions (int *pargc, char **argv, int *i) } #endif -#if 1 if (ISOPT(OPTIMIZE_GOTO)) { pic16_options.opt_flags |= OF_OPTIMIZE_GOTO; return TRUE; } -#endif + + if(ISOPT(OPTIMIZE_CMP)) { + pic16_options.opt_flags |= OF_OPTIMIZE_CMP; + return TRUE; + } + return FALSE; } @@ -515,6 +542,9 @@ static void _pic16_initPaths(void) setMainValue("mcu", pic16->name[2] ); addSet(&preArgvSet, Safe_strdup("-D{mcu}")); + setMainValue("mcu1", pic16->name[1] ); + addSet(&preArgvSet, Safe_strdup("-D__{mcu1}")); + sprintf(pic16incDir, "%s%cpic16", INCLUDE_DIR_SUFFIX, DIR_SEPARATOR_CHAR); sprintf(pic16libDir, "%s%cpic16", LIB_DIR_SUFFIX, DIR_SEPARATOR_CHAR); @@ -661,6 +691,15 @@ _pic16_finaliseOptions (void) if(options.model == MODEL_LARGE) addSet(&asmOptionsSet, Safe_strdup("-DSDCC_MODEL_LARGE")); + { + char buf[128]; + + sprintf(buf, "-D%s -D%s", pic16->name[2], pic16->name[1]); + *(strrchr(buf, 'f')) = 'F'; + addSet(&asmOptionsSet, Safe_strdup( buf )); + } + + if(STACK_MODEL_LARGE) { addSet(&preArgvSet, Safe_strdup("-DSTACK_MODEL_LARGE")); addSet(&asmOptionsSet, Safe_strdup("-DSTACK_MODEL_LARGE")); diff --git a/src/pic16/pcode.c b/src/pic16/pcode.c index e2d9ea3a..d6a4205b 100644 --- a/src/pic16/pcode.c +++ b/src/pic16/pcode.c @@ -127,7 +127,7 @@ pCodeOpReg *pic16_frame_plusw; pCodeOpReg pic16_pc_gpsimio = {{PO_GPR_REGISTER, "GPSIMIO"}, -1, NULL, 0, NULL}; pCodeOpReg pic16_pc_gpsimio2 = {{PO_GPR_REGISTER, "GPSIMIO2"}, -1, NULL, 0, NULL}; -char *OPT_TYPE_STR[] = { "begin", "end" }; +char *OPT_TYPE_STR[] = { "begin", "end", "jumptable_begin", "jumptable_end" }; char *LR_TYPE_STR[] = { "entry begin", "entry end", "exit begin", "exit end" }; @@ -281,7 +281,7 @@ pCodeInstruction pic16_pciADDWFC = { // mdubuc - New 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER | PCC_C), // inCond - (PCC_REGISTER | PCC_Z), // outCond + (PCC_REGISTER | PCC_Z | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond PCI_MAGIC }; @@ -309,7 +309,7 @@ pCodeInstruction pic16_pciADDFWC = { 0, // second literal operand POC_NOP, (PCC_W | PCC_REGISTER | PCC_C), // inCond - (PCC_W | PCC_Z), // outCond + (PCC_W | PCC_Z | PCC_DC | PCC_Z | PCC_OV | PCC_N), // outCond PCI_MAGIC }; @@ -868,7 +868,7 @@ pCodeInstruction pic16_pciCOMF = { 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_REGISTER , // outCond + (PCC_REGISTER | PCC_Z | PCC_N) , // outCond PCI_MAGIC }; @@ -924,7 +924,7 @@ pCodeInstruction pic16_pciCLRF = { 0, // second literal operand POC_NOP, PCC_REGISTER, // inCond - PCC_REGISTER , // outCond + (PCC_REGISTER | PCC_Z), // outCond PCI_MAGIC }; diff --git a/src/pic16/pcode.h b/src/pic16/pcode.h index 43657a5d..1787df9c 100644 --- a/src/pic16/pcode.h +++ b/src/pic16/pcode.h @@ -1010,6 +1010,7 @@ pCodeOp *pic16_newpCodeOpLit(int lit); pCodeOp *pic16_newpCodeOpLit2(int lit, pCodeOp *arg2); pCodeOp *pic16_newpCodeOpBit(char *name, int bit,int inBitSpace, PIC_OPTYPE subt); pCodeOp *pic16_newpCodeOpRegFromStr(char *name); +pCodeOp *pic16_newpCodeOpReg(int rIdx); pCodeOp *pic16_newpCodeOp(char *name, PIC_OPTYPE p); pCodeOp *pic16_pCodeOpCopy(pCodeOp *pcop); diff --git a/src/pic16/pcoderegs.c b/src/pic16/pcoderegs.c index 807d9c04..ffa28c93 100644 --- a/src/pic16/pcoderegs.c +++ b/src/pic16/pcoderegs.c @@ -168,6 +168,7 @@ static void pCodeRegMapLiveRangesInFlow(pCodeFlow *pcfl) reg = pic16_getRegFromInstruction(pc); if(reg && (reg->type != REG_TMP)) { + #if 0 fprintf(stderr, "reg= %p\n", reg); fprintf(stderr, "flow seq %d, inst seq %d %s ",PCODE(pcfl)->seq,pc->seq,reg->name); @@ -358,6 +359,9 @@ static void RemoveRegsFromSet(set *regset) fprintf(stderr,"reg %s, type =%d\n",r->name, r->type); } + + pc->print(stderr, pc); + fprintf(stderr,"%s:%d: removing reg %s because it is used only once\n",__FILE__, __LINE__, reg->name); @@ -470,6 +474,8 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re int t = total_registers_saved; + if(reg->type == REG_SFR)return 0; + if(pc2->seq < pc1->seq) { pct1 = pc2; pc2 = pc1; @@ -508,7 +514,27 @@ static int pCodeOptime2pCodes(pCode *pc1, pCode *pc2, pCode *pcfl_used, regs *re PCI(newpc)->pcflow = PCFL(pcfl_used); newpc->seq = pc2->seq; - Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free); + /* take care if register is used after pc2, if yes, then don't delete + * clrf reg, because, reg should be initialized with zero */ + { + pCode *spc; + int maxSeq=0; + + for(spc=setFirstItem(reg->reglives.usedpCodes);spc;spc=setNextItem(reg->reglives.usedpCodes)) { + if(maxSeq < spc->seq)maxSeq = spc->seq; + } + +// fprintf(stderr, "pc1->seq = %d\tpc2->seq = %d\tspc->seq = %d\n", pc1->seq, pc2->seq, maxSeq); + + if(maxSeq > pc2->seq) { + /* this means that a pCode uses register after pc2, then + * we can't delete pc1 pCode */ + Remove2pcodes(pcfl_used, NULL, pc2, reg, can_free); + } else { + /* we can remove both pCodes */ + Remove2pcodes(pcfl_used, pc1, pc2, reg, can_free); + } + } total_registers_saved++; // debugging stats. } else if((PCI(pc1)->op == POC_CLRF) && (PCI(pc2)->op == POC_IORFW) ){ @@ -827,6 +853,7 @@ void pic16_pCodeRegOptimizeRegUsage(int level) if(!register_optimization) return; + #define OPT_PASSES 4 passes = OPT_PASSES; diff --git a/src/pic16/peeph.def b/src/pic16/peeph.def index 9819a946..dffb192d 100644 --- a/src/pic16/peeph.def +++ b/src/pic16/peeph.def @@ -293,3 +293,16 @@ replace restart { movf %2,w } +replace restart { + movf %1,w + xorlw %2 + bz %3 + bra %4 +%3: %5 +} by { + ; peep 101 - test for equality + movlw %2 + cpfseq %1 + bra %4 +%3: %5 +} diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index 03202901..1ffe9863 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -737,7 +737,7 @@ pic16_allocDirReg (operand *op ) if(!SPEC_OCLS( OP_SYM_ETYPE(op))) { -#if 1 +#if 0 if(pic16_debug_verbose) { fprintf(stderr, "%s:%d symbol %s(r:%s) is not assigned to a memmap\n", __FILE__, __LINE__, @@ -2304,6 +2304,10 @@ serialRegAssign (eBBlock ** ebbs, int count) or this one is rematerializable then spill this one */ willCS = willCauseSpill (sym->nRegs, sym->regType); + + /* explicit turn off register spilling */ + willCS = 0; + spillable = computeSpillable (ic); if (sym->remat || (willCS && bitVectIsZero (spillable))) @@ -2319,12 +2323,13 @@ serialRegAssign (eBBlock ** ebbs, int count) have been allocated after sym->liveFrom but freed before ic->seq. This is complicated, so spill this symbol instead and let fillGaps handle the allocation. */ +#if 0 if (sym->liveFrom < ic->seq) { spillThis (sym); continue; } - +#endif /* if it has a spillocation & is used less than all other live ranges then spill this */ if (willCS) { @@ -3322,11 +3327,17 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) if (!IS_SYMOP (op)) return NULL; + if(OP_SYMBOL(op)->remat || OP_SYMBOL(op)->ruonly) + return NULL; + /* only upto 2 bytes since we cannot predict the usage of b, & acc */ - if (getSize (operandType (op)) > (pic16_fReturnSizePic - 3) && /* was 2, changed to 3 -- VR */ - ic->op != RETURN && - ic->op != SEND) + if (getSize (operandType (op)) > (pic16_fReturnSizePic - 1) + && ic->op != RETURN + && ic->op != SEND + && !POINTER_SET(ic) + && !POINTER_GET(ic) + ) return NULL; /* this routine will mark the a symbol as used in one @@ -3335,10 +3346,18 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) that definition is either a return value from a function or does not contain any variables in far space */ + +#if 0 uses = bitVectCopy (OP_USES (op)); bitVectUnSetBit (uses, ic->key); /* take away this iCode */ if (!bitVectIsZero (uses)) /* has other uses */ return NULL; +#endif + +#if 1 + if (bitVectnBitsOn (OP_USES (op)) > 1) + return NULL; +#endif /* if it has only one defintion */ if (bitVectnBitsOn (OP_DEFS (op)) > 1) @@ -3367,6 +3386,8 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) } dic = dic->next; } + else + { /* otherwise check that the definition does @@ -3388,6 +3409,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) if (POINTER_GET (dic) && !IS_DATA_PTR (aggrToPtr (operandType (IC_LEFT (dic)), FALSE))) return NULL; + } sic = dic; @@ -3418,7 +3440,7 @@ packRegsForOneuse (iCode * ic, operand * op, eBBlock * ebp) operation is a '*','/' or '%' then 'b' may cause a problem */ if ((dic->op == '%' || dic->op == '/' || dic->op == '*') && - getSize (operandType (op)) >= 3) + getSize (operandType (op)) >= 2) return NULL; /* if left or right or result is in far space */ @@ -3969,6 +3991,32 @@ pic16_packRegisters (eBBlock * ebp) debugLog (" marking as a pointer (get) =>"); debugAopGet (" left:", IC_LEFT (ic)); } + + if(getenv("OPTIMIZE_BITFIELD_POINTER_GET")) { + if(IS_ITEMP(IC_LEFT(ic)) && IS_BITFIELD(OP_SYM_ETYPE(IC_LEFT(ic)))) { + iCode *dic = ic->prev; + + fprintf(stderr, "%s:%d might give opt POINTER_GET && IS_BITFIELD(IC_LEFT)\n", __FILE__, __LINE__); + + if(dic && dic->op == '=' + && isOperandEqual(IC_RESULT(dic), IC_LEFT(ic))) { + + fprintf(stderr, "%s:%d && prev is '=' && prev->result == ic->left\n", __FILE__, __LINE__); + + + /* replace prev->left with ic->left */ + IC_LEFT(ic) = IC_RIGHT(dic); + IC_RIGHT(ic->prev) = NULL; + + /* remove ic->prev iCode (assignment) */ + remiCodeFromeBBlock (ebp, dic); + bitVectUnSetBit(OP_SYMBOL(IC_RESULT(dic))->defs,ic->key); + + + hTabDeleteItem (&iCodehTab, dic->key, dic, DELETE_ITEM, NULL); + } + } + } } //debugLog(" %d %s\n", __LINE__, __FUNCTION__);