X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fgenutils.c;h=f36b7ab48b9c7cf4242c4adb682103449b1806bc;hb=35abef5d818f86c51e157fd340f2252f588a49f5;hp=16dfc1a1aac8fae8e5bf500909da0730f5707a44;hpb=a4d219fe6e7a7b938a3fb60a136149595e4e6f15;p=fw%2Fsdcc diff --git a/src/pic16/genutils.c b/src/pic16/genutils.c index 16dfc1a1..f36b7ab4 100644 --- a/src/pic16/genutils.c +++ b/src/pic16/genutils.c @@ -54,6 +54,7 @@ #include "SDCCpeeph.h" #include "ralloc.h" #include "pcode.h" +#include "device.h" #include "gen.h" #include "genutils.h" @@ -75,46 +76,46 @@ void pic16_genNot (iCode *ic) * result[AOP_CRY,AOP_REG] = ! left[AOP_CRY, AOP_REG] */ - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - - /* assign asmOps to operand & result */ - pic16_aopOp (IC_LEFT(ic),ic,FALSE); - pic16_aopOp (IC_RESULT(ic),ic,TRUE); - DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic)); - - /* if in bit space then a special case */ - if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) { - if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) { - pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0)); - pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); - } else { - pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0)); - pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0)); - pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0)); - } - goto release; - } - - size = AOP_SIZE(IC_LEFT(ic)); + FENTRY; + + /* assign asmOps to operand & result */ + pic16_aopOp (IC_LEFT(ic),ic,FALSE); + pic16_aopOp (IC_RESULT(ic),ic,TRUE); + DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic)); + + /* if in bit space then a special case */ + if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) { + if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) { + pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); + } else { + pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0)); + pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0)); + } + goto release; + } + + size = AOP_SIZE(IC_LEFT(ic)); #if 0 - if(size == 1) { - pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0)); - pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1)); - pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); - goto release; - } + if(size == 1) { + pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0)); + pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1)); + pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0)); + goto release; + } #endif - pic16_toBoolean( IC_LEFT(ic) ); - emitSETC; - pic16_emitpcode(POC_TSTFSZ, pic16_popCopyReg( &pic16_pc_wreg )); - emitCLRC; - pic16_outBitC( IC_RESULT(ic) ); + pic16_toBoolean( IC_LEFT(ic) ); + emitSETC; + pic16_emitpcode(POC_TSTFSZ, pic16_popCopyReg( &pic16_pc_wreg )); + emitCLRC; + pic16_outBitC( IC_RESULT(ic) ); release: - /* release the aops */ - pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1)); - pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); + /* release the aops */ + pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1)); + pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE); } #endif /* defined(GEN_Not) */ @@ -133,37 +134,66 @@ void pic16_genCpl (iCode *ic) /* * result[CRY,REG] = ~left[CRY,REG] */ - - - DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); - /* assign asmOps to operand & result */ - pic16_aopOp (IC_LEFT(ic),ic,FALSE); - pic16_aopOp (IC_RESULT(ic),ic,TRUE); - DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic)); - - /* if both are in bit space then - a special case */ - if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY && - AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { - - /* FIXME */ - pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); - pic16_emitcode("cpl","c"); - pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); - goto release; - } - - size = AOP_SIZE(IC_RESULT(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)); - } else { - pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); - pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset)); - } - offset++; - } + FENTRY; + + DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__); + /* assign asmOps to operand & result */ + pic16_aopOp (IC_LEFT(ic),ic,FALSE); + pic16_aopOp (IC_RESULT(ic),ic,TRUE); + DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic)); + + /* if both are in bit space then + * a special case */ + if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY + && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { + + /* FIXME */ + pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); + pic16_emitcode("cpl","c"); + pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); + goto release; + } + + 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)); + } else { + pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset)); + pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(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 */ @@ -287,23 +317,10 @@ void pic16_DumpAop(char *prefix, asmop *aop) 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); @@ -418,6 +435,25 @@ void pic16_DumpOp(char *prefix, operand *op) } +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; @@ -464,3 +500,128 @@ void gpsimDebug_StackDump(char *fname, int line, char *info) 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 */ +static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx, + operand *result, int offset, int invert_op) +{ + /* add code here */ + + /* check condition, > or < ?? */ + if(rIfx->condition != 0)invert_op ^= 1; + + if(ifx && IC_FALSE(ifx))invert_op ^= 1; + + if(!ifx)invert_op ^= 1; + + DEBUGpic16_emitcode("; +++", "%s:%d %s] rIfx->condition= %d, ifx&&IC_FALSE(ifx)= %d, invert_op = %d", + __FILE__, __LINE__, __FUNCTION__, rIfx->condition, (ifx && IC_FALSE(ifx)), invert_op); + + /* do selection */ + if(!invert_op)return POC_CPFSGT; + else return POC_CPFSLT; +} + +/* return 1 if function handles compare, 0 otherwise */ +/* this functions handles special cases like: + * reg vs. zero + * reg vs. one + */ +int pic16_genCmp_special(operand *left, operand *right, operand *result, + iCode *ifx, resolvedIfx *rIfx, int sign) +{ + int size; + int offs=0; + symbol *tmplbl; + unsigned long lit; + 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; + + dummy = left; + left = right; + right = dummy; + + /* invert comparing operand */ +// cmp_op ^= 1; + rIfx->condition ^= 1; + } + + + if(isAOP_REGlike(left) && isAOP_LIT(right)) { + /* comparing register vs. literal */ + lit = ulFromVal(AOP(right)->aopu.aop_lit); + + + if(size == 1) { + op = selectCompareOp(rIfx, ifx, result, offs, cmp_op); + + DEBUGpic16_emitcode("%%", "comparing operand %s, condition: %d", (op==POC_CPFSLT?"POC_CPFSLT":"POC_CPFSGT"), rIfx->condition); + + if(!sign) { + /* unsigned compare */ + switch( lit ) { + case 0: + if(ifx && IC_FALSE(ifx)) { + 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_emitpLabel(tmplbl->key); + + ifx->generated = 1; + return 1; + } + break; + } /* switch */ + + } /* if(!sign) */ + + } /* if(size==1) */ + + } /* */ + + rIfx->condition = cond_pre; + return 0; +}