From 73dcfcdb63f80c8d624e320f41ffb74b2b77e252 Mon Sep 17 00:00:00 2001 From: tecodev Date: Mon, 4 Jul 2005 10:48:49 +0000 Subject: [PATCH] * src/pic/gen.c (popGet): changed assert to allow for bit operands * (popGetAddr): changed signature to provide an additional index, patched all call sites * (genCmpEq): handle literal-like operands correctly * (genAddrOf): added sanity checks on __code/__data pointers * (genAssign): added handling of symbols from __code section * (gencjne): do not generate code for comparisons whose result is neither stored nor used, fixes bug #1171114 * (AccLsh, AccRsh): operate on operand instead of WREG * (shift{Left,Right}_Left2ResultLit): NEW, size independant replacement for Shift{LR}{12}Left2Result; shift (byte/int/long) by known count * rewrote complete shift-by-literal logic, commented unused functions out * (genConstPointerGet): get multiple bytes (if result size > 1), fixed handling of non-immediate addresses * (genPointerGet): handle CODE pointers like CONST pointers * (genpic14Code): insert C-SRC lines as Cource-pCodes * ({aop,op}_isLitLike): NEW, single place to decide whether an operand is to be treated as a literal or not * (mov2w,genPcall,genCmpEq), src/pic/genarith.c: use aop_isLitLike() to decide between literal/register contents * (addSign): added missing offset * src/pic/gen.h: remove newline after FENTRY/FEXIT comments, only emit comment in debug-mode, use {aop,op}_isLitLike throughout the file * src/pic/glue.c: fix initializers for pointers (work in progress) * src/pic/pcode.c (get_op): honor index on _const symbols * ({reset,dump}pCodeStatistics): NEW, estimate code size * (dumppBlock): added pCode size estimation * src/pic/ralloc.c (deassignLRs,serialRegAssign,packRegisters): check for IS_SYMOP before OP_SYMBOL'ing * fixed indentation, compacted switch-statements * (allocReg): find free register and allocate it instead of allocating new registers all the time * (deassignLRs): prevent POINTER_GET's from being assigned the same registers as its operands (necessary only for multibyte GETs) git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3793 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- ChangeLog | 44 +++- src/pic/gen.c | 543 +++++++++++++++++++++++++++++++++++---------- src/pic/gen.h | 19 +- src/pic/genarith.c | 41 ++-- src/pic/glue.c | 113 +++++++++- src/pic/pcode.c | 50 ++++- src/pic/pcode.h | 4 +- src/pic/ralloc.c | 384 +++++++++++++------------------- 8 files changed, 793 insertions(+), 405 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3017b6da..5687854c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,49 @@ +2005-07-04 Raphael Neider + + * src/pic/gen.c (popGet): changed assert to allow for + bit operands + * (popGetAddr): changed signature to provide + an additional index, patched all call sites + * (genCmpEq): handle literal-like operands correctly + * (genAddrOf): added sanity checks on __code/__data pointers + * (genAssign): added handling of symbols from __code section + * (gencjne): do not generate code for comparisons whose result + is neither stored nor used, fixes bug #1171114 + * (AccLsh, AccRsh): operate on operand instead of WREG + * (shift{Left,Right}_Left2ResultLit): NEW, size independant + replacement for Shift{LR}{12}Left2Result; shift (byte/int/long) + by known count + * rewrote complete shift-by-literal logic, commented unused + functions out + * (genConstPointerGet): get multiple bytes (if result size > 1), + fixed handling of non-immediate addresses + * (genPointerGet): handle CODE pointers like CONST pointers + * (genpic14Code): insert C-SRC lines as Cource-pCodes + * ({aop,op}_isLitLike): NEW, single place to decide whether an + operand is to be treated as a literal or not + * (mov2w,genPcall,genCmpEq), + src/pic/genarith.c: use aop_isLitLike() to decide between + literal/register contents + * (addSign): added missing offset + * src/pic/gen.h: remove newline after FENTRY/FEXIT comments, + only emit comment in debug-mode, + use {aop,op}_isLitLike throughout the file + * src/pic/glue.c: fix initializers for pointers (work in progress) + * src/pic/pcode.c (get_op): honor index on _const symbols + * ({reset,dump}pCodeStatistics): NEW, estimate code size + * (dumppBlock): added pCode size estimation + * src/pic/ralloc.c (deassignLRs,serialRegAssign,packRegisters): + check for IS_SYMOP before OP_SYMBOL'ing + * fixed indentation, compacted switch-statements + * (allocReg): find free register and allocate it instead of + allocating new registers all the time + * (deassignLRs): prevent POINTER_GET's from being assigned the same + registers as its operands (necessary only for multibyte GETs) + 2005-07-01 Raphael Neider * src/pic/gen.h: added prototypes emitpComment, popGetAddr and - debugging .asm-output macros FENRY + FEXIT + debugging .asm-output macros FENTRY + FEXIT * src/pic/gen.c (Safe_vsnprintf): NEW, is there a more generic way... I wonder... * (emitpComment): NEW, printf to pCode diff --git a/src/pic/gen.c b/src/pic/gen.c index c85d097f..5d1e22ba 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -1352,8 +1352,13 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) /* offset is greater than size then zero */ - assert (offset >= 0 && offset < aop->size); + if (!(offset >= 0 && ((offset < aop->size) || (aop->size == 0)))) + { + fprintf (stderr, "%s:%u: offset=%d, aop-type:%s, size:%d\n", __FILE__, __LINE__, offset, AopType (aop->type), aop->size); + } + assert (offset >= 0 && ((offset < aop->size) || (aop->size == 0))); + /* XXX: still needed for BIT operands (AOP_CRY) */ if (offset > (aop->size - 1) && aop->type != AOP_LIT) return NULL; //zero; @@ -1439,7 +1444,7 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset, __LINE__, ((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name")); - emitpComment ("popGet; name %s, offset: %i\n", aop->aopu.pcop->name, offset); + //emitpComment ("popGet; name %s, offset: %i, pcop-type: %s\n", aop->aopu.pcop->name, offset, pCodeOpType (aop->aopu.pcop)); switch (aop->aopu.pcop->type) { case PO_IMMEDIATE: @@ -1469,19 +1474,19 @@ pCodeOp *popGet (asmop *aop, int offset) //, bool bit16, bool dname) /* popGetAddr - access the low/high word of a symbol (immediate) */ /* (for non-PO_IMMEDIATEs this is the same as poGet) */ /*-----------------------------------------------------------------*/ -pCodeOp *popGetAddr (asmop *aop, int offset) +pCodeOp *popGetAddr (asmop *aop, int offset, int index) { if (aop->type == AOP_PCODE && aop->aopu.pcop->type == PO_IMMEDIATE) { pCodeOp *pcop = aop->aopu.pcop; - emitpComment ("popGet; name %s, offset: %i\n", pcop->name, offset); pcop = pCodeOpCopy (pcop); /* usually we want to access the memory at " + offset" (using ->index), * but sometimes we want to access the high byte of the symbol's address (using ->offset) */ PCOI(pcop)->offset += offset; + PCOI(pcop)->index += index; return pcop; } else { - return popGet (aop, offset); + return popGet (aop, offset + index); } } @@ -1727,10 +1732,8 @@ void mov2w (asmop *aop, int offset) DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset); - if ( aop->type == AOP_PCODE || - aop->type == AOP_LIT || - aop->type == AOP_IMMD ) - emitpcode(POC_MOVLW,popGet(aop,offset)); + if ( aop_isLitLike (aop) ) + emitpcode(POC_MOVLW,popGetAddr(aop,offset,0)); else emitpcode(POC_MOVFW,popGet(aop,offset)); @@ -2598,11 +2601,11 @@ static void genPcall (iCode *ic) emitpcode(POC_GOTO,pcop); emitpLabel(albl->key); - poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW); + poc = ( aop_isLitLike (AOP(left)) ? POC_MOVLW : POC_MOVFW ); - emitpcode(poc,popGet(AOP(left),1)); + emitpcode(poc,popGetAddr(AOP(left),1,0)); emitpcode(POC_MOVWF,popCopyReg(&pc_pclath)); - emitpcode(poc,popGet(AOP(left),0)); + emitpcode(poc,popGetAddr(AOP(left),0,0)); emitpcode(POC_MOVWF,popCopyReg(&pc_pcl)); emitpLabel(blbl->key); @@ -3060,7 +3063,7 @@ static void genRet (iCode *ic) AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) || ( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) || ( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) { - emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset)); + emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); }else { emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset)); } @@ -4529,7 +4532,6 @@ static void genc16bit2lit(operand *op, int lit, int offset) else i=0; - emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i); switch( BYTEofLONG(lit,i)) { case 0: emitpcode(POC_MOVFW,popGet(AOP(op),offset+i)); @@ -4547,7 +4549,6 @@ static void genc16bit2lit(operand *op, int lit, int offset) i ^= 1; - emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i); switch( BYTEofLONG(lit,i)) { case 0: emitpcode(POC_IORFW,popGet(AOP(op),offset+i)); @@ -4583,6 +4584,10 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) unsigned long lit = 0L; FENTRY; + if (!ifx && (!result || AOP_TYPE(result) == AOP_CRY)) { + emitpComment ("gencjne: no ifx, no (real) result -- comparison ignored"); + return; + } DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); DEBUGpic14_AopType(__LINE__,left,right,result); if(result) @@ -4642,7 +4647,8 @@ static void gencjne(operand *left, operand *right, operand *result, iCode *ifx) int lbl_key = lbl->key; if(result) { - emitpcode(POC_CLRF,popGet(AOP(result),res_offset)); + if (AOP_TYPE(result) != AOP_CRY) + emitpcode(POC_CLRF,popGet(AOP(result),res_offset)); //emitpcode(POC_INCF,popGet(AOP(result),res_offset)); }else { DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__); @@ -4814,8 +4820,8 @@ static void genCmpEq (iCode *ic, iCode *ifx) /* if literal, literal on the right or if the right is in a pointer register and left is not */ - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) || - (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) { + if (aop_isLitLike (AOP(IC_LEFT(ic))) + || (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) { operand *tmp = right ; right = left; left = tmp; @@ -4980,8 +4986,8 @@ static void genCmpEq (iCode *ic, iCode *ifx) tlbl = newiTempLabel(NULL); while(size--) { - emitpcode(POC_MOVFW,popGet(AOP(left),offset)); - emitpcode(POC_XORFW,popGet(AOP(right),offset)); + mov2w (AOP(right),offset); /* right might be litLike() */ + emitpcode(POC_XORFW,popGet(AOP(left),offset)); if ( IC_TRUE(ifx) ) { if(size) { @@ -5928,6 +5934,7 @@ static void genXor (iCode *ic, iCode *ifx) pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir); goto release; } else { + assert ( !"incomplete genXor" ); pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir); pic14_emitcode("cpl","c"); } @@ -6318,30 +6325,17 @@ static void AccLsh (operand *op,int offset,int shCount) { FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(shCount != 0){ - /* - if(shCount == 1) { - pic14_emitcode("add","a,acc"); + if(shCount != 0) { + if (shCount == 1) + { emitCLRC; - emitpcode(POC_RLF,popGet(AOP(op),offset)); + emitpcode (POC_RLF, popGet (AOP(op), 0)); } else { - if(shCount == 2) { - pic14_emitcode("add","a,acc"); - emitCLRC; - emitpcode(POC_RLF,popGet(AOP(op),offset)); - pic14_emitcode("add","a,acc"); - emitCLRC; - emitpcode(POC_RLF,popGet(AOP(op),offset)); - } else { - */ - { - { - /* rotate left accumulator */ - AccRol(op,offset,shCount); - /* and kill the lower order bits */ - pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]); - emitpcode(POC_ANDLW,popGetLit(SLMask[shCount])); - } + /* rotate left accumulator */ + AccRol(op,offset,shCount); + /* and kill the lower order bits */ + emitpcode(POC_MOVLW,popGetLit(SLMask[shCount])); + emitpcode (POC_ANDWF, popGet (AOP(op),0)); } } } @@ -6355,13 +6349,14 @@ static void AccRsh (operand *op,int offset,int shCount) DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); if(shCount != 0){ if(shCount == 1){ - CLRC; - pic14_emitcode("rrc","a"); + emitCLRC; + emitpcode (POC_RRF, popGet (AOP(op), 0)); } else { /* rotate right accumulator */ AccRol(op,offset,8 - shCount); /* and kill the higher order bits */ - pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]); + emitpcode (POC_MOVLW, popGetLit (SRMask[shCount])); + emitpcode (POC_ANDWF, popGet (AOP(op),0)); } } } @@ -6396,7 +6391,7 @@ static void AccSRsh (int shCount) } } } -#endif + /*-----------------------------------------------------------------*/ /* shiftR1Left2Result - shift right one byte from left to result */ /*-----------------------------------------------------------------*/ @@ -6676,6 +6671,7 @@ static void shiftL1Left2Result (operand *left, int offl, } } +#endif /*-----------------------------------------------------------------*/ /* movLeft2Result - move byte from left to result */ @@ -6699,6 +6695,194 @@ static void movLeft2Result (operand *left, int offl, } } +/*-----------------------------------------------------------------*/ +/* shiftLeft_Left2ResultLit - shift left by known count */ +/*-----------------------------------------------------------------*/ + +static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount) +{ + int size, same, offr, i; + + size = AOP_SIZE(left); + if (AOP_SIZE(result) < size) size = AOP_SIZE(result); + + same = pic14_sameRegs (AOP(left), AOP(result)); + + offr = shCount / 8; + shCount = shCount & 0x07; + + size -= offr; + + switch (shCount) + { + case 0: /* takes 0 or 2N cycles (for offr==0) */ + if (!same || offr) { + for (i=size-1; i >= 0; i--) + movLeft2Result (left, i, result, offr + i); + } // if + break; + + case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */ + if (same && offr) { + shiftLeft_Left2ResultLit (left, result, 8 * offr); + shiftLeft_Left2ResultLit (result, result, shCount); + return; /* prevent clearing result again */ + } else { + emitCLRC; + for (i=0; i < size; i++) { + if (same && !offr) { + emitpcode (POC_RLF, popGet (AOP(left), i)); + } else { + emitpcode (POC_RLFW, popGet (AOP(left), i)); + emitpcode (POC_MOVWF, popGet (AOP(result), i + offr)); + } // if + } // for + } // if (offr) + break; + + case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */ + /* works in-place/with offr as well */ + emitpcode (POC_SWAPFW, popGet (AOP(left), size-1)); + emitpcode (POC_ANDLW, popGetLit (0xF0)); + emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr)); + + for (i = size - 2; i >= 0; i--) + { + emitpcode (POC_SWAPFW, popGet (AOP(left), i)); + emitpcode (POC_MOVWF, popGet (AOP(result), i + offr)); + emitpcode (POC_ANDLW, popGetLit (0x0F)); + emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1)); + emitpcode (POC_XORWF, popGet (AOP(result), i + offr)); + } // for i + break; + + case 7: /* takes 2(N-1)+3 = 2N+1 cycles */ + /* works in-place/with offr as well */ + emitpcode (POC_RRFW, popGet (AOP(left), size-1)); + for (i = size-2; i >= 0; i--) { + emitpcode (POC_RRFW, popGet (AOP(left), i)); + emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1)); + } // for i + emitpcode (POC_CLRF, popGet (AOP(result), offr)); + emitpcode (POC_RRF, popGet (AOP(result), offr)); + break; + + default: + shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1); + shiftLeft_Left2ResultLit (result, result, 1); + return; /* prevent clearing result again */ + break; + } // switch + + while (0 < offr--) + { + emitpcode (POC_CLRF, popGet (AOP(result), offr)); + } // while +} + +/*-----------------------------------------------------------------*/ +/* shiftRight_Left2ResultLit - shift right by known count */ +/*-----------------------------------------------------------------*/ + +static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign) +{ + int size, same, offr, i; + + size = AOP_SIZE(left); + if (AOP_SIZE(result) < size) size = AOP_SIZE(result); + + same = pic14_sameRegs (AOP(left), AOP(result)); + + offr = shCount / 8; + shCount = shCount & 0x07; + + size -= offr; + + if (size) + { + switch (shCount) + { + case 0: /* takes 0 or 2N cycles (for offr==0) */ + if (!same || offr) { + for (i=0; i < size; i++) + movLeft2Result (left, i + offr, result, i); + } // if + break; + + case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */ + emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr); + if (same && offr) { + shiftRight_Left2ResultLit (left, result, 8 * offr, sign); + shiftRight_Left2ResultLit (result, result, shCount, sign); + return; /* prevent sign-extending result again */ + } else { + emitCLRC; + if (sign) { + emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0)); + emitSETC; + } + for (i = size-1; i >= 0; i--) { + if (same && !offr) { + emitpcode (POC_RRF, popGet (AOP(left), i)); + } else { + emitpcode (POC_RRFW, popGet (AOP(left), i + offr)); + emitpcode (POC_MOVWF, popGet (AOP(result), i)); + } + } // for i + } // if (offr) + break; + + case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */ + /* works in-place/with offr as well */ + emitpcode (POC_SWAPFW, popGet (AOP(left), offr)); + emitpcode (POC_ANDLW, popGetLit (0x0F)); + emitpcode (POC_MOVWF, popGet(AOP(result), 0)); + + for (i = 1; i < size; i++) + { + emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr)); + emitpcode (POC_MOVWF, popGet (AOP(result), i)); + emitpcode (POC_ANDLW, popGetLit (0xF0)); + emitpcode (POC_IORWF, popGet (AOP(result), i - 1)); + emitpcode (POC_XORWF, popGet (AOP(result), i)); + } // for i + + if (sign) + { + emitpcode (POC_MOVLW, popGetLit (0xF0)); + emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0)); + emitpcode (POC_IORWF, popGet (AOP(result), size-1)); + } // if + break; + + case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */ + /* works in-place/with offr as well */ + emitpcode (POC_RLFW, popGet (AOP(left), offr)); + for (i = 0; i < size-1; i++) { + emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1)); + emitpcode (POC_MOVWF, popGet (AOP(result), i)); + } // for i + emitpcode (POC_CLRF, popGet (AOP(result), size-1)); + if (!sign) { + emitpcode (POC_RLF, popGet (AOP(result), size-1)); + } else { + emitSKPNC; + emitpcode (POC_DECF, popGet (AOP(result), size-1)); + } + break; + + default: + shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign); + shiftRight_Left2ResultLit (result, result, 1, sign); + return; /* prevent sign extending result again */ + break; + } // switch + } // if + + addSign (result, size, sign); +} + +#if 0 /*-----------------------------------------------------------------*/ /* shiftL2Left2Result - shift left two bytes from left to result */ /*-----------------------------------------------------------------*/ @@ -6826,6 +7010,7 @@ static void shiftL2Left2Result (operand *left, int offl, } } + /*-----------------------------------------------------------------*/ /* shiftR2Left2Result - shift right two bytes from left to result */ /*-----------------------------------------------------------------*/ @@ -6978,7 +7163,6 @@ static void shiftR2Left2Result (operand *left, int offl, } } - /*-----------------------------------------------------------------*/ /* shiftLLeftOrResult - shift left one byte from left, or to result*/ /*-----------------------------------------------------------------*/ @@ -6987,13 +7171,12 @@ static void shiftLLeftOrResult (operand *left, int offl, { FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); + /* shift left accumulator */ AccLsh(left,offl,shCount); /* or with result */ - pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE)); - /* back to result */ - aopPut(AOP(result),"a",offr); + emitpcode (POC_IORWF, popGet (AOP(result), offr)); + assert ( !"broken (modifies left, fails for left==result))" ); } /*-----------------------------------------------------------------*/ @@ -7004,13 +7187,12 @@ static void shiftRLeftOrResult (operand *left, int offl, { FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); + /* shift right accumulator */ AccRsh(left,offl,shCount); /* or with result */ - pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE)); - /* back to result */ - aopPut(AOP(result),"a",offr); + emitpcode (POC_IORWF, popGet (AOP(result), offr)); + assert ( !"broken (modifies left, fails for left==result))" ); } /*-----------------------------------------------------------------*/ @@ -7202,7 +7384,9 @@ static void genlshFour (operand *result, operand *left, int shCount) shiftL2Left2Result(left, LSB, result, LSB, shCount); } } +#endif +#if 0 /*-----------------------------------------------------------------*/ /* genLeftShiftLiteral - left shifting by known count */ /*-----------------------------------------------------------------*/ @@ -7212,7 +7396,7 @@ static void genLeftShiftLiteral (operand *left, iCode *ic) { int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit); - int size; + //int size; FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -7220,7 +7404,7 @@ static void genLeftShiftLiteral (operand *left, aopOp(left,ic,FALSE); aopOp(result,ic,FALSE); - + size = getSize(operandType(result)); #if VIEW_SIZE @@ -7257,6 +7441,7 @@ static void genLeftShiftLiteral (operand *left, freeAsmop(left,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); } +#endif /*-----------------------------------------------------------------* * genMultiAsm - repeat assembly instruction for size of register. @@ -7307,11 +7492,14 @@ static void genLeftShift (iCode *ic) result = IC_RESULT(ic); aopOp(right,ic,FALSE); + aopOp(left,ic,FALSE); + aopOp(result,ic,FALSE); + /* if the shift count is known then do it as efficiently as possible */ if (AOP_TYPE(right) == AOP_LIT) { - genLeftShiftLiteral (left,right,result,ic); + shiftLeft_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit)); return ; } @@ -7322,9 +7510,6 @@ static void genLeftShift (iCode *ic) largest size of an object can be only 32 bits ) */ - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); - /* now move the left to the result if they are not the same */ if (!pic14_sameRegs(AOP(left),AOP(result)) && @@ -7464,6 +7649,7 @@ release: freeAsmop(result,NULL,ic,TRUE); } +#if 0 /*-----------------------------------------------------------------*/ /* genrshOne - right shift a one byte quantity by known count */ /*-----------------------------------------------------------------*/ @@ -7512,32 +7698,35 @@ static void genrshTwo (operand *result,operand *left, static void shiftRLong (operand *left, int offl, operand *result, int sign) { + int size, same; + FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(!sign) - pic14_emitcode("clr","c"); - MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE)); - if(sign) - pic14_emitcode("mov","c,acc.7"); - pic14_emitcode("rrc","a"); - aopPut(AOP(result),"a",MSB32-offl); - if(offl == MSB16) - /* add sign of "a" */ - addSign(result, MSB32, sign); - MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE)); - pic14_emitcode("rrc","a"); - aopPut(AOP(result),"a",MSB24-offl); + size = AOP_SIZE(left); + if (AOP_SIZE(result) < size) size = AOP_SIZE(result); - MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE)); - pic14_emitcode("rrc","a"); - aopPut(AOP(result),"a",MSB16-offl); - - if(offl == LSB){ - MOVA(aopGet(AOP(left),LSB,FALSE,FALSE)); - pic14_emitcode("rrc","a"); - aopPut(AOP(result),"a",LSB); - } + if (sign) + emitpcode (POC_RLFW, popGet (AOP(left), AOP_SIZE(left)-1)); + else + emitCLRC; + + assert (offl >= 0 && offl < size); + + same = pic14_sameRegs (AOP(left), AOP(result)); + + /* perform the shift */ + while (size--) + { + if (same && !offl) { + emitpcode (POC_RRF, popGet (AOP(result), size)); + } else { + emitpcode (POC_RRFW, popGet (AOP(left), size)); + emitpcode (POC_MOVWF, popGet (AOP(result), size-offl)); + } + } // while + + addSign (result, AOP_SIZE(left) - offl, sign); } /*-----------------------------------------------------------------*/ @@ -7631,7 +7820,7 @@ static void genRightShiftLiteral (operand *left, /* I suppose that the left size >= result size */ if(shCount == 0){ while(res_size--) - movLeft2Result(left, lsize, result, res_size); + movLeft2Result(left, res_size, result, res_size); } else if(shCount >= (lsize * 8)){ @@ -7676,10 +7865,11 @@ static void genRightShiftLiteral (operand *left, } } - + freeAsmop(left,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); } +#endif /*-----------------------------------------------------------------*/ /* genSignedRightShift - right shift of signed number */ @@ -7709,7 +7899,8 @@ static void genSignedRightShift (iCode *ic) if ( AOP_TYPE(right) == AOP_LIT) { - genRightShiftLiteral (left,right,result,ic,1); + shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 1); + //genRightShiftLiteral (left,right,result,ic,1); return ; } /* shift count is unknown then we have to form @@ -7856,11 +8047,14 @@ static void genRightShift (iCode *ic) result = IC_RESULT(ic); aopOp(right,ic,FALSE); + aopOp(left,ic,FALSE); + aopOp(result,ic,FALSE); /* if the shift count is known then do it as efficiently as possible */ if (AOP_TYPE(right) == AOP_LIT) { - genRightShiftLiteral (left,right,result,ic, 0); + shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 0); + //genRightShiftLiteral (left,right,result,ic, 0); return ; } @@ -7872,8 +8066,6 @@ static void genRightShift (iCode *ic) pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); pic14_emitcode("inc","b"); - aopOp(left,ic,FALSE); - aopOp(result,ic,FALSE); /* now move the left to the result if they are not the same */ @@ -8167,7 +8359,7 @@ static void genNearPointerGet (operand *left, if (!AOP_INPREG(AOP(left)) && !direct) { /* otherwise get a free pointer register */ DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if (PCOP(AOP(result))->type == PO_LITERAL) + if (PCOP(AOP(result))->type == PO_LITERAL) /* XXX: check me */ emitpcode(POC_MOVLW, popGet(AOP(left),0)); else emitpcode(POC_MOVFW, popGet(AOP(left),0)); @@ -8475,9 +8667,9 @@ static void genConstPointerGet (operand *left, operand *result, iCode *ic) { //sym_link *retype = getSpec(operandType(result)); - symbol *albl = newiTempLabel(NULL); - symbol *blbl = newiTempLabel(NULL); + symbol *albl, *blbl;//, *clbl; PIC_OPCODE poc; + int i, size, lit; pCodeOp *pcop; FENTRY; @@ -8485,28 +8677,75 @@ static void genConstPointerGet (operand *left, aopOp(left,ic,FALSE); aopOp(result,ic,FALSE); + size = AOP_SIZE(result); DEBUGpic14_AopType(__LINE__,left,NULL,result); DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__); - - emitpcode(POC_CALL,popGetLabel(albl->key)); - pcop = popGetLabel(blbl->key); - emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */ - emitpcode(POC_GOTO,pcop); - emitpLabel(albl->key); - - poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW); - - emitpcode(poc,popGet(AOP(left),1)); - emitpcode(POC_MOVWF,popCopyReg(&pc_pclath)); - emitpcode(poc,popGet(AOP(left),0)); - emitpcode(POC_MOVWF,popCopyReg(&pc_pcl)); - - emitpLabel(blbl->key); - - emitpcode(POC_MOVWF,popGet(AOP(result),0)); - + + lit = aop_isLitLike (AOP(left)); + poc = lit ? POC_MOVLW : POC_MOVFW; + + if (lit) + { + for (i = 0; i < size; i++) + { + albl = newiTempLabel(NULL); + blbl = newiTempLabel(NULL); + + emitpcode(POC_CALL,popGetLabel(albl->key)); + pcop = popGetLabel(blbl->key); + emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */ + emitpcode(POC_GOTO,pcop); + + emitpLabel(albl->key); + emitpcode(poc,popGetAddr(AOP(left),1,i)); + emitpcode(POC_MOVWF,popCopyReg(&pc_pclath)); + emitpcode(poc,popGetAddr(AOP(left),0,i)); + emitpcode(POC_MOVWF,popCopyReg(&pc_pcl)); + + emitpLabel(blbl->key); + emitpcode(POC_MOVWF,popGet(AOP(result),i)); + } // for + } else { + albl = newiTempLabel(NULL); + blbl = newiTempLabel(NULL); + //clbl = newiTempLabel(NULL); + + emitpcode (POC_GOTO, popGetLabel (blbl->key)); + + emitpLabel(albl->key); + emitpcode(poc,popGet(AOP(left),1)); + emitpcode(POC_MOVWF,popCopyReg(&pc_pclath)); + emitpcode(poc,popGet(AOP(left),0)); + emitpcode(POC_MOVWF,popCopyReg(&pc_pcl)); + + emitpLabel(blbl->key); + + for (i = 0; i < size; i++) + { + emitpcode(POC_CALL,popGetLabel(albl->key)); + /* the next two instructions (plus clbl) might be useless... */ + //pcop = popGetLabel(clbl->key); + //emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */ + //emitpcode(POC_GOTO,pcop); + //emitpLabel(clbl->key); + + if (i+1 < size) { + emitpcode (POC_INCF, popGet (AOP(left), 0)); + emitSKPNZ; + emitpcode (POC_INCF, popGet (AOP(left), 1)); + } + emitpcode(POC_MOVWF,popGet(AOP(result),i)); + } // for + if (size > 1) { + /* restore left's value */ + emitpcode (POC_MOVLW, popGetLit (size-1)); + emitpcode (POC_SUBWF, popGet (AOP(left), 0)); + emitSKPC; + emitpcode (POC_DECF, popGet (AOP(left), 1)); + } // if + } // if (lit) freeAsmop(left,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); @@ -8519,7 +8758,7 @@ static void genPointerGet (iCode *ic) { operand *left, *result ; sym_link *type, *etype; - int p_type; + int p_type = -1; FENTRY; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); @@ -8588,11 +8827,14 @@ static void genPointerGet (iCode *ic) break; case GPOINTER: - if (IS_PTR_CONST(type)) + if (IS_CODEPTR(type) || IS_PTR_CONST(type)) genConstPointerGet (left,result,ic); else genGenPointerGet (left,result,ic); break; + default: + assert ( !"unhandled pointer type" ); + break; } } @@ -9373,6 +9615,27 @@ static void genAddrOf (iCode *ic) aopOp((result=IC_RESULT(ic)),ic,TRUE); DEBUGpic14_AopType(__LINE__,left,right,result); + assert (IS_SYMOP (left)); + + /* sanity check: generic pointers to code space are not yet supported, + * pionters to codespace must not be assigned addresses of __data values. */ + #if 0 + fprintf (stderr, "result: %s, left: %s\n", OP_SYMBOL(result)->name, OP_SYMBOL(left)->name); + fprintf (stderr, "result->type : "); printTypeChain (OP_SYM_TYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(result)))), IS_CODEPTR(OP_SYM_TYPE(result)), IS_PTR_CONST(OP_SYM_TYPE(result))); + fprintf (stderr, "result->etype: "); printTypeChain (OP_SYM_ETYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(result)))), IS_CODEPTR(OP_SYM_ETYPE(result)), IS_PTR_CONST(OP_SYM_ETYPE(result))); + fprintf (stderr, "left->type : "); printTypeChain (OP_SYM_TYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left)))), IS_CODEPTR(OP_SYM_TYPE(left)), IS_PTR_CONST(OP_SYM_TYPE(left))); + fprintf (stderr, "left->etype : "); printTypeChain (OP_SYM_ETYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n",IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(left)))), IS_CODEPTR(OP_SYM_ETYPE(left)), IS_PTR_CONST(OP_SYM_ETYPE(left))); +#endif + + if (IS_CODEPTR(OP_SYM_TYPE(result)) && !IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left))))) { + fprintf (stderr, "trying to assign __code pointer (%s) an address in __data space (&%s) -- expect trouble\n", + IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown", + OP_SYMBOL(left)->name); + } else if (!IS_CODEPTR (OP_SYM_TYPE(result)) && IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))))) { + fprintf (stderr, "trying to assign __data pointer (%s) an address in __code space (&%s) -- expect trouble\n", + IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown", + OP_SYMBOL(left)->name); + } size = AOP_SIZE(IC_RESULT(ic)); offset = 0; @@ -9450,7 +9713,27 @@ static void genAssign (iCode *ic) /* if they are the same registers */ if (pic14_sameRegs(AOP(right),AOP(result))) goto release; + + /* special case: assign from __code */ + if (!IS_ITEMP(right) /* --> iTemps never reside in __code */ + && IS_SYMOP (right) /* --> must be an immediate (otherwise we would be in genConstPointerGet) */ + && !IS_FUNC(OP_SYM_TYPE(right)) /* --> we would want its address instead of the first instruction */ + && !IS_CODEPTR(OP_SYM_TYPE(right)) /* --> get symbols address instread */ + && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(right))))) + { + emitpComment ("genAssign from CODESPACE"); + genConstPointerGet (right, result, ic); + goto release; + } + /* just for symmetry reasons... */ + if (!IS_ITEMP(result) + && IS_SYMOP (result) + && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(result))))) + { + assert ( !"cannot write to CODESPACE" ); + } + /* if the result is a bit */ if (AOP_TYPE(result) == AOP_CRY) { @@ -9827,9 +10110,9 @@ static void genCast (iCode *ic) DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__); if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) { - emitpcode(POC_MOVLW, popGetAddr(AOP(right),0)); + emitpcode(POC_MOVLW, popGetAddr(AOP(right),0,0)); emitpcode(POC_MOVWF, popGet(AOP(result),0)); - emitpcode(POC_MOVLW, popGetAddr(AOP(right),1)); + emitpcode(POC_MOVLW, popGetAddr(AOP(right),1,0)); emitpcode(POC_MOVWF, popGet(AOP(result),1)); if(AOP_SIZE(result) <2) fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__); @@ -9896,7 +10179,7 @@ static void genCast (iCode *ic) DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__); if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) { - emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset)); + emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset,0)); emitpcode(POC_MOVWF, popGet(AOP(result),offset)); } else { aopPut(AOP(result), @@ -10133,6 +10416,7 @@ void genpic14Code (iCode *lic) { iCode *ic; int cln = 0; + const char *cline; FENTRY; lineHead = lineCurr = NULL; @@ -10158,7 +10442,10 @@ void genpic14Code (iCode *lic) if (!options.noCcodeInAsm && (cln != ic->lineno)) { cln = ic->lineno; //fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno)); - emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, printCLine (ic->filename, cln)); + cline = printCLine (ic->filename, ic->lineno); + if (!cline || strlen (cline) == 0) cline = printCLine (ic->filename, ic->lineno); + addpCode2pBlock (pb, newpCodeCSource (ic->lineno, ic->filename, cline)); + //emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, cline); } if (options.iCodeInAsm) { @@ -10379,3 +10666,27 @@ void genpic14Code (iCode *lic) return; } + +int +aop_isLitLike (asmop *aop) +{ + assert (aop); + if (aop->type == AOP_LIT) return 1; + if (aop->type == AOP_IMMD) return 1; + if ((aop->type == AOP_PCODE) && + ((aop->aopu.pcop->type == PO_LITERAL) || (aop->aopu.pcop->type == PO_IMMEDIATE))) + { + /* this should be treated like a literal/immediate (use MOVLW/ADDLW/SUBLW + * instead of MOVFW/ADDFW/SUBFW, use popGetAddr instead of popGet) */ + return 1; + } + return 0; +} + +int +op_isLitLike (operand *op) +{ + assert (op); + if (aop_isLitLike (AOP(op))) return 1; + return 0; +} diff --git a/src/pic/gen.h b/src/pic/gen.h index 94603bda..cd40bfe0 100644 --- a/src/pic/gen.h +++ b/src/pic/gen.h @@ -26,13 +26,19 @@ #ifndef SDCCGENPIC14_H #define SDCCGENPIC14_H -#define FENTRY do { \ +extern int debug_verbose; + +#define FENTRY do { \ /*fprintf (stderr, "%s:%u:%s: *{*\n", __FILE__, __LINE__, __FUNCTION__);*/ \ - emitpComment ("; %s:%u:%s *{*\n", __FILE__, __LINE__, __FUNCTION__); \ + if (options.debug || debug_verbose) { \ + emitpComment ("; %s:%u:%s *{*", __FILE__, __LINE__, __FUNCTION__); \ + } \ } while (0) -#define FEXIT do { \ +#define FEXIT do { \ /*fprintf (stderr, "%s:%u:%s: *}*\n", __FILE__, __LINE__, __FUNCTION__);*/ \ - emitpComment ("; %s:%u:%s *}*\n", __FILE__, __LINE__, __FUNCTION__); \ + if (options.debug || debug.verbose) { \ + emitpComment ("; %s:%u:%s *}*", __FILE__, __LINE__, __FUNCTION__); \ + } \ } while (0) struct pCodeOp; @@ -172,7 +178,7 @@ pCodeOp *popGetLit(unsigned int lit); pCodeOp *popGetWithString(char *str, int isExtern); pCodeOp *popRegFromString(char *str, int size, int offset); pCodeOp *popGet (asmop *aop, int offset);//, bool bit16, bool dname); -pCodeOp *popGetAddr (asmop *aop, int offset); +pCodeOp *popGetAddr (asmop *aop, int offset, int index); pCodeOp *popGetTempReg(void); void popReleaseTempReg(pCodeOp *pcop); @@ -186,6 +192,7 @@ void freeAsmop (operand *op, asmop *aaop, iCode *ic, bool pop); void mov2w (asmop *aop, int offset); const char *pCodeOpType( pCodeOp *pcop); - +int aop_isLitLike (asmop *aop); +int op_isLitLike (operand *op); #endif diff --git a/src/pic/genarith.c b/src/pic/genarith.c index bdb8f8d4..66bb1e24 100644 --- a/src/pic/genarith.c +++ b/src/pic/genarith.c @@ -1024,11 +1024,9 @@ void genPlus (iCode *ic) else { PIC_OPCODE poc = POC_ADDFW; - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) + if (op_isLitLike (IC_LEFT (ic))) poc = POC_ADDLW; - emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0)); + emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),0,0)); if ( AOP_TYPE(IC_RESULT(ic)) != AOP_ACC) emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0)); } @@ -1041,14 +1039,13 @@ void genPlus (iCode *ic) if(size){ if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) { - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) { + if (op_isLitLike (IC_LEFT(ic))) + { while(size--){ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); emitSKPNC; emitpcode(POC_INCFSZW, popGet(AOP(IC_RIGHT(ic)),offset)); - emitpcode(POC_ADDLW, popGetAddr(AOP(IC_LEFT(ic)),offset)); + emitpcode(POC_ADDLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); offset++; } @@ -1063,13 +1060,11 @@ void genPlus (iCode *ic) } } else { PIC_OPCODE poc = POC_MOVFW; - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) + if (op_isLitLike (IC_LEFT(ic))) poc = POC_MOVLW; while(size--){ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset)); + emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); } emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); @@ -1094,12 +1089,10 @@ void genPlus (iCode *ic) if (AOP_SIZE(IC_LEFT(ic)) > AOP_SIZE(IC_RIGHT(ic))) { int leftsize = AOP_SIZE(IC_LEFT(ic)) - AOP_SIZE(IC_RIGHT(ic)); PIC_OPCODE poc = POC_MOVFW; - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) + if (op_isLitLike (IC_LEFT(ic))) poc = POC_MOVLW; while(leftsize-- > 0) { - emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset)); + emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); emitSKPNC; emitpcode(POC_INCF, popGet(AOP(IC_RESULT(ic)),offset)); @@ -1281,8 +1274,7 @@ void addSign(operand *result, int offset, int sign) emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(result),offset-1,FALSE,FALSE),7,0)); emitpcode(POC_MOVLW, popGetLit(0xff)); while(size--) - emitpcode(POC_MOVWF, popGet(AOP(result),size)); - + emitpcode(POC_MOVWF, popGet(AOP(result),offset+size)); } } else while(size--) @@ -1616,28 +1608,23 @@ void genMinus (iCode *ic) if(size){ if (pic14_sameRegs(AOP(IC_RIGHT(ic)), AOP(IC_RESULT(ic)))) { int lit = 0; - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) { + if (op_isLitLike (IC_LEFT(ic))) lit = 1; - } while(size--){ emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); emitSKPC; emitpcode(POC_INCFW, popGet(AOP(IC_RIGHT(ic)),offset)); - emitpcode(lit?POC_SUBLW:POC_SUBFW, popGetAddr(AOP(IC_LEFT(ic)),offset)); + emitpcode(lit?POC_SUBLW:POC_SUBFW, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); offset++; } } else { PIC_OPCODE poc = POC_MOVFW; - if ((AOP_TYPE(IC_LEFT(ic)) == AOP_PCODE) && ( - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_LITERAL) || - (AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE))) + if (op_isLitLike (IC_LEFT(ic))) poc = POC_MOVLW; while(size--){ if (!pic14_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) { - emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset)); + emitpcode(poc, popGetAddr(AOP(IC_LEFT(ic)),offset,0)); emitpcode(POC_MOVWF, popGet(AOP(IC_RESULT(ic)),offset)); } emitpcode(POC_MOVFW, popGet(AOP(IC_RIGHT(ic)),offset)); diff --git a/src/pic/glue.c b/src/pic/glue.c index 85d49a3a..79184f0d 100644 --- a/src/pic/glue.c +++ b/src/pic/glue.c @@ -27,6 +27,7 @@ #include "ralloc.h" #include "pcode.h" #include "newalloc.h" +#include "gen.h" #ifdef WORDS_BIGENDIAN @@ -424,7 +425,7 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist, { initList *iloop; unsigned size = 0; - + if(!pb) return; if (ilist) { @@ -474,6 +475,89 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist, return; } +/*-----------------------------------------------------------------*/ +/* printIvalPtr - generates code for initial value of pointers */ +/*-----------------------------------------------------------------*/ +extern value *initPointer (initList *, sym_link *toType); + +static void +printIvalPtr (symbol * sym, sym_link * type, initList * ilist, pBlock *pb) +{ + value *val; + + if (!ilist || !pb) + return; + + fprintf (stderr, "FIXME: initializers for pointers...\n"); + printTypeChain (type, stderr); + + fprintf (stderr, "symbol: %s, DCL_TYPE():%d, DCL_ELEM():%d, IS_ARRAY():%d", sym->rname, DCL_TYPE(type), DCL_ELEM(type), IS_ARRAY(type)); + fprintf (stderr, "ilist: type=%d (INIT_DEEP=%d, INIT_NODE=%d)\n", ilist->type, INIT_DEEP, INIT_NODE); + + if (ilist && (ilist->type == INIT_DEEP)) + ilist = ilist->init.deep; + + /* function pointers */ + if (IS_FUNC (type->next)) + { + assert ( !"function pointers not yet handled" ); + //printIvalFuncPtr (type, ilist, pb); + } + + if (!(val = initPointer (ilist, type))) + return; + + if (IS_CHAR (type->next)) + { + if (printIvalChar (type, ilist, pb, NULL)) return; + } + + /* check the type */ + if (compareType (type, val->type) == 0) + { + werrorfl (ilist->filename, ilist->lineno, W_INIT_WRONG); + printFromToType (val->type, type); + } + + if (IS_LITERAL (val->etype)) + { + switch (getSize (type)) + { + case 1: + fprintf (stderr, "BYTE: %i\n", (unsigned char)floatFromVal (val) & 0x00FF); + break; + case 2: + fprintf (stderr, "WORD: %i\n", (unsigned int)floatFromVal (val) & 0x00FFFF); + break; + case 3: /* gneric pointers */ + assert ( !"generic pointers not yet handled" ); + case 4: + fprintf (stderr, "LONG: %i\n", (unsigned int)floatFromVal (val) & 0x0000FFFFFFFF); + break; + default: + assert ( !"invaild size of value -- aborting" ); + } // switch + + return; + } // if (IS_LITERAL) + + /* now handle symbolic values */ + switch (getSize (type)) + { + case 1: + fprintf (stderr, "BYTE: %s", val->name); + break; + case 2: + fprintf (stderr, "WORD: %s", val->name); + break; + case 4: + fprintf (stderr, "LONG: %s", val->name); + break; + default: + assert ( !"invalid size of (symbolic) value -- aborting" ); + } // switch +} + /*-----------------------------------------------------------------*/ /* printIval - generates code for initial value */ /*-----------------------------------------------------------------*/ @@ -486,31 +570,31 @@ printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb) /* if structure then */ if (IS_STRUCT (type)) { - //fprintf(stderr,"%s struct\n",__FUNCTION__); + //fprintf(stderr,"%s struct: %s\n",__FUNCTION__, sym->rname); printIvalStruct (sym, type, ilist, pb); return; } - /* if this is a pointer */ - if (IS_PTR (type)) + /* if this is an array */ + if (IS_ARRAY (type)) { - //fprintf(stderr,"%s pointer\n",__FUNCTION__); - //printIvalPtr (sym, type, ilist, oFile); + //fprintf(stderr,"%s array: %s\n",__FUNCTION__, sym->rname); + printIvalArray (sym, type, ilist, pb); return; } - /* if this is an array */ - if (IS_ARRAY (type)) + /* if this is a pointer */ + if (IS_PTR (type)) { - //fprintf(stderr,"%s array\n",__FUNCTION__); - printIvalArray (sym, type, ilist, pb); + //fprintf(stderr,"%s pointer: %s\n",__FUNCTION__, sym->rname); + printIvalPtr (sym, type, ilist, pb); return; } /* if type is SPECIFIER */ if (IS_SPEC (type)) { - //fprintf(stderr,"%s spec\n",__FUNCTION__); + //fprintf(stderr,"%s spec %s\n",__FUNCTION__, sym->rname); printIvalType (sym, type, ilist, pb); return; } @@ -933,6 +1017,9 @@ picglue () werror (E_FILE_OPEN_ERR, buffer); exit (1); } + + /* prepare statistics */ + resetpCodeStatistics (); /* initial comments */ pic14initialComments (asmFile); @@ -1019,7 +1106,7 @@ picglue () fprintf (asmFile, "; bit data\n"); fprintf (asmFile, "%s", iComments2); copyFile (asmFile, bit->oFile); - + /* copy the interrupt vector table */ if (mainf && IFFUNC_HASBODY(mainf->type)) { copyFile (asmFile, vFile); @@ -1070,6 +1157,8 @@ picglue () /* unknown */ copypCode(asmFile, 'P'); + + dumppCodeStatistics (asmFile); fprintf (asmFile,"\tend\n"); diff --git a/src/pic/pcode.c b/src/pic/pcode.c index d28f0b3d..4e226db9 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -82,6 +82,11 @@ int debug_verbose = 0; /* Set true to inundate .asm file */ // static int GpCodeSequenceNumber = 1; int GpcFlowSeq = 1; +/* statistics (code size estimation) */ +static unsigned int pcode_insns = 0; +static unsigned int pcode_doubles = 0; + + unsigned maxIdx; /* This keeps track of the maximum register index for call tree register reuse */ unsigned peakIdx; /* This keeps track of the peak register index for call tree register reuse */ @@ -1639,7 +1644,7 @@ void copypCode(FILE *of, char dbName) if(!of || !the_pFile) return; - + for(pb = the_pFile->pbHead; pb; pb = pb->next) { if(getpBlock_dbName(pb) == dbName) { pBlockStats(of,pb); @@ -1649,6 +1654,21 @@ void copypCode(FILE *of, char dbName) } } + +void resetpCodeStatistics (void) +{ + pcode_insns = pcode_doubles = 0; +} + +void dumppCodeStatistics (FILE *of) +{ + /* dump statistics */ + fprintf (of, "\n"); + fprintf (of, ";\tcode size estimation:\n"); + fprintf (of, ";\t%5u+%5u = %5u instructions (%5u byte)\n", pcode_insns, pcode_doubles, pcode_insns + pcode_doubles, 2*(pcode_insns + 2*pcode_doubles)); + fprintf (of, "\n"); +} + void pcode_test(void) { @@ -1994,7 +2014,7 @@ pCodeFlowLink *newpCodeFlowLink(pCodeFlow *pcflow) /* newpCodeCSource - create a new pCode Source Symbol */ /*-----------------------------------------------------------------*/ -pCode *newpCodeCSource(int ln, char *f, char *l) +pCode *newpCodeCSource(int ln, char *f, const char *l) { pCodeCSource *pccs; @@ -2610,9 +2630,19 @@ void printpBlock(FILE *of, pBlock *pb) if(!of) of = stderr; - for(pc = pb->pcHead; pc; pc = pc->next) + for(pc = pb->pcHead; pc; pc = pc->next) { printpCode(of,pc); - + + if (isPCI(pc)) + { + if (isPCI(pc) && (PCI(pc)->op == POC_PAGESEL || PCI(pc)->op == POC_BANKSEL)) { + pcode_doubles++; + } else { + pcode_insns++; + } + } + } // for + } /*-----------------------------------------------------------------*/ @@ -2968,22 +2998,24 @@ char *get_op(pCodeOp *pcop,char *buffer, size_t size) s = buffer; if(PCOI(pcop)->_const) { - if( PCOI(pcop)->offset && PCOI(pcop)->offset<4) { + if( PCOI(pcop)->offset >= 0 && PCOI(pcop)->offset<4) { switch(PCOI(pcop)->offset) { case 0: - SAFE_snprintf(&s,&size,"low %s",pcop->name); + SAFE_snprintf(&s,&size,"low (%s+%d)",pcop->name, PCOI(pcop)->index); break; case 1: - SAFE_snprintf(&s,&size,"high %s",pcop->name); + SAFE_snprintf(&s,&size,"high (%s+%d)",pcop->name, PCOI(pcop)->index); break; default: + fprintf (stderr, "PO_IMMEDIATE/_const/offset=%d\n", PCOI(pcop)->offset); + assert ( !"offset too large" ); SAFE_snprintf(&s,&size,"(((%s+%d) >> %d)&0xff)", pcop->name, PCOI(pcop)->index, 8 * PCOI(pcop)->offset ); } } else - SAFE_snprintf(&s,&size,"LOW(%s+%d)",pcop->name,PCOI(pcop)->index); + SAFE_snprintf(&s,&size,"LOW (%s+%d)",pcop->name,PCOI(pcop)->index); } else { if( !PCOI(pcop)->offset) { // && PCOI(pcc->pcop)->offset<4) { SAFE_snprintf(&s,&size,"(%s + %d)", @@ -2998,6 +3030,8 @@ char *get_op(pCodeOp *pcop,char *buffer, size_t size) SAFE_snprintf(&s,&size,"high (%s + %d)",pcop->name, PCOI(pcop)->index); break; default: + fprintf (stderr, "PO_IMMEDIATE/mutable/offset=%d\n", PCOI(pcop)->offset); + assert ( !"offset too large" ); SAFE_snprintf(&s,&size,"((%s + %d) >> %d)&0xff",pcop->name, PCOI(pcop)->index, 8*PCOI(pcop)->offset); break; } diff --git a/src/pic/pcode.h b/src/pic/pcode.h index cc6cf135..89b6bb82 100644 --- a/src/pic/pcode.h +++ b/src/pic/pcode.h @@ -831,7 +831,7 @@ pCode *newpCodeCharP(char *cP); // Create a new pCode given a char pCode *newpCodeInlineP(char *cP); // Create a new pCode given a char * pCode *newpCodeFunction(char *g, char *f,int); // Create a new function pCode *newpCodeLabel(char *name,int key); // Create a new label given a key -pCode *newpCodeCSource(int ln, char *f, char *l); // Create a new symbol line +pCode *newpCodeCSource(int ln, char *f, const char *l); // Create a new symbol line pCode *findNextInstruction(pCode *pci); pCode *findNextpCode(pCode *pc, PC_TYPE pct); pCode *pCodeInstructionCopy(pCodeInstruction *pci,int invert); @@ -867,6 +867,8 @@ int isPCinFlow(pCode *pc, pCode *pcflow); struct regs * getRegFromInstruction(pCode *pc); extern void pcode_test(void); +void resetpCodeStatistics (void); +void dumppCodeStatistics (FILE *of); /*-----------------------------------------------------------------* * pCode objects. diff --git a/src/pic/ralloc.c b/src/pic/ralloc.c index dad9f522..4d4bd48f 100644 --- a/src/pic/ralloc.c +++ b/src/pic/ralloc.c @@ -5,23 +5,23 @@ Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998) Added Pic Port T.scott Dattalo scott@dattalo.com (2000) - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! -------------------------------------------------------------------------*/ #include "common.h" @@ -193,208 +193,107 @@ static char * switch (op) { - case IDENTIFIER: - return "IDENTIFIER"; - case TYPE_NAME: - return "TYPE_NAME"; - case CONSTANT: - return "CONSTANT"; - case STRING_LITERAL: - return "STRING_LITERAL"; - case SIZEOF: - return "SIZEOF"; - case PTR_OP: - return "PTR_OP"; - case INC_OP: - return "INC_OP"; - case DEC_OP: - return "DEC_OP"; - case LEFT_OP: - return "LEFT_OP"; - case RIGHT_OP: - return "RIGHT_OP"; - case LE_OP: - return "LE_OP"; - case GE_OP: - return "GE_OP"; - case EQ_OP: - return "EQ_OP"; - case NE_OP: - return "NE_OP"; - case AND_OP: - return "AND_OP"; - case OR_OP: - return "OR_OP"; - case MUL_ASSIGN: - return "MUL_ASSIGN"; - case DIV_ASSIGN: - return "DIV_ASSIGN"; - case MOD_ASSIGN: - return "MOD_ASSIGN"; - case ADD_ASSIGN: - return "ADD_ASSIGN"; - case SUB_ASSIGN: - return "SUB_ASSIGN"; - case LEFT_ASSIGN: - return "LEFT_ASSIGN"; - case RIGHT_ASSIGN: - return "RIGHT_ASSIGN"; - case AND_ASSIGN: - return "AND_ASSIGN"; - case XOR_ASSIGN: - return "XOR_ASSIGN"; - case OR_ASSIGN: - return "OR_ASSIGN"; - case TYPEDEF: - return "TYPEDEF"; - case EXTERN: - return "EXTERN"; - case STATIC: - return "STATIC"; - case AUTO: - return "AUTO"; - case REGISTER: - return "REGISTER"; - case CODE: - return "CODE"; - case EEPROM: - return "EEPROM"; - case INTERRUPT: - return "INTERRUPT"; - case SFR: - return "SFR"; - case AT: - return "AT"; - case SBIT: - return "SBIT"; - case REENTRANT: - return "REENTRANT"; - case USING: - return "USING"; - case XDATA: - return "XDATA"; - case DATA: - return "DATA"; - case IDATA: - return "IDATA"; - case PDATA: - return "PDATA"; - case VAR_ARGS: - return "VAR_ARGS"; - case CRITICAL: - return "CRITICAL"; - case NONBANKED: - return "NONBANKED"; - case BANKED: - return "BANKED"; - case CHAR: - return "CHAR"; - case SHORT: - return "SHORT"; - case INT: - return "INT"; - case LONG: - return "LONG"; - case SIGNED: - return "SIGNED"; - case UNSIGNED: - return "UNSIGNED"; - case FLOAT: - return "FLOAT"; - case DOUBLE: - return "DOUBLE"; - case CONST: - return "CONST"; - case VOLATILE: - return "VOLATILE"; - case VOID: - return "VOID"; - case BIT: - return "BIT"; - case STRUCT: - return "STRUCT"; - case UNION: - return "UNION"; - case ENUM: - return "ENUM"; - case ELIPSIS: - return "ELIPSIS"; - case RANGE: - return "RANGE"; - case FAR: - return "FAR"; - case CASE: - return "CASE"; - case DEFAULT: - return "DEFAULT"; - case IF: - return "IF"; - case ELSE: - return "ELSE"; - case SWITCH: - return "SWITCH"; - case WHILE: - return "WHILE"; - case DO: - return "DO"; - case FOR: - return "FOR"; - case GOTO: - return "GOTO"; - case CONTINUE: - return "CONTINUE"; - case BREAK: - return "BREAK"; - case RETURN: - return "RETURN"; - case INLINEASM: - return "INLINEASM"; - case IFX: - return "IFX"; - case ADDRESS_OF: - return "ADDRESS_OF"; - case GET_VALUE_AT_ADDRESS: - return "GET_VALUE_AT_ADDRESS"; - case SPIL: - return "SPIL"; - case UNSPIL: - return "UNSPIL"; - case GETHBIT: - return "GETHBIT"; - case BITWISEAND: - return "BITWISEAND"; - case UNARYMINUS: - return "UNARYMINUS"; - case IPUSH: - return "IPUSH"; - case IPOP: - return "IPOP"; - case PCALL: - return "PCALL"; - case ENDFUNCTION: - return "ENDFUNCTION"; - case JUMPTABLE: - return "JUMPTABLE"; - case RRC: - return "RRC"; - case RLC: - return "RLC"; - case CAST: - return "CAST"; - case CALL: - return "CALL"; - case PARAM: - return "PARAM "; - case NULLOP: - return "NULLOP"; - case BLOCK: - return "BLOCK"; - case LABEL: - return "LABEL"; - case RECEIVE: - return "RECEIVE"; - case SEND: - return "SEND"; + case IDENTIFIER: return "IDENTIFIER"; + case TYPE_NAME: return "TYPE_NAME"; + case CONSTANT: return "CONSTANT"; + case STRING_LITERAL: return "STRING_LITERAL"; + case SIZEOF: return "SIZEOF"; + case PTR_OP: return "PTR_OP"; + case INC_OP: return "INC_OP"; + case DEC_OP: return "DEC_OP"; + case LEFT_OP: return "LEFT_OP"; + case RIGHT_OP: return "RIGHT_OP"; + case LE_OP: return "LE_OP"; + case GE_OP: return "GE_OP"; + case EQ_OP: return "EQ_OP"; + case NE_OP: return "NE_OP"; + case AND_OP: return "AND_OP"; + case OR_OP: return "OR_OP"; + case MUL_ASSIGN: return "MUL_ASSIGN"; + case DIV_ASSIGN: return "DIV_ASSIGN"; + case MOD_ASSIGN: return "MOD_ASSIGN"; + case ADD_ASSIGN: return "ADD_ASSIGN"; + case SUB_ASSIGN: return "SUB_ASSIGN"; + case LEFT_ASSIGN: return "LEFT_ASSIGN"; + case RIGHT_ASSIGN: return "RIGHT_ASSIGN"; + case AND_ASSIGN: return "AND_ASSIGN"; + case XOR_ASSIGN: return "XOR_ASSIGN"; + case OR_ASSIGN: return "OR_ASSIGN"; + case TYPEDEF: return "TYPEDEF"; + case EXTERN: return "EXTERN"; + case STATIC: return "STATIC"; + case AUTO: return "AUTO"; + case REGISTER: return "REGISTER"; + case CODE: return "CODE"; + case EEPROM: return "EEPROM"; + case INTERRUPT: return "INTERRUPT"; + case SFR: return "SFR"; + case AT: return "AT"; + case SBIT: return "SBIT"; + case REENTRANT: return "REENTRANT"; + case USING: return "USING"; + case XDATA: return "XDATA"; + case DATA: return "DATA"; + case IDATA: return "IDATA"; + case PDATA: return "PDATA"; + case VAR_ARGS: return "VAR_ARGS"; + case CRITICAL: return "CRITICAL"; + case NONBANKED: return "NONBANKED"; + case BANKED: return "BANKED"; + case CHAR: return "CHAR"; + case SHORT: return "SHORT"; + case INT: return "INT"; + case LONG: return "LONG"; + case SIGNED: return "SIGNED"; + case UNSIGNED: return "UNSIGNED"; + case FLOAT: return "FLOAT"; + case DOUBLE: return "DOUBLE"; + case CONST: return "CONST"; + case VOLATILE: return "VOLATILE"; + case VOID: return "VOID"; + case BIT: return "BIT"; + case STRUCT: return "STRUCT"; + case UNION: return "UNION"; + case ENUM: return "ENUM"; + case ELIPSIS: return "ELIPSIS"; + case RANGE: return "RANGE"; + case FAR: return "FAR"; + case CASE: return "CASE"; + case DEFAULT: return "DEFAULT"; + case IF: return "IF"; + case ELSE: return "ELSE"; + case SWITCH: return "SWITCH"; + case WHILE: return "WHILE"; + case DO: return "DO"; + case FOR: return "FOR"; + case GOTO: return "GOTO"; + case CONTINUE: return "CONTINUE"; + case BREAK: return "BREAK"; + case RETURN: return "RETURN"; + case INLINEASM: return "INLINEASM"; + case IFX: return "IFX"; + case ADDRESS_OF: return "ADDRESS_OF"; + case GET_VALUE_AT_ADDRESS: return "GET_VALUE_AT_ADDRESS"; + case SPIL: return "SPIL"; + case UNSPIL: return "UNSPIL"; + case GETHBIT: return "GETHBIT"; + case BITWISEAND: return "BITWISEAND"; + case UNARYMINUS: return "UNARYMINUS"; + case IPUSH: return "IPUSH"; + case IPOP: return "IPOP"; + case PCALL: return "PCALL"; + case ENDFUNCTION: return "ENDFUNCTION"; + case JUMPTABLE: return "JUMPTABLE"; + case RRC: return "RRC"; + case RLC: return "RLC"; + case CAST: return "CAST"; + case CALL: return "CALL"; + case PARAM: return "PARAM "; + case NULLOP: return "NULLOP"; + case BLOCK: return "BLOCK"; + case LABEL: return "LABEL"; + case RECEIVE: return "RECEIVE"; + case SEND: return "SEND"; } sprintf (buffer, "unknown op %d %c", op, op & 0xff); return buffer; @@ -407,12 +306,9 @@ debugLogRegType (short type) switch (type) { - case REG_GPR: - return "REG_GPR"; - case REG_PTR: - return "REG_PTR"; - case REG_CND: - return "REG_CND"; + case REG_GPR: return "REG_GPR"; + case REG_PTR: return "REG_PTR"; + case REG_CND: return "REG_CND"; } sprintf (buffer, "unknown reg type %d", type); @@ -456,7 +352,6 @@ static regs* newReg(short type, short pc_type, int rIdx, char *name, int size, i sprintf(buffer,"r0x%02X", dReg->rIdx); dReg->name = Safe_strdup(buffer); } - //fprintf(stderr,"newReg: %s, rIdx = 0x%02x\n",dReg->name,rIdx); dReg->isFree = 0; dReg->wasUsed = 1; if (type == REG_SFR) @@ -628,12 +523,20 @@ allocInternalRegister(int rIdx, char * name, short po_type, int alias) static regs * allocReg (short type) { + regs *reg; debugLog ("%s of type %s\n", __FUNCTION__, debugLogRegType (type)); //fprintf(stderr,"allocReg\n"); + reg = pic14_findFreeReg (type); + + reg->isFree = 0; + reg->wasUsed = 1; + + return reg; - return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0)); + + //return addSet(&dynAllocRegs,newReg(REG_GPR, PO_GPR_TEMP,dynrIdx++,NULL,1,0)); } @@ -1998,7 +1901,7 @@ tryAgain: if (sym->regs[j]) sym->regs[j]->isFree = 0; - /* this looks like an infinite loop but + /* this looks like an infinite loop but in really selectSpil will abort */ goto tryAgain; } @@ -2039,6 +1942,13 @@ deassignLRs (iCode * ic, eBBlock * ebp) /* if it does not end here */ if (sym->liveTo > ic->seq) continue; + + /* HACK: result and addr must be disjoint for POINTER_GET */ + if (sym->liveTo == ic->seq && POINTER_GET(ic)) + { + //piCode (ic, stderr); fprintf (stderr, " -- registers NOT deallocated\n"); + continue; + } /* if it was spilt on stack then we can mark the stack spil location as free */ @@ -2054,7 +1964,6 @@ deassignLRs (iCode * ic, eBBlock * ebp) if (!bitVectBitValue (_G.regAssigned, sym->key)) continue; - /* special case check if this is an IFX & the privious one was a pop and the previous one was not spilt then keep track @@ -2062,6 +1971,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) if (ic->op == IFX && ic->prev && ic->prev->op == IPOP && !ic->prev->parmPush && + IS_SYMOP(IC_LEFT (ic->prev)) && !OP_SYMBOL (IC_LEFT (ic->prev))->isspilt) psym = OP_SYMBOL (IC_LEFT (ic->prev)); @@ -2082,6 +1992,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) ic->op == IPOP || ic->op == RETURN || POINTER_SET (ic)) && + IS_SYMOP (IC_RESULT (ic)) && (result = OP_SYMBOL (IC_RESULT (ic))) && /* has a result */ result->liveTo > ic->seq && /* and will live beyond this */ result->liveTo <= ebp->lSeq && /* does not go beyond this block */ @@ -2108,7 +2019,7 @@ deassignLRs (iCode * ic, eBBlock * ebp) _G.regAssigned = bitVectSetBit (_G.regAssigned, result->key); } - + /* free the remaining */ for (; i < sym->nRegs; i++) { @@ -2273,7 +2184,6 @@ serialRegAssign (eBBlock ** ebbs, int count) /* of all instructions do */ for (ic = ebbs[i]->sch; ic; ic = ic->next) { - debugLog (" op: %s\n", decodeOp (ic->op)); /* if this is an ipop that means some live @@ -2301,7 +2211,7 @@ serialRegAssign (eBBlock ** ebbs, int count) /* now we need to allocate registers only for the result */ - if (IC_RESULT (ic)) + if (IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic))) { symbol *sym = OP_SYMBOL (IC_RESULT (ic)); bitVect *spillable; @@ -2387,8 +2297,10 @@ serialRegAssign (eBBlock ** ebbs, int count) /* if we need ptr regs for the right side then mark it */ - if (POINTER_GET (ic) && getSize (OP_SYMBOL (IC_LEFT (ic))->type) - <= (unsigned) PTRSIZE) + if (POINTER_GET (ic) + && IS_SYMOP(IC_LEFT(ic)) + && getSize (OP_SYMBOL (IC_LEFT (ic))->type) + <= (unsigned) PTRSIZE) { pic14_ptrRegReq++; ptrRegSet = 1; @@ -2416,11 +2328,13 @@ serialRegAssign (eBBlock ** ebbs, int count) /* if it shares registers with operands make sure that they are in the same position */ if (IC_LEFT (ic) && IS_SYMOP (IC_LEFT (ic)) && + IS_SYMOP(IC_RESULT(ic)) && OP_SYMBOL (IC_LEFT (ic))->nRegs && ic->op != '=') positionRegs (OP_SYMBOL (IC_RESULT (ic)), OP_SYMBOL (IC_LEFT (ic)), ic->lineno); /* do the same for the right operand */ if (IC_RIGHT (ic) && IS_SYMOP (IC_RIGHT (ic)) && + IS_SYMOP(IC_RESULT(ic)) && OP_SYMBOL (IC_RIGHT (ic))->nRegs && ic->op != '=') positionRegs (OP_SYMBOL (IC_RESULT (ic)), OP_SYMBOL (IC_RIGHT (ic)), ic->lineno); @@ -3918,13 +3832,13 @@ packRegisters (eBBlock * ebp) } /* mark the pointer usages */ - if (POINTER_SET (ic)) + if (POINTER_SET (ic) && IS_SYMOP(IC_RESULT(ic))) { OP_SYMBOL (IC_RESULT (ic))->uptr = 1; debugLog (" marking as a pointer (set) =>"); debugAopGet (" result:", IC_RESULT (ic)); } - if (POINTER_GET (ic)) + if (POINTER_GET (ic) && IS_SYMOP(IC_LEFT(ic))) { OP_SYMBOL (IC_LEFT (ic))->uptr = 1; debugLog (" marking as a pointer (get) =>"); @@ -3996,6 +3910,7 @@ packRegisters (eBBlock * ebp) one and right is not in far space */ if (POINTER_SET (ic) && !isOperandInFarSpace (IC_RIGHT (ic)) && + IS_SYMOP(IC_RESULT(ic)) && !OP_SYMBOL (IC_RESULT (ic))->remat && !IS_OP_RUONLY (IC_RIGHT (ic)) && getSize (aggrToPtr (operandType (IC_RESULT (ic)), FALSE)) > 1) @@ -4005,6 +3920,7 @@ packRegisters (eBBlock * ebp) /* if pointer get */ if (POINTER_GET (ic) && !isOperandInFarSpace (IC_RESULT (ic)) && + IS_SYMOP(IC_LEFT(ic)) && !OP_SYMBOL (IC_LEFT (ic))->remat && !IS_OP_RUONLY (IC_RESULT (ic)) && getSize (aggrToPtr (operandType (IC_LEFT (ic)), FALSE)) > 1) -- 2.30.2