}
size = AOP_SIZE(IC_RESULT(ic));
+ if (size >= AOP_SIZE(IC_LEFT(ic))) size = AOP_SIZE(IC_LEFT(ic));
+
while (size--) {
if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
offset++;
}
+ /* handle implicit upcast */
+ size = AOP_SIZE(IC_RESULT(ic));
+ if (offset < size)
+ {
+ if (SPEC_USIGN(operandType(IC_LEFT(ic)))) {
+ while (offset < size) {
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
+ offset++;
+ } // while
+ } else {
+ if ((offset + 1) == size) {
+ /* just one byte to fix */
+ pic16_emitpcode(POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
+ } else {
+ /* two or more byte to adjust */
+ pic16_emitpcode(POC_SETF, pic16_popCopyReg( &pic16_pc_wreg ));
+ pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
+ pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_wreg ));
+ while (offset < size) {
+ pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
+ offset++;
+ } // while
+ } // if
+ }
+ } // if
+
release:
/* release the aops */
pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
DEBUGpic16_emitcode (";", " %s type:AOP_DIR",prefix);
DEBUGpic16_emitcode (";", " %s aopu.aop_dir:%s",prefix,aop->aopu.aop_dir);
}
- if (aop->type == AOP_DPTR)
- DEBUGpic16_emitcode (";", " %s type:AOP_DPTR",prefix);
- if (aop->type == AOP_DPTR2)
- DEBUGpic16_emitcode (";", " %s type:AOP_DPTR2",prefix);
- if (aop->type == AOP_R0)
- DEBUGpic16_emitcode (";", " %s type:AOP_R0",prefix);
- if (aop->type == AOP_R1)
- DEBUGpic16_emitcode (";", " %s type:AOP_R1",prefix);
if (aop->type == AOP_STK)
DEBUGpic16_emitcode (";", " %s type:AOP_STK",prefix);
if (aop->type == AOP_STA)
DEBUGpic16_emitcode (";", " %s type:AOP_STA",prefix);
- if (aop->type == AOP_IMMD)
- {
- DEBUGpic16_emitcode (";", " %s type:AOP_IMMD",prefix);
- DEBUGpic16_emitcode (";", " %s aopu.aop_immd:%s",prefix,aop->aopu.aop_immd);
- }
if (aop->type == AOP_STR)
{
DEBUGpic16_emitcode (";", " %s type:AOP_STR",prefix);
}
+void pic16_DumpOpX(FILE *fp, char *prefix, operand *op)
+{
+ if(!op)return;
+
+ fprintf(fp, "%s [", prefix);
+ fprintf(fp, "%s", IS_SYMOP(op)?"S":" ");
+ fprintf(fp, "%s", IS_VALOP(op)?"V":" ");
+ fprintf(fp, "%s", IS_TYPOP(op)?"T":" ");
+ fprintf(fp, "] ");
+
+ fprintf(fp, "isaddr:%d,", op->isaddr);
+ fprintf(fp, "isvolatile:%d,", op->isvolatile);
+ fprintf(fp, "isGlobal:%d,", op->isGlobal);
+ fprintf(fp, "isPtr:%d,", op->isPtr);
+ fprintf(fp, "isParm:%d,", op->isParm);
+ fprintf(fp, "isLit:%d\n", op->isLiteral);
+}
+
+
void _debugf(char *f, int l, char *frm, ...)
{
va_list ap;
gpsimio2_lit('\n');
}
+const char *gptr_fns[4][2] = {
+ { "_gptrget1", "_gptrput1" },
+ { "_gptrget2", "_gptrput2" },
+ { "_gptrget3", "_gptrput3" },
+ { "_gptrget4", "_gptrput4" } };
+
+extern set *externs;
+
+/* generate a call to the generic pointer read/write functions */
+void pic16_callGenericPointerRW(int rw, int size)
+{
+ char buf[32];
+ symbol *sym;
+
+ if(size>4) {
+ werror(W_POSSBUG2, __FILE__, __LINE__);
+ abort();
+ }
+
+ strcpy(buf, port->fun_prefix);
+ strcat(buf, gptr_fns[size-1][rw]);
+
+ pic16_emitpcode (POC_CALL, pic16_popGetWithString (buf));
+
+ sym = newSymbol( buf, 0 );
+ sym->used++;
+ strcpy(sym->rname, buf);
+ checkAddSym(&externs, sym);
+}
+
/* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */
iCode *ifx, resolvedIfx *rIfx, int sign)
{
int size;
- int offs;
+ int offs=0;
symbol *tmplbl;
unsigned long lit;
- int op, cmp_op=0;
+ int op, cmp_op=0, cond_pre;
FENTRY;
if(!(pic16_options.opt_flags & OF_OPTIMIZE_CMP))return 0;
size = max(AOP_SIZE(left), AOP_SIZE(right));
+
+ cond_pre = rIfx->condition; // must restore old value on return with 0!!!
if(!isAOP_REGlike(left)) {
operand *dummy;
if(isAOP_REGlike(left) && isAOP_LIT(right)) {
/* comparing register vs. literal */
- lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
+ lit = ulFromVal(AOP(right)->aopu.aop_lit);
if(size == 1) {
tmplbl = newiTempLabel( NULL );
pic16_emitpcode(POC_TSTFSZ, pic16_popGet(AOP(left), 0));
pic16_emitpcode(POC_BRA, pic16_popGetLabel(tmplbl->key));
- pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx->lbl->key));
+ pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rIfx->lbl->key));
pic16_emitpLabel(tmplbl->key);
ifx->generated = 1;
} /* */
+ rIfx->condition = cond_pre;
return 0;
}