Imported Upstream version 2.9.0
[debian/cc1111] / src / pic16 / genutils.c
1 /*-------------------------------------------------------------------------
2  genutils.c - source file for code generation for pic16
3         code generation utility functions
4
5         Created by Vangelis Rokas (vrokas@otenet.gr) [Nov-2003]
6
7         Based on :
8
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)
14   
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
18   later version.
19   
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.
24   
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.
28   
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!
32   
33   Notes:
34   000123 mlh    Moved aopLiteral to SDCCglue.c to help the split
35                 Made everything static
36 -------------------------------------------------------------------------*/
37
38 /**********************************************************
39  * Here is a list with completed genXXXXX functions
40  *
41  * genNot
42  *
43  */
44
45
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <ctype.h>
50 #include "SDCCglobl.h"
51 #include "newalloc.h"
52
53 #include "common.h"
54 #include "SDCCpeeph.h"
55 #include "ralloc.h"
56 #include "pcode.h"
57 #include "device.h"
58 #include "gen.h"
59
60 #include "genutils.h"
61
62 #if 1
63 #define pic16_emitcode  DEBUGpic16_emitcode
64 #endif
65
66 #if defined(GEN_Not)
67 /*-----------------------------------------------------------------*/
68 /* pic16_genNot - generate code for ! operation                    */
69 /*-----------------------------------------------------------------*/
70 void pic16_genNot (iCode *ic)
71 {
72   int size;
73 //  symbol *tlbl;
74
75 /*
76  * result[AOP_CRY,AOP_REG]  = ! left[AOP_CRY, AOP_REG]
77  */
78
79     FENTRY;
80    
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));
85
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));
91       } else {
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));
95       }
96       goto release;
97     }
98
99     size = AOP_SIZE(IC_LEFT(ic));
100 #if 0
101     if(size == 1) {
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));
105       goto release;
106     }
107 #endif
108
109     pic16_toBoolean( IC_LEFT(ic) );
110     emitSETC;
111     pic16_emitpcode(POC_TSTFSZ, pic16_popCopyReg( &pic16_pc_wreg ));
112     emitCLRC;
113     pic16_outBitC( IC_RESULT(ic) );
114
115 release:    
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);
119 }
120
121 #endif  /* defined(GEN_Not) */
122
123
124
125 #if defined(GEN_Cpl)
126 /*-----------------------------------------------------------------*/
127 /* pic16_genCpl - generate code for complement                     */
128 /*-----------------------------------------------------------------*/
129 void pic16_genCpl (iCode *ic)
130 {
131   int offset = 0;
132   int size ;
133
134 /*
135  * result[CRY,REG] = ~left[CRY,REG]
136  */
137     FENTRY;
138
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));
144
145     /* if both are in bit space then 
146      * a special case */
147     if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY
148       && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
149
150         /* FIXME */
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); 
154         goto release; 
155     } 
156
157     size = AOP_SIZE(IC_RESULT(ic));
158     if (size >= AOP_SIZE(IC_LEFT(ic))) size = AOP_SIZE(IC_LEFT(ic));
159     
160     while (size--) {
161       if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
162         pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)), offset));
163       } else {
164         pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
165         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
166       }
167       offset++;
168     }
169
170     /* handle implicit upcast */
171     size = AOP_SIZE(IC_RESULT(ic));
172     if (offset < size)
173     {
174       if (SPEC_USIGN(operandType(IC_LEFT(ic)))) {
175         while (offset < size) {
176           pic16_emitpcode(POC_SETF, pic16_popGet(AOP(IC_RESULT(ic)), offset));
177           offset++;
178         } // while
179       } else {
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));
185         } else {
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));
192             offset++;
193           } // while
194         } // if
195       }
196     } // if
197
198 release:
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);
202 }
203 #endif  /* defined(GEN_Cpl) */
204
205
206
207 /*-----------------------------------------------------------------*/
208 /* Helper function to dump operand into comment lines              */
209 /*-----------------------------------------------------------------*/
210
211 void pic16_DumpValue(char *prefix, value *val)
212 {
213 //      char s[INITIAL_INLINEASM];  
214         if(!val) return;
215
216         DEBUGpic16_emitcode (";", " %s Dump value",prefix);
217         DEBUGpic16_emitcode (";", " %s name:%s",prefix,val->name);
218 }
219
220 void pic16_DumpPcodeOp(char *prefix, pCodeOp *pcop)
221 {
222 //      char s[INITIAL_INLINEASM];  
223         if(!pcop) return;
224
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);
229         }
230         if(pcop->type == PO_W) {
231                 DEBUGpic16_emitcode (";", " %s type:PO_W",prefix);
232         }
233         if(pcop->type == PO_WREG) {
234                 DEBUGpic16_emitcode (";", " %s type:PO_WREG",prefix);
235         }
236         if(pcop->type == PO_STATUS) {
237                 DEBUGpic16_emitcode (";", " %s type:PO_STATUS",prefix);
238         }
239         if(pcop->type == PO_BSR) {
240                 DEBUGpic16_emitcode (";", " %s type:PO_BSR",prefix);
241         }
242         if(pcop->type == PO_FSR0) {
243                 DEBUGpic16_emitcode (";", " %s type:PO_FSR0",prefix);
244         }
245         if(pcop->type == PO_INDF0) {
246                 DEBUGpic16_emitcode (";", " %s type:PO_INDF0",prefix);
247         }
248         if(pcop->type == PO_INTCON) {
249                 DEBUGpic16_emitcode (";", " %s type:PO_INTCON",prefix);
250         }
251         if(pcop->type == PO_GPR_REGISTER) {
252                 DEBUGpic16_emitcode (";", " %s type:PO_GPR_REGISTER",prefix);
253         }
254         if(pcop->type == PO_GPR_BIT) {
255                 DEBUGpic16_emitcode (";", " %s type:PO_GPR_BIT",prefix);
256         }
257         if(pcop->type == PO_GPR_TEMP) {
258                 DEBUGpic16_emitcode (";", " %s type:PO_GPR_TEMP",prefix);
259         }
260         if(pcop->type == PO_SFR_REGISTER) {
261                 DEBUGpic16_emitcode (";", " %s type:PO_SFR_REGISTER",prefix);
262         }
263         if(pcop->type == PO_PCL) {
264                 DEBUGpic16_emitcode (";", " %s type:PO_PCL",prefix);
265         }
266         if(pcop->type == PO_PCLATH) {
267                 DEBUGpic16_emitcode (";", " %s type:PO_PCLATH",prefix);
268         }
269         if(pcop->type == PO_LITERAL) {
270                 DEBUGpic16_emitcode (";", " %s type:PO_LITERAL",prefix);
271                 DEBUGpic16_emitcode (";", " %s lit:%s",prefix,PCOL(pcop)->lit);
272         }
273         if(pcop->type == PO_REL_ADDR) {
274                 DEBUGpic16_emitcode (";", " %s type:PO_REL_ADDR",prefix);
275         }
276         if(pcop->type == PO_IMMEDIATE) {
277                 DEBUGpic16_emitcode (";", " %s type:PO_IMMEDIATE",prefix);
278         }
279         if(pcop->type == PO_DIR) {
280                 DEBUGpic16_emitcode (";", " %s type:PO_DIR",prefix);
281         }
282         if(pcop->type == PO_CRY) {
283                 DEBUGpic16_emitcode (";", " %s type:PO_CRY",prefix);
284         }
285         if(pcop->type == PO_BIT) {
286                 DEBUGpic16_emitcode (";", " %s type:PO_BIT",prefix);
287         }
288         if(pcop->type == PO_STR) {
289                 DEBUGpic16_emitcode (";", " %s type:PO_STR",prefix);
290         }
291         if(pcop->type == PO_LABEL) {
292                 DEBUGpic16_emitcode (";", " %s type:PO_LABEL",prefix);
293         }
294         if(pcop->type == PO_WILD) {
295                 DEBUGpic16_emitcode (";", " %s type:PO_WILD",prefix);
296         }
297 }
298
299
300
301 void pic16_DumpAop(char *prefix, asmop *aop)
302 {
303         char s[INITIAL_INLINEASM];  
304         if(!aop) return;
305
306         DEBUGpic16_emitcode (";", " %s Dump asmop",prefix);
307         if (aop->type == AOP_LIT)
308         {
309                 DEBUGpic16_emitcode (";", " %s type:AOP_LIT",prefix);
310                 sprintf(s,"%s (aopu.aop_lit)",prefix);
311                 pic16_DumpValue(s,aop->aopu.aop_lit);
312         }
313         if (aop->type == AOP_REG)
314                 DEBUGpic16_emitcode (";", " %s type:AOP_REG",prefix);
315         if (aop->type == AOP_DIR)
316         {
317                 DEBUGpic16_emitcode (";", " %s type:AOP_DIR",prefix);
318                 DEBUGpic16_emitcode (";", " %s aopu.aop_dir:%s",prefix,aop->aopu.aop_dir);
319         }
320         if (aop->type == AOP_STK)
321                 DEBUGpic16_emitcode (";", " %s type:AOP_STK",prefix);
322         if (aop->type == AOP_STA)
323                 DEBUGpic16_emitcode (";", " %s type:AOP_STA",prefix);
324         if (aop->type == AOP_STR)
325         {
326                 DEBUGpic16_emitcode (";", " %s type:AOP_STR",prefix);
327                 DEBUGpic16_emitcode (";", " %s aopu.aop_str:%s/%s/%s/%s",prefix,aop->aopu.aop_str[0],
328                                 aop->aopu.aop_str[1],aop->aopu.aop_str[2],aop->aopu.aop_str[3]);
329         }
330         if (aop->type == AOP_CRY)
331                 DEBUGpic16_emitcode (";", " %s type:AOP_CRY",prefix);
332         if (aop->type == AOP_ACC)
333                 DEBUGpic16_emitcode (";", " %s type:AOP_ACC",prefix);
334         if (aop->type == AOP_PCODE)
335         {
336                 DEBUGpic16_emitcode (";", " %s type:AOP_PCODE",prefix);
337                 sprintf(s,"%s (aopu.pcop)",prefix);
338                 pic16_DumpPcodeOp(s,aop->aopu.pcop);
339         }
340
341
342         DEBUGpic16_emitcode (";", " %s coff:%d",prefix,aop->coff);
343         DEBUGpic16_emitcode (";", " %s size:%d",prefix,aop->size);
344         DEBUGpic16_emitcode (";", " %s code:%d",prefix,aop->code);
345         DEBUGpic16_emitcode (";", " %s paged:%d",prefix,aop->paged);
346         DEBUGpic16_emitcode (";", " %s freed:%d",prefix,aop->freed);
347
348 }
349
350 void pic16_DumpSymbol(char *prefix, symbol *sym)
351 {
352         char s[INITIAL_INLINEASM];  
353         if(!sym) return;
354
355         DEBUGpic16_emitcode (";", " %s Dump symbol",prefix);
356         DEBUGpic16_emitcode (";", " %s name:%s",prefix,sym->name);
357         DEBUGpic16_emitcode (";", " %s rname:%s",prefix,sym->rname);
358         DEBUGpic16_emitcode (";", " %s level:%d",prefix,sym->level);
359         DEBUGpic16_emitcode (";", " %s block:%d",prefix,sym->block);
360         DEBUGpic16_emitcode (";", " %s key:%d",prefix,sym->key);
361         DEBUGpic16_emitcode (";", " %s implicit:%d",prefix,sym->implicit);
362         DEBUGpic16_emitcode (";", " %s undefined:%d",prefix,sym->undefined);
363         DEBUGpic16_emitcode (";", " %s _isparm:%d",prefix,sym->_isparm);
364         DEBUGpic16_emitcode (";", " %s ismyparm:%d",prefix,sym->ismyparm);
365         DEBUGpic16_emitcode (";", " %s isitmp:%d",prefix,sym->isitmp);
366         DEBUGpic16_emitcode (";", " %s islbl:%d",prefix,sym->islbl);
367         DEBUGpic16_emitcode (";", " %s isref:%d",prefix,sym->isref);
368         DEBUGpic16_emitcode (";", " %s isind:%d",prefix,sym->isind);
369         DEBUGpic16_emitcode (";", " %s isinvariant:%d",prefix,sym->isinvariant);
370         DEBUGpic16_emitcode (";", " %s cdef:%d",prefix,sym->cdef);
371         DEBUGpic16_emitcode (";", " %s addrtaken:%d",prefix,sym->addrtaken);
372         DEBUGpic16_emitcode (";", " %s isreqv:%d",prefix,sym->isreqv);
373         DEBUGpic16_emitcode (";", " %s udChked:%d",prefix,sym->udChked);
374         DEBUGpic16_emitcode (";", " %s isLiveFcall:%d",prefix,sym->isLiveFcall);
375         DEBUGpic16_emitcode (";", " %s isspilt:%d",prefix,sym->isspilt);
376         DEBUGpic16_emitcode (";", " %s spillA:%d",prefix,sym->spillA);
377         DEBUGpic16_emitcode (";", " %s remat:%d",prefix,sym->remat);
378         DEBUGpic16_emitcode (";", " %s isptr:%d",prefix,sym->isptr);
379         DEBUGpic16_emitcode (";", " %s uptr:%d",prefix,sym->uptr);
380         DEBUGpic16_emitcode (";", " %s isFree:%d",prefix,sym->isFree);
381         DEBUGpic16_emitcode (";", " %s islocal:%d",prefix,sym->islocal);
382         DEBUGpic16_emitcode (";", " %s blockSpil:%d",prefix,sym->blockSpil);
383         DEBUGpic16_emitcode (";", " %s remainSpil:%d",prefix,sym->remainSpil);
384         DEBUGpic16_emitcode (";", " %s stackSpil:%d",prefix,sym->stackSpil);
385         DEBUGpic16_emitcode (";", " %s onStack:%d",prefix,sym->onStack);
386         DEBUGpic16_emitcode (";", " %s iaccess:%d",prefix,sym->iaccess);
387         DEBUGpic16_emitcode (";", " %s ruonly:%d",prefix,sym->ruonly);
388         DEBUGpic16_emitcode (";", " %s spildir:%d",prefix,sym->spildir);
389         DEBUGpic16_emitcode (";", " %s ptrreg:%d",prefix,sym->ptrreg);
390         DEBUGpic16_emitcode (";", " %s noSpilLoc:%d",prefix,sym->noSpilLoc);
391         DEBUGpic16_emitcode (";", " %s isstrlit:%d",prefix,sym->isstrlit);
392         DEBUGpic16_emitcode (";", " %s accuse:%d",prefix,sym->accuse);
393         DEBUGpic16_emitcode (";", " %s dptr:%d",prefix,sym->dptr);
394         DEBUGpic16_emitcode (";", " %s allocreq:%d",prefix,sym->allocreq);
395         DEBUGpic16_emitcode (";", " %s stack:%d",prefix,sym->stack);
396         DEBUGpic16_emitcode (";", " %s xstack:%d",prefix,sym->xstack);
397         DEBUGpic16_emitcode (";", " %s nRegs:%d",prefix,sym->nRegs);
398         DEBUGpic16_emitcode (";", " %s regType:%d",prefix,sym->regType);
399
400         // struct regs !!!
401
402         if(sym->aop)
403         {
404                 sprintf(s,"%s (aop)",prefix);
405                 pic16_DumpAop(s,sym->aop);
406         } else {
407                 DEBUGpic16_emitcode (";", " %s aop:NULL",prefix);
408         }
409 }
410
411 void pic16_DumpOp(char *prefix, operand *op)
412 {
413         char s[INITIAL_INLINEASM];  
414         if(!op) return;
415
416         DEBUGpic16_emitcode (";", " %s Dump operand",prefix);
417         if(IS_SYMOP(op))
418                 DEBUGpic16_emitcode (";", " %s type: SYMBOL",prefix);
419         if(IS_VALOP(op))
420                 DEBUGpic16_emitcode (";", " %s type: VALUE",prefix);
421         if(IS_TYPOP(op))
422                 DEBUGpic16_emitcode (";", " %s type: TYPE",prefix);
423         DEBUGpic16_emitcode (";", " %s isaddr:%d",prefix,op->isaddr);
424         DEBUGpic16_emitcode (";", " %s isvolatile:%d",prefix,op->isvolatile);
425         DEBUGpic16_emitcode (";" ," %s isGlobal:%d",prefix,op->isGlobal);
426         DEBUGpic16_emitcode (";", " %s isPtr:%d",prefix,op->isPtr);
427         DEBUGpic16_emitcode (";", " %s isGptr:%d",prefix,op->isGptr);
428         DEBUGpic16_emitcode (";", " %s isParm:%d",prefix,op->isParm);
429         DEBUGpic16_emitcode (";", " %s isLiteral:%d",prefix,op->isLiteral);
430         DEBUGpic16_emitcode (";", " %s key:%d",prefix,op->key);
431         if(IS_SYMOP(op)) {
432                 sprintf(s,"%s (symOperand)",prefix);
433                 pic16_DumpSymbol(s,op->operand.symOperand);
434         }
435
436 }
437
438 void pic16_DumpOpX(FILE *fp, char *prefix, operand *op)
439 {
440   if(!op)return;
441     
442   fprintf(fp, "%s [", prefix);
443   fprintf(fp, "%s", IS_SYMOP(op)?"S":" ");
444   fprintf(fp, "%s", IS_VALOP(op)?"V":" ");
445   fprintf(fp, "%s", IS_TYPOP(op)?"T":" ");
446   fprintf(fp, "] ");
447
448   fprintf(fp, "isaddr:%d,", op->isaddr);
449   fprintf(fp, "isvolatile:%d,", op->isvolatile);
450   fprintf(fp, "isGlobal:%d,", op->isGlobal);
451   fprintf(fp, "isPtr:%d,", op->isPtr);
452   fprintf(fp, "isParm:%d,", op->isParm);
453   fprintf(fp, "isLit:%d\n", op->isLiteral);
454 }  
455     
456
457 void _debugf(char *f, int l, char *frm, ...)
458 {
459   va_list ap;
460   
461     va_start(ap, frm);
462     fprintf(stderr, "%s:%d ", f, l);
463     vfprintf(stderr, frm, ap);
464     va_end(ap);
465 }
466
467
468
469 void gpsimio2_pcop(pCodeOp *pcop)
470 {
471   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_gpsimio2)));
472 }
473
474 void gpsimio2_lit(unsigned char lit)
475 {
476   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit));
477   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_wreg), pic16_popCopyReg(&pic16_pc_gpsimio2)));
478 }
479
480 void gpsimio2_str(char *buf)
481 {
482   while(*buf) {
483     gpsimio2_lit(*buf);
484     buf++;
485   }
486 }
487
488 void gpsimDebug_StackDump(char *fname, int line, char *info)
489 {
490   pic16_emitpcomment("; gpsim debug stack dump; %s @ %d\tinfo: ", fname, line, info);
491   
492   gpsimio2_str("&c[S:");
493   gpsimio2_str(info);
494   gpsimio2_str("] &h");
495   
496   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr1h),
497                 pic16_popCopyReg(&pic16_pc_gpsimio2)));
498   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr1l),
499                 pic16_popCopyReg(&pic16_pc_gpsimio2)));
500
501   gpsimio2_lit('\n');
502 }
503
504 const char *gptr_fns[4][2] = {
505   { "_gptrget1", "_gptrput1" },
506   { "_gptrget2", "_gptrput2" },
507   { "_gptrget3", "_gptrput3" },
508   { "_gptrget4", "_gptrput4" } };
509
510 extern set *externs;
511   
512 /* generate a call to the generic pointer read/write functions */
513 void pic16_callGenericPointerRW(int rw, int size)
514 {
515   char buf[32];
516   symbol *sym;
517
518     if(size>4) {
519       werror(W_POSSBUG2, __FILE__, __LINE__);
520       abort();
521     }
522
523     strcpy(buf, port->fun_prefix);
524     strcat(buf, gptr_fns[size-1][rw]);
525     
526     pic16_emitpcode (POC_CALL, pic16_popGetWithString (buf));
527     
528     sym = newSymbol( buf, 0 );
529     sym->used++;
530     strcpy(sym->rname, buf);
531     checkAddSym(&externs, sym);
532 }
533
534
535
536 /* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */
537 static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx,
538         operand *result, int offset, int invert_op)
539 {
540   /* add code here */
541   
542   /* check condition, > or < ?? */
543   if(rIfx->condition != 0)invert_op ^= 1;
544   
545   if(ifx && IC_FALSE(ifx))invert_op ^= 1;
546
547   if(!ifx)invert_op ^= 1;
548
549   DEBUGpic16_emitcode("; +++", "%s:%d %s] rIfx->condition= %d, ifx&&IC_FALSE(ifx)= %d, invert_op = %d",
550       __FILE__, __LINE__, __FUNCTION__, rIfx->condition, (ifx && IC_FALSE(ifx)), invert_op);
551   
552   /* do selection */
553   if(!invert_op)return POC_CPFSGT;
554   else return POC_CPFSLT;
555 }
556
557 /* return 1 if function handles compare, 0 otherwise */
558 /* this functions handles special cases like:
559  * reg vs. zero
560  * reg vs. one
561  */
562 int pic16_genCmp_special(operand *left, operand *right, operand *result,
563                     iCode *ifx, resolvedIfx *rIfx, int sign)
564 {
565   int size;
566   int offs=0;
567   symbol *tmplbl;
568   unsigned long lit;
569   int op, cmp_op=0, cond_pre;
570
571     FENTRY;
572     
573     if(!(pic16_options.opt_flags & OF_OPTIMIZE_CMP))return 0;
574
575     size = max(AOP_SIZE(left), AOP_SIZE(right));
576
577     cond_pre = rIfx->condition; // must restore old value on return with 0!!!
578     
579     if(!isAOP_REGlike(left)) {
580       operand *dummy;
581
582         dummy = left;
583         left = right;
584         right = dummy;
585         
586         /* invert comparing operand */
587 //        cmp_op ^= 1;
588         rIfx->condition ^= 1;
589     }
590     
591     
592     if(isAOP_REGlike(left) && isAOP_LIT(right)) {
593       /* comparing register vs. literal */
594       lit = ulFromVal(AOP(right)->aopu.aop_lit);
595       
596       
597       if(size == 1) {
598         op = selectCompareOp(rIfx, ifx, result, offs, cmp_op);
599         
600         DEBUGpic16_emitcode("%%", "comparing operand %s, condition: %d", (op==POC_CPFSLT?"POC_CPFSLT":"POC_CPFSGT"), rIfx->condition);
601
602         if(!sign) {
603           /* unsigned compare */
604           switch( lit ) {
605             case 0:
606               if(ifx && IC_FALSE(ifx)) {
607                 tmplbl = newiTempLabel( NULL );
608                 pic16_emitpcode(POC_TSTFSZ, pic16_popGet(AOP(left), 0));
609                 pic16_emitpcode(POC_BRA, pic16_popGetLabel(tmplbl->key));
610                 pic16_emitpcode(POC_GOTO, pic16_popGetLabel(rIfx->lbl->key));
611                 pic16_emitpLabel(tmplbl->key);
612
613                 ifx->generated = 1;
614                 return 1;
615               }
616               break;
617           }     /* switch */
618
619         }       /* if(!sign) */
620
621       }         /* if(size==1) */
622
623     }           /* */
624       
625   rIfx->condition = cond_pre;
626   return 0;
627 }