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;
+ }
}
{
/*-----------------------------------------------------------------*/
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 */
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 */
/*-----------------------------------------------------------------*/
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");
}
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) {
- if (AOP_TYPE(result) != AOP_CRY)
- 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
more that 32 bits make no sense anyway, ( the
largest size of an object can be only 32 bits ) */
+ /* 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));
}
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) {
break;
case GPOINTER:
- if (IS_CODEPTR(type) || IS_PTR_CONST(type))
+ if (IS_CODEPTR(type) || IS_PTR_CONST(type) || SPEC_CONST(etype))
genConstPointerGet (left,result,ic);
else
genGenPointerGet (left,result,ic);
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);