From: sdattalo Date: Sun, 30 Sep 2001 03:53:13 +0000 (+0000) Subject: Added more regression test to the pic port. Added support for <<, >>, ^ X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=d29d3bd3d0ba71cced0f534b9c08c41d042a5a38;p=fw%2Fsdcc Added more regression test to the pic port. Added support for <<, >>, ^ git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@1329 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/src/pic/gen.c b/src/pic/gen.c index 42b0b375..265e9fc0 100644 --- a/src/pic/gen.c +++ b/src/pic/gen.c @@ -61,6 +61,7 @@ static int labelOffset=0; static int debug_verbose=1; +static int optimized_for_speed = 0; unsigned int pic14aopLiteral (value *val, int offset); @@ -611,10 +612,10 @@ void aopOp (operand *op, iCode *ic, bool result) DEBUGpic14_emitcode(";","%d",__LINE__); /* if this a literal */ if (IS_OP_LITERAL(op)) { - DEBUGpic14_emitcode(";","%d",__LINE__); op->aop = aop = newAsmop(AOP_LIT); aop->aopu.aop_lit = op->operand.valOperand; aop->size = getSize(operandType(op)); + DEBUGpic14_emitcode(";","%d, lit = %d",__LINE__,aop->aopu.aop_lit); return; } @@ -631,7 +632,7 @@ void aopOp (operand *op, iCode *ic, bool result) /* if this is a true symbol */ if (IS_TRUE_SYMOP(op)) { - DEBUGpic14_emitcode(";","%d",__LINE__); + DEBUGpic14_emitcode(";","%d - true symop",__LINE__); op->aop = aopForSym(ic,OP_SYMBOL(op),result); return ; } @@ -973,7 +974,7 @@ pCodeOp *popCopyReg(pCodeOpReg *pc) pcor = Safe_calloc(1,sizeof(pCodeOpReg) ); pcor->pcop.type = pc->pcop.type; - if(!(pcor->pcop.name = strdup(pc->pcop.name))) + if(!(pcor->pcop.name = Safe_strdup(pc->pcop.name))) fprintf(stderr,"oops %s %d",__FILE__,__LINE__); pcor->r = pc->r; pcor->rIdx = pc->rIdx; @@ -985,13 +986,13 @@ pCodeOp *popCopyReg(pCodeOpReg *pc) /*-----------------------------------------------------------------*/ /* popCopy - copy a pcode operator */ /*-----------------------------------------------------------------*/ -pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval) +pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval) { pCodeOp *pcop; pcop = Safe_calloc(1,sizeof(pCodeOpBit) ); pcop->type = PO_BIT; - if(!(pcop->name = strdup(pc->pcop.name))) + if(!(pcop->name = Safe_strdup(pc->name))) fprintf(stderr,"oops %s %d",__FILE__,__LINE__); ((pCodeOpBit *)pcop)->bit = bitval; @@ -1117,8 +1118,11 @@ pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname) int rIdx = aop->aopu.aop_reg[offset]->rIdx; DEBUGpic14_emitcode(";","%d",__LINE__); - pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); - pcop->type = PO_GPR_REGISTER; + if(bit16) + pcop = Safe_calloc(1,sizeof(pCodeOpRegBit) ); + else + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + //pcop->type = PO_GPR_REGISTER; PCOR(pcop)->rIdx = rIdx; PCOR(pcop)->r = pic14_regWithIdx(rIdx); pcop->type = PCOR(pcop)->r->pc_type; @@ -1134,7 +1138,7 @@ pCodeOp *popGet (asmop *aop, int offset, bool bit16, bool dname) } case AOP_CRY: - pcop = newpCodeOpBit(aop->aopu.aop_dir,0); + pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1); return pcop; case AOP_LIT: @@ -2738,9 +2742,11 @@ static void genRet (iCode *ic) /* generate a jump to the return label if the next is not the return statement */ if (!(ic->next && ic->next->op == LABEL && - IC_LABEL(ic->next) == returnLabel)) + IC_LABEL(ic->next) == returnLabel)) { + emitpcode(POC_GOTO,popGetLabel(returnLabel->key)); pic14_emitcode("goto","_%05d_DS_",returnLabel->key+100 + labelOffset); + } } @@ -2764,7 +2770,8 @@ static void genLabel (iCode *ic) //tsd static void genGoto (iCode *ic) { - pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset); + emitpcode(POC_GOTO,popGetLabel(IC_LABEL(ic)->key)); + pic14_emitcode ("goto","_%05d_DS_",(IC_LABEL(ic)->key+100)+labelOffset); } /*-----------------------------------------------------------------*/ @@ -3217,6 +3224,9 @@ release : /*-----------------------------------------------------------------*/ /* genIfxJump :- will create a jump depending on the ifx */ /*-----------------------------------------------------------------*/ +/* + note: May need to add parameter to indicate when a variable is in bit space. +*/ static void genIfxJump (iCode *ic, char *jval) { @@ -3230,11 +3240,8 @@ static void genIfxJump (iCode *ic, char *jval) else if (strcmp(jval,"c") == 0) emitSKPC; else { - //pCodeOp *p = popGetWithString(jval); - //p->type = PO_BIT; - //emitpcode(POC_BTFSC, p); - emitpcode(POC_BTFSC, newpCodeOpBit(jval,0)); - //pic14_emitcode("btfsc","(%s >> 3),(%s & 7)",jval,jval); + DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); + emitpcode(POC_BTFSC, newpCodeOpBit(jval,-1,1)); } emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key)); @@ -3248,12 +3255,8 @@ static void genIfxJump (iCode *ic, char *jval) else if (strcmp(jval,"c") == 0) emitSKPNC; else { - //pCodeOp *p = popGetWithString(jval); - //p->type = PO_BIT; - //emitpcode(POC_BTFSS, p); - emitpcode(POC_BTFSS, newpCodeOpBit(jval,0)); - - // pic14_emitcode("btfss","(%s >> 3),(%s & 7)",jval,jval); + DEBUGpic14_emitcode ("; ***","%d - assuming %s is in bit space",__LINE__,jval); + emitpcode(POC_BTFSS, newpCodeOpBit(jval,-1,1)); } emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key)); @@ -4192,7 +4195,7 @@ static void genAnd (iCode *ic, iCode *ifx) int size, offset=0; unsigned long lit = 0L; int bytelit = 0; - char buffer[10]; + // char buffer[10]; DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); aopOp((left = IC_LEFT(ic)),ic,FALSE); @@ -4288,19 +4291,29 @@ static void genAnd (iCode *ic, iCode *ifx) int posbit = isLiteralBit(lit); /* left & 2^n */ if(posbit){ - posbit--; - MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE)); + posbit--; + //MOVA(aopGet(AOP(left),posbit>>3,FALSE,FALSE)); // bit = left & 2^n - if(size) - pic14_emitcode("mov","c,acc.%d",posbit&0x07); + if(size) + pic14_emitcode("mov","c,acc.%d",posbit&0x07); // if(left & 2^n) - else{ - if(ifx){ - sprintf(buffer,"acc.%d",posbit&0x07); - genIfxJump(ifx, buffer); - } - goto release; - } + else{ + if(ifx){ + pCodeOp *pcorb = popGet(AOP(left),0,TRUE,FALSE); + PCORB(pcorb)->subtype = PCOP(pcorb)->type; + PCOP(pcorb)->type = PO_GPR_BIT; + PCORB(pcorb)->bit = posbit; + if(IC_TRUE(ifx)) { + emitpcode(POC_BTFSC, pcorb); + emitpcode(POC_GOTO,popGetLabel(IC_TRUE(ic)->key)); + } else { + emitpcode(POC_BTFSS, pcorb); + emitpcode(POC_GOTO,popGetLabel(IC_FALSE(ic)->key)); + } + ifx->generated = 1; + } + goto release; + } } else { symbol *tlbl = newiTempLabel(NULL); int sizel = AOP_SIZE(left); @@ -4345,9 +4358,11 @@ static void genAnd (iCode *ic, iCode *ifx) case 0x00: /* and'ing with 0 has clears the result */ pic14_emitcode("clrf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE)); break; case 0xff: pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(right),offset,FALSE,FALSE)); break; default: @@ -4356,18 +4371,25 @@ static void genAnd (iCode *ic, iCode *ifx) if(p>=0) { /* only one bit is set in the literal, so use a bcf instruction */ pic14_emitcode("bcf","%s,%d",aopGet(AOP(left),offset,FALSE,TRUE),p); + emitpcode(POC_BCF,popGet(AOP(left),offset,FALSE,TRUE)); } else { pic14_emitcode("movlw","0x%x", (lit & 0xff)); - pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE),p); + pic14_emitcode("andwf","%s,f",aopGet(AOP(left),offset,FALSE,TRUE)); + emitpcode(POC_MOVLW, popGetLit(lit & 0xff)); + emitpcode(POC_ANDWF,popGet(AOP(left),offset,FALSE,TRUE)); } } } } else { - if (AOP_TYPE(left) == AOP_ACC) - pic14_emitcode("iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - else { + if (AOP_TYPE(left) == AOP_ACC) { + pic14_emitcode("?iorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); + emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE)); + + } else { pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - pic14_emitcode("iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE)); + pic14_emitcode("?iorwf","%s,f",aopGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE)); + emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE)); } } @@ -4406,12 +4428,15 @@ static void genAnd (iCode *ic, iCode *ifx) case 0x00: pic14_emitcode("clrf","%s", aopGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_CLRF,popGet(AOP(result),offset,FALSE,FALSE)); break; case 0xff: pic14_emitcode("movf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE)); break; default: pic14_emitcode("movlw","0x%x",t); @@ -4420,18 +4445,25 @@ static void genAnd (iCode *ic, iCode *ifx) pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE)); } continue; } - if (AOP_TYPE(left) == AOP_ACC) + if (AOP_TYPE(left) == AOP_ACC) { pic14_emitcode("andwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - else { + emitpcode(POC_ANDFW,popGet(AOP(right),offset,FALSE,FALSE)); + } else { pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); pic14_emitcode("andwf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE)); + emitpcode(POC_ANDFW,popGet(AOP(left),offset,FALSE,FALSE)); } pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE)); } } } @@ -4842,17 +4874,21 @@ static void genXor (iCode *ic, iCode *ifx) /* if left is same as result */ for(;size--; offset++) { if(AOP_TYPE(right) == AOP_LIT){ - if(((lit >> (offset*8)) & 0x0FFL) == 0x00L) + int t = (lit >> (offset*8)) & 0x0FFL; + if(t == 0x00L) continue; else if (IS_AOP_PREG(left)) { MOVA(aopGet(AOP(right),offset,FALSE,FALSE)); pic14_emitcode("xrl","a,%s",aopGet(AOP(left),offset,FALSE,TRUE)); aopPut(AOP(result),"a",offset); - } else - pic14_emitcode("xrl","%s,%s", - aopGet(AOP(left),offset,FALSE,TRUE), - aopGet(AOP(right),offset,FALSE,FALSE)); + } else { + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_XORWF,popGet(AOP(left),offset,FALSE,FALSE)); + pic14_emitcode("xrl","%s,%s", + aopGet(AOP(left),offset,FALSE,TRUE), + aopGet(AOP(right),offset,FALSE,FALSE)); + } } else { if (AOP_TYPE(left) == AOP_ACC) pic14_emitcode("xrl","a,%s",aopGet(AOP(right),offset,FALSE,FALSE)); @@ -4902,18 +4938,25 @@ static void genXor (iCode *ic, iCode *ifx) int t = (lit >> (offset*8)) & 0x0FFL; switch(t) { case 0x00: + emitpcode(POC_MOVFW,popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE)); pic14_emitcode("movf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE)); break; case 0xff: + emitpcode(POC_COMFW,popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE)); pic14_emitcode("comf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); pic14_emitcode("movwf","%s", aopGet(AOP(result),offset,FALSE,FALSE)); break; default: + emitpcode(POC_MOVLW, popGetLit(t)); + emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE)); pic14_emitcode("movlw","0x%x",t); pic14_emitcode("xorwf","%s,w", aopGet(AOP(left),offset,FALSE,FALSE)); @@ -4926,14 +4969,19 @@ static void genXor (iCode *ic, iCode *ifx) // faster than result <- left, anl result,right // and better if result is SFR - if (AOP_TYPE(left) == AOP_ACC) + if (AOP_TYPE(left) == AOP_ACC) { + emitpcode(POC_XORFW,popGet(AOP(right),offset,FALSE,FALSE)); pic14_emitcode("xorwf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); - else { + } else { + emitpcode(POC_MOVFW,popGet(AOP(right),offset,FALSE,FALSE)); + emitpcode(POC_XORFW,popGet(AOP(left),offset,FALSE,FALSE)); pic14_emitcode("movf","%s,w",aopGet(AOP(right),offset,FALSE,FALSE)); pic14_emitcode("xorwf","%s,w",aopGet(AOP(left),offset,FALSE,FALSE)); } - if ( AOP_TYPE(result) != AOP_ACC) + if ( AOP_TYPE(result) != AOP_ACC){ + emitpcode(POC_MOVWF,popGet(AOP(result),offset,FALSE,FALSE)); pic14_emitcode("movwf","%s",aopGet(AOP(result),offset,FALSE,FALSE)); + } } } @@ -5171,6 +5219,7 @@ static void AccRsh (int shCount) } } +#if 0 /*-----------------------------------------------------------------*/ /* AccSRsh - signed right shift accumulator by known count */ /*-----------------------------------------------------------------*/ @@ -5200,6 +5249,36 @@ static void AccSRsh (int shCount) } } } +#endif +/*-----------------------------------------------------------------*/ +/* shiftR1Left2Result - shift right one byte from left to result */ +/*-----------------------------------------------------------------*/ +static void shiftR1Left2ResultSigned (operand *left, int offl, + operand *result, int offr, + int shCount) +{ + int same; + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + same = (left == result) || (AOP(left) == AOP(result)); + + switch(shCount) { + case 1: + emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE)); + if(same) + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); + else { + emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + } + + break; + + default: + break; + } +} /*-----------------------------------------------------------------*/ /* shiftR1Left2Result - shift right one byte from left to result */ @@ -5208,14 +5287,103 @@ static void shiftR1Left2Result (operand *left, int offl, operand *result, int offr, int shCount, int sign) { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - /* shift right accumulator */ - if(sign) - AccSRsh(shCount); - else - AccRsh(shCount); - aopPut(AOP(result),"a",offr); + int same; + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + same = (left == result) || (AOP(left) == AOP(result)); + + /* Copy the msb into the carry if signed. */ + if(sign) { + shiftR1Left2ResultSigned(left,offl,result,offr,shCount); + return; + } + + + + switch(shCount) { + case 1: + emitCLRC; + if(same) + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); + else { + emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + } + break; + case 2: + emitCLRC; + if(same) { + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); + } else { + emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + } + emitCLRC; + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); + + break; + case 3: + if(same) + emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE)); + else { + emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + } + + emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLFW, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ANDLW, popGetLit(0x1f)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + break; + + case 4: + emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_ANDLW, popGetLit(0x1f)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + break; + + case 5: + emitpcode(POC_SWAPFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_ANDLW, popGetLit(0x1f)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + emitCLRC; + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); + + break; + case 6: + + emitpcode(POC_RLFW, popGet(AOP(left),offr,FALSE,FALSE)); + emitpcode(POC_ANDLW, popGetLit(0x80)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE)); + break; + + case 7: + + emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE)); + + break; + + default: + break; + } + + +#if 0 + + MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); + + /* shift right accumulator */ + if(sign) + AccSRsh(shCount); + else + AccRsh(shCount); + aopPut(AOP(result),"a",offr); +#endif } /*-----------------------------------------------------------------*/ @@ -5224,13 +5392,71 @@ static void shiftR1Left2Result (operand *left, int offl, static void shiftL1Left2Result (operand *left, int offl, operand *result, int offr, int shCount) { - char *l; - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - l = aopGet(AOP(left),offl,FALSE,FALSE); - MOVA(l); + int same; + + // char *l; + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + same = ((left == result) || (AOP(left) == AOP(result))) && (offl==offr); + DEBUGpic14_emitcode ("; ***","same = %d",same); + // l = aopGet(AOP(left),offl,FALSE,FALSE); + // MOVA(l); /* shift left accumulator */ - AccLsh(shCount); - aopPut(AOP(result),"a",offr); + //AccLsh(shCount); // don't comment out just yet... + // aopPut(AOP(result),"a",offr); + + switch(shCount) { + case 1: + /* Shift left 1 bit position */ + emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE)); + if(same) { + emitpcode(POC_ADDWF, popGet(AOP(left),offl,FALSE,FALSE)); + } else { + emitpcode(POC_ADDFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + } + break; + case 2: + emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_ANDLW,popGetLit(0x7e)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE)); + break; + case 3: + emitpcode(POC_RLFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_ANDLW,popGetLit(0x3e)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE)); + break; + case 4: + emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_ANDLW, popGetLit(0xf0)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE)); + break; + case 5: + emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_ANDLW, popGetLit(0xf0)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE)); + break; + case 6: + emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_ANDLW, popGetLit(0x30)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE)); + break; + case 7: + emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); + break; + + default: + DEBUGpic14_emitcode ("; ***","%s %d, shift count is %d",__FUNCTION__,__LINE__,shCount); + } + } /*-----------------------------------------------------------------*/ @@ -5248,9 +5474,12 @@ static void movLeft2Result (operand *left, int offl, pic14_emitcode("mov","a,%s",l); aopPut(AOP(result),"a",offr); } else { - if(!sign) - aopPut(AOP(result),l,offr); - else{ + if(!sign) { + emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + + //aopPut(AOP(result),l,offr); + }else{ /* MSB sign in acc.7 ! */ if(pic14_getDataSize(left) == offl+1){ pic14_emitcode("mov","a,%s",l); @@ -5284,7 +5513,7 @@ static void AccAXLrl1 (char *x) pic14_emitcode("xch","a,%s",x); pic14_emitcode("rlc","a"); } - +#if 0 /*-----------------------------------------------------------------*/ /* AccAXLsh1 - left shift a:x<-0 by 1 */ /*-----------------------------------------------------------------*/ @@ -5296,7 +5525,8 @@ static void AccAXLsh1 (char *x) pic14_emitcode("xch","a,%s",x); pic14_emitcode("rlc","a"); } - +#endif +#if 0 /*-----------------------------------------------------------------*/ /* AccAXLsh - left shift a:x by known count (0..7) */ /*-----------------------------------------------------------------*/ @@ -5348,7 +5578,7 @@ static void AccAXLsh (char *x, int shCount) break; } } - +#endif /*-----------------------------------------------------------------*/ /* AccAXRsh - right shift a:x known count (0..7) */ /*-----------------------------------------------------------------*/ @@ -5481,22 +5711,129 @@ static void AccAXRshS (char *x, int shCount) static void shiftL2Left2Result (operand *left, int offl, operand *result, int offr, int shCount) { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(pic14_sameRegs(AOP(result), AOP(left)) && - ((offl + MSB16) == offr)){ - /* don't crash result[offr] */ - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } else { - movLeft2Result(left,offl, result, offr, 0); - MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); + + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + + if(pic14_sameRegs(AOP(result), AOP(left))) { + switch(shCount) { + case 0: + break; + case 1: + case 2: + case 3: + + emitpcode(POC_MOVFW,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ADDWF,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + + while(--shCount) { + emitCLRC; + emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + } + + break; + case 4: + case 5: + emitpcode(POC_MOVLW, popGetLit(0x0f)); + emitpcode(POC_ANDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_SWAPF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_SWAPF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ANDFW, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + if(shCount >=5) { + emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + } + break; + case 6: + emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_ANDLW,popGetLit(0xc0)); + emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + break; + case 7: + emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_RRFW, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); } - /* ax << shCount (x = lsb(result))*/ - AccAXLsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); - aopPut(AOP(result),"a",offr+MSB16); -} + } else { + switch(shCount) { + case 0: + break; + case 1: + case 2: + /* note, use a mov/add for the shift since the mov has a + chance of getting optimized out */ + emitpcode(POC_MOVFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + + while(--shCount) { + emitCLRC; + emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + } + break; + case 3: + case 4: + case 5: + emitpcode(POC_SWAPFW,popGet(AOP(left),offl+MSB16,FALSE,FALSE)); + emitpcode(POC_ANDLW, popGetLit(0xF0)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_SWAPFW,popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ANDLW, popGetLit(0xF0)); + emitpcode(POC_XORWF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_ADDWF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + + if(shCount == 3) { + emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); + } + if(shCount == 5) { + emitpcode(POC_RLF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RLF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + } + break; + case 6: + emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_RRFW, popGet(AOP(result),offl,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),offr,FALSE,FALSE)); + + emitpcode(POC_RRF, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RRFW, popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_ANDLW,popGetLit(0xc0)); + emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_XORWF,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_XORFW,popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + break; + case 7: + emitpcode(POC_RRFW, popGet(AOP(left),offl+MSB16,FALSE,FALSE)); + emitpcode(POC_RRFW, popGet(AOP(left),offl,FALSE,FALSE)); + emitpcode(POC_MOVWF,popGet(AOP(result),offr+MSB16,FALSE,FALSE)); + emitpcode(POC_CLRF, popGet(AOP(result),offr,FALSE,FALSE)); + emitpcode(POC_RRF, popGet(AOP(result),offr,FALSE,FALSE)); + } + } +} /*-----------------------------------------------------------------*/ /* shiftR2Left2Result - shift right two bytes from left to result */ /*-----------------------------------------------------------------*/ @@ -5504,23 +5841,30 @@ static void shiftR2Left2Result (operand *left, int offl, operand *result, int offr, int shCount, int sign) { - DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - if(pic14_sameRegs(AOP(result), AOP(left)) && - ((offl + MSB16) == offr)){ - /* don't crash result[offr] */ - MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); - pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } else { - movLeft2Result(left,offl, result, offr, 0); - MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); - } - /* a:x >> shCount (x = lsb(result))*/ - if(sign) - AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); - else - AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); + int same=0; + + DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + if(pic14_sameRegs(AOP(result), AOP(left)) && + ((offl + MSB16) == offr)){ + same=1; + /* don't crash result[offr] */ + MOVA(aopGet(AOP(left),offl,FALSE,FALSE)); + pic14_emitcode("xch","a,%s", aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); + } else { + movLeft2Result(left,offl, result, offr, 0); + MOVA(aopGet(AOP(left),offl+MSB16,FALSE,FALSE)); + } + /* a:x >> shCount (x = lsb(result))*/ + if(sign) + AccAXRshS( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); + else { + //AccAXRsh( aopGet(AOP(result),offr,FALSE,FALSE) , shCount); + + // switch() { + //} if(pic14_getDataSize(result) > 1) - aopPut(AOP(result),"a",offr+MSB16); + aopPut(AOP(result),"a",offr+MSB16); + } } /*-----------------------------------------------------------------*/ @@ -5584,7 +5928,7 @@ static void genlshTwo (operand *result,operand *left, int shCount) else movLeft2Result(left, LSB, result, MSB16, 0); } - aopPut(AOP(result),zero,LSB); + emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE)); } /* 1 <= shCount <= 7 */ @@ -5826,9 +6170,7 @@ static void genLeftShift (iCode *ic) more that 32 bits make no sense anyway, ( the largest size of an object can be only 32 bits ) */ - pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); - pic14_emitcode("inc","b"); - freeAsmop (right,NULL,ic,TRUE); + aopOp(left,ic,FALSE); aopOp(result,ic,FALSE); @@ -5851,26 +6193,47 @@ static void genLeftShift (iCode *ic) } } - tlbl = newiTempLabel(NULL); size = AOP_SIZE(result); - offset = 0 ; - tlbl1 = newiTempLabel(NULL); /* if it is only one byte then */ if (size == 1) { - symbol *tlbl1 = newiTempLabel(NULL); + if(optimized_for_speed) { + emitpcode(POC_SWAPFW, popGet(AOP(left),0,FALSE,FALSE)); + emitpcode(POC_ANDLW, popGetLit(0xf0)); + emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),2,0)); + emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_BTFSS, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),0,0)); + emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_RLFW, popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_ANDLW, popGetLit(0xfe)); + emitpcode(POC_ADDFW, popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_BTFSC, newpCodeOpBit(aopGet(AOP(right),0,FALSE,FALSE),1,0)); + emitpcode(POC_ADDWF, popGet(AOP(result),0,FALSE,FALSE)); + } else { + + tlbl = newiTempLabel(NULL); + if (!pic14_sameRegs(AOP(left),AOP(result))) { + emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + } - l = aopGet(AOP(left),0,FALSE,FALSE); - MOVA(l); - pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); - pic14_emitcode("","%05d_DS_:",tlbl->key+100); - pic14_emitcode("add","a,acc"); - pic14_emitcode("","%05d_DS_:",tlbl1->key+100); - pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100); - aopPut(AOP(result),"a",0); - goto release ; + emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE)); + emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE)); + emitpLabel(tlbl->key+100+labelOffset); + emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_ADDLW, popGetLit(1)); + emitSKPC; + emitpcode(POC_GOTO,popGetLabel(tlbl->key)); + } + goto release ; } + + tlbl = newiTempLabel(NULL); + offset = 0 ; + tlbl1 = newiTempLabel(NULL); + reAdjustPreg(AOP(result)); pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); @@ -5890,6 +6253,7 @@ static void genLeftShift (iCode *ic) pic14_emitcode("","%05d_DS_:",tlbl1->key+100); pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100); release: + freeAsmop (right,NULL,ic,TRUE); freeAsmop(left,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); } @@ -6226,7 +6590,6 @@ static void genRightShift (iCode *ic) pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE)); pic14_emitcode("inc","b"); - freeAsmop (right,NULL,ic,TRUE); aopOp(left,ic,FALSE); aopOp(result,ic,FALSE); @@ -6256,6 +6619,7 @@ static void genRightShift (iCode *ic) /* if it is only one byte then */ if (size == 1) { +/* l = aopGet(AOP(left),0,FALSE,FALSE); MOVA(l); pic14_emitcode("sjmp","%05d_DS_",tlbl1->key+100); @@ -6265,6 +6629,21 @@ static void genRightShift (iCode *ic) pic14_emitcode("","%05d_DS_:",tlbl1->key+100); pic14_emitcode("djnz","b,%05d_DS_",tlbl->key+100); aopPut(AOP(result),"a",0); +*/ + tlbl = newiTempLabel(NULL); + if (!pic14_sameRegs(AOP(left),AOP(result))) { + emitpcode(POC_MOVFW, popGet(AOP(left),0,FALSE,FALSE)); + emitpcode(POC_MOVWF, popGet(AOP(result),0,FALSE,FALSE)); + } + + emitpcode(POC_COMFW, popGet(AOP(right),0,FALSE,FALSE)); + emitpcode(POC_RLF, popGet(AOP(result),0,FALSE,FALSE)); + emitpLabel(tlbl->key+100+labelOffset); + emitpcode(POC_RRF, popGet(AOP(result),0,FALSE,FALSE)); + emitpcode(POC_ADDLW, popGetLit(1)); + emitSKPC; + emitpcode(POC_GOTO,popGetLabel(tlbl->key)); + goto release ; } @@ -6285,6 +6664,7 @@ static void genRightShift (iCode *ic) release: freeAsmop(left,NULL,ic,TRUE); + freeAsmop (right,NULL,ic,TRUE); freeAsmop(result,NULL,ic,TRUE); } @@ -7724,16 +8104,28 @@ static void genJumpTab (iCode *ic) /* multiply by three */ pic14_emitcode("add","a,acc"); pic14_emitcode("add","a,%s",aopGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE)); - freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE); jtab = newiTempLabel(NULL); pic14_emitcode("mov","dptr,#%05d_DS_",jtab->key+100); pic14_emitcode("jmp","@a+dptr"); pic14_emitcode("","%05d_DS_:",jtab->key+100); + + emitpcode(POC_MOVLW, popGetLabel(jtab->key)); + emitpcode(POC_ADDFW, popGet(AOP(IC_JTCOND(ic)),0,FALSE,FALSE)); + emitSKPNC; + emitpcode(POC_INCF, popCopyReg(&pc_pclath)); + emitpcode(POC_MOVWF, popCopyReg(&pc_pcl)); + emitpLabel(jtab->key+100+labelOffset); + + freeAsmop(IC_JTCOND(ic),NULL,ic,TRUE); + /* now generate the jump labels */ for (jtab = setFirstItem(IC_JTLABELS(ic)) ; jtab; - jtab = setNextItem(IC_JTLABELS(ic))) + jtab = setNextItem(IC_JTLABELS(ic))) { pic14_emitcode("ljmp","%05d_DS_",jtab->key+100); + emitpcode(POC_GOTO,popGetLabel(jtab->key)); + + } } diff --git a/src/pic/gen.h b/src/pic/gen.h index 3bb90fbe..8a17d33b 100644 --- a/src/pic/gen.h +++ b/src/pic/gen.h @@ -119,18 +119,18 @@ extern unsigned fReturnSizePic; /* Macros for emitting skip instructions */ /*-----------------------------------------------------------------*/ -#define emitSKPC emitpcode(POC_BTFSS,popCopyGPR2Bit(&pc_status,PIC_C_BIT)) -#define emitSKPNC emitpcode(POC_BTFSC,popCopyGPR2Bit(&pc_status,PIC_C_BIT)) -#define emitSKPZ emitpcode(POC_BTFSS,popCopyGPR2Bit(&pc_status,PIC_Z_BIT)) -#define emitSKPNZ emitpcode(POC_BTFSC,popCopyGPR2Bit(&pc_status,PIC_Z_BIT)) -#define emitSKPDC emitpcode(POC_BTFSS,popCopyGPR2Bit(&pc_status,PIC_DC_BIT)) -#define emitSKPNDC emitpcode(POC_BTFSC,popCopyGPR2Bit(&pc_status,PIC_DC_BIT)) -#define emitCLRZ emitpcode(POC_BCF, popCopyGPR2Bit(&pc_status,PIC_Z_BIT)) -#define emitCLRC emitpcode(POC_BCF, popCopyGPR2Bit(&pc_status,PIC_C_BIT)) -#define emitCLRDC emitpcode(POC_BCF, popCopyGPR2Bit(&pc_status,PIC_DC_BIT)) -#define emitSETZ emitpcode(POC_BSF, popCopyGPR2Bit(&pc_status,PIC_Z_BIT)) -#define emitSETC emitpcode(POC_BSF, popCopyGPR2Bit(&pc_status,PIC_C_BIT)) -#define emitSETDC emitpcode(POC_BSF, popCopyGPR2Bit(&pc_status,PIC_DC_BIT)) +#define emitSKPC emitpcode(POC_BTFSS,popCopyGPR2Bit(PCOP(&pc_status),PIC_C_BIT)) +#define emitSKPNC emitpcode(POC_BTFSC,popCopyGPR2Bit(PCOP(&pc_status),PIC_C_BIT)) +#define emitSKPZ emitpcode(POC_BTFSS,popCopyGPR2Bit(PCOP(&pc_status),PIC_Z_BIT)) +#define emitSKPNZ emitpcode(POC_BTFSC,popCopyGPR2Bit(PCOP(&pc_status),PIC_Z_BIT)) +#define emitSKPDC emitpcode(POC_BTFSS,popCopyGPR2Bit(PCOP(&pc_status),PIC_DC_BIT)) +#define emitSKPNDC emitpcode(POC_BTFSC,popCopyGPR2Bit(PCOP(&pc_status),PIC_DC_BIT)) +#define emitCLRZ emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_Z_BIT)) +#define emitCLRC emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_C_BIT)) +#define emitCLRDC emitpcode(POC_BCF, popCopyGPR2Bit(PCOP(&pc_status),PIC_DC_BIT)) +#define emitSETZ emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_Z_BIT)) +#define emitSETC emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_C_BIT)) +#define emitSETDC emitpcode(POC_BSF, popCopyGPR2Bit(PCOP(&pc_status),PIC_DC_BIT)) int pic14_getDataSize(operand *op); void emitpcode(PIC_OPCODE poc, pCodeOp *pcop); @@ -153,7 +153,7 @@ void genMinus (iCode *ic); pCodeOp *popGetLabel(unsigned int key); pCodeOp *popCopyReg(pCodeOpReg *pc); -pCodeOp *popCopyGPR2Bit(pCodeOpReg *pc, int bitval); +pCodeOp *popCopyGPR2Bit(pCodeOp *pc, int bitval); pCodeOp *popGetLit(unsigned int lit); pCodeOp *popGetWithString(char *str); pCodeOp *popRegFromString(char *str); diff --git a/src/pic/pcode.c b/src/pic/pcode.c index 95da354e..dd15d09c 100644 --- a/src/pic/pcode.c +++ b/src/pic/pcode.c @@ -37,42 +37,11 @@ pCodeOpReg pc_status = {{PO_STATUS, "STATUS"}, -1, NULL,NULL}; pCodeOpReg pc_indf = {{PO_INDF, "INDF"}, -1, NULL,NULL}; pCodeOpReg pc_fsr = {{PO_FSR, "FSR"}, -1, NULL,NULL}; +pCodeOpReg pc_pcl = {{PO_PCL, "PCL"}, -1, NULL,NULL}; +pCodeOpReg pc_pclath = {{PO_PCLATH, "PCLATH"}, -1, NULL,NULL}; static int mnemonics_initialized = 0; -#if 0 -//static char *PIC_mnemonics[] = { -static char *scpADDLW = "ADDLW"; -static char *scpADDWF = "ADDWF"; -static char *scpANDLW = "ANDLW"; -static char *scpANDWF = "ANDWF"; -static char *scpBCF = "BCF"; -static char *scpBSF = "BSF"; -static char *scpBTFSC = "BTFSC"; -static char *scpBTFSS = "BTFSS"; -static char *scpCALL = "CALL"; -static char *scpCOMF = "COMF"; -static char *scpCLRF = "CLRF"; -static char *scpCLRW = "CLRW"; -static char *scpDECF = "DECF"; -static char *scpDECFSZ = "DECFSZ"; -static char *scpGOTO = "GOTO"; -static char *scpINCF = "INCF"; -static char *scpINCFSZ = "INCFSZ"; -static char *scpIORLW = "IORLW"; -static char *scpIORWF = "IORWF"; -static char *scpMOVF = "MOVF"; -static char *scpMOVLW = "MOVLW"; -static char *scpMOVWF = "MOVWF"; -static char *scpNEGF = "NEGF"; -static char *scpRETLW = "RETLW"; -static char *scpRETURN = "RETURN"; -static char *scpSUBLW = "SUBLW"; -static char *scpSUBWF = "SUBWF"; -static char *scpTRIS = "TRIS"; -static char *scpXORLW = "XORLW"; -static char *scpXORWF = "XORWF"; -#endif static hTab *pic14MnemonicsHash = NULL; @@ -257,7 +226,6 @@ pCodeInstruction pciCALL = { PCC_NONE // outCond }; -//fixme - need a COMFW instruction. pCodeInstruction pciCOMF = { {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, genericAnalyze, @@ -267,9 +235,23 @@ pCodeInstruction pciCOMF = { "COMF", NULL, // operand 2, // num ops + 1,0, // dest, bit instruction + PCC_REGISTER, // inCond + PCC_REGISTER // outCond +}; + +pCodeInstruction pciCOMFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_COMFW, + "COMF", + NULL, // operand + 2, // num ops 0,0, // dest, bit instruction - PCC_NONE, // inCond - PCC_NONE // outCond + PCC_REGISTER, // inCond + PCC_W // outCond }; pCodeInstruction pciCLRF = { @@ -569,6 +551,62 @@ pCodeInstruction pciRETURN = { }; +pCodeInstruction pciRLF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_RLF, + "RLF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + (PCC_C | PCC_REGISTER), // inCond + (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond +}; + +pCodeInstruction pciRLFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_RLFW, + "RLF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + (PCC_C | PCC_REGISTER), // inCond + (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond +}; + +pCodeInstruction pciRRF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_RRF, + "RRF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + (PCC_C | PCC_REGISTER), // inCond + (PCC_REGISTER | PCC_Z | PCC_C | PCC_DC) // outCond +}; + +pCodeInstruction pciRRFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_RRFW, + "RRF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + (PCC_C | PCC_REGISTER), // inCond + (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond +}; + pCodeInstruction pciSUBWF = { {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, genericAnalyze, @@ -611,6 +649,33 @@ pCodeInstruction pciSUBLW = { (PCC_W | PCC_Z | PCC_C | PCC_DC) // outCond }; +pCodeInstruction pciSWAPF = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_SWAPF, + "SWAPF", + NULL, // operand + 2, // num ops + 1,0, // dest, bit instruction + (PCC_REGISTER), // inCond + (PCC_REGISTER) // outCond +}; + +pCodeInstruction pciSWAPFW = { + {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, + genericAnalyze, + genericDestruct, + genericPrint}, + POC_SWAPFW, + "SWAPF", + NULL, // operand + 2, // num ops + 0,0, // dest, bit instruction + (PCC_REGISTER), // inCond + (PCC_W) // outCond +}; pCodeInstruction pciTRIS = { {PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL, genericAnalyze, @@ -775,6 +840,7 @@ void pic14initMnemonics(void) pic14Mnemonics[POC_BTFSS] = &pciBTFSS; pic14Mnemonics[POC_CALL] = &pciCALL; pic14Mnemonics[POC_COMF] = &pciCOMF; + pic14Mnemonics[POC_COMFW] = &pciCOMFW; pic14Mnemonics[POC_CLRF] = &pciCLRF; pic14Mnemonics[POC_CLRW] = &pciCLRW; pic14Mnemonics[POC_DECF] = &pciDECF; @@ -796,9 +862,15 @@ void pic14initMnemonics(void) pic14Mnemonics[POC_NEGF] = &pciNEGF; pic14Mnemonics[POC_RETLW] = &pciRETLW; pic14Mnemonics[POC_RETURN] = &pciRETURN; + pic14Mnemonics[POC_RLF] = &pciRLF; + pic14Mnemonics[POC_RLFW] = &pciRLFW; + pic14Mnemonics[POC_RRF] = &pciRRF; + pic14Mnemonics[POC_RRFW] = &pciRRFW; pic14Mnemonics[POC_SUBLW] = &pciSUBLW; pic14Mnemonics[POC_SUBWF] = &pciSUBWF; pic14Mnemonics[POC_SUBFW] = &pciSUBFW; + pic14Mnemonics[POC_SWAPF] = &pciSWAPF; + pic14Mnemonics[POC_SWAPFW] = &pciSWAPFW; pic14Mnemonics[POC_TRIS] = &pciTRIS; pic14Mnemonics[POC_XORLW] = &pciXORLW; pic14Mnemonics[POC_XORWF] = &pciXORWF; @@ -1126,7 +1198,7 @@ static void pCodeLabelDestruct(pCode *pc) unlinkPC(pc); - if(PCL(pc)->label) + if((pc->type == PC_LABEL) && PCL(pc)->label) free(PCL(pc)->label); free(pc); @@ -1279,7 +1351,7 @@ pCodeOp *newpCodeOpWild(int id, pCodePeep *pcp, pCodeOp *subtype) return pcop; } -pCodeOp *newpCodeOpBit(char *s, int bit) +pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace) { pCodeOp *pcop; @@ -1288,10 +1360,20 @@ pCodeOp *newpCodeOpBit(char *s, int bit) pcop->name = Safe_strdup(s); PCOB(pcop)->bit = bit; - if(bit>=0) - PCOB(pcop)->inBitSpace = 1; - else - PCOB(pcop)->inBitSpace = 0; + PCOB(pcop)->inBitSpace = inBitSpace; + + return pcop; +} + +pCodeOp *newpCodeOpReg(int rIdx) +{ + pCodeOp *pcop; + + pcop = Safe_calloc(1,sizeof(pCodeOpReg) ); + + PCOR(pcop)->rIdx = rIdx; + PCOR(pcop)->r = pic14_regWithIdx(rIdx); + pcop->type = PCOR(pcop)->r->pc_type; return pcop; } @@ -1305,7 +1387,7 @@ pCodeOp *newpCodeOp(char *name, PIC_OPTYPE type) switch(type) { case PO_BIT: - pcop = newpCodeOpBit(name, -1); + pcop = newpCodeOpBit(name, -1,0); break; case PO_LITERAL: @@ -1409,10 +1491,16 @@ void printpBlock(FILE *of, pBlock *pb) static void unlinkPC(pCode *pc) { - if(pc && pc->prev && pc->next) { - pc->prev->next = pc->next; - pc->next->prev = pc->prev; + + if(pc) { + + if(pc->prev) + pc->prev->next = pc->next; + if(pc->next) + pc->next->prev = pc->prev; + + pc->prev = pc->next = NULL; } } static void genericDestruct(pCode *pc) @@ -1449,6 +1537,7 @@ static char *get_op( pCodeInstruction *pcc) case PO_FSR: case PO_GPR_TEMP: + case PO_GPR_BIT: r = pic14_regWithIdx(PCOR(pcc->pcop)->r->rIdx); //fprintf(stderr,"getop: getting %s\nfrom:\n",r->name); //pcc->pcop->name); pBlockRegs(stderr,pcc->pc.pb); @@ -1493,7 +1582,9 @@ char *pCode2str(char *str, int size, pCode *pc) else SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)), (((pCodeOpBit *)(PCI(pc)->pcop))->bit )); - } else + } else if(PCI(pc)->pcop->type == PO_GPR_BIT) { + SAFE_snprintf(&s,&size,"%s,%d", get_op(PCI(pc)),PCORB(PCI(pc)->pcop)->bit); + }else SAFE_snprintf(&s,&size,"%s,0 ; ?bug", get_op(PCI(pc))); //PCI(pc)->pcop->t.bit ); } else { @@ -1664,6 +1755,22 @@ static void pCodePrintLabel(FILE *of, pCode *pc) } /*-----------------------------------------------------------------*/ +static void unlinkpCodeFromBranch(pBranch *pb , pCode *pc) +{ + pBranch *b, *bprev; + + bprev = NULL; + b = pb; + while(b) { + if(b->pc == pc) { + if(bprev) + bprev->next = b->next; + } + bprev = b; + b = b->next; + } + +} static pBranch * pBranchAppend(pBranch *h, pBranch *n) { @@ -1799,6 +1906,29 @@ static void genericAnalyze(pCode *pc) } } +/*-----------------------------------------------------------------*/ +int compareLabel(pCode *pc, pCodeOpLabel *pcop_label) +{ + pBranch *pbr; + + if(pc->type == PC_LABEL) { + if( ((pCodeLabel *)pc)->key == pcop_label->key) + return TRUE; + } + if(pc->type == PC_OPCODE) { + pbr = pc->label; + while(pbr) { + if(pbr->pc->type == PC_LABEL) { + if( ((pCodeLabel *)(pbr->pc))->key == pcop_label->key) + return TRUE; + } + pbr = pbr->next; + } + } + + return FALSE; +} + /*-----------------------------------------------------------------*/ /* findLabel - Search the pCode for a particular label */ /*-----------------------------------------------------------------*/ @@ -1806,29 +1936,15 @@ pCode * findLabel(pCodeOpLabel *pcop_label) { pBlock *pb; pCode *pc; - pBranch *pbr; if(!the_pFile) return NULL; for(pb = the_pFile->pbHead; pb; pb = pb->next) { - for(pc = pb->pcHead; pc; pc = pc->next) { - if(pc->type == PC_LABEL) { - if( ((pCodeLabel *)pc)->key == pcop_label->key) - return pc; - } - if(pc->type == PC_OPCODE) { - pbr = pc->label; - while(pbr) { - if(pbr->pc->type == PC_LABEL) { - if( ((pCodeLabel *)(pbr->pc))->key == pcop_label->key) - return pc; - } - pbr = pbr->next; - } - } - - } + for(pc = pb->pcHead; pc; pc = pc->next) + if(compareLabel(pc,pcop_label)) + return pc; + } fprintf(stderr,"Couldn't find label %s", pcop_label->pcop.name); @@ -1954,14 +2070,79 @@ int OptimizepBlock(pBlock *pb) if(!pb || !peepOptimizing) return 0; - fprintf(stderr," Optimizing pBlock\n"); - + fprintf(stderr," Optimizing pBlock: %c\n",getpBlock_dbName(pb)); for(pc = pb->pcHead; pc; pc = pc->next) matches += pCodePeepMatchRule(pc); return matches; } + +/*-----------------------------------------------------------------*/ +/* pBlockRemoveUnusedLabels - remove the pCode labels from the */ +/*-----------------------------------------------------------------*/ +pCode * findInstructionUsingLabel(pCodeLabel *pcl, pCode *pcs) +{ + pCode *pc; + + for(pc = pcs; pc; pc = pc->next) { + + if((pc->type == PC_OPCODE) && + (PCI(pc)->pcop) && + (PCI(pc)->pcop->type == PO_LABEL) && + (PCOLAB(PCI(pc)->pcop)->key == pcl->key)) + return pc; + } + + + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* pBlockRemoveUnusedLabels - remove the pCode labels from the */ +/* pCode chain if they're not used. */ +/*-----------------------------------------------------------------*/ +void pBlockRemoveUnusedLabels(pBlock *pb) +{ + pCode *pc; pCodeLabel *pcl; + + if(!pb) + return; + + for(pc = pb->pcHead; pc; pc = pc->next) { + + if(pc->type == PC_LABEL) + pcl = PCL(pc); + else if (pc->label) + pcl = PCL(pc->label->pc); + else continue; + + /* This pCode is a label, so search the pBlock to see if anyone + * refers to it */ + + if( (pcl->key>0) && (!findInstructionUsingLabel(pcl, pb->pcHead))) { + /* Couldn't find an instruction that refers to this label + * So, unlink the pCode label from it's pCode chain + * and destroy the label */ + + fprintf(stderr," !!! REMOVED A LABEL !!! key = %d\n", pcl->key); + + if(pc->type == PC_LABEL) { + //unlinkPC(pc); + pCodeLabelDestruct(pc); + } else { + unlinkpCodeFromBranch(pc->label, pc); + if(pc->label->next == NULL && pc->label->pc == NULL) { + free(pc->label); + } + } + + } + } + +} + + /*-----------------------------------------------------------------*/ /* pBlockMergeLabels - remove the pCode labels from the pCode */ /* chain and put them into pBranches that are */ @@ -1976,18 +2157,22 @@ void pBlockMergeLabels(pBlock *pb) if(!pb) return; + /* First, Try to remove any unused labels */ + //pBlockRemoveUnusedLabels(pb); + + /* Now loop through the pBlock and merge the labels with the opcodes */ + for(pc = pb->pcHead; pc; pc = pc->next) { if(pc->type == PC_LABEL) { + fprintf(stderr,"Checking label key = %d\n",PCL(pc)->key); if( !(pcnext = findNextInstruction(pc)) ) return; // Couldn't find an instruction associated with this label // Unlink the pCode label from it's pCode chain - if(pc->prev) - pc->prev->next = pc->next; - if(pc->next) - pc->next->prev = pc->prev; + unlinkPC(pc); + fprintf(stderr,"Merged label key = %d\n",PCL(pc)->key); // And link it into the instruction's pBranch labels. (Note, since // it's possible to have multiple labels associated with one instruction // we must provide a means to accomodate the additional labels. Thus @@ -1999,9 +2184,14 @@ void pBlockMergeLabels(pBlock *pb) pbr->next = NULL; pcnext->label = pBranchAppend(pcnext->label,pbr); + if(pcnext->prev) + pc = pcnext->prev; + else + pc = pcnext; } } + pBlockRemoveUnusedLabels(pb); } @@ -2052,6 +2242,8 @@ void AnalyzepCode(char dbName) /* First, merge the labels with the instructions */ for(pb = the_pFile->pbHead; pb; pb = pb->next) { if('*' == dbName || getpBlock_dbName(pb) == dbName) { + + fprintf(stderr," analyze and merging block %c\n",dbName); pBlockMergeLabels(pb); AnalyzepBlock(pb); } diff --git a/src/pic/pcode.h b/src/pic/pcode.h index 4f2afc36..1d5961eb 100644 --- a/src/pic/pcode.h +++ b/src/pic/pcode.h @@ -105,8 +105,11 @@ typedef enum PO_FSR, // The "file select register" (in 18c it's one of three) PO_INDF, // The Indirect register PO_GPR_REGISTER, // A general purpose register + PO_GPR_BIT, // A bit of a general purpose register PO_GPR_TEMP, // A general purpose temporary register PO_SFR_REGISTER, // A special function register (e.g. PORTA) + PO_PCL, // Program counter Low register + PO_PCLATH, // Program counter Latch high register PO_LITERAL, // A constant PO_IMMEDIATE, // (8051 legacy) PO_DIR, // Direct memory (8051 legacy) @@ -174,6 +177,7 @@ typedef enum POC_BTFSS, POC_CALL, POC_COMF, + POC_COMFW, POC_CLRF, POC_CLRW, POC_DECF, @@ -195,9 +199,15 @@ typedef enum POC_NEGF, POC_RETLW, POC_RETURN, + POC_RLF, + POC_RLFW, + POC_RRF, + POC_RRFW, POC_SUBLW, POC_SUBWF, POC_SUBFW, + POC_SWAPF, + POC_SWAPFW, POC_TRIS, POC_XORLW, POC_XORWF, @@ -296,6 +306,12 @@ typedef struct pCodeOpReg struct pBlock *pb; } pCodeOpReg; +typedef struct pCodeOpRegBit +{ + pCodeOpReg pcor; // The Register containing this bit + int bit; // 0-7 bit number. + PIC_OPTYPE subtype; // The type of this register. +} pCodeOpRegBit; /************************************************* @@ -550,6 +566,7 @@ typedef struct pCodeOpWild #define PCOL(x) ((pCodeOpLit *)(x)) #define PCOLAB(x) ((pCodeOpLabel *)(x)) #define PCOR(x) ((pCodeOpReg *)(x)) +#define PCORB(x) ((pCodeOpRegBit *)(x)) #define PCOW(x) ((pCodeOpWild *)(x)) #define PBR(x) ((pBranch *)(x)) @@ -577,7 +594,7 @@ void pCodePeepInit(void); pCodeOp *newpCodeOpLabel(int key); pCodeOp *newpCodeOpLit(int lit); -pCodeOp *newpCodeOpBit(char *name, int bit); +pCodeOp *newpCodeOpBit(char *name, int bit,int inBitSpace); pCodeOp *newpCodeOp(char *name, PIC_OPTYPE p); extern void pcode_test(void); @@ -588,6 +605,8 @@ extern void pcode_test(void); extern pCodeOpReg pc_status; extern pCodeOpReg pc_indf; extern pCodeOpReg pc_fsr; +extern pCodeOpReg pc_pcl; +extern pCodeOpReg pc_pclath; //////////////////// DELETE THIS /////////////////// diff --git a/src/pic/pcodepeep.c b/src/pic/pcodepeep.c index c51bcb42..e23e667c 100644 --- a/src/pic/pcodepeep.c +++ b/src/pic/pcodepeep.c @@ -443,7 +443,7 @@ static void * cvt_altpat_mnem1a(void *pp) } if(pic14Mnemonics[opcode]->bit_inst) - pcosubtype = newpCodeOpBit(NULL,-1); + pcosubtype = newpCodeOpBit(NULL,-1,0); else pcosubtype = newpCodeOp(NULL,PO_GPR_REGISTER); @@ -1367,7 +1367,7 @@ void pCodePeepInit(void) pCodeOp *pcwb; // Create a new wild operand subtyped as a bit - pcwb = newpCodeOpWild(0,pcp,newpCodeOpBit(NULL,-1)); + pcwb = newpCodeOpWild(0,pcp,newpCodeOpBit(NULL,-1,0)); // Create a pb = newpCodeChain(NULL, 'W',newpCode(POC_BTFSC,pcwb)); @@ -1477,7 +1477,30 @@ int pCodeSearchCondition(pCode *pc, unsigned int cond) /*-----------------------------------------------------------------*/ /* pCodePeepMatchLine - Compare source and destination pCodes to */ /* see they're the same. */ +/* */ +/* In this context, "source" refers to the coded generated by gen.c*/ +/* and "destination" refers to a pcode in a peep rule. If the dest-*/ +/* ination has no wild cards, then MatchLine will compare the two */ +/* pcodes (src and dest) for a one-to-one match. If the destination*/ +/* has wildcards, then those get expanded. When a wild card is */ +/* encountered for the first time it autmatically is considered a */ +/* match and the object that matches it is referenced in the */ +/* variables or opcodes array (depending on the type of match). */ +/* */ +/* */ +/* Inputs: */ +/* *peepBlock - A pointer to the peepBlock that contains the */ +/* entire rule to which the destination pcode belongs*/ +/* *pcs - a pointer to the source pcode */ +/* *pcd - a pointer to the destination pcode */ +/* */ +/* Returns: */ +/* 1 - pcodes match */ +/* 0 - pcodes don't match */ +/* */ +/* */ /*-----------------------------------------------------------------*/ + int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) { int index; // index into wild card arrays @@ -1524,11 +1547,14 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) if(peepBlock->vars[index]) return (strcmp(peepBlock->vars[index],n) == 0); else { + fprintf(stderr,"first time for a variable: %d, %s\n",index,n); peepBlock->vars[index] = n; //PCI(pcs)->pcop->name; return 1; } } } + /* FIXME - need an else to check the case when the destination + * isn't a wild card */ } else /* The pcd has no operand. Lines match if pcs has no operand either*/ return (PCI(pcs)->pcop == NULL); @@ -1557,12 +1583,13 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) return 0; pcl = pcd->label->pc; - - labindex = PCOW(pcl)->id; + //labindex = PCOW(pcl)->id; + labindex = -PCL(pcl)->key; + fprintf(stderr,"label id = %d (labindex = %d)\n",PCL(pcl)->key,labindex); if(peepBlock->vars[labindex] == NULL) { // First time to encounter this label peepBlock->vars[labindex] = PCL(pcs->label->pc)->label; - fprintf(stderr,"first time for a label\n"); + fprintf(stderr,"first time for a label: %d %s\n",labindex, peepBlock->vars[labindex]); } else { if(strcmp(peepBlock->vars[labindex],PCL(pcs->label->pc)->label) != 0) { fprintf(stderr,"labels don't match\n"); @@ -1596,6 +1623,9 @@ int pCodePeepMatchLine(pCodePeep *peepBlock, pCode *pcs, pCode *pcd) if(pcs) { fprintf(stderr," (next to match)\n"); pcs->print(stderr,pcs); + } else if(pcd->next) { + /* oops, we ran out of code, but there's more to the rule */ + return 0; } return 1; /* wild card matches */ @@ -1690,6 +1720,7 @@ static pCodeOp *pCodeOpCopy(pCodeOp *pcop) case PO_GPR_REGISTER: case PO_GPR_TEMP: + case PO_GPR_BIT: fprintf(stderr,"pCodeOpCopy GPR register\n"); pcopnew = Safe_calloc(1,sizeof(pCodeOpReg) ); PCOR(pcopnew)->r = PCOR(pcop)->r; @@ -1706,6 +1737,8 @@ static pCodeOp *pCodeOpCopy(pCodeOp *pcop) case PO_STATUS: case PO_FSR: case PO_INDF: + case PO_PCL: + case PO_PCLATH: fprintf(stderr,"pCodeOpCopy register type %d\n", pcop->type); pcopnew = Safe_calloc(1,sizeof(pCodeOp) ); @@ -1784,7 +1817,7 @@ int pCodePeepMatchRule(pCode *pc) fprintf(stderr," end of rule\n"); } - if(matched && pcin) { + if(matched) { /* So far we matched the rule up to the point of the conditions . * In other words, all of the opcodes match. Now we need to see @@ -1795,12 +1828,12 @@ int pCodePeepMatchRule(pCode *pc) * the `postFalseCond' as input then we abort the match */ fprintf(stderr," matched rule so far, now checking conditions\n"); - if (peepBlock->postFalseCond && + if (pcin && peepBlock->postFalseCond && (pCodeSearchCondition(pcin,peepBlock->postFalseCond) > 0) ) matched = 0; } - if(matched && pcin) { + if(matched) { pCode *pcprev; pCode *pcr; @@ -1813,13 +1846,16 @@ int pCodePeepMatchRule(pCode *pc) printpCodeString(stderr,peepBlock->target->pcHead,10); fprintf(stderr,"first thing matched\n"); pc->print(stderr,pc); - fprintf(stderr,"last thing matched\n"); - pcin->print(stderr,pcin); + if(pcin) { + fprintf(stderr,"last thing matched\n"); + pcin->print(stderr,pcin); + } /* Unlink the original code */ pcprev = pc->prev; pcprev->next = pcin; - pcin->prev = pc->prev; + if(pcin) + pcin->prev = pc->prev; { /* DEBUG */ @@ -1838,7 +1874,8 @@ int pCodePeepMatchRule(pCode *pc) } } - pCodeDeleteChain(pc,pcin); + if(pcin) + pCodeDeleteChain(pc,pcin); /* Generate the replacement code */ pc = pcprev; @@ -1871,7 +1908,8 @@ int pCodePeepMatchRule(pCode *pc) pc = pc->next; - pc->print(stderr,pc); + if(pc) + pc->print(stderr,pc); pcr = pcr->next; } diff --git a/src/regression/Makefile b/src/regression/Makefile index a0d97077..a2bd9a2a 100644 --- a/src/regression/Makefile +++ b/src/regression/Makefile @@ -62,9 +62,14 @@ SRC = b.c \ compare2.c \ compare3.c \ for.c \ + rotate1.c \ + rotate2.c \ + rotate3.c \ struct1.c \ sub.c \ - while.c + switch1.c \ + while.c \ + xor.c COD := $(patsubst %.c, %.cod, $(SRC)) ASM := $(patsubst %.c, %.asm, $(SRC)) diff --git a/src/regression/compare3.c b/src/regression/compare3.c index ce91b6b9..4cc21613 100644 --- a/src/regression/compare3.c +++ b/src/regression/compare3.c @@ -190,6 +190,19 @@ void c_abcd(void) } +// assumes achar1 == 0 +void c_ifelse1(void) +{ + + if(achar0) + achar0 = achar1; + else + achar0 = 0; + + if(achar0) + failures++; +} + void main (void) { @@ -214,6 +227,13 @@ main (void) aint0 = 0xabcd; c_abcd(); + achar0 = 0; + achar1 = 0; + c_ifelse1(); + + achar0 = 1; + c_ifelse1(); + success = failures; done (); } diff --git a/src/regression/rotate1.c b/src/regression/rotate1.c new file mode 100644 index 00000000..2402a500 --- /dev/null +++ b/src/regression/rotate1.c @@ -0,0 +1,211 @@ +// Shift bytes left and right by a constant. + +unsigned char success=0; +unsigned char failures=0; +unsigned char dummy=0; + +bit bit0 = 0; +unsigned int aint0 = 0; +unsigned int aint1 = 0; +unsigned char achar0 = 0; +unsigned char achar1 = 0; +unsigned char achar2 = 0; + +void done() +{ + + dummy++; + +} + +void check(void) +{ + if(achar0 != achar1) + failures++; +} + +void shift_left_1(void) +{ + + achar0 <<= 1; + + check(); +} + +void shift_left_2(void) +{ + + achar0 <<= 2; + + if(achar0 != achar1) + failures++; +} + + +void shift_left_3(void) +{ + + achar0 <<= 3; + + if(achar0 != achar1) + failures++; +} + +void shift_left_4(void) +{ + + achar0 <<= 4; + + if(achar0 != achar1) + failures++; +} + +void shift_left_5(void) +{ + + achar0 <<= 5; + + if(achar0 != achar1) + failures++; +} + +void shift_left_6(void) +{ + + achar0 <<= 6; + + if(achar0 != achar1) + failures++; +} + +void shift_left_7(void) +{ + + achar0 <<= 7; + + if(achar0 != achar1) + failures++; +} + +void shift_right_1(void) +{ + + achar0 >>= 1; + + check(); +} + +void shift_right_2(void) +{ + + achar0 >>= 2; + + check(); +} + +void shift_right_3(void) +{ + + achar0 >>= 3; + + check(); +} + +void shift_right_4(void) +{ + + achar0 >>= 4; + + check(); +} + +void shift_right_5(void) +{ + + achar0 >>= 5; + + check(); +} + +void shift_right_6(void) +{ + + achar0 >>= 6; + + check(); +} + +void shift_right_7(void) +{ + + achar0 >>= 7; + + check(); +} + + +void main(void) +{ + + // call with both values zero + shift_left_1(); + + achar0 = 1; + achar1 = 2; + for(achar2=0; achar2<6; achar2++) { + shift_left_1(); + achar1 <<=1; + } + + achar0 = 1; + achar1 = 4; + shift_left_2(); + + achar0 = 1; + achar1 = 8; + shift_left_3(); + + achar0 = 1; + achar1 = 0x10; + shift_left_4(); + + achar0 = 1; + achar1 = 0x20; + shift_left_5(); + + achar0 = 1; + achar1 = 0x40; + shift_left_6(); + + achar0 = 1; + achar1 = 0x80; + shift_left_7(); + + + + + achar0 = 2; + achar1 = 1; + shift_right_1(); + + achar0 = 4; + shift_right_2(); + + achar0 = 8; + shift_right_3(); + + achar0 = 0x10; + shift_right_4(); + + achar0 = 0x20; + shift_right_5(); + + achar0 = 0x40; + shift_right_6(); + + achar0 = 0x80; + shift_right_7(); + + success=failures; + done(); +} diff --git a/src/regression/rotate2.c b/src/regression/rotate2.c new file mode 100644 index 00000000..7891534a --- /dev/null +++ b/src/regression/rotate2.c @@ -0,0 +1,65 @@ +// Shift bytes left and right by a variable. + +unsigned char success=0; +unsigned char failures=0; +unsigned char dummy=0; + +bit bit0 = 0; +unsigned int aint0 = 0; +unsigned int aint1 = 0; +unsigned char achar0 = 0; +unsigned char achar1 = 0; +unsigned char achar2 = 0; +unsigned char achar3 = 0; + +void done() +{ + + dummy++; + +} + +void shift_right_var(void) +{ + + achar0 >>= achar1; +} + +void shift_left_var(void) +{ + + achar0 <<= achar1; +} + +void shift_int_left_1(void) +{ + + aint0 <<= 1; + +} + +void main(void) +{ + char i; + + achar0 = 1; + achar1 = 1; + shift_left_var(); + + if(achar0 !=2) + failures++; + + achar0 = 1; + achar1 = 1; + achar2 = 1; + for(i=0; i<7; i++) { + shift_left_var(); + achar2 <<= 1; + + if(achar2 != achar0) + failures++; + } + + success=failures; + done(); +} diff --git a/src/regression/rotate3.c b/src/regression/rotate3.c new file mode 100644 index 00000000..f0f5330f --- /dev/null +++ b/src/regression/rotate3.c @@ -0,0 +1,232 @@ +// Shift ints left and right + +unsigned char success=0; +unsigned char failures=0; +unsigned char dummy=0; + +bit bit0 = 0; +unsigned int aint0 = 0; +unsigned int aint1 = 0; +unsigned char achar0 = 0; +unsigned char achar1 = 0; +unsigned char achar2 = 0; +unsigned char achar3 = 0; + +void done() +{ + + dummy++; + +} + +void shift_int_left_1(void) +{ + + aint0 <<= 1; + +} + +void shift_int_left_2(void) +{ + + aint0 <<= 2; + +} + +void shift_int_left_3(void) +{ + + aint0 <<= 3; + +} + +void shift_int_left_4(void) +{ + + aint0 <<= 4; + +} + +void shift_int_left_5(void) +{ + + aint0 <<= 5; + +} + +void shift_int_left_6(void) +{ + + aint0 <<= 6; + +} + +void shift_int_left_7(void) +{ + + aint0 <<= 7; + +} + +void shift_int_left_8(void) +{ + + aint0 <<= 8; + +} + +void shift_int_left_9(void) +{ + + aint0 <<= 9; + +} + +void shift_int_left_10(void) +{ + + aint0 <<= 10; + +} + +void shift_int_left_11(void) +{ + + aint0 <<= 11; + +} + +void shift_int_left_12(void) +{ + + aint0 <<= 12; + +} + +void shift_int_left_13(void) +{ + + aint0 <<= 13; + +} + +void shift_int_left_14(void) +{ + + aint0 <<= 14; + +} + +void shift_int_left_15(void) +{ + + aint0 <<= 15; + +} + +/*****************************************************/ +void shift_int_right_1(void) +{ + + aint0 >>= 1; + +} + +/*****************************************************/ +void main(void) +{ + char i; + + aint0 = 0xabcd; + + shift_int_left_1(); + if(aint0 != 0x579a) + failures++; + + aint0 = 0xabcd; + + shift_int_left_2(); + if(aint0 != 0xaf34) + failures++; + + aint0 = 0xabcd; + + shift_int_left_3(); + if(aint0 != 0x5e68) + failures++; + + aint0 = 0xabcd; + + shift_int_left_4(); + if(aint0 != 0xbcd0) + failures++; + + aint0 = 0xabcd; + + shift_int_left_5(); + if(aint0 != 0x79a0) + failures++; + + aint0 = 0xabcd; + + shift_int_left_6(); + if(aint0 != 0xf340) + failures++; + + aint0 = 0xabcd; + + shift_int_left_7(); + if(aint0 != 0xe680) + failures++; + + aint0 = 0xabcd; + + shift_int_left_8(); + if(aint0 != 0xcd00) + failures++; + + aint0 = 0xabcd; + + shift_int_left_9(); + if(aint0 != 0x9a00) + failures++; + + aint0 = 0xabcd; + + shift_int_left_10(); + if(aint0 != 0x3400) + failures++; + + aint0 = 0xabcd; + + shift_int_left_11(); + if(aint0 != 0x6800) + failures++; + + aint0 = 0xabcd; + + shift_int_left_12(); + if(aint0 != 0xd000) + failures++; + + aint0 = 0xabcd; + + shift_int_left_13(); + if(aint0 != 0xa000) + failures++; + + aint0 = 0xabcd; + + shift_int_left_14(); + if(aint0 != 0x4000) + failures++; + + aint0 = 0xabcd; + + shift_int_left_15(); + if(aint0 != 0x8000) + failures++; + + success=failures; + done(); +} diff --git a/src/regression/xor.c b/src/regression/xor.c new file mode 100644 index 00000000..5e77a2a3 --- /dev/null +++ b/src/regression/xor.c @@ -0,0 +1,58 @@ +unsigned char success=0; +unsigned char failures=0; +unsigned char dummy=0; + +unsigned char achar0 = 0; +unsigned char achar1 = 0; +unsigned char achar2 = 0; + +void done() +{ + + dummy++; + +} + +void xor_chars_0_1(void) +{ + + achar2 = achar0 ^ achar1; + + achar0 = achar0 ^ 0x1; + + achar1 = achar0 ^ achar1 ^ 4; +} + +void xor_if(void) +{ + + if(achar0 ^ achar1) + failures++; + + achar0 ^= 0xff; + + if( !(achar0 ^ achar1) ) + failures++; + +} + +void main(void) +{ + + xor_chars_0_1(); + + if(achar2) + failures++; + + if(achar0 != 1) + failures++; + + if(achar1 != 5) + failures++; + + achar0 = achar1; + xor_if(); + + success = failures; + done(); +}