From 2fd915c3bc6488cd960572406ba8580a90b28b78 Mon Sep 17 00:00:00 2001 From: vrokas Date: Mon, 6 Mar 2006 08:27:52 +0000 Subject: [PATCH] * src/pic16/device.h (struct pic16_options_t): added 'int CATregs' flag which dumps before the function entry point a data byte which represents the number of the local variables used by the specified function, added 'xinst' for initial support for Extended Instruction Support, * src/pic16/gen.c (aopForSym, pic16_aopGet): beautifications, (pic16_testStackOverflow): do not prefix GSTACK_TEST_NAME with port->fun_prefix anymore (may change later), (genFunction, genEndFunction): do not store/restore local registers for _main (this should take care the --main-return command line option in the future), (genOr): removed some legacy pic-port instructions, * src/pic16/genarith.c (genAddLit): re-enabled old code because performing operations with SFR's causes data to be written more than once to each SFR. Perhaps SFRs should be handled in special cases... * src/pic16/glue.c: macros BIG_ENDIAN and BYTE_IN_LONG are moved to pcode.h * src/pic16/main.c (_process_pragma): stack bound checking did not take into account for stack starting position, (struct OPTIONS pic16_optionsTable): added command line argument --extended or -y for Extended Instruction Support, * src/pic16/ralloc.c (pic16_decodeOp): added case for FUNCTION, (deassignLRs): *** perhaps the most important change, old 'for' code (comented out for reference), didn't account for some registers which were left marked 'not free' after a pointer operation. The change reduces register usage a lot in some cases git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@4051 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 28 +++ src/pic16/device.h | 3 + src/pic16/gen.c | 557 ++++++++++++++++++++----------------------- src/pic16/genarith.c | 302 ++++++++++++++++++++++- src/pic16/genutils.c | 19 ++ src/pic16/genutils.h | 1 + src/pic16/glue.c | 22 +- src/pic16/main.c | 21 +- src/pic16/pcode.h | 17 ++ src/pic16/ralloc.c | 102 ++++---- 10 files changed, 699 insertions(+), 373 deletions(-) diff --git a/ChangeLog b/ChangeLog index 53c0c85c..bef7add7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2006-03-06 Vangelis Rokas + + * src/pic16/device.h (struct pic16_options_t): added 'int CATregs' flag + which dumps before the function entry point a data byte which represents + the number of the local variables used by the specified function, added + 'xinst' for initial support for Extended Instruction Support, + * src/pic16/gen.c (aopForSym, pic16_aopGet): beautifications, + (pic16_testStackOverflow): do not prefix GSTACK_TEST_NAME with + port->fun_prefix anymore (may change later), + (genFunction, genEndFunction): do not store/restore local registers for + _main (this should take care the --main-return command line option in + the future), + (genOr): removed some legacy pic-port instructions, + * src/pic16/genarith.c (genAddLit): re-enabled old code because + performing operations with SFR's causes data to be written more than + once to each SFR. Perhaps SFRs should be handled in special cases... + * src/pic16/glue.c: macros BIG_ENDIAN and BYTE_IN_LONG are moved to + pcode.h + * src/pic16/main.c (_process_pragma): stack bound checking did not take + into account for stack starting position, + (struct OPTIONS pic16_optionsTable): added command line argument + --extended or -y for Extended Instruction Support, + * src/pic16/ralloc.c (pic16_decodeOp): added case for FUNCTION, + (deassignLRs): *** perhaps the most important change, old 'for' code + (comented out for reference), didn't account for some registers which + were left marked 'not free' after a pointer operation. The change + reduces register usage a lot in some cases + 2006-03-04 Borut Razem * support/regression/ports/hc08/spec.mk: remove *.asm in traget diff --git a/src/pic16/device.h b/src/pic16/device.h index e20b74c6..ada8cd6d 100644 --- a/src/pic16/device.h +++ b/src/pic16/device.h @@ -107,8 +107,11 @@ typedef struct { unsigned long opt_flags; int gstack; unsigned int debgen; + int CATregs; } pic16_options_t; +extern int xinst; + #define STACK_MODEL_SMALL (pic16_options.stack_model == 0) #define STACK_MODEL_LARGE (pic16_options.stack_model == 1) diff --git a/src/pic16/gen.c b/src/pic16/gen.c index d184da35..826a7195 100644 --- a/src/pic16/gen.c +++ b/src/pic16/gen.c @@ -729,7 +729,7 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) for(i=0;isize;i++) { /* initialise for stack access via frame pointer */ - // operands on stack are accessible via "FSR2 + index" with index + // operands on stack are accessible via "{FRAME POINTER} + index" with index // starting at 2 for arguments and growing from 0 downwards for // local variables (index == 0 is not assigned so we add one here) { @@ -854,8 +854,8 @@ static asmop *aopForSym (iCode *ic, operand *op, bool result) sym->aop = aop = newAsmop (AOP_DIR); aop->aopu.aop_dir = sym->rname ; aop->size = getSize(sym->type); - DEBUGpic16_emitcode(";","%d sym->rname = %s, size = %d",__LINE__,sym->rname,aop->size); - pic16_allocDirReg( IC_LEFT(ic) ); + DEBUGpic16_emitcode(";","%d sym->rname (AOP_DIR) = %s, size = %d",__LINE__,sym->rname,aop->size); + pic16_allocDirReg( IC_LEFT(ic) ); return aop; } @@ -1554,13 +1554,9 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) return rs; case AOP_REG: - //if (dname) - // return aop->aopu.aop_reg[offset]->dname; - //else - return aop->aopu.aop_reg[offset]->name; + return aop->aopu.aop_reg[offset]->name; case AOP_CRY: - //pic16_emitcode(";","%d",__LINE__); return aop->aopu.aop_dir; case AOP_ACC: @@ -1572,7 +1568,7 @@ char *pic16_aopGet (asmop *aop, int offset, bool bit16, bool dname) return (rs); case AOP_LIT: - sprintf(s,"0X%02x", pic16aopLiteral (aop->aopu.aop_lit,offset)); + sprintf(s,"0x%02x", pic16aopLiteral (aop->aopu.aop_lit,offset)); rs = Safe_calloc(1,strlen(s)+1); strcpy(rs,s); return rs; @@ -2446,7 +2442,7 @@ void pic16_testStackOverflow(void) symbol *sym; sym = newSymbol( GSTACK_TEST_NAME , 0 ); - sprintf(sym->rname, "%s%s", port->fun_prefix, GSTACK_TEST_NAME); + sprintf(sym->rname, "%s", /*port->fun_prefix,*/ GSTACK_TEST_NAME); // strcpy(sym->rname, GSTACK_TEST_NAME); checkAddSym(&externs, sym); } @@ -2457,7 +2453,7 @@ void pic16_testStackOverflow(void) void pic16_pushpCodeOp(pCodeOp *pcop) { // DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec ))); //&pic16_pc_postdec1))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg( pic16_stack_postdec ))); if(pic16_options.gstack) pic16_testStackOverflow(); @@ -3745,7 +3741,7 @@ static void genFunction (iCode *ic) /* if callee-save to be used for this function * then save the registers being used in this function */ // if (IFFUNC_CALLEESAVES(sym->type)) - { + if(strcmp(sym->name, "main")) { int i; /* if any registers used */ @@ -3811,7 +3807,7 @@ static void genEndFunction (iCode *ic) } } - if (sym->regsUsed) { + if (strcmp(sym->name, "main") && sym->regsUsed) { int i; pic16_emitpinfo(INF_LOCALREGS, pic16_newpCodeOpLocalRegs(LR_EXIT_BEGIN)); @@ -7822,13 +7818,13 @@ static void genOr (iCode *ic, iCode *ifx) } else { if (AOP_TYPE(left) == AOP_ACC) { pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(right),offset)); - pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); +// pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); } else { pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(left),offset)); - pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE)); +// pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); +// pic16_emitcode("iorwf","%s,f",pic16_aopGet(AOP(left),offset,FALSE,FALSE)); } } @@ -7869,21 +7865,21 @@ static void genOr (iCode *ic, iCode *ifx) pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(left),offset)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - pic16_emitcode("movf","%s,w", - pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s", - pic16_aopGet(AOP(result),offset,FALSE,FALSE)); +// pic16_emitcode("movf","%s,w", +// pic16_aopGet(AOP(left),offset,FALSE,FALSE)); +// pic16_emitcode("movwf","%s", +// pic16_aopGet(AOP(result),offset,FALSE,FALSE)); break; default: pic16_emitpcode(POC_MOVLW, pic16_popGetLit(t)); pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset)); pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - pic16_emitcode("movlw","0x%x",t); - pic16_emitcode("iorwf","%s,w", - pic16_aopGet(AOP(left),offset,FALSE,FALSE)); - pic16_emitcode("movwf","%s", - pic16_aopGet(AOP(result),offset,FALSE,FALSE)); +// pic16_emitcode("movlw","0x%x",t); +// pic16_emitcode("iorwf","%s,w", +// pic16_aopGet(AOP(left),offset,FALSE,FALSE)); +// pic16_emitcode("movwf","%s", +// pic16_aopGet(AOP(result),offset,FALSE,FALSE)); } continue; @@ -7893,17 +7889,17 @@ static void genOr (iCode *ic, iCode *ifx) // and better if result is SFR if (AOP_TYPE(left) == AOP_ACC) { pic16_emitpcode(POC_IORWF, pic16_popGet(AOP(right),offset)); - pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); +// pic16_emitcode("iorwf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); } else { pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); pic16_emitpcode(POC_IORFW, pic16_popGet(AOP(left),offset)); - pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); - pic16_emitcode("iorwf","%s,w", - pic16_aopGet(AOP(left),offset,FALSE,FALSE)); +// pic16_emitcode("movf","%s,w",pic16_aopGet(AOP(right),offset,FALSE,FALSE)); +// pic16_emitcode("iorwf","%s,w", +// pic16_aopGet(AOP(left),offset,FALSE,FALSE)); } pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE)); +// pic16_emitcode("movwf","%s",pic16_aopGet(AOP(result),offset,FALSE,FALSE)); } } @@ -10639,9 +10635,7 @@ static void genUnpackBits (operand *result, operand *left, char *rname, int ptyp } -static void genDataPointerGet(operand *left, - operand *result, - iCode *ic) +static void genDataPointerGet(operand *left, operand *result, iCode *ic) { int size, offset = 0, leoffset=0 ; @@ -10654,25 +10648,6 @@ static void genDataPointerGet(operand *left, // fprintf(stderr, "%s:%d size= %d\n", __FILE__, __LINE__, size); -#if 0 - /* The following tests may save a redudant movff instruction when - * accessing unions */ - - /* if they are the same */ - if (operandsEqu (left, result)) { - DEBUGpic16_emitcode("; ***", "left and result operands are equ/same"); - goto release; - } -#endif - -#if 0 - /* if they are the same registers */ - if (pic16_sameRegs(AOP(left),AOP(result))) { - DEBUGpic16_emitcode("; ***", "left and result registers are same"); - goto release; - } -#endif - #if 1 if(!strcmp(pic16_aopGet(AOP(result), 0, TRUE, FALSE), pic16_aopGet(AOP(left), 0, TRUE, FALSE))) { @@ -10681,17 +10656,6 @@ static void genDataPointerGet(operand *left, } #endif - -#if 0 - if ( AOP_TYPE(left) == AOP_PCODE) { - fprintf(stderr,"genDataPointerGet %s, %d\n", - AOP(left)->aopu.pcop->name, - (AOP(left)->aopu.pcop->type == PO_DIR)? - PCOR(AOP(left)->aopu.pcop)->instance: - PCOI(AOP(left)->aopu.pcop)->offset); - } -#endif - if(AOP(left)->aopu.pcop->type == PO_DIR) leoffset=PCOR(AOP(left)->aopu.pcop)->instance; @@ -11575,7 +11539,7 @@ static void genDataPointerSet(operand *right, operand *result, iCode *ic) { - int size, offset = 0, resoffset=0 ; + int size, offset = 0, resoffset=0 ; DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); pic16_aopOp(right,ic,FALSE); @@ -11594,26 +11558,25 @@ static void genDataPointerSet(operand *right, } #endif - if(AOP(result)->aopu.pcop->type == PO_DIR) - resoffset=PCOR(AOP(result)->aopu.pcop)->instance; + if(AOP(result)->aopu.pcop->type == PO_DIR) + resoffset=PCOR(AOP(result)->aopu.pcop)->instance; - while (size--) { - if (AOP_TYPE(right) == AOP_LIT) { - unsigned int lit; - - if(!IS_FLOAT(operandType( right ))) - lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); - else { - union { - unsigned long lit_int; - float lit_float; - } info; + while (size--) { + if (AOP_TYPE(right) == AOP_LIT) { + unsigned int lit; + + if(!IS_FLOAT(operandType( right ))) + lit = (unsigned long)floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + else { + union { + unsigned long lit_int; + float lit_float; + } info; - /* take care if literal is a float */ - info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); - lit = info.lit_int; - } - + /* take care if literal is a float */ + info.lit_float = floatFromVal(AOP(IC_RIGHT(ic))->aopu.aop_lit); + lit = info.lit_int; + } lit = lit >> (8*offset); pic16_movLit2f(pic16_popGet(AOP(result),offset), lit); } else { @@ -11641,89 +11604,90 @@ static void genNearPointerSet (operand *right, sym_link *ptype = operandType(result); sym_link *resetype; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - retype= getSpec(operandType(right)); - resetype = getSpec(operandType(result)); + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + retype= getSpec(operandType(right)); + resetype = getSpec(operandType(result)); - pic16_aopOp(result,ic,FALSE); + pic16_aopOp(result,ic,FALSE); - /* if the result is rematerializable & - * in data space & not a bit variable */ + /* if the result is rematerializable & + * in data space & not a bit variable */ - /* and result is not a bit variable */ - if (AOP_TYPE(result) == AOP_PCODE -// && AOP_TYPE(result) == AOP_IMMD - && DCL_TYPE(ptype) == POINTER - && !IS_BITFIELD(retype) - && !IS_BITFIELD(resetype)) { - - genDataPointerSet (right,result,ic); - pic16_freeAsmop(result,NULL,ic,TRUE); - return; - } + /* and result is not a bit variable */ + if (AOP_TYPE(result) == AOP_PCODE +// && AOP_TYPE(result) == AOP_IMMD + && DCL_TYPE(ptype) == POINTER + && !IS_BITFIELD(retype) + && !IS_BITFIELD(resetype)) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_aopOp(right,ic,FALSE); - DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); + genDataPointerSet (right,result,ic); + pic16_freeAsmop(result,NULL,ic,TRUE); + return; + } - /* if bitfield then unpack the bits */ - if (IS_BITFIELD(resetype)) { - genPackBits (resetype, result, right, NULL, POINTER); - } else { - /* we have can just get the values */ - int size = AOP_SIZE(right); - int offset = 0 ; + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_aopOp(right,ic,FALSE); + DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - pic16_loadFSR0(result, 0); - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - while (size--) { - if (AOP_TYPE(right) == AOP_LIT) { - pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); - if (size) { - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); - } else { - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); - } - } else { // no literal - if(size) { - pic16_emitpcode(POC_MOVFF, - pic16_popGet2p(pic16_popGet(AOP(right),offset), - pic16_popCopyReg(&pic16_pc_postinc0))); - } else { - pic16_emitpcode(POC_MOVFF, - pic16_popGet2p(pic16_popGet(AOP(right),offset), - pic16_popCopyReg(&pic16_pc_indf0))); - } - } - offset++; - } - } + /* if bitfield then unpack the bits */ + if (IS_BITFIELD(resetype)) { + genPackBits (resetype, result, right, NULL, POINTER); + } else { + /* we have can just get the values */ + int size = AOP_SIZE(right); + int offset = 0 ; - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* now some housekeeping stuff */ - if (aop) { - /* we had to allocate for this iCode */ - pic16_freeAsmop(NULL,aop,ic,TRUE); - } else { - /* we did not allocate which means left - * already in a pointer register, then - * if size > 0 && this could be used again - * we have to point it back to where it - * belongs */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (AOP_SIZE(right) > 1 - && !OP_SYMBOL(result)->remat - && ( OP_SYMBOL(result)->liveTo > ic->seq - || ic->depth )) { - - int size = AOP_SIZE(right) - 1; - - while (size--) - pic16_emitcode("decf","fsr0,f"); - //pic16_emitcode("dec","%s",rname); + pic16_loadFSR0(result, 0); + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + while (size--) { + if (AOP_TYPE(right) == AOP_LIT) { + pic16_emitpcode(POC_MOVLW, pic16_popGet(AOP(right),offset)); + if (size) { + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_postinc0)); + } else { + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_indf0)); + } + } else { // no literal + if(size) { + pic16_emitpcode(POC_MOVFF, + pic16_popGet2p(pic16_popGet(AOP(right),offset), + pic16_popCopyReg(&pic16_pc_postinc0))); + } else { + pic16_emitpcode(POC_MOVFF, + pic16_popGet2p(pic16_popGet(AOP(right),offset), + pic16_popCopyReg(&pic16_pc_indf0))); } + } + + offset++; } + } + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* now some housekeeping stuff */ + if (aop) { + /* we had to allocate for this iCode */ + pic16_freeAsmop(NULL,aop,ic,TRUE); + } else { + /* we did not allocate which means left + * already in a pointer register, then + * if size > 0 && this could be used again + * we have to point it back to where it + * belongs */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if (AOP_SIZE(right) > 1 + && !OP_SYMBOL(result)->remat + && ( OP_SYMBOL(result)->liveTo > ic->seq + || ic->depth )) { + + int size = AOP_SIZE(right) - 1; + + while (size--) + pic16_emitcode("decf","fsr0,f"); + //pic16_emitcode("dec","%s",rname); + } + } DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); /* done */ @@ -12025,7 +11989,7 @@ static void genGenPointerSet (operand *right, /* load value to write in TBLPTRH:TBLPTRL:PRODH:[stack] */ /* value of right+0 is placed on stack, which will be retrieved - * by the support function this restoring the stack. The important + * by the support function thus restoring the stack. The important * thing is that there is no need to manually restore stack pointer * here */ pushaop(AOP(right), 0); @@ -12187,18 +12151,20 @@ static void genAddrOf (iCode *ic) // starting at 2 for arguments and growing from 0 downwards for // local variables (index == 0 is not assigned so we add one here) { - int soffs = OP_SYMBOL( IC_LEFT(ic))->stack; - if (soffs <= 0) { - assert (soffs < 0); - soffs++; - } // if - DEBUGpic16_emitcode("*!*", "accessing stack symbol at offset=%d", soffs); - pic16_emitpcode(POC_MOVLW , pic16_popGetLit( soffs & 0x00FF )); - pic16_emitpcode(POC_ADDFW , pic16_popCopyReg(pic16_framepnt_lo)); - pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 0)); - pic16_emitpcode(POC_MOVLW , pic16_popGetLit( (soffs >> 8) & 0x00FF )); - pic16_emitpcode(POC_ADDFWC, pic16_popCopyReg(pic16_framepnt_hi)); - pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 1)); + int soffs = OP_SYMBOL( IC_LEFT(ic))->stack; + + if (soffs <= 0) { + assert (soffs < 0); + soffs++; + } // if + + DEBUGpic16_emitcode("*!*", "accessing stack symbol at offset=%d", soffs); + pic16_emitpcode(POC_MOVLW , pic16_popGetLit( soffs & 0x00FF )); + pic16_emitpcode(POC_ADDFW , pic16_popCopyReg(pic16_framepnt_lo)); + pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 0)); + pic16_emitpcode(POC_MOVLW , pic16_popGetLit( (soffs >> 8) & 0x00FF )); + pic16_emitpcode(POC_ADDFWC, pic16_popCopyReg(pic16_framepnt_hi)); + pic16_emitpcode(POC_MOVWF , pic16_popGet(AOP(result), 1)); } goto release; @@ -12279,73 +12245,70 @@ static void genAssign (iCode *ic) int size, offset,know_W; unsigned long lit = 0L; - result = IC_RESULT(ic); - right = IC_RIGHT(ic) ; + result = IC_RESULT(ic); + right = IC_RIGHT(ic) ; - FENTRY; + FENTRY; - /* if they are the same */ - if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic))) - return ; + /* if they are the same */ + if (operandsEqu (IC_RESULT(ic),IC_RIGHT(ic))) + return ; - /* reversed order operands are aopOp'ed so that result operand - * is effective in case right is a stack symbol. This maneauver - * allows to use the _G.resDirect flag later */ - pic16_aopOp(result,ic,TRUE); - pic16_aopOp(right,ic,FALSE); + /* reversed order operands are aopOp'ed so that result operand + * is effective in case right is a stack symbol. This maneauver + * allows to use the _G.resDirect flag later */ + pic16_aopOp(result,ic,TRUE); + pic16_aopOp(right,ic,FALSE); - DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); + DEBUGpic16_pic16_AopType(__LINE__,NULL,right,result); - /* if they are the same registers */ - if (pic16_sameRegs(AOP(right),AOP(result))) - goto release; + /* if they are the same registers */ + if (pic16_sameRegs(AOP(right),AOP(result))) + goto release; - /* if the result is a bit */ - if (AOP_TYPE(result) == AOP_CRY) { - /* if the right size is a literal then - we know what the value is */ - if (AOP_TYPE(right) == AOP_LIT) { + /* if the result is a bit */ + if (AOP_TYPE(result) == AOP_CRY) { + /* if the right size is a literal then + we know what the value is */ + if (AOP_TYPE(right) == AOP_LIT) { - pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF), - pic16_popGet(AOP(result),0)); + pic16_emitpcode( ( ((int) operandLitValue(right)) ? POC_BSF : POC_BCF), + pic16_popGet(AOP(result),0)); - if (((int) operandLitValue(right))) - pic16_emitcode("bsf","(%s >> 3),(%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - else - pic16_emitcode("bcf","(%s >> 3),(%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - goto release; - } + if (((int) operandLitValue(right))) + pic16_emitcode("bsf","(%s >> 3),(%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + else + pic16_emitcode("bcf","(%s >> 3),(%s & 7)", + AOP(result)->aopu.aop_dir, + AOP(result)->aopu.aop_dir); + + goto release; + } + + /* the right is also a bit variable */ + if (AOP_TYPE(right) == AOP_CRY) { + pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); + + goto release ; + } - /* the right is also a bit variable */ - if (AOP_TYPE(right) == AOP_CRY) { + /* we need to or */ pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); - pic16_emitpcode(POC_BTFSC, pic16_popGet(AOP(right),0)); + pic16_toBoolean(right); + emitSKPZ; pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); - - pic16_emitcode("bcf","(%s >> 3),(%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); - pic16_emitcode("btfsc","(%s >> 3),(%s & 7)", - AOP(right)->aopu.aop_dir, - AOP(right)->aopu.aop_dir); - pic16_emitcode("bsf","(%s >> 3),(%s & 7)", - AOP(result)->aopu.aop_dir, - AOP(result)->aopu.aop_dir); + //pic16_aopPut(AOP(result),"a",0); goto release ; } - /* we need to or */ - pic16_emitpcode(POC_BCF, pic16_popGet(AOP(result),0)); - pic16_toBoolean(right); - emitSKPZ; - pic16_emitpcode(POC_BSF, pic16_popGet(AOP(result),0)); - //pic16_aopPut(AOP(result),"a",0); - goto release ; - } + /* bit variables done */ + /* general case */ + size = AOP_SIZE(result); + offset = 0 ; /* bit variables done */ /* general case */ @@ -12401,84 +12364,84 @@ static void genAssign (iCode *ic) // sizeof(unsigned long int), sizeof(float)); - if (AOP_TYPE(right) == AOP_REG) { - DEBUGpic16_emitcode("; ", "%s:%d assign from register\n", __FUNCTION__, __LINE__); - while (size--) { - pic16_emitpcode (POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset++)); - } // while - goto release; - } + if (AOP_TYPE(right) == AOP_REG) { + DEBUGpic16_emitcode("; ", "%s:%d assign from register\n", __FUNCTION__, __LINE__); + while (size--) { + pic16_emitpcode (POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset++)); + } // while + goto release; + } - /* when do we have to read the program memory? - * - if right itself is a symbol in code space - * (we don't care what it points to if it's a pointer) - * - AND right is not a function (we would want its address) - */ - if(AOP_TYPE(right) != AOP_LIT - && IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(right))) - && !IS_FUNC(OP_SYM_TYPE(right)) - && !IS_ITEMP(right)) - { - DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__); - fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name); - - // set up table pointer - if(is_LitOp(right)) { -// fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__); - pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl)); - pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh)); - pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2)); - pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru)); - } else { -// fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0), - pic16_popCopyReg(&pic16_pc_tblptrl))); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1), - pic16_popCopyReg(&pic16_pc_tblptrh))); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2), - pic16_popCopyReg(&pic16_pc_tblptru))); - } + /* when do we have to read the program memory? + * - if right itself is a symbol in code space + * (we don't care what it points to if it's a pointer) + * - AND right is not a function (we would want its address) + */ + if(AOP_TYPE(right) != AOP_LIT + && IN_CODESPACE(SPEC_OCLS(OP_SYM_ETYPE(right))) + && !IS_FUNC(OP_SYM_TYPE(right)) + && !IS_ITEMP(right)) { - /* must fetch 3 bytes for pointers (was OP_SYM_ETYPE before) */ - size = min(getSize(OP_SYM_TYPE(right)), AOP_SIZE(result)); - while(size--) { - pic16_emitpcodeNULLop(POC_TBLRD_POSTINC); - pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), - pic16_popGet(AOP(result),offset))); - offset++; - } + DEBUGpic16_emitcode("; ", "%s:%d symbol in code space, take special care\n", __FUNCTION__, __LINE__); + fprintf(stderr, "%s:%d symbol %s = [ %s ] is in code space\n", __FILE__, __LINE__, OP_SYMBOL(result)->name, OP_SYMBOL(right)->name); + + // set up table pointer + if(is_LitOp(right)) { +// fprintf(stderr, "%s:%d inside block 1\n", __FILE__, __LINE__); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),0)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrl)); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),1)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptrh)); + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(right),2)); + pic16_emitpcode(POC_MOVWF,pic16_popCopyReg(&pic16_pc_tblptru)); + } else { +// fprintf(stderr, "%s:%d inside block 2\n", __FILE__, __LINE__); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),0), + pic16_popCopyReg(&pic16_pc_tblptrl))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),1), + pic16_popCopyReg(&pic16_pc_tblptrh))); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popGet(AOP(right),2), + pic16_popCopyReg(&pic16_pc_tblptru))); + } - /* FIXME: for pointers we need to extend differently (according - * to pointer type DATA/CODE/EEPROM/... :*/ - size = getSize(OP_SYM_TYPE(right)); - if(AOP_SIZE(result) > size) { - size = AOP_SIZE(result) - size; - while(size--) { - pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset)); - offset++; - } - } - goto release; - } + /* must fetch 3 bytes for pointers (was OP_SYM_ETYPE before) */ + size = min(getSize(OP_SYM_TYPE(right)), AOP_SIZE(result)); + while(size--) { + pic16_emitpcodeNULLop(POC_TBLRD_POSTINC); + pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_tablat), + pic16_popGet(AOP(result),offset))); + offset++; + } -#if 0 -/* VR - What is this?! */ - if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) { - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(aopIdx(AOP(result),0) == 4) { + /* FIXME: for pointers we need to extend differently (according + * to pointer type DATA/CODE/EEPROM/... :*/ + size = getSize(OP_SYM_TYPE(right)); + if(AOP_SIZE(result) > size) { + size = AOP_SIZE(result) - size; + while(size--) { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result), offset)); + offset++; + } + } + goto release; + } - /* this is a workaround to save value of right into wreg too, - * value of wreg is going to be used later */ +#if 0 + /* VR - What is this?! */ + if( AOP_TYPE(right) == AOP_DIR && (AOP_TYPE(result) == AOP_REG) && size==1) { DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); - goto release; - } else + + if(aopIdx(AOP(result),0) == 4) { + /* this is a workaround to save value of right into wreg too, + * value of wreg is going to be used later */ + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(right),offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); + goto release; + } else // assert(0); DEBUGpic16_emitcode ("; WARNING","%s %d ignoring register storage",__FUNCTION__,__LINE__); - } + } #endif know_W=-1; @@ -12511,11 +12474,11 @@ static void genAssign (iCode *ic) if(!_G.resDirect) /* use this aopForSym feature */ pic16_emitpcode(POC_MOVFF, pic16_popGet2(AOP(right), AOP(result), offset)); } - - offset++; - } + + offset++; + } - release: +release: pic16_freeAsmop (right,NULL,ic,FALSE); pic16_freeAsmop (result,NULL,ic,TRUE); } @@ -13332,7 +13295,7 @@ void genpic16Code (iCode *lic) l = Safe_strdup(printILine(ic)); pic16_emitpcomment("ic:%d: %s", ic->seq, l); } - + /* if the result is marked as * spilt and rematerializable or code for * this has already been generated then diff --git a/src/pic16/genarith.c b/src/pic16/genarith.c index fe778852..e8ada618 100644 --- a/src/pic16/genarith.c +++ b/src/pic16/genarith.c @@ -203,7 +203,7 @@ bool pic16_genPlusIncr (iCode *ic) return TRUE; } - DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__); +// DEBUGpic16_emitcode ("; ","%s %d",__FUNCTION__,__LINE__); /* if left is in accumulator - probably a bit operation*/ // VR - why this is a bit operation?! if( (AOP_TYPE(IC_LEFT(ic)) == AOP_ACC) && (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) ) { @@ -416,7 +416,7 @@ static void adjustArithmeticResult(iCode *ic) } #endif -#if 0 +#if 1 /*-----------------------------------------------------------------*/ /* genAddlit - generates code for addition */ /*-----------------------------------------------------------------*/ @@ -455,6 +455,301 @@ static void emitMOVWF(operand *reg, int offset) } + +#if 1 + +static void genAddLit (iCode *ic, int lit) +{ + + int size,same; + int lo; + + operand *result; + operand *left; + + FENTRY; + + + left = IC_LEFT(ic); + result = IC_RESULT(ic); + same = pic16_sameRegs(AOP(left), AOP(result)); + size = pic16_getDataSize(result); + + if(same) { + + /* Handle special cases first */ + if(size == 1) + genAddLit2byte (result, 0, lit); + + else if(size == 2) { + int hi = 0xff & (lit >> 8); + lo = lit & 0xff; + + switch(hi) { + case 0: + + /* lit = 0x00LL */ + DEBUGpic16_emitcode ("; hi = 0","%s %d",__FUNCTION__,__LINE__); + switch(lo) { + case 0: + break; + case 1: + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0)); + emitSKPNZ; + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16)); + break; + case 0xff: + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16)); + + break; + default: + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lit&0xff)); + pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0)); + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16)); + + + } + break; + + case 1: + /* lit = 0x01LL */ + DEBUGpic16_emitcode ("; hi = 1","%s %d",__FUNCTION__,__LINE__); + switch(lo) { + case 0: /* 0x0100 */ + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16)); + break; + case 1: /* 0x0101 */ + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16)); + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0)); + emitSKPNZ; + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16)); + break; + case 0xff: /* 0x01ff */ + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16)); + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16)); + break; + default: /* 0x01LL */ + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo)); + pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0)); + emitSKPNC; + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16)); + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16)); + } + break; + + case 0xff: + DEBUGpic16_emitcode ("; hi = ff","%s %d",__FUNCTION__,__LINE__); + /* lit = 0xffLL */ + switch(lo) { + case 0: /* 0xff00 */ + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16)); + break; + case 1: /*0xff01 */ + pic16_emitpcode(POC_INCFSZ, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16)); + break; +/* case 0xff: * 0xffff * + pic16_emitpcode(POC_INCFSZW, pic16_popGet(AOP(result),0,FALSE,FALSE)); + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE)); + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),0,FALSE,FALSE)); + break; +*/ + default: + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo)); + pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),0)); + emitSKPC; + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16)); + + } + + break; + + default: + DEBUGpic16_emitcode ("; hi is generic","%d %s %d",hi,__FUNCTION__,__LINE__); + + /* lit = 0xHHLL */ + switch(lo) { + case 0: /* 0xHH00 */ + genAddLit2byte (result, MSB16, hi); + break; + case 1: /* 0xHH01 */ + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi)); + pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16)); + break; +/* case 0xff: * 0xHHff * + pic16_emitpcode(POC_MOVFW, pic16_popGet(AOP(result),0,FALSE,FALSE)); + pic16_emitpcode(POC_DECF, pic16_popGet(AOP(result),MSB16,FALSE,FALSE)); + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi)); + pic16_emitpcode(POC_ADDWF,pic16_popGet(AOP(result),MSB16,FALSE,FALSE)); + break; +*/ default: /* 0xHHLL */ + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo)); + pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0)); + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(hi)); + pic16_emitpcode(POC_ADDWFC,pic16_popGet(AOP(result),MSB16)); + break; + } + + } + } else { + int carry_info = 0; + int offset = 0; + /* size > 2 */ + DEBUGpic16_emitcode ("; add lit to long","%s %d",__FUNCTION__,__LINE__); + + while(size--) { + lo = BYTEofLONG(lit,0); + + if(carry_info) { + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo)); + pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset)); + }else { + /* no carry info from previous step */ + /* this means this is the first time to add */ + switch(lo) { + case 0: + break; + case 1: + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),offset)); + carry_info=1; + break; + default: + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo)); + pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),offset)); + if(lit <0x100) + carry_info = 3; /* Were adding only one byte and propogating the carry */ + else + carry_info = 2; + break; + } + } + offset++; + lit >>= 8; + } + +/* + lo = BYTEofLONG(lit,0); + + if(lit < 0x100) { + if(lo) { + if(lo == 1) { + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),0,FALSE,FALSE)); + emitSKPNZ; + } else { + pic16_emitpcode(POC_MOVLW,pic16_popGetLit(lo)); + pic16_emitpcode(POC_ADDWF, pic16_popGet(AOP(result),0,FALSE,FALSE)); + emitSKPNC; + } + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),1,FALSE,FALSE)); + emitSKPNZ; + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),2,FALSE,FALSE)); + emitSKPNZ; + pic16_emitpcode(POC_INCF, pic16_popGet(AOP(result),3,FALSE,FALSE)); + + } + } + } + +*/ + } + } else { + int offset = 1; + DEBUGpic16_emitcode ("; left and result aren't same","%s %d",__FUNCTION__,__LINE__); + + if(size == 1) { + + if(AOP_TYPE(left) == AOP_ACC) { + /* left addend is already in accumulator */ + switch(lit & 0xff) { + case 0: + //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + break; + default: + pic16_emitpcode(POC_ADDLW, pic16_popGetLit(lit & 0xff)); + //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + } + } else { + /* left addend is in a register */ + switch(lit & 0xff) { + case 0: + pic16_mov2w(AOP(left),0); + emitMOVWF(result, 0); + break; + case 1: + pic16_emitpcode(POC_INCFW, pic16_popGet(AOP(left),0)); + //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + break; + case 0xff: + pic16_emitpcode(POC_DECFW, pic16_popGet(AOP(left),0)); + //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + break; + default: + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff)); + pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); + //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + } + } + + } else { + int clear_carry=0; + + /* left is not the accumulator */ + if(lit & 0xff) { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff)); + pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),0)); + } else { + pic16_mov2w(AOP(left),0); + /* We don't know the state of the carry bit at this point */ + clear_carry = 1; + } + //pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),0,FALSE,FALSE)); + emitMOVWF(result,0); + while(--size) { + + lit >>= 8; + if(lit & 0xff) { + if(clear_carry) { + /* The ls byte of the lit must've been zero - that + means we don't have to deal with carry */ + + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff)); + pic16_emitpcode(POC_ADDFW, pic16_popGet(AOP(left),offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); + + clear_carry = 0; + + } else { + pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit & 0xff)); + pic16_emitpcode(POC_ADDFWC, pic16_popGet(AOP(left),offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(result),offset)); + } + + } else { + pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(result),offset)); + pic16_mov2w(AOP(left),offset); + pic16_emitpcode(POC_ADDWFC, pic16_popGet(AOP(result),offset)); + } + offset++; + } + } + } +} + +#else + /* this fails when result is an SFR because value is written there + * during addition and not at the end */ + static void genAddLit (iCode *ic, int lit) { @@ -722,7 +1017,6 @@ static void genAddLit (iCode *ic, int lit) } } - } */ } @@ -815,6 +1109,8 @@ static void genAddLit (iCode *ic, int lit) #endif } +#endif + /*-----------------------------------------------------------------*/ /* pic16_genPlus - generates code for addition */ /*-----------------------------------------------------------------*/ diff --git a/src/pic16/genutils.c b/src/pic16/genutils.c index 4913f948..46ff7731 100644 --- a/src/pic16/genutils.c +++ b/src/pic16/genutils.c @@ -448,6 +448,25 @@ void pic16_DumpOp(char *prefix, operand *op) } +void pic16_DumpOpX(FILE *fp, char *prefix, operand *op) +{ + if(!op)return; + + fprintf(fp, "%s [", prefix); + fprintf(fp, "%s", IS_SYMOP(op)?"S":" "); + fprintf(fp, "%s", IS_VALOP(op)?"V":" "); + fprintf(fp, "%s", IS_TYPOP(op)?"T":" "); + fprintf(fp, "] "); + + fprintf(fp, "isaddr:%d,", op->isaddr); + fprintf(fp, "isvolatile:%d,", op->isvolatile); + fprintf(fp, "isGlobal:%d,", op->isGlobal); + fprintf(fp, "isPtr:%d,", op->isPtr); + fprintf(fp, "isParm:%d,", op->isParm); + fprintf(fp, "isLit:%d\n", op->isLiteral); +} + + void _debugf(char *f, int l, char *frm, ...) { va_list ap; diff --git a/src/pic16/genutils.h b/src/pic16/genutils.h index 0695c576..ea2ca70a 100644 --- a/src/pic16/genutils.h +++ b/src/pic16/genutils.h @@ -52,6 +52,7 @@ void pic16_DumpPcodeOp(char *prefix, pCodeOp *pcop); void pic16_DumpAop(char *prefix, asmop *aop); void pic16_DumpSymbol(char *prefix, symbol *sym); void pic16_DumpOp(char *prefix, operand *op); +void pic16_DumpOpX(FILE *fp, char *prefix, operand *op); pCodeOp *pic16_popGetWithString(char *str); void pic16_callGenericPointerRW(int rw, int size); diff --git a/src/pic16/glue.c b/src/pic16/glue.c index d148eb3e..3d26af46 100644 --- a/src/pic16/glue.c +++ b/src/pic16/glue.c @@ -35,13 +35,6 @@ #include -#ifdef WORDS_BIGENDIAN - #define _ENDIAN(x) (3-x) -#else - #define _ENDIAN(x) (x) -#endif - -#define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff) extern symbol *interrupts[256]; void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p); @@ -818,19 +811,19 @@ void pic16_printIvalBitFields(symbol **sym, initList **ilist, char ptype, void * switch (size) { case 1: pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p); - break; + break; case 2: pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p); pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p); - break; + break; case 4: /* EEP: why is this db and not dw? */ pic16_emitDB(BYTE_IN_LONG(ival, 0), ptype, p); pic16_emitDB(BYTE_IN_LONG(ival, 1), ptype, p); pic16_emitDB(BYTE_IN_LONG(ival, 2), ptype, p); pic16_emitDB(BYTE_IN_LONG(ival, 3), ptype, p); - break; + break; default: /* VR - only 1,2,4 size long can be handled???? Why? */ fprintf(stderr, "%s:%d: unhandled case. Contact author.\n", __FILE__, __LINE__); @@ -1516,13 +1509,16 @@ pic16initialComments (FILE * afile) { initialComments (afile); fprintf (afile, "; PIC16 port for the Microchip 16-bit core micros\n"); + if(xinst) + fprintf (afile, "; * Extended Instruction Set\n"); + if(pic16_mplab_comp) - fprintf(afile, "; MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n"); + fprintf(afile, "; * MPLAB/MPASM/MPASMWIN/MPLINK compatibility mode enabled\n"); fprintf (afile, iComments2); if(options.debug) { - fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]\"\n", - SDCC_VERSION_STR, getBuildNumber() ); + fprintf (afile, "\n\t.ident \"SDCC version %s #%s [pic16 port]%s\"\n", + SDCC_VERSION_STR, getBuildNumber(), (!xinst?"":" {extended}") ); } } diff --git a/src/pic16/main.c b/src/pic16/main.c index e630439c..7f799cfe 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -62,6 +62,9 @@ static char *_pic16_keywords[] = "_naked", "shadowregs", "wparam", + "prodlp", + "prodhp", + "fsr0lp", "fixed16x16", // "bit", @@ -76,6 +79,8 @@ static char *_pic16_keywords[] = pic16_sectioninfo_t pic16_sectioninfo; +int xinst=0; + extern char *pic16_processor_base_name(void); @@ -206,14 +211,10 @@ _process_pragma(const char *sz) 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, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen); - /* check sanity of stack */ - if ((stackPos >> 8) != ((stackPos+stackLen) >> 8)) { + if ((stackPos >> 8) != ((stackPos+stackLen-1) >> 8)) { fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] crosses memory bank boundaries (not fully tested)\n", filename,lineno-1, stackPos, stackPos+stackLen-1); } @@ -477,6 +478,10 @@ OPTION pic16_optionsTable[]= { { 0, OPTIMIZE_GOTO, NULL, "try to use (conditional) BRA instead of GOTO"}, { 0, OPTIMIZE_CMP, NULL, "try to optimize some compares"}, { 0, OPTIMIZE_DF, NULL, "thoroughly analyze data flow (memory and time intensive!)"}, + { 0, "--num-func-alloc-regs", &pic16_options.CATregs, "dump number of temporary registers allocated for each function"}, +#if XINST + { 'y', "--extended", &xinst, "enable Extended Instruction Set/Literal Offset Addressing mode"}, +#endif { 0, NULL, NULL, NULL} }; @@ -648,9 +653,9 @@ extern set *asmOptionsSet; static void _pic16_linkEdit(void) { hTab *linkValues=NULL; - char lfrm[256]; + char lfrm[1024]; char *lcmd; - char temp[128]; + char temp[1024]; set *tSet=NULL; int ret; @@ -659,7 +664,6 @@ static void _pic16_linkEdit(void) * {linker} {incdirs} {lflags} -o {outfile} {spec_ofiles} {ofiles} {libs} * */ - sprintf(lfrm, "{linker} {incdirs} {lflags} -o {outfile} {user_ofile} {ofiles} {spec_ofiles} {libs}"); shash_add(&linkValues, "linker", pic16_linkCmd[0]); @@ -826,6 +830,7 @@ _pic16_setDefaultOptions (void) pic16_options.ip_stack = 1; /* set to 1 to enable ipop/ipush for stack */ pic16_options.gstack = 0; pic16_options.debgen = 0; + pic16_options.CATregs = 0; } static const char * diff --git a/src/pic16/pcode.h b/src/pic16/pcode.h index 1b21fd76..c639122d 100644 --- a/src/pic16/pcode.h +++ b/src/pic16/pcode.h @@ -86,6 +86,23 @@ struct regs; #endif +#ifdef WORDS_BIGENDIAN + #define _ENDIAN(x) (3-x) +#else + #define _ENDIAN(x) (x) +#endif + + +#define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff) + + +/*********************************************************************** + * Extended Instruction Set/Indexed Literal Offset Mode * + * Set this macro to enable code generation with the extended * + * instruction set and the new Indexed Literal Offset Mode * + ***********************************************************************/ +#define XINST 1 + /*********************************************************************** * PIC status bits - this will move into device dependent headers ***********************************************************************/ diff --git a/src/pic16/ralloc.c b/src/pic16/ralloc.c index 197cf013..b3b3392c 100644 --- a/src/pic16/ralloc.c +++ b/src/pic16/ralloc.c @@ -170,10 +170,10 @@ debugLog (char *fmt,...) static void debugNewLine (void) { - if(!pic16_ralloc_debug)return; - - if (debugF) - fputc ('\n', debugF); + if(!pic16_ralloc_debug)return; + + if (debugF) + fputc ('\n', debugF); } /*-----------------------------------------------------------------*/ /* debugLogClose - closes the debug log file (if opened) */ @@ -181,10 +181,10 @@ debugNewLine (void) static void debugLogClose (void) { - if (debugF) { - fclose (debugF); - debugF = NULL; - } + if (debugF) { + fclose (debugF); + debugF = NULL; + } } #define AOP(op) op->aop @@ -302,6 +302,7 @@ pic16_decodeOp (unsigned int op) case IPUSH: return "IPUSH"; case IPOP: return "IPOP"; case PCALL: return "PCALL"; + case FUNCTION: return "FUNCTION"; case ENDFUNCTION: return "ENDFUNCTION"; case JUMPTABLE: return "JUMPTABLE"; case RRC: return "RRC"; @@ -371,10 +372,10 @@ regs* newReg(short type, short pc_type, int rIdx, char *name, int size, int alia dReg->name = Safe_strdup(name); else { sprintf(buffer,"r0x%02X", dReg->rIdx); - if(type == REG_STK) { - *buffer = 's'; - } - dReg->name = Safe_strdup(buffer); + if(type == REG_STK) { + *buffer = 's'; + } + dReg->name = Safe_strdup(buffer); } @@ -1287,52 +1288,40 @@ static void packBits(set *bregs) void pic16_writeUsedRegs(FILE *of) { - packBits(pic16_dynDirectBitRegs); - -// fprintf(stderr, "%s: pic16_dynAllocRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynAllocRegs); - -// fprintf(stderr, "%s: pic16_dynInternalRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynInternalRegs); - -// fprintf(stderr, "%s: pic16_dynStackRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynStackRegs); - -// fprintf(stderr, "%s: pic16_dynDirectRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynDirectRegs); - -// fprintf(stderr, "%s: pic16_dynDirectBitsRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynDirectBitRegs); - -// fprintf(stderr, "%s: pic16_dynProcessorRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynProcessorRegs); - -// fprintf(stderr, "%s: pic16_dynAccessRegs\n", __FUNCTION__); - pic16_groupRegistersInSection(pic16_dynAccessRegs); + packBits(pic16_dynDirectBitRegs); + + pic16_groupRegistersInSection(pic16_dynAllocRegs); + pic16_groupRegistersInSection(pic16_dynInternalRegs); + pic16_groupRegistersInSection(pic16_dynStackRegs); + pic16_groupRegistersInSection(pic16_dynDirectRegs); + pic16_groupRegistersInSection(pic16_dynDirectBitRegs); + pic16_groupRegistersInSection(pic16_dynProcessorRegs); + pic16_groupRegistersInSection(pic16_dynAccessRegs); - /* dump equates */ - pic16_dump_equates(of, pic16_equ_data); + /* dump equates */ + pic16_dump_equates(of, pic16_equ_data); // pic16_dump_esection(of, pic16_rel_eedata, 0); // pic16_dump_esection(of, pic16_fix_eedata, 0); - /* dump access bank symbols */ - pic16_dump_access(of, pic16_acs_udata); + /* dump access bank symbols */ + pic16_dump_access(of, pic16_acs_udata); - /* dump initialised data */ - pic16_dump_isection(of, rel_idataSymSet, 0); - pic16_dump_isection(of, fix_idataSymSet, 1); + /* dump initialised data */ + pic16_dump_isection(of, rel_idataSymSet, 0); + pic16_dump_isection(of, fix_idataSymSet, 1); - /* dump internal registers */ - pic16_dump_int_registers(of, pic16_int_regs); + if(!xinst) { + /* dump internal registers */ + pic16_dump_int_registers(of, pic16_int_regs); + } - /* dump generic section variables */ - pic16_dump_gsection(of, sectNames); + /* dump generic section variables */ + pic16_dump_gsection(of, sectNames); - /* dump other variables */ - pic16_dump_usection(of, pic16_rel_udata, 0); - pic16_dump_usection(of, pic16_fix_udata, 1); - + /* dump other variables */ + pic16_dump_usection(of, pic16_rel_udata, 0); + pic16_dump_usection(of, pic16_fix_udata, 1); } @@ -2106,15 +2095,20 @@ deassignLRs (iCode * ic, eBBlock * ebp) sym->nRegs) >= result->nRegs) ) { + + +// for (i = 0; i < max (sym->nRegs, result->nRegs); i++) + /* the above does not free the unsued registers in sym, + * leaving them marked as used, and increasing register usage + * until the end of the function - VR 23/11/05 */ - for (i = 0; i < max (sym->nRegs, result->nRegs); i++) + for (i = 0; i < result->nRegs; i++) if (i < sym->nRegs) result->regs[i] = sym->regs[i]; else result->regs[i] = getRegGpr (ic, ebp, result); _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key); - } /* free the remaining */ @@ -2796,6 +2790,7 @@ regTypeNum () !IS_BITVAR (sym->etype) && (aggrToPtrDclType (operandType (IC_LEFT (ic)), FALSE) == POINTER)) { +// continue; /* FIXME -- VR */ if (ptrPseudoSymSafe (sym, ic)) { symbol *psym; @@ -4399,19 +4394,21 @@ pic16_assignRegisters (ebbIndex * ebbi) for (i = 0; i < count; i++) pic16_packRegisters (ebbs[i]); + { regs *reg; int hkey; - int i=0; debugLog("dir registers allocated so far:\n"); reg = hTabFirstItem(dynDirectRegNames, &hkey); +#if 0 while(reg) { debugLog(" -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size); // fprintf(stderr, " -- #%d reg = %s key %d, rIdx = %d, size %d\n",i++,reg->name,hkey, reg->rIdx,reg->size); reg = hTabNextItem(dynDirectRegNames, &hkey); } +#endif } @@ -4470,6 +4467,7 @@ pic16_assignRegisters (ebbIndex * ebbi) debugLog ("ebbs after optimizing:\n"); dumpEbbsToDebug (ebbs, count); + _inRegAllocator = 0; genpic16Code (ic); -- 2.47.2