1 /*-------------------------------------------------------------------------
2 genutils.c - source file for code generation for pic16
3 code generation utility functions
5 Created by Vangelis Rokas (vrokas@otenet.gr) [Nov-2003]
9 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
10 and - Jean-Louis VERN.jlvern@writeme.com (1999)
11 Bug Fixes - Wojciech Stryjewski wstryj1@tiger.lsu.edu (1999 v2.1.9a)
12 PIC port - Scott Dattalo scott@dattalo.com (2000)
13 PIC16 port - Martin Dubuc m.dubuc@rogers.com (2002)
15 This program is free software; you can redistribute it and/or modify it
16 under the terms of the GNU General Public License as published by the
17 Free Software Foundation; either version 2, or (at your option) any
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 In other words, you are welcome to use, share and improve this program.
30 You are forbidden to forbid anyone else to use, share and improve
31 what you give them. Help stamp out software-hoarding!
34 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
35 Made everything static
36 -------------------------------------------------------------------------*/
38 /**********************************************************
39 * Here is a list with completed genXXXXX functions
50 #include "SDCCglobl.h"
54 #include "SDCCpeeph.h"
63 #define pic16_emitcode DEBUGpic16_emitcode
67 /*-----------------------------------------------------------------*/
68 /* pic16_genNot - generate code for ! operation */
69 /*-----------------------------------------------------------------*/
70 void pic16_genNot (iCode *ic)
76 * result[AOP_CRY,AOP_REG] = ! left[AOP_CRY, AOP_REG]
81 /* assign asmOps to operand & result */
82 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
83 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
84 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
86 /* if in bit space then a special case */
87 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
88 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
89 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
90 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
92 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
93 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
94 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
99 size = AOP_SIZE(IC_LEFT(ic));
102 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
103 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
104 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
109 pic16_toBoolean( IC_LEFT(ic) );
111 pic16_emitpcode(POC_TSTFSZ, pic16_popCopyReg( &pic16_pc_wreg ));
113 pic16_outBitC( IC_RESULT(ic) );
116 /* release the aops */
117 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
118 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
121 #endif /* defined(GEN_Not) */
126 /*-----------------------------------------------------------------*/
127 /* pic16_genCpl - generate code for complement */
128 /*-----------------------------------------------------------------*/
129 void pic16_genCpl (iCode *ic)
135 * result[CRY,REG] = ~left[CRY,REG]
139 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
140 /* assign asmOps to operand & result */
141 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
142 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
143 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
145 /* if both are in bit space then
147 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY
148 && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
151 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
152 pic16_emitcode("cpl","c");
153 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
157 size = AOP_SIZE(IC_RESULT(ic));
158 if (size >= AOP_SIZE(IC_LEFT(ic))) size = AOP_SIZE(IC_LEFT(ic));
161 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
162 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
164 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
165 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
170 /* handle implicit upcast */
171 size = AOP_SIZE(IC_RESULT(ic));
174 if (SPEC_USIGN(operandType(IC_LEFT(ic)))) {
175 while (offset < size) {
176 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
180 if ((offset + 1) == size) {
181 /* just one byte to fix */
182 pic16_emitpcode(POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
183 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
184 pic16_emitpcode(POC_CLRF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
186 /* two or more byte to adjust */
187 pic16_emitpcode(POC_SETF, pic16_popCopyReg( &pic16_pc_wreg ));
188 pic16_emitpcode(POC_BTFSC, pic16_newpCodeOpBit(pic16_aopGet(AOP(IC_RESULT(ic)),offset-1,FALSE,FALSE),7,0, PO_GPR_REGISTER));
189 pic16_emitpcode(POC_CLRF, pic16_popCopyReg( &pic16_pc_wreg ));
190 while (offset < size) {
191 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
199 /* release the aops */
200 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
201 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
203 #endif /* defined(GEN_Cpl) */
207 /*-----------------------------------------------------------------*/
208 /* Helper function to dump operand into comment lines */
209 /*-----------------------------------------------------------------*/
211 void pic16_DumpValue(char *prefix, value *val)
213 // char s[INITIAL_INLINEASM];
216 DEBUGpic16_emitcode (";", " %s Dump value",prefix);
217 DEBUGpic16_emitcode (";", " %s name:%s",prefix,val->name);
220 void pic16_DumpPcodeOp(char *prefix, pCodeOp *pcop)
222 // char s[INITIAL_INLINEASM];
225 DEBUGpic16_emitcode (";", " %s Dump pCodeOp",prefix);
226 DEBUGpic16_emitcode (";", " %s name:%s",prefix,pcop->name);
227 if(pcop->type == PO_NONE) {
228 DEBUGpic16_emitcode (";", " %s type:PO_NONE",prefix);
230 if(pcop->type == PO_W) {
231 DEBUGpic16_emitcode (";", " %s type:PO_W",prefix);
233 if(pcop->type == PO_WREG) {
234 DEBUGpic16_emitcode (";", " %s type:PO_WREG",prefix);
236 if(pcop->type == PO_STATUS) {
237 DEBUGpic16_emitcode (";", " %s type:PO_STATUS",prefix);
239 if(pcop->type == PO_BSR) {
240 DEBUGpic16_emitcode (";", " %s type:PO_BSR",prefix);
242 if(pcop->type == PO_FSR0) {
243 DEBUGpic16_emitcode (";", " %s type:PO_FSR0",prefix);
245 if(pcop->type == PO_INDF0) {
246 DEBUGpic16_emitcode (";", " %s type:PO_INDF0",prefix);
248 if(pcop->type == PO_INTCON) {
249 DEBUGpic16_emitcode (";", " %s type:PO_INTCON",prefix);
251 if(pcop->type == PO_GPR_REGISTER) {
252 DEBUGpic16_emitcode (";", " %s type:PO_GPR_REGISTER",prefix);
254 if(pcop->type == PO_GPR_BIT) {
255 DEBUGpic16_emitcode (";", " %s type:PO_GPR_BIT",prefix);
257 if(pcop->type == PO_GPR_TEMP) {
258 DEBUGpic16_emitcode (";", " %s type:PO_GPR_TEMP",prefix);
260 if(pcop->type == PO_SFR_REGISTER) {
261 DEBUGpic16_emitcode (";", " %s type:PO_SFR_REGISTER",prefix);
263 if(pcop->type == PO_PCL) {
264 DEBUGpic16_emitcode (";", " %s type:PO_PCL",prefix);
266 if(pcop->type == PO_PCLATH) {
267 DEBUGpic16_emitcode (";", " %s type:PO_PCLATH",prefix);
269 if(pcop->type == PO_LITERAL) {
270 DEBUGpic16_emitcode (";", " %s type:PO_LITERAL",prefix);
271 DEBUGpic16_emitcode (";", " %s lit:%s",prefix,PCOL(pcop)->lit);
273 if(pcop->type == PO_REL_ADDR) {
274 DEBUGpic16_emitcode (";", " %s type:PO_REL_ADDR",prefix);
276 if(pcop->type == PO_IMMEDIATE) {
277 DEBUGpic16_emitcode (";", " %s type:PO_IMMEDIATE",prefix);
279 if(pcop->type == PO_DIR) {
280 DEBUGpic16_emitcode (";", " %s type:PO_DIR",prefix);
282 if(pcop->type == PO_CRY) {
283 DEBUGpic16_emitcode (";", " %s type:PO_CRY",prefix);
285 if(pcop->type == PO_BIT) {
286 DEBUGpic16_emitcode (";", " %s type:PO_BIT",prefix);
288 if(pcop->type == PO_STR) {
289 DEBUGpic16_emitcode (";", " %s type:PO_STR",prefix);
291 if(pcop->type == PO_LABEL) {
292 DEBUGpic16_emitcode (";", " %s type:PO_LABEL",prefix);
294 if(pcop->type == PO_WILD) {
295 DEBUGpic16_emitcode (";", " %s type:PO_WILD",prefix);
301 void pic16_DumpAop(char *prefix, asmop *aop)
303 char s[INITIAL_INLINEASM];
306 DEBUGpic16_emitcode (";", " %s Dump asmop",prefix);
307 if (aop->type == AOP_LIT)
309 DEBUGpic16_emitcode (";", " %s type:AOP_LIT",prefix);
310 sprintf(s,"%s (aopu.aop_lit)",prefix);
311 pic16_DumpValue(s,aop->aopu.aop_lit);
313 if (aop->type == AOP_REG)
314 DEBUGpic16_emitcode (";", " %s type:AOP_REG",prefix);
315 if (aop->type == AOP_DIR)
317 DEBUGpic16_emitcode (";", " %s type:AOP_DIR",prefix);
318 DEBUGpic16_emitcode (";", " %s aopu.aop_dir:%s",prefix,aop->aopu.aop_dir);
320 if (aop->type == AOP_DPTR)
321 DEBUGpic16_emitcode (";", " %s type:AOP_DPTR",prefix);
322 if (aop->type == AOP_DPTR2)
323 DEBUGpic16_emitcode (";", " %s type:AOP_DPTR2",prefix);
324 if (aop->type == AOP_R0)
325 DEBUGpic16_emitcode (";", " %s type:AOP_R0",prefix);
326 if (aop->type == AOP_R1)
327 DEBUGpic16_emitcode (";", " %s type:AOP_R1",prefix);
328 if (aop->type == AOP_STK)
329 DEBUGpic16_emitcode (";", " %s type:AOP_STK",prefix);
330 if (aop->type == AOP_STA)
331 DEBUGpic16_emitcode (";", " %s type:AOP_STA",prefix);
332 if (aop->type == AOP_IMMD)
334 DEBUGpic16_emitcode (";", " %s type:AOP_IMMD",prefix);
335 DEBUGpic16_emitcode (";", " %s aopu.aop_immd:%s",prefix,aop->aopu.aop_immd);
337 if (aop->type == AOP_STR)
339 DEBUGpic16_emitcode (";", " %s type:AOP_STR",prefix);
340 DEBUGpic16_emitcode (";", " %s aopu.aop_str:%s/%s/%s/%s",prefix,aop->aopu.aop_str[0],
341 aop->aopu.aop_str[1],aop->aopu.aop_str[2],aop->aopu.aop_str[3]);
343 if (aop->type == AOP_CRY)
344 DEBUGpic16_emitcode (";", " %s type:AOP_CRY",prefix);
345 if (aop->type == AOP_ACC)
346 DEBUGpic16_emitcode (";", " %s type:AOP_ACC",prefix);
347 if (aop->type == AOP_PCODE)
349 DEBUGpic16_emitcode (";", " %s type:AOP_PCODE",prefix);
350 sprintf(s,"%s (aopu.pcop)",prefix);
351 pic16_DumpPcodeOp(s,aop->aopu.pcop);
355 DEBUGpic16_emitcode (";", " %s coff:%d",prefix,aop->coff);
356 DEBUGpic16_emitcode (";", " %s size:%d",prefix,aop->size);
357 DEBUGpic16_emitcode (";", " %s code:%d",prefix,aop->code);
358 DEBUGpic16_emitcode (";", " %s paged:%d",prefix,aop->paged);
359 DEBUGpic16_emitcode (";", " %s freed:%d",prefix,aop->freed);
363 void pic16_DumpSymbol(char *prefix, symbol *sym)
365 char s[INITIAL_INLINEASM];
368 DEBUGpic16_emitcode (";", " %s Dump symbol",prefix);
369 DEBUGpic16_emitcode (";", " %s name:%s",prefix,sym->name);
370 DEBUGpic16_emitcode (";", " %s rname:%s",prefix,sym->rname);
371 DEBUGpic16_emitcode (";", " %s level:%d",prefix,sym->level);
372 DEBUGpic16_emitcode (";", " %s block:%d",prefix,sym->block);
373 DEBUGpic16_emitcode (";", " %s key:%d",prefix,sym->key);
374 DEBUGpic16_emitcode (";", " %s implicit:%d",prefix,sym->implicit);
375 DEBUGpic16_emitcode (";", " %s undefined:%d",prefix,sym->undefined);
376 DEBUGpic16_emitcode (";", " %s _isparm:%d",prefix,sym->_isparm);
377 DEBUGpic16_emitcode (";", " %s ismyparm:%d",prefix,sym->ismyparm);
378 DEBUGpic16_emitcode (";", " %s isitmp:%d",prefix,sym->isitmp);
379 DEBUGpic16_emitcode (";", " %s islbl:%d",prefix,sym->islbl);
380 DEBUGpic16_emitcode (";", " %s isref:%d",prefix,sym->isref);
381 DEBUGpic16_emitcode (";", " %s isind:%d",prefix,sym->isind);
382 DEBUGpic16_emitcode (";", " %s isinvariant:%d",prefix,sym->isinvariant);
383 DEBUGpic16_emitcode (";", " %s cdef:%d",prefix,sym->cdef);
384 DEBUGpic16_emitcode (";", " %s addrtaken:%d",prefix,sym->addrtaken);
385 DEBUGpic16_emitcode (";", " %s isreqv:%d",prefix,sym->isreqv);
386 DEBUGpic16_emitcode (";", " %s udChked:%d",prefix,sym->udChked);
387 DEBUGpic16_emitcode (";", " %s isLiveFcall:%d",prefix,sym->isLiveFcall);
388 DEBUGpic16_emitcode (";", " %s isspilt:%d",prefix,sym->isspilt);
389 DEBUGpic16_emitcode (";", " %s spillA:%d",prefix,sym->spillA);
390 DEBUGpic16_emitcode (";", " %s remat:%d",prefix,sym->remat);
391 DEBUGpic16_emitcode (";", " %s isptr:%d",prefix,sym->isptr);
392 DEBUGpic16_emitcode (";", " %s uptr:%d",prefix,sym->uptr);
393 DEBUGpic16_emitcode (";", " %s isFree:%d",prefix,sym->isFree);
394 DEBUGpic16_emitcode (";", " %s islocal:%d",prefix,sym->islocal);
395 DEBUGpic16_emitcode (";", " %s blockSpil:%d",prefix,sym->blockSpil);
396 DEBUGpic16_emitcode (";", " %s remainSpil:%d",prefix,sym->remainSpil);
397 DEBUGpic16_emitcode (";", " %s stackSpil:%d",prefix,sym->stackSpil);
398 DEBUGpic16_emitcode (";", " %s onStack:%d",prefix,sym->onStack);
399 DEBUGpic16_emitcode (";", " %s iaccess:%d",prefix,sym->iaccess);
400 DEBUGpic16_emitcode (";", " %s ruonly:%d",prefix,sym->ruonly);
401 DEBUGpic16_emitcode (";", " %s spildir:%d",prefix,sym->spildir);
402 DEBUGpic16_emitcode (";", " %s ptrreg:%d",prefix,sym->ptrreg);
403 DEBUGpic16_emitcode (";", " %s noSpilLoc:%d",prefix,sym->noSpilLoc);
404 DEBUGpic16_emitcode (";", " %s isstrlit:%d",prefix,sym->isstrlit);
405 DEBUGpic16_emitcode (";", " %s accuse:%d",prefix,sym->accuse);
406 DEBUGpic16_emitcode (";", " %s dptr:%d",prefix,sym->dptr);
407 DEBUGpic16_emitcode (";", " %s allocreq:%d",prefix,sym->allocreq);
408 DEBUGpic16_emitcode (";", " %s stack:%d",prefix,sym->stack);
409 DEBUGpic16_emitcode (";", " %s xstack:%d",prefix,sym->xstack);
410 DEBUGpic16_emitcode (";", " %s nRegs:%d",prefix,sym->nRegs);
411 DEBUGpic16_emitcode (";", " %s regType:%d",prefix,sym->regType);
417 sprintf(s,"%s (aop)",prefix);
418 pic16_DumpAop(s,sym->aop);
420 DEBUGpic16_emitcode (";", " %s aop:NULL",prefix);
424 void pic16_DumpOp(char *prefix, operand *op)
426 char s[INITIAL_INLINEASM];
429 DEBUGpic16_emitcode (";", " %s Dump operand",prefix);
431 DEBUGpic16_emitcode (";", " %s type: SYMBOL",prefix);
433 DEBUGpic16_emitcode (";", " %s type: VALUE",prefix);
435 DEBUGpic16_emitcode (";", " %s type: TYPE",prefix);
436 DEBUGpic16_emitcode (";", " %s isaddr:%d",prefix,op->isaddr);
437 DEBUGpic16_emitcode (";", " %s isvolatile:%d",prefix,op->isvolatile);
438 DEBUGpic16_emitcode (";" ," %s isGlobal:%d",prefix,op->isGlobal);
439 DEBUGpic16_emitcode (";", " %s isPtr:%d",prefix,op->isPtr);
440 DEBUGpic16_emitcode (";", " %s isGptr:%d",prefix,op->isGptr);
441 DEBUGpic16_emitcode (";", " %s isParm:%d",prefix,op->isParm);
442 DEBUGpic16_emitcode (";", " %s isLiteral:%d",prefix,op->isLiteral);
443 DEBUGpic16_emitcode (";", " %s key:%d",prefix,op->key);
445 sprintf(s,"%s (symOperand)",prefix);
446 pic16_DumpSymbol(s,op->operand.symOperand);
451 void pic16_DumpOpX(FILE *fp, char *prefix, operand *op)
455 fprintf(fp, "%s [", prefix);
456 fprintf(fp, "%s", IS_SYMOP(op)?"S":" ");
457 fprintf(fp, "%s", IS_VALOP(op)?"V":" ");
458 fprintf(fp, "%s", IS_TYPOP(op)?"T":" ");
461 fprintf(fp, "isaddr:%d,", op->isaddr);
462 fprintf(fp, "isvolatile:%d,", op->isvolatile);
463 fprintf(fp, "isGlobal:%d,", op->isGlobal);
464 fprintf(fp, "isPtr:%d,", op->isPtr);
465 fprintf(fp, "isParm:%d,", op->isParm);
466 fprintf(fp, "isLit:%d\n", op->isLiteral);
470 void _debugf(char *f, int l, char *frm, ...)
475 fprintf(stderr, "%s:%d ", f, l);
476 vfprintf(stderr, frm, ap);
482 void gpsimio2_pcop(pCodeOp *pcop)
484 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_gpsimio2)));
487 void gpsimio2_lit(unsigned char lit)
489 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit));
490 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_wreg), pic16_popCopyReg(&pic16_pc_gpsimio2)));
493 void gpsimio2_str(char *buf)
501 void gpsimDebug_StackDump(char *fname, int line, char *info)
503 pic16_emitpcomment("; gpsim debug stack dump; %s @ %d\tinfo: ", fname, line, info);
505 gpsimio2_str("&c[S:");
507 gpsimio2_str("] &h");
509 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr1h),
510 pic16_popCopyReg(&pic16_pc_gpsimio2)));
511 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr1l),
512 pic16_popCopyReg(&pic16_pc_gpsimio2)));
517 const char *gptr_fns[4][2] = {
518 { "_gptrget1", "_gptrput1" },
519 { "_gptrget2", "_gptrput2" },
520 { "_gptrget3", "_gptrput3" },
521 { "_gptrget4", "_gptrput4" } };
525 /* generate a call to the generic pointer read/write functions */
526 void pic16_callGenericPointerRW(int rw, int size)
532 werror(W_POSSBUG2, __FILE__, __LINE__);
536 strcpy(buf, port->fun_prefix);
537 strcat(buf, gptr_fns[size-1][rw]);
539 pic16_emitpcode (POC_CALL, pic16_popGetWithString (buf));
541 sym = newSymbol( buf, 0 );
543 strcpy(sym->rname, buf);
544 checkAddSym(&externs, sym);
549 /* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */
550 static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx,
551 operand *result, int offset, int invert_op)
555 /* check condition, > or < ?? */
556 if(rIfx->condition != 0)invert_op ^= 1;
558 if(ifx && IC_FALSE(ifx))invert_op ^= 1;
560 if(!ifx)invert_op ^= 1;
562 DEBUGpic16_emitcode("; +++", "%s:%d %s] rIfx->condition= %d, ifx&&IC_FALSE(ifx)= %d, invert_op = %d",
563 __FILE__, __LINE__, __FUNCTION__, rIfx->condition, (ifx && IC_FALSE(ifx)), invert_op);
566 if(!invert_op)return POC_CPFSGT;
567 else return POC_CPFSLT;
570 /* return 1 if function handles compare, 0 otherwise */
571 /* this functions handles special cases like:
575 int pic16_genCmp_special(operand *left, operand *right, operand *result,
576 iCode *ifx, resolvedIfx *rIfx, int sign)
582 int op, cmp_op=0, cond_pre;
586 if(!(pic16_options.opt_flags & OF_OPTIMIZE_CMP))return 0;
588 size = max(AOP_SIZE(left), AOP_SIZE(right));
590 cond_pre = rIfx->condition; // must restore old value on return with 0!!!
592 if(!isAOP_REGlike(left)) {
599 /* invert comparing operand */
601 rIfx->condition ^= 1;
605 if(isAOP_REGlike(left) && isAOP_LIT(right)) {
606 /* comparing register vs. literal */
607 lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
611 op = selectCompareOp(rIfx, ifx, result, offs, cmp_op);
613 DEBUGpic16_emitcode("%%", "comparing operand %s, condition: %d", (op==POC_CPFSLT?"POC_CPFSLT":"POC_CPFSGT"), rIfx->condition);
616 /* unsigned compare */
619 if(ifx && IC_FALSE(ifx)) {
620 tmplbl = newiTempLabel( NULL );
621 pic16_emitpcode(POC_TSTFSZ, pic16_popGet(AOP(left), 0));
622 pic16_emitpcode(POC_BRA, pic16_popGetLabel(tmplbl->key));
623 pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx->lbl->key));
624 pic16_emitpLabel(tmplbl->key);
638 rIfx->condition = cond_pre;