unsigned fReturnSizePic = 4; /* shared with ralloc.c */
static char **fReturn = fReturnpic14;
-static char *accUse[] = {"a","b"};
+//static char *accUse[] = {"a","b"};
//static short rbank = -1;
{
va_list ap;
char lb[INITIAL_INLINEASM];
- char *lbp = lb;
+ unsigned char *lbp = lb;
if(!debug_verbose && !options.debug)
return;
addpCode2pBlock(pb,newpCodeLabel(NULL,key+100+labelOffset));
}
-void emitpcode(PIC_OPCODE poc, pCodeOp *pcop)
+/* gen.h defines a macro emitpcode that should be used to call emitpcode
+ * as this allows for easy debugging (ever asked the question: where was
+ * this instruction geenrated? Here is the answer... */
+void emitpcode_real(PIC_OPCODE poc, pCodeOp *pcop)
{
if(pcop)
addpCode2pBlock(pb,newpCode(poc,pcop));
{
va_list ap;
char lb[INITIAL_INLINEASM];
- char *lbp = lb;
+ unsigned char *lbp = lb;
va_start(ap,fmt);
resIfx->generated = 0; /* indicate that the ifx has not been used */
if(!ifx) {
- resIfx->lbl = newiTempLabel(NULL); /* oops, there is no ifx. so create a label */
+ resIfx->lbl = NULL; /* this is wrong: newiTempLabel(NULL); / * oops, there is no ifx. so create a label */
/*
DEBUGpic14_emitcode("; ***","%s %d null ifx creating new label key =%d",
__FUNCTION__,__LINE__,resIfx->lbl->key);
return;
}
+#if 0
+ /* WREG is not usable as an ordinary operand with PIC architecture,
+ * one might introduce a scratch register that can be used to make
+ * WREG accesible as an operand... disable WREG for now */
if (sym->accuse) {
int i;
aop = op->aop = sym->aop = newAsmop(AOP_ACC);
DEBUGpic14_emitcode(";","%d size=%d",__LINE__,aop->size);
return;
}
+#endif
if (sym->ruonly ) {
if(sym->isptr) { // && sym->uptr
}
/* else spill location */
- if (sym->usl.spillLoc && getSize(sym->type) != getSize(sym->usl.spillLoc->type)) {
- /* force a new aop if sizes differ */
- sym->usl.spillLoc->aop = NULL;
- }
- DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
- __FUNCTION__,__LINE__,
- sym->usl.spillLoc->rname,
- sym->rname, sym->usl.spillLoc->offset);
-
- sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
- //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
- aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
- getSize(sym->type),
- sym->usl.spillLoc->offset);
- aop->size = getSize(sym->type);
+ if (sym->usl.spillLoc)
+ {
+ if (getSize(sym->type) != getSize(sym->usl.spillLoc->type))
+ {
+ /* force a new aop if sizes differ */
+ sym->usl.spillLoc->aop = NULL;
+ }
+ DEBUGpic14_emitcode(";","%s %d %s sym->rname = %s, offset %d",
+ __FUNCTION__,__LINE__,
+ sym->usl.spillLoc->rname,
+ sym->rname, sym->usl.spillLoc->offset);
+
+ sym->aop = op->aop = aop = newAsmop(AOP_PCODE);
+ //aop->aopu.pcop = popGetImmd(sym->usl.spillLoc->rname,0,sym->usl.spillLoc->offset);
+ aop->aopu.pcop = popRegFromString(sym->usl.spillLoc->rname,
+ getSize(sym->type),
+ sym->usl.spillLoc->offset);
+ aop->size = getSize(sym->type);
- return;
+ return;
+ }
}
{
/* offset is greater than
size then zero */
- assert (offset >= 0 && offset < aop->size);
+ if (!(offset >= 0 && ((offset < aop->size) || (aop->size == 0))))
+ {
+ fprintf (stderr, "%s:%u: offset=%d, aop-type:%s, size:%d\n", __FILE__, __LINE__, offset, AopType (aop->type), aop->size);
+ }
+ assert (offset >= 0 && ((offset < aop->size) || (aop->size == 0)));
+ /* XXX: still needed for BIT operands (AOP_CRY) */
if (offset > (aop->size - 1) &&
aop->type != AOP_LIT)
return NULL; //zero;
DEBUGpic14_emitcode(";","popGet AOP_PCODE (%s + %i) %d %s",pCodeOpType(aop->aopu.pcop), offset,
__LINE__,
((aop->aopu.pcop->name)? (aop->aopu.pcop->name) : "no name"));
- emitpComment ("popGet; name %s, offset: %i\n", aop->aopu.pcop->name, offset);
+ //emitpComment ("popGet; name %s, offset: %i, pcop-type: %s\n", aop->aopu.pcop->name, offset, pCodeOpType (aop->aopu.pcop));
switch (aop->aopu.pcop->type)
{
case PO_IMMEDIATE:
/* popGetAddr - access the low/high word of a symbol (immediate) */
/* (for non-PO_IMMEDIATEs this is the same as poGet) */
/*-----------------------------------------------------------------*/
-pCodeOp *popGetAddr (asmop *aop, int offset)
+pCodeOp *popGetAddr (asmop *aop, int offset, int index)
{
if (aop->type == AOP_PCODE && aop->aopu.pcop->type == PO_IMMEDIATE)
{
pCodeOp *pcop = aop->aopu.pcop;
- emitpComment ("popGet; name %s, offset: %i\n", pcop->name, offset);
pcop = pCodeOpCopy (pcop);
/* usually we want to access the memory at "<symbol> + offset" (using ->index),
* but sometimes we want to access the high byte of the symbol's address (using ->offset) */
PCOI(pcop)->offset += offset;
+ PCOI(pcop)->index += index;
return pcop;
} else {
- return popGet (aop, offset);
+ return popGet (aop, offset + index);
}
}
DEBUGpic14_emitcode ("; ***","%s %d offset=%d",__FUNCTION__,__LINE__,offset);
- if ( aop->type == AOP_PCODE ||
- aop->type == AOP_LIT ||
- aop->type == AOP_IMMD )
- emitpcode(POC_MOVLW,popGet(aop,offset));
+ if ( aop_isLitLike (aop) )
+ emitpcode(POC_MOVLW,popGetAddr(aop,offset,0));
else
emitpcode(POC_MOVFW,popGet(aop,offset));
/*-----------------------------------------------------------------*/
static void genNot (iCode *ic)
{
- symbol *tlbl;
+ //symbol *tlbl;
int size;
FENTRY;
goto release;
}
+ assert (!pic14_sameRegs (AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))));
size = AOP_SIZE(IC_LEFT(ic));
- if(size == 1) {
- emitpcode(POC_COMFW,popGet(AOP(IC_LEFT(ic)),0));
- emitpcode(POC_ANDLW,popGetLit(1));
- emitpcode(POC_MOVWF,popGet(AOP(IC_RESULT(ic)),0));
- goto release;
+ emitpcode(POC_CLRF,popGet(AOP(IC_RESULT(ic)),0));
+ mov2w (AOP(IC_LEFT(ic)),0);
+ while (--size > 0)
+ {
+ if (aop_isLitLike (AOP(IC_LEFT(ic))))
+ emitpcode (POC_IORLW, popGetAddr (AOP(IC_LEFT(ic)), size, 0));
+ else
+ emitpcode (POC_IORFW, popGet (AOP(IC_LEFT(ic)), size));
}
- pic14_toBoolean(IC_LEFT(ic));
-
- tlbl = newiTempLabel(NULL);
- pic14_emitcode("cjne","a,#0x01,%05d_DS_",tlbl->key+100);
- pic14_emitcode("","%05d_DS_:",tlbl->key+100);
- pic14_outBitC(IC_RESULT(ic));
+ emitSKPNZ;
+ emitpcode(POC_INCF,popGet(AOP(IC_RESULT(ic)),0));
+ goto release;
release:
/* release the aops */
emitpcode(POC_GOTO,pcop);
emitpLabel(albl->key);
- poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
+ poc = ( aop_isLitLike (AOP(left)) ? POC_MOVLW : POC_MOVFW );
- emitpcode(poc,popGet(AOP(left),1));
+ emitpcode(poc,popGetAddr(AOP(left),1,0));
emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
- emitpcode(poc,popGet(AOP(left),0));
+ emitpcode(poc,popGetAddr(AOP(left),0,0));
emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
emitpLabel(blbl->key);
AOP(IC_LEFT(ic))->aopu.pcop->type == PO_IMMEDIATE) ||
( (AOP(IC_LEFT(ic))->type) == AOP_IMMD) ||
( (AOP(IC_LEFT(ic))->type) == AOP_LIT) ) {
- emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset));
+ emitpcode(POC_MOVLW, popGetAddr(AOP(IC_LEFT(ic)),offset,0));
}else {
emitpcode(POC_MOVFW, popGet(AOP(IC_LEFT(ic)),offset));
}
return;
if(rifx->condition)
- emitSKPC;
- else
emitSKPNC;
+ else
+ emitSKPC;
emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
+ emitpComment ("%s:%u: created from rifx:%p", __FUNCTION__, __LINE__, rifx);
rifx->generated = 1;
}
pic14_emitcode("goto","_%05d_DS_",IC_FALSE(ifx)->key+100+labelOffset);
}
+
+#if 0
/*-----------------------------------------------------------------*/
/* genSkipCond */
/*-----------------------------------------------------------------*/
emitpcode(POC_GOTO,popGetLabel(rifx->lbl->key));
rifx->generated = 1;
}
+#endif
#if 0
/*-----------------------------------------------------------------*/
}
#endif
+
+#define isAOP_REGlike(x) (AOP_TYPE(x) == AOP_REG || AOP_TYPE(x) == AOP_DIR || AOP_TYPE(x) == AOP_PCODE)
+#define isAOP_LIT(x) (AOP_TYPE(x) == AOP_LIT)
+#define DEBUGpc emitpComment
+
+/*-----------------------------------------------------------------*/
+/* mov2w_regOrLit :- move to WREG either the offset's byte from */
+/* aop (if it's NOT a literal) or from lit (if */
+/* aop is a literal) */
+/*-----------------------------------------------------------------*/
+void pic14_mov2w_regOrLit (asmop *aop, unsigned long lit, int offset) {
+ if (aop->type == AOP_LIT) {
+ emitpcode (POC_MOVLW, popGetLit((lit >> (offset*8)) & 0x00FF));
+ } else {
+ emitpcode (POC_MOVFW, popGet (aop, offset));
+ }
+}
+
+/* genCmp performs a left < right comparison, stores
+ * the outcome in result (if != NULL) and generates
+ * control flow code for the ifx (if != NULL).
+ *
+ * This version leaves in sequences like
+ * "B[CS]F STATUS,0; BTFS[CS] STATUS,0"
+ * which should be optmized by the peephole
+ * optimizer - RN 2005-01-01 */
+static void genCmp (operand *left,operand *right,
+ operand *result, iCode *ifx, int sign)
+{
+ resolvedIfx rIfx;
+ int size;
+ int offs;
+ symbol *templbl;
+ operand *dummy;
+ unsigned long lit;
+ unsigned long mask;
+ int performedLt;
+ int invert_result = 0;
+
+ FENTRY;
+
+ assert (AOP_SIZE(left) == AOP_SIZE(right));
+ assert (left && right);
+
+ size = AOP_SIZE(right) - 1;
+ mask = (0x100UL << (size*8)) - 1;
+ // in the end CARRY holds "left < right" (performedLt == 1) or "left >= right" (performedLt == 0)
+ performedLt = 1;
+ templbl = NULL;
+ lit = 0;
+
+ resolveIfx (&rIfx, ifx);
+
+ /**********************************************************************
+ * handle bits - bit compares are promoted to int compares seemingly! *
+ **********************************************************************/
+#if 0
+ // THIS IS COMPLETELY UNTESTED!
+ if (AOP_TYPE(left) == AOP_CRY && AOP_TYPE(right) == AOP_CRY) {
+ pCodeOp *pcleft = pic16_popGet(AOP(left), 0);
+ pCodeOp *pcright = pic16_popGet(AOP(right), 0);
+ assert (pcleft->type == PO_GPR_BIT && pcright->type == PO_GPR_BIT);
+
+ emitSETC;
+ // 1 < {0,1} is false --> clear C by skipping the next instruction
+ //pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit (AOP(left),0), PCORB(pcleft)->bit);
+ pic16_emitpcode (POC_BTFSS, pic16_popGet (AOP(left), 0));
+ // {0,1} < 0 is false --> clear C by NOT skipping the next instruction
+ pic16_emitpcode (POC_BTFSS, pic16_popCopyGPR2Bit (pic16_popGet(AOP(right),0), PCORB(pcright)->bit));
+ emitCLRC; // only skipped for left=0 && right=1
+
+ goto correct_result_in_carry;
+ } // if
+#endif
+
+ /*************************************************
+ * make sure that left is register (or the like) *
+ *************************************************/
+ if (!isAOP_REGlike(left)) {
+ DEBUGpc ("swapping arguments (AOP_TYPEs %d/%d)", AOP_TYPE(left), AOP_TYPE(right));
+ assert (isAOP_LIT(left));
+ assert (isAOP_REGlike(right));
+ // swap left and right
+ // left < right <==> right > left <==> (right >= left + 1)
+ lit = (unsigned long)floatFromVal(AOP(left)->aopu.aop_lit);
+
+ if ( (!sign && (lit & mask) == mask) || (sign && (lit & mask) == (mask >> 1)) ) {
+ // MAXVALUE < right? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ } // if
+
+ // This fails for lit = 0xFF (unsigned) AND lit = 0x7F (signed),
+ // that's why we handled it above.
+ lit++;
+
+ dummy = left;
+ left = right;
+ right = dummy;
+
+ performedLt ^= 1; // instead of "left < right" we check for "right >= left+1, i.e. "right < left+1"
+ } else if (isAOP_LIT(right)) {
+ lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ } // if
+
+ assert (isAOP_REGlike(left)); // left must be register or the like
+ assert (isAOP_REGlike(right) || isAOP_LIT(right)); // right may be register-like or a literal
+
+ /*************************************************
+ * special cases go here *
+ *************************************************/
+
+ if (isAOP_LIT(right)) {
+ if (!sign) {
+ // unsigned comparison to a literal
+ DEBUGpc ("unsigned compare: left %s lit(0x%X=%lu), size=%d", performedLt ? "<" : ">=", lit, lit, size+1);
+ if (lit == 0) {
+ // unsigned left < 0? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ }
+ } else {
+ // signed comparison to a literal
+ DEBUGpc ("signed compare: left %s lit(0x%X=%ld), size=%d, mask=%x", performedLt ? "<" : ">=", lit, lit, size+1, mask);
+ if ((lit & mask) == ((0x80 << (size*8)) & mask)) {
+ // signed left < 0x80000000? always false
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ } else if (lit == 0) {
+ // compare left < 0; set CARRY if SIGNBIT(left) is set
+ if (performedLt) emitSETC; else emitCLRC;
+ emitpcode (POC_BTFSS, newpCodeOpBit (aopGet (AOP(left), size, FALSE, FALSE), 7, 0));
+ if (performedLt) emitCLRC; else emitSETC;
+ goto correct_result_in_carry;
+ }
+ } // if (!sign)
+ } // right is literal
+
+ /*************************************************
+ * perform a general case comparison *
+ * make sure we get CARRY==1 <==> left >= right *
+ *************************************************/
+ // compare most significant bytes
+ //DEBUGpc ("comparing bytes at offset %d", size);
+ if (!sign) {
+ // unsigned comparison
+ pic14_mov2w_regOrLit (AOP(right), lit, size);
+ emitpcode (POC_SUBFW, popGet (AOP(left), size));
+ } else {
+ // signed comparison
+ // (add 2^n to both operands then perform an unsigned comparison)
+ if (isAOP_LIT(right)) {
+ // left >= LIT <-> LIT-left <= 0 <-> LIT-left == 0 OR !(LIT-left >= 0)
+ unsigned char litbyte = (lit >> (8*size)) & 0xFF;
+
+ if (litbyte == 0x80) {
+ // left >= 0x80 -- always true, but more bytes to come
+ mov2w (AOP(left), size);
+ emitpcode (POC_XORLW, popGetLit (0x80)); // set ZERO flag
+ emitSETC;
+ } else {
+ // left >= LIT <-> left + (-LIT) >= 0 <-> left + (0x100-LIT) >= 0x100
+ mov2w (AOP(left), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_ADDLW, popGetLit ((0x100 - (litbyte + 0x80)) & 0x00FF));
+ } // if
+ } else {
+ pCodeOp *pctemp = popGetTempReg();
+ mov2w (AOP(left), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_MOVWF, pctemp);
+ mov2w (AOP(right), size);
+ emitpcode (POC_ADDLW, popGetLit (0x80));
+ emitpcode (POC_SUBFW, pctemp);
+ popReleaseTempReg(pctemp);
+ }
+ } // if (!sign)
+
+ // compare remaining bytes (treat as unsigned case from above)
+ templbl = newiTempLabel ( NULL );
+ offs = size;
+ while (offs--) {
+ //DEBUGpc ("comparing bytes at offset %d", offs);
+ emitSKPZ;
+ emitpcode (POC_GOTO, popGetLabel (templbl->key));
+ pic14_mov2w_regOrLit (AOP(right), lit, offs);
+ emitpcode (POC_SUBFW, popGet (AOP(left), offs));
+ } // while (offs)
+ emitpLabel (templbl->key);
+ goto result_in_carry;
+
+result_in_carry:
+
+ /****************************************************
+ * now CARRY contains the result of the comparison: *
+ * SUBWF sets CARRY iff *
+ * F-W >= 0 <==> F >= W <==> !(F < W) *
+ * (F=left, W=right) *
+ ****************************************************/
+
+ if (performedLt) {
+ invert_result = 1;
+ // value will be used in the following genSkipc()
+ rIfx.condition ^= 1;
+ } // if
+
+correct_result_in_carry:
+
+ // assign result to variable (if neccessary)
+ if (result && AOP_TYPE(result) != AOP_CRY) {
+ //DEBUGpc ("assign result");
+ size = AOP_SIZE(result);
+ while (size--) {
+ emitpcode (POC_CLRF, popGet (AOP(result), size));
+ } // while
+ if (invert_result) {
+ emitSKPC;
+ emitpcode (POC_BSF, newpCodeOpBit (aopGet (AOP(result), 0, FALSE, FALSE), 0, 0));
+ } else {
+ emitpcode (POC_RLF, popGet (AOP(result), 0));
+ }
+ } // if (result)
+
+ // perform conditional jump
+ if (ifx) {
+ //DEBUGpc ("generate control flow");
+ genSkipc (&rIfx);
+ ifx->generated = 1;
+ } // if
+}
+
+
+#if 0
+/* OLD VERSION -- BUGGY, DO NOT USE */
+
/*-----------------------------------------------------------------*/
/* genCmp :- greater or less than comparison */
/*-----------------------------------------------------------------*/
} else {
emitpcode(POC_ADDLW, popGetLit(0x80));
emitpcode(POC_ADDLW, popGetLit(i^0x80));
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
}
} else {
genSkipz2(&rFalseIfx,1);
} else {
emitpcode(POC_ADDLW, popGetLit(i));
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
}
}
emitSKPNZ;
}
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
emitpLabel(truelbl->key);
if(ifx) ifx->generated = 1;
return;
emitpcode(POC_MOVFW, popGet(AOP(left),size));
emitpcode(POC_ADDLW, popGetLit( 0x80));
emitpcode(POC_ADDLW, popGetLit(0x100-i));
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
emitpcode(POC_MOVFW, popGet(AOP(left),size));
emitpcode(POC_ADDLW, popGetLit( 0x80));
emitpcode(POC_ADDLW, popGetLit(0x100-i));
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
emitpcode(POC_SUBFW, popGet(AOP(left),size));
}
//rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
emitpLabel(truelbl->key);
emitpLabel(lbl->key);
//if(emitFinalCheck)
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(sign)
emitpLabel(truelbl->key);
emitpcode(POC_ADDLW, popGetLit(0x80));
emitpcode(POC_ADDLW, popGetLit(((0-(lit+1)) & 0xff) ^ 0x80));
rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
break;
}
if(ifx) ifx->generated = 1;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
rFalseIfx.condition ^= 1;
if (AOP_TYPE(result) == AOP_CRY) {
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
} else {
DEBUGpic14_emitcode ("; ***","%s %d RFIfx.cond=%d",__FUNCTION__,__LINE__, rFalseIfx.condition);
emitpcode(POC_ADDLW, popGetLit( 0x80));
emitpcode(POC_ADDLW, popGetLit(0x100-i));
rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
}
rFalseIfx.condition ^= 1;
//rFalseIfx.condition = 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
emitpLabel(truelbl->key);
emitpcode(POC_SUBFW, popGet(AOP(right),0));
rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
}
emitpLabel(truelbl->key);
emitpLabel(lbl->key);
rFalseIfx.condition ^= 1;
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
}
if(sign)
emitpcode(POC_ADDLW, popGetLit(0x80));
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
return;
emitpcode(POC_CLRF, popGet(AOP(result),0));
emitpcode(POC_RLF, popGet(AOP(result),0));
} else {
- genSkipc(&rFalseIfx);
+ genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
}
- //genSkipc(&rFalseIfx);
+ //genSkipc(&rFalseIfx); assert ( !"genSkipc should have inverse logic" );
if(ifx) ifx->generated = 1;
return;
}
}
+#endif
/*-----------------------------------------------------------------*/
/* genCmpGt :- greater than comparison */
else
i=0;
- emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i);
switch( BYTEofLONG(lit,i)) {
case 0:
emitpcode(POC_MOVFW,popGet(AOP(op),offset+i));
i ^= 1;
- emitpComment ("lit: %i, byte: %i, offset: %i, i: %i\n", lit, BYTEofLONG(lit,i), offset, i);
switch( BYTEofLONG(lit,i)) {
case 0:
emitpcode(POC_IORFW,popGet(AOP(op),offset+i));
/*-----------------------------------------------------------------*/
static void gencjne(operand *left, operand *right, operand *result, iCode *ifx)
{
- int size = max(AOP_SIZE(left),AOP_SIZE(right));
+ int size = min(AOP_SIZE(left),AOP_SIZE(right));
int offset = 0;
- int res_offset = 0; /* the result may be a different size then left or right */
- int res_size = AOP_SIZE(result);
- resolvedIfx rIfx;
+ //resolvedIfx rIfx;
symbol *lbl;
- unsigned long lit = 0L;
+ //unsigned long lit = 0L;
FENTRY;
+ if (!ifx && (!result || AOP_TYPE(result) == AOP_CRY)) {
+ emitpComment ("gencjne: no ifx, no (real) result -- comparison ignored");
+ return;
+ }
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
DEBUGpic14_AopType(__LINE__,left,right,result);
+
+ assert (!pic14_sameRegs (AOP(left), AOP(result)));
+ assert (!pic14_sameRegs (AOP(right), AOP(result)));
+ if (AOP_SIZE(result)) {
+ for (offset = 0; offset < AOP_SIZE(result); offset++)
+ emitpcode (POC_CLRF, popGet (AOP(result), offset));
+ }
+
+ assert (AOP_SIZE(left) == AOP_SIZE(right));
+ //resolveIfx(&rIfx,ifx);
+ lbl = newiTempLabel (NULL);
+ while (size--)
+ {
+ mov2w (AOP(right),size);
+ emitpcode (POC_XORFW, popGet (AOP(left), size));
+ if (size)
+ {
+ emitSKPZ;
+ emitpcode (POC_GOTO, popGetLabel (lbl->key));
+ }
+ } // while
+ emitpLabel (lbl->key);
+ if (AOP_SIZE(result)) {
+ emitSKPNZ;
+ emitpcode (POC_INCF, popGet (AOP(result), 0));
+ } else {
+ assert (ifx);
+ genSkipz (ifx, NULL != IC_TRUE(ifx));
+ ifx->generated = 1;
+ }
+ return;
+#if 0
if(result)
+ {
DEBUGpic14_emitcode ("; ***","%s %d result is not null",__FUNCTION__,__LINE__);
- resolveIfx(&rIfx,ifx);
- lbl = newiTempLabel(NULL);
+ assert (!pic14_sameRegs (AOP(result), AOP(left)));
+ assert (!pic14_sameRegs (AOP(result), AOP(right)));
+ for (offset=0; offset < AOP_SIZE(result); offset++)
+ {
+ emitpcode (POC_CLRF, popGet (AOP(result), offset));
+ } // for offset
+ }
/* if the left side is a literal or
emitpcode(POC_GOTO,popGetLabel(lbl->key));
break;
default:
+ offset = 0;
while (size--) {
if(lit & 0xff) {
emitpcode(POC_MOVFW,popGet(AOP(left),offset));
emitSKPNZ;
emitpcode(POC_GOTO,popGetLabel(lbl->key));
offset++;
- if(res_offset < res_size-1)
- res_offset++;
lit >>= 8;
}
break;
//int lbl_key = (rIfx.condition) ? rIfx.lbl->key : lbl->key;
int lbl_key = lbl->key;
- if(result) {
- emitpcode(POC_CLRF,popGet(AOP(result),res_offset));
- //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
- }else {
+ if(!result) {
DEBUGpic14_emitcode ("; ***","%s %d -- ERROR",__FUNCTION__,__LINE__);
fprintf(stderr, "%s %d error - expecting result to be non_null\n",
__FUNCTION__,__LINE__);
/* emitpcode(POC_GOTO,popGetLabel(lbl->key)); */
/* break; */
/* default: */
+ offset = 0;
while (size--) {
int emit_skip=1;
if((AOP_TYPE(left) == AOP_DIR) &&
break;
case 1:
emitpcode(POC_DECFSZW,popGet(AOP(left),offset));
- emitpcode(POC_INCF,popGet(AOP(result),res_offset));
- //emitpcode(POC_GOTO,popGetLabel(lbl->key));
+ //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+ emitpcode(POC_GOTO,popGetLabel(lbl->key));
emit_skip=0;
break;
case 0xff:
else
emitSKPNZ;
emitpcode(POC_GOTO,popGetLabel(lbl_key));
- //emitpcode(POC_INCF,popGet(AOP(result),res_offset));
}
if(ifx)
ifx->generated=1;
}
emit_skip++;
offset++;
- if(res_offset < res_size-1)
- res_offset++;
}
/* break; */
/* } */
} else if(AOP_TYPE(right) == AOP_REG &&
AOP_TYPE(left) != AOP_DIR){
-
+
+ offset = 0;
while(size--) {
emitpcode(POC_MOVFW,popGet(AOP(left),offset));
emitpcode(POC_XORFW,popGet(AOP(right),offset));
emitSKPZ;
emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
offset++;
- if(res_offset < res_size-1)
- res_offset++;
}
}else{
/* right is a pointer reg need both a & b */
+ offset = 0;
while(size--) {
char *l = aopGet(AOP(left),offset,FALSE,FALSE);
if(strcmp(l,"b"))
}
}
- emitpcode(POC_INCF,popGet(AOP(result),res_offset));
+ emitpcode(POC_INCF,popGet(AOP(result),0));
if(!rIfx.condition)
emitpcode(POC_GOTO,popGetLabel(rIfx.lbl->key));
if(ifx)
ifx->generated = 1;
+#endif
}
#if 0
/* if literal, literal on the right or
if the right is in a pointer register and left
is not */
- if ((AOP_TYPE(IC_LEFT(ic)) == AOP_LIT) ||
- (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
+ if (aop_isLitLike (AOP(IC_LEFT(ic)))
+ || (IS_AOP_PREG(right) && !IS_AOP_PREG(left))) {
operand *tmp = right ;
right = left;
left = tmp;
tlbl = newiTempLabel(NULL);
while(size--) {
- emitpcode(POC_MOVFW,popGet(AOP(left),offset));
- emitpcode(POC_XORFW,popGet(AOP(right),offset));
+ mov2w (AOP(right),offset); /* right might be litLike() */
+ emitpcode(POC_XORFW,popGet(AOP(left),offset));
if ( IC_TRUE(ifx) ) {
if(size) {
pic14_emitcode("cpl","%s",AOP(result)->aopu.aop_dir);
goto release;
} else {
+ assert ( !"incomplete genXor" );
pic14_emitcode("mov","c,%s",AOP(left)->aopu.aop_dir);
pic14_emitcode("cpl","c");
}
{
FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(shCount != 0){
- /*
- if(shCount == 1) {
- pic14_emitcode("add","a,acc");
+ if(shCount != 0) {
+ if (shCount == 1)
+ {
emitCLRC;
- emitpcode(POC_RLF,popGet(AOP(op),offset));
+ emitpcode (POC_RLF, popGet (AOP(op), 0));
} else {
- if(shCount == 2) {
- pic14_emitcode("add","a,acc");
- emitCLRC;
- emitpcode(POC_RLF,popGet(AOP(op),offset));
- pic14_emitcode("add","a,acc");
- emitCLRC;
- emitpcode(POC_RLF,popGet(AOP(op),offset));
- } else {
- */
- {
- {
- /* rotate left accumulator */
- AccRol(op,offset,shCount);
- /* and kill the lower order bits */
- pic14_emitcode("anl","a,#0x%02x", SLMask[shCount]);
- emitpcode(POC_ANDLW,popGetLit(SLMask[shCount]));
- }
+ /* rotate left accumulator */
+ AccRol(op,offset,shCount);
+ /* and kill the lower order bits */
+ emitpcode(POC_MOVLW,popGetLit(SLMask[shCount]));
+ emitpcode (POC_ANDWF, popGet (AOP(op),0));
}
}
}
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
if(shCount != 0){
if(shCount == 1){
- CLRC;
- pic14_emitcode("rrc","a");
+ emitCLRC;
+ emitpcode (POC_RRF, popGet (AOP(op), 0));
} else {
/* rotate right accumulator */
AccRol(op,offset,8 - shCount);
/* and kill the higher order bits */
- pic14_emitcode("anl","a,#0x%02x", SRMask[shCount]);
+ emitpcode (POC_MOVLW, popGetLit (SRMask[shCount]));
+ emitpcode (POC_ANDWF, popGet (AOP(op),0));
}
}
}
}
}
}
-#endif
+
/*-----------------------------------------------------------------*/
/* shiftR1Left2Result - shift right one byte from left to result */
/*-----------------------------------------------------------------*/
}
}
+#endif
/*-----------------------------------------------------------------*/
/* movLeft2Result - move byte from left to result */
}
}
+/*-----------------------------------------------------------------*/
+/* shiftLeft_Left2ResultLit - shift left by known count */
+/*-----------------------------------------------------------------*/
+
+static void shiftLeft_Left2ResultLit (operand *left, operand *result, int shCount)
+{
+ int size, same, offr, i;
+
+ size = AOP_SIZE(left);
+ if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+
+ same = pic14_sameRegs (AOP(left), AOP(result));
+
+ offr = shCount / 8;
+ shCount = shCount & 0x07;
+
+ size -= offr;
+
+ switch (shCount)
+ {
+ case 0: /* takes 0 or 2N cycles (for offr==0) */
+ if (!same || offr) {
+ for (i=size-1; i >= 0; i--)
+ movLeft2Result (left, i, result, offr + i);
+ } // if
+ break;
+
+ case 1: /* takes 1N+1 or 2N+1 cycles (or offr==0) */
+ if (same && offr) {
+ shiftLeft_Left2ResultLit (left, result, 8 * offr);
+ shiftLeft_Left2ResultLit (result, result, shCount);
+ return; /* prevent clearing result again */
+ } else {
+ emitCLRC;
+ for (i=0; i < size; i++) {
+ if (same && !offr) {
+ emitpcode (POC_RLF, popGet (AOP(left), i));
+ } else {
+ emitpcode (POC_RLFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+ } // if
+ } // for
+ } // if (offr)
+ break;
+
+ case 4: /* takes 3+5(N-1) = 5N-2 cycles (for offr==0) */
+ /* works in-place/with offr as well */
+ emitpcode (POC_SWAPFW, popGet (AOP(left), size-1));
+ emitpcode (POC_ANDLW, popGetLit (0xF0));
+ emitpcode (POC_MOVWF, popGet(AOP(result), size-1+offr));
+
+ for (i = size - 2; i >= 0; i--)
+ {
+ emitpcode (POC_SWAPFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i + offr));
+ emitpcode (POC_ANDLW, popGetLit (0x0F));
+ emitpcode (POC_IORWF, popGet (AOP(result), i + offr + 1));
+ emitpcode (POC_XORWF, popGet (AOP(result), i + offr));
+ } // for i
+ break;
+
+ case 7: /* takes 2(N-1)+3 = 2N+1 cycles */
+ /* works in-place/with offr as well */
+ emitpcode (POC_RRFW, popGet (AOP(left), size-1));
+ for (i = size-2; i >= 0; i--) {
+ emitpcode (POC_RRFW, popGet (AOP(left), i));
+ emitpcode (POC_MOVWF, popGet (AOP(result), offr + i + 1));
+ } // for i
+ emitpcode (POC_CLRF, popGet (AOP(result), offr));
+ emitpcode (POC_RRF, popGet (AOP(result), offr));
+ break;
+
+ default:
+ shiftLeft_Left2ResultLit (left, result, offr * 8 + shCount-1);
+ shiftLeft_Left2ResultLit (result, result, 1);
+ return; /* prevent clearing result again */
+ break;
+ } // switch
+
+ while (0 < offr--)
+ {
+ emitpcode (POC_CLRF, popGet (AOP(result), offr));
+ } // while
+}
+
+/*-----------------------------------------------------------------*/
+/* shiftRight_Left2ResultLit - shift right by known count */
+/*-----------------------------------------------------------------*/
+
+static void shiftRight_Left2ResultLit (operand *left, operand *result, int shCount, int sign)
+{
+ int size, same, offr, i;
+
+ size = AOP_SIZE(left);
+ if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
+
+ same = pic14_sameRegs (AOP(left), AOP(result));
+
+ offr = shCount / 8;
+ shCount = shCount & 0x07;
+
+ size -= offr;
+
+ if (size)
+ {
+ switch (shCount)
+ {
+ case 0: /* takes 0 or 2N cycles (for offr==0) */
+ if (!same || offr) {
+ for (i=0; i < size; i++)
+ movLeft2Result (left, i + offr, result, i);
+ } // if
+ break;
+
+ case 1: /* takes 1N+1(3) or 2N+1(3) cycles (or offr==0) */
+ emitpComment ("%s:%d: shCount=%d, size=%d, sign=%d, same=%d, offr=%d", __FUNCTION__, __LINE__, shCount, size, sign, same, offr);
+ if (same && offr) {
+ shiftRight_Left2ResultLit (left, result, 8 * offr, sign);
+ shiftRight_Left2ResultLit (result, result, shCount, sign);
+ return; /* prevent sign-extending result again */
+ } else {
+ emitCLRC;
+ if (sign) {
+ emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(left), AOP_SIZE(left)-1, FALSE, FALSE), 7, 0));
+ emitSETC;
+ }
+ for (i = size-1; i >= 0; i--) {
+ if (same && !offr) {
+ emitpcode (POC_RRF, popGet (AOP(left), i));
+ } else {
+ emitpcode (POC_RRFW, popGet (AOP(left), i + offr));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ }
+ } // for i
+ } // if (offr)
+ break;
+
+ case 4: /* takes 3(6)+5(N-1) = 5N-2(+1) cycles (for offr==0) */
+ /* works in-place/with offr as well */
+ emitpcode (POC_SWAPFW, popGet (AOP(left), offr));
+ emitpcode (POC_ANDLW, popGetLit (0x0F));
+ emitpcode (POC_MOVWF, popGet(AOP(result), 0));
+
+ for (i = 1; i < size; i++)
+ {
+ emitpcode (POC_SWAPFW, popGet (AOP(left), i + offr));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ emitpcode (POC_ANDLW, popGetLit (0xF0));
+ emitpcode (POC_IORWF, popGet (AOP(result), i - 1));
+ emitpcode (POC_XORWF, popGet (AOP(result), i));
+ } // for i
+
+ if (sign)
+ {
+ emitpcode (POC_MOVLW, popGetLit (0xF0));
+ emitpcode (POC_BTFSC, newpCodeOpBit (aopGet (AOP(result), size-1, FALSE, FALSE), 3, 0));
+ emitpcode (POC_IORWF, popGet (AOP(result), size-1));
+ } // if
+ break;
+
+ case 7: /* takes 2(N-1)+3(4) = 2N+1(2) cycles */
+ /* works in-place/with offr as well */
+ emitpcode (POC_RLFW, popGet (AOP(left), offr));
+ for (i = 0; i < size-1; i++) {
+ emitpcode (POC_RLFW, popGet (AOP(left), offr + i + 1));
+ emitpcode (POC_MOVWF, popGet (AOP(result), i));
+ } // for i
+ emitpcode (POC_CLRF, popGet (AOP(result), size-1));
+ if (!sign) {
+ emitpcode (POC_RLF, popGet (AOP(result), size-1));
+ } else {
+ emitSKPNC;
+ emitpcode (POC_DECF, popGet (AOP(result), size-1));
+ }
+ break;
+
+ default:
+ shiftRight_Left2ResultLit (left, result, offr * 8 + shCount-1, sign);
+ shiftRight_Left2ResultLit (result, result, 1, sign);
+ return; /* prevent sign extending result again */
+ break;
+ } // switch
+ } // if
+
+ addSign (result, size, sign);
+}
+
+#if 0
/*-----------------------------------------------------------------*/
/* shiftL2Left2Result - shift left two bytes from left to result */
/*-----------------------------------------------------------------*/
}
}
+
/*-----------------------------------------------------------------*/
/* shiftR2Left2Result - shift right two bytes from left to result */
/*-----------------------------------------------------------------*/
}
}
-
/*-----------------------------------------------------------------*/
/* shiftLLeftOrResult - shift left one byte from left, or to result*/
/*-----------------------------------------------------------------*/
{
FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+
/* shift left accumulator */
AccLsh(left,offl,shCount);
/* or with result */
- pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
- /* back to result */
- aopPut(AOP(result),"a",offr);
+ emitpcode (POC_IORWF, popGet (AOP(result), offr));
+ assert ( !"broken (modifies left, fails for left==result))" );
}
/*-----------------------------------------------------------------*/
{
FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- MOVA(aopGet(AOP(left),offl,FALSE,FALSE));
+
/* shift right accumulator */
AccRsh(left,offl,shCount);
/* or with result */
- pic14_emitcode("orl","a,%s", aopGet(AOP(result),offr,FALSE,FALSE));
- /* back to result */
- aopPut(AOP(result),"a",offr);
+ emitpcode (POC_IORWF, popGet (AOP(result), offr));
+ assert ( !"broken (modifies left, fails for left==result))" );
}
/*-----------------------------------------------------------------*/
shiftL2Left2Result(left, LSB, result, LSB, shCount);
}
}
+#endif
+#if 0
/*-----------------------------------------------------------------*/
/* genLeftShiftLiteral - left shifting by known count */
/*-----------------------------------------------------------------*/
iCode *ic)
{
int shCount = (int) floatFromVal (AOP(right)->aopu.aop_lit);
- int size;
+ //int size;
FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(left,ic,FALSE);
aopOp(result,ic,FALSE);
-
+
size = getSize(operandType(result));
#if VIEW_SIZE
freeAsmop(left,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
}
+#endif
/*-----------------------------------------------------------------*
* genMultiAsm - repeat assembly instruction for size of register.
result = IC_RESULT(ic);
aopOp(right,ic,FALSE);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
+
/* if the shift count is known then do it
as efficiently as possible */
if (AOP_TYPE(right) == AOP_LIT) {
- genLeftShiftLiteral (left,right,result,ic);
+ shiftLeft_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit));
return ;
}
more that 32 bits make no sense anyway, ( the
largest size of an object can be only 32 bits ) */
-
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
+ /* this code fails for RIGHT == RESULT */
+ assert (!pic14_sameRegs (AOP(right), AOP(result)));
/* now move the left to the result if they are not the
same */
tlbl = newiTempLabel(NULL);
if (!pic14_sameRegs(AOP(left),AOP(result))) {
- if (AOP_TYPE(left) == AOP_LIT)
- emitpcode(POC_MOVLW, popGetLit(lit));
- else
- emitpcode(POC_MOVFW, popGet(AOP(left),0));
+ mov2w (AOP(left), 0);
emitpcode(POC_MOVWF, popGet(AOP(result),0));
}
freeAsmop(result,NULL,ic,TRUE);
}
+#if 0
/*-----------------------------------------------------------------*/
/* genrshOne - right shift a one byte quantity by known count */
/*-----------------------------------------------------------------*/
static void shiftRLong (operand *left, int offl,
operand *result, int sign)
{
+ int size, same;
+
FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if(!sign)
- pic14_emitcode("clr","c");
- MOVA(aopGet(AOP(left),MSB32,FALSE,FALSE));
- if(sign)
- pic14_emitcode("mov","c,acc.7");
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",MSB32-offl);
- if(offl == MSB16)
- /* add sign of "a" */
- addSign(result, MSB32, sign);
-
- MOVA(aopGet(AOP(left),MSB24,FALSE,FALSE));
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",MSB24-offl);
- MOVA(aopGet(AOP(left),MSB16,FALSE,FALSE));
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",MSB16-offl);
+ size = AOP_SIZE(left);
+ if (AOP_SIZE(result) < size) size = AOP_SIZE(result);
- if(offl == LSB){
- MOVA(aopGet(AOP(left),LSB,FALSE,FALSE));
- pic14_emitcode("rrc","a");
- aopPut(AOP(result),"a",LSB);
- }
+ if (sign)
+ emitpcode (POC_RLFW, popGet (AOP(left), AOP_SIZE(left)-1));
+ else
+ emitCLRC;
+
+ assert (offl >= 0 && offl < size);
+
+ same = pic14_sameRegs (AOP(left), AOP(result));
+
+ /* perform the shift */
+ while (size--)
+ {
+ if (same && !offl) {
+ emitpcode (POC_RRF, popGet (AOP(result), size));
+ } else {
+ emitpcode (POC_RRFW, popGet (AOP(left), size));
+ emitpcode (POC_MOVWF, popGet (AOP(result), size-offl));
+ }
+ } // while
+
+ addSign (result, AOP_SIZE(left) - offl, sign);
}
/*-----------------------------------------------------------------*/
/* I suppose that the left size >= result size */
if(shCount == 0){
while(res_size--)
- movLeft2Result(left, lsize, result, res_size);
+ movLeft2Result(left, res_size, result, res_size);
}
else if(shCount >= (lsize * 8)){
}
}
-
+
freeAsmop(left,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
}
+#endif
/*-----------------------------------------------------------------*/
/* genSignedRightShift - right shift of signed number */
if ( AOP_TYPE(right) == AOP_LIT) {
- genRightShiftLiteral (left,right,result,ic,1);
+ shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 1);
+ //genRightShiftLiteral (left,right,result,ic,1);
return ;
}
/* shift count is unknown then we have to form
result = IC_RESULT(ic);
aopOp(right,ic,FALSE);
+ aopOp(left,ic,FALSE);
+ aopOp(result,ic,FALSE);
/* if the shift count is known then do it
as efficiently as possible */
if (AOP_TYPE(right) == AOP_LIT) {
- genRightShiftLiteral (left,right,result,ic, 0);
+ shiftRight_Left2ResultLit (left, result, (int) floatFromVal (AOP(right)->aopu.aop_lit), 0);
+ //genRightShiftLiteral (left,right,result,ic, 0);
return ;
}
pic14_emitcode("mov","b,%s",aopGet(AOP(right),0,FALSE,FALSE));
pic14_emitcode("inc","b");
- aopOp(left,ic,FALSE);
- aopOp(result,ic,FALSE);
/* now move the left to the result if they are not the
same */
resolvedIfx rIfx;
resolveIfx(&rIfx,ifx);
if (ptype == -1) /* direct */
- pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
+ pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0);
else
pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
emitpcode((rIfx.condition) ? POC_BTFSC : POC_BTFSS,pcop);
ifx->generated=1;
} else {
pCodeOp *pcop;
+ int i;
+ assert (!pic14_sameRegs (AOP(result), AOP(left)));
+ for (i=0; i < AOP_SIZE(result); i++)
+ emitpcode (POC_CLRF, popGet (AOP(result), i));
if (ptype == -1) /* direct */
- pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
+ pcop = newpCodeOpBit(aopGet (AOP(left),0,FALSE,FALSE),bstr,0);
else
pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
emitpcode(POC_BTFSC,pcop);
- emitpcode(POC_BSF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
-
- if (ptype == -1) /* direct */
- pcop = newpCodeOpBit(AOP(left)->aopu.pcop->name,bstr,0);
- else
- pcop = newpCodeOpBit(pc_indf.pcop.name,bstr,0);
- emitpcode(POC_BTFSS,pcop);
- emitpcode(POC_BCF,newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0));
+ emitpcode(POC_BSF,newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),0,0));
}
return;
}
+ {
+ static int has_warned=0;
+ if (!has_warned)
+ {
+ fprintf (stderr, "%s: bitfields with more than 1 bit are probably broken...", __FUNCTION__);
+ has_warned=1;
+ }
+ }
+
/* read the first byte */
switch (ptype) {
if (!AOP_INPREG(AOP(left)) && !direct) {
/* otherwise get a free pointer register */
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
- if (PCOP(AOP(result))->type == PO_LITERAL)
+ if (PCOP(AOP(result))->type == PO_LITERAL) /* XXX: check me */
emitpcode(POC_MOVLW, popGet(AOP(left),0));
else
emitpcode(POC_MOVFW, popGet(AOP(left),0));
operand *result, iCode *ic)
{
//sym_link *retype = getSpec(operandType(result));
- symbol *albl = newiTempLabel(NULL);
- symbol *blbl = newiTempLabel(NULL);
+ symbol *albl, *blbl;//, *clbl;
PIC_OPCODE poc;
+ int i, size, lit;
pCodeOp *pcop;
FENTRY;
aopOp(left,ic,FALSE);
aopOp(result,ic,FALSE);
+ size = AOP_SIZE(result);
DEBUGpic14_AopType(__LINE__,left,NULL,result);
DEBUGpic14_emitcode ("; "," %d getting const pointer",__LINE__);
-
- emitpcode(POC_CALL,popGetLabel(albl->key));
- pcop = popGetLabel(blbl->key);
- emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
- emitpcode(POC_GOTO,pcop);
- emitpLabel(albl->key);
-
- poc = ( (AOP_TYPE(left) == AOP_PCODE) ? POC_MOVLW : POC_MOVFW);
-
- emitpcode(poc,popGet(AOP(left),1));
- emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
- emitpcode(poc,popGet(AOP(left),0));
- emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
-
- emitpLabel(blbl->key);
-
- emitpcode(POC_MOVWF,popGet(AOP(result),0));
-
+
+ lit = aop_isLitLike (AOP(left));
+ poc = lit ? POC_MOVLW : POC_MOVFW;
+
+ if (lit)
+ {
+ for (i = 0; i < size; i++)
+ {
+ albl = newiTempLabel(NULL);
+ blbl = newiTempLabel(NULL);
+
+ emitpcode(POC_CALL,popGetLabel(albl->key));
+ pcop = popGetLabel(blbl->key);
+ emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
+ emitpcode(POC_GOTO,pcop);
+
+ emitpLabel(albl->key);
+ emitpcode(poc,popGetAddr(AOP(left),1,i));
+ emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
+ emitpcode(poc,popGetAddr(AOP(left),0,i));
+ emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
+
+ emitpLabel(blbl->key);
+ emitpcode(POC_MOVWF,popGet(AOP(result),i));
+ } // for
+ } else {
+ albl = newiTempLabel(NULL);
+ blbl = newiTempLabel(NULL);
+ //clbl = newiTempLabel(NULL);
+
+ emitpcode (POC_GOTO, popGetLabel (blbl->key));
+
+ emitpLabel(albl->key);
+ emitpcode(poc,popGet(AOP(left),1));
+ emitpcode(POC_MOVWF,popCopyReg(&pc_pclath));
+ emitpcode(poc,popGet(AOP(left),0));
+ emitpcode(POC_MOVWF,popCopyReg(&pc_pcl));
+
+ emitpLabel(blbl->key);
+
+ for (i = 0; i < size; i++)
+ {
+ emitpcode(POC_CALL,popGetLabel(albl->key));
+ /* the next two instructions (plus clbl) might be useless... */
+ //pcop = popGetLabel(clbl->key);
+ //emitpcode(POC_PAGESEL,popGetWithString(pcop->name,0)); /* Must restore PCLATH before goto, without destroying W */
+ //emitpcode(POC_GOTO,pcop);
+ //emitpLabel(clbl->key);
+
+ if (i+1 < size) {
+ emitpcode (POC_INCF, popGet (AOP(left), 0));
+ emitSKPNZ;
+ emitpcode (POC_INCF, popGet (AOP(left), 1));
+ }
+ emitpcode(POC_MOVWF,popGet(AOP(result),i));
+ } // for
+ if (size > 1) {
+ /* restore left's value */
+ emitpcode (POC_MOVLW, popGetLit (size-1));
+ emitpcode (POC_SUBWF, popGet (AOP(left), 0));
+ emitSKPC;
+ emitpcode (POC_DECF, popGet (AOP(left), 1));
+ } // if
+ } // if (lit)
freeAsmop(left,NULL,ic,TRUE);
freeAsmop(result,NULL,ic,TRUE);
{
operand *left, *result ;
sym_link *type, *etype;
- int p_type;
+ int p_type = -1;
FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
break;
case GPOINTER:
- if (IS_PTR_CONST(type))
+ if (IS_CODEPTR(type) || IS_PTR_CONST(type) || SPEC_CONST(etype))
genConstPointerGet (left,result,ic);
else
genGenPointerGet (left,result,ic);
break;
+ default:
+ assert ( !"unhandled pointer type" );
+ break;
}
}
if (p_type == -1) {
pCodeOp *pcop;
if (AOP(result)->type == AOP_PCODE)
- pcop = newpCodeOpBit(AOP(result)->aopu.pcop->name,bstr,0);
+ pcop = newpCodeOpBit(aopGet(AOP(result),0,FALSE,FALSE),bstr,0);
else
pcop = popGet(AOP(result),0);
emitpcode(lit?POC_BSF:POC_BCF,pcop);
if (blen==1) {
if (p_type == -1) {
/* Note more efficient code, of pre clearing bit then only setting it if required, can only be done if it is known that the result is not a SFR */
- emitpcode(POC_RLF,popGet(AOP(right),0));
+ emitpcode(POC_RRFW,popGet(AOP(right),0));
emitSKPC;
- emitpcode(POC_BCF,popGet(AOP(result),0));
+ emitpcode(POC_BCF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
emitSKPNC;
- emitpcode(POC_BSF,popGet(AOP(result),0));
+ emitpcode(POC_BSF,newpCodeOpBit (aopGet(AOP(result), 0, FALSE, FALSE), bstr, 0));
+ return;
} else if (p_type!=GPOINTER) {
/* Case with a bitfield length == 1 and no generic pointer
*/
iCode *ic)
{
int size, offset = 0 ;
- char *l, buffer[256];
FENTRY;
DEBUGpic14_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
aopOp(right,ic,FALSE);
+ aopOp(result,ic,FALSE);
- l = aopGet(AOP(result),0,FALSE,TRUE);
size = AOP_SIZE(right);
/*
if ( AOP_TYPE(result) == AOP_PCODE) {
// tsd, was l+1 - the underline `_' prefix was being stripped
while (size--) {
emitpComment ("%s:%u: size=%i, offset=%i", __FILE__,__LINE__, size, offset);
- if (offset) {
- sprintf(buffer,"(%s + %d)",l,offset);
- fprintf(stderr,"%s:%i: oops %s (%i, AOP_LIT=%i)\n",__FILE__,__LINE__,buffer, AOP_TYPE(right), AOP_LIT);
- } else
- sprintf(buffer,"%s",l);
if (AOP_TYPE(right) == AOP_LIT) {
unsigned int lit = (unsigned int) floatFromVal (AOP(IC_RIGHT(ic))->aopu.aop_lit);
aopOp((result=IC_RESULT(ic)),ic,TRUE);
DEBUGpic14_AopType(__LINE__,left,right,result);
+ assert (IS_SYMOP (left));
+
+ /* sanity check: generic pointers to code space are not yet supported,
+ * pionters to codespace must not be assigned addresses of __data values. */
+ #if 0
+ fprintf (stderr, "result: %s, left: %s\n", OP_SYMBOL(result)->name, OP_SYMBOL(left)->name);
+ fprintf (stderr, "result->type : "); printTypeChain (OP_SYM_TYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(result)))), IS_CODEPTR(OP_SYM_TYPE(result)), IS_PTR_CONST(OP_SYM_TYPE(result)));
+ fprintf (stderr, "result->etype: "); printTypeChain (OP_SYM_ETYPE(result), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(result)))), IS_CODEPTR(OP_SYM_ETYPE(result)), IS_PTR_CONST(OP_SYM_ETYPE(result)));
+ fprintf (stderr, "left->type : "); printTypeChain (OP_SYM_TYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n", IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left)))), IS_CODEPTR(OP_SYM_TYPE(left)), IS_PTR_CONST(OP_SYM_TYPE(left)));
+ fprintf (stderr, "left->etype : "); printTypeChain (OP_SYM_ETYPE(left), stderr); fprintf (stderr, ", codesp:%d, codeptr:%d, constptr:%d\n",IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_ETYPE(left)))), IS_CODEPTR(OP_SYM_ETYPE(left)), IS_PTR_CONST(OP_SYM_ETYPE(left)));
+#endif
+
+ if (IS_CODEPTR(OP_SYM_TYPE(result)) && !IN_CODESPACE(SPEC_OCLS(getSpec (OP_SYM_TYPE(left))))) {
+ fprintf (stderr, "trying to assign __code pointer (%s) an address in __data space (&%s) -- expect trouble\n",
+ IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
+ OP_SYMBOL(left)->name);
+ } else if (!IS_CODEPTR (OP_SYM_TYPE(result)) && IN_CODESPACE(SPEC_OCLS(getSpec(OP_SYM_TYPE(left))))) {
+ fprintf (stderr, "trying to assign __data pointer (%s) an address in __code space (&%s) -- expect trouble\n",
+ IS_SYMOP(result) ? OP_SYMBOL(result)->name : "unknown",
+ OP_SYMBOL(left)->name);
+ }
size = AOP_SIZE(IC_RESULT(ic));
offset = 0;
/* if they are the same registers */
if (pic14_sameRegs(AOP(right),AOP(result)))
goto release;
+
+ /* special case: assign from __code */
+ if (!IS_ITEMP(right) /* --> iTemps never reside in __code */
+ && IS_SYMOP (right) /* --> must be an immediate (otherwise we would be in genConstPointerGet) */
+ && !IS_FUNC(OP_SYM_TYPE(right)) /* --> we would want its address instead of the first instruction */
+ && !IS_CODEPTR(OP_SYM_TYPE(right)) /* --> get symbols address instread */
+ && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(right)))))
+ {
+ emitpComment ("genAssign from CODESPACE");
+ genConstPointerGet (right, result, ic);
+ goto release;
+ }
+ /* just for symmetry reasons... */
+ if (!IS_ITEMP(result)
+ && IS_SYMOP (result)
+ && IN_CODESPACE (SPEC_OCLS (getSpec (OP_SYM_TYPE(result)))))
+ {
+ assert ( !"cannot write to CODESPACE" );
+ }
+
/* if the result is a bit */
if (AOP_TYPE(result) == AOP_CRY) {
DEBUGpic14_emitcode ("; ***","%d - result is const pointer",__LINE__);
if ((AOP_TYPE(right) == AOP_PCODE) && AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
- emitpcode(POC_MOVLW, popGetAddr(AOP(right),0));
+ emitpcode(POC_MOVLW, popGetAddr(AOP(right),0,0));
emitpcode(POC_MOVWF, popGet(AOP(result),0));
- emitpcode(POC_MOVLW, popGetAddr(AOP(right),1));
+ emitpcode(POC_MOVLW, popGetAddr(AOP(right),1,0));
emitpcode(POC_MOVWF, popGet(AOP(result),1));
if(AOP_SIZE(result) <2)
fprintf(stderr,"%d -- result is not big enough to hold a ptr\n",__LINE__);
DEBUGpic14_emitcode("; ***","%s %d - pointer cast3",__FUNCTION__,__LINE__);
if ((AOP_TYPE(right) == AOP_PCODE) &&
AOP(right)->aopu.pcop->type == PO_IMMEDIATE) {
- emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset));
+ emitpcode(POC_MOVLW, popGetAddr(AOP(right),offset,0));
emitpcode(POC_MOVWF, popGet(AOP(result),offset));
} else {
aopPut(AOP(result),
{
iCode *ic;
int cln = 0;
+ const char *cline;
FENTRY;
lineHead = lineCurr = NULL;
if (!options.noCcodeInAsm && (cln != ic->lineno)) {
cln = ic->lineno;
//fprintf (stderr, "%s\n", printCLine (ic->filename, ic->lineno));
- emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, printCLine (ic->filename, cln));
+ cline = printCLine (ic->filename, ic->lineno);
+ if (!cline || strlen (cline) == 0) cline = printCLine (ic->filename, ic->lineno);
+ addpCode2pBlock (pb, newpCodeCSource (ic->lineno, ic->filename, cline));
+ //emitpComment ("[C-SRC] %s:%d: %s", ic->filename, cln, cline);
}
if (options.iCodeInAsm) {
return;
}
+
+int
+aop_isLitLike (asmop *aop)
+{
+ assert (aop);
+ if (aop->type == AOP_LIT) return 1;
+ if (aop->type == AOP_IMMD) return 1;
+ if ((aop->type == AOP_PCODE) &&
+ ((aop->aopu.pcop->type == PO_LITERAL) || (aop->aopu.pcop->type == PO_IMMEDIATE)))
+ {
+ /* this should be treated like a literal/immediate (use MOVLW/ADDLW/SUBLW
+ * instead of MOVFW/ADDFW/SUBFW, use popGetAddr instead of popGet) */
+ return 1;
+ }
+ return 0;
+}
+
+int
+op_isLitLike (operand *op)
+{
+ assert (op);
+ if (aop_isLitLike (AOP(op))) return 1;
+ return 0;
+}