static int labelOffset=0;
static int debug_verbose=1;
+static int optimized_for_speed = 0;
unsigned int pic14aopLiteral (value *val, int offset);
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;
}
/* 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 ;
}
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;
/*-----------------------------------------------------------------*/
/* 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;
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;
}
case AOP_CRY:
- pcop = newpCodeOpBit(aop->aopu.aop_dir,0);
+ pcop = newpCodeOpBit(aop->aopu.aop_dir,-1,1);
return pcop;
case AOP_LIT:
/* 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);
+ }
}
//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);
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/* 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)
{
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));
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));
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);
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);
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:
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));
}
}
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);
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));
}
}
}
/* 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));
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));
// 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));
+ }
}
}
}
}
+#if 0
/*-----------------------------------------------------------------*/
/* AccSRsh - signed right shift accumulator by known count */
/*-----------------------------------------------------------------*/
}
}
}
+#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 */
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
}
/*-----------------------------------------------------------------*/
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);
+ }
+
}
/*-----------------------------------------------------------------*/
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);
pic14_emitcode("xch","a,%s",x);
pic14_emitcode("rlc","a");
}
-
+#if 0
/*-----------------------------------------------------------------*/
/* AccAXLsh1 - left shift a:x<-0 by 1 */
/*-----------------------------------------------------------------*/
pic14_emitcode("xch","a,%s",x);
pic14_emitcode("rlc","a");
}
-
+#endif
+#if 0
/*-----------------------------------------------------------------*/
/* AccAXLsh - left shift a:x by known count (0..7) */
/*-----------------------------------------------------------------*/
break;
}
}
-
+#endif
/*-----------------------------------------------------------------*/
/* AccAXRsh - right shift a:x known count (0..7) */
/*-----------------------------------------------------------------*/
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 */
/*-----------------------------------------------------------------*/
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);
+ }
}
/*-----------------------------------------------------------------*/
else
movLeft2Result(left, LSB, result, MSB16, 0);
}
- aopPut(AOP(result),zero,LSB);
+ emitpcode(POC_CLRF,popGet(AOP(result),LSB,FALSE,FALSE));
}
/* 1 <= shCount <= 7 */
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);
}
}
- 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);
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);
}
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);
/* 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);
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 ;
}
release:
freeAsmop(left,NULL,ic,TRUE);
+ freeAsmop (right,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
}
/* 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));
+
+ }
}
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;
PCC_NONE // outCond
};
-//fixme - need a COMFW instruction.
pCodeInstruction pciCOMF = {
{PC_OPCODE, NULL, NULL, 0, NULL, NULL, NULL, NULL,
genericAnalyze,
"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 = {
};
+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,
(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,
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;
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;
unlinkPC(pc);
- if(PCL(pc)->label)
+ if((pc->type == PC_LABEL) && PCL(pc)->label)
free(PCL(pc)->label);
free(pc);
return pcop;
}
-pCodeOp *newpCodeOpBit(char *s, int bit)
+pCodeOp *newpCodeOpBit(char *s, int bit, int inBitSpace)
{
pCodeOp *pcop;
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;
}
switch(type) {
case PO_BIT:
- pcop = newpCodeOpBit(name, -1);
+ pcop = newpCodeOpBit(name, -1,0);
break;
case PO_LITERAL:
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)
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);
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 {
}
/*-----------------------------------------------------------------*/
+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)
{
}
}
+/*-----------------------------------------------------------------*/
+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 */
/*-----------------------------------------------------------------*/
{
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);
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 */
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
pbr->next = NULL;
pcnext->label = pBranchAppend(pcnext->label,pbr);
+ if(pcnext->prev)
+ pc = pcnext->prev;
+ else
+ pc = pcnext;
}
}
+ pBlockRemoveUnusedLabels(pb);
}
/* 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);
}