* device/include/pic16/pic18f1220.h,
[fw/sdcc] / 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_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)
333         {
334                 DEBUGpic16_emitcode (";", " %s type:AOP_IMMD",prefix);
335                 DEBUGpic16_emitcode (";", " %s aopu.aop_immd:%s",prefix,aop->aopu.aop_immd);
336         }
337         if (aop->type == AOP_STR)
338         {
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]);
342         }
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)
348         {
349                 DEBUGpic16_emitcode (";", " %s type:AOP_PCODE",prefix);
350                 sprintf(s,"%s (aopu.pcop)",prefix);
351                 pic16_DumpPcodeOp(s,aop->aopu.pcop);
352         }
353
354
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);
360
361 }
362
363 void pic16_DumpSymbol(char *prefix, symbol *sym)
364 {
365         char s[INITIAL_INLINEASM];  
366         if(!sym) return;
367
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);
412
413         // struct regs !!!
414
415         if(sym->aop)
416         {
417                 sprintf(s,"%s (aop)",prefix);
418                 pic16_DumpAop(s,sym->aop);
419         } else {
420                 DEBUGpic16_emitcode (";", " %s aop:NULL",prefix);
421         }
422 }
423
424 void pic16_DumpOp(char *prefix, operand *op)
425 {
426         char s[INITIAL_INLINEASM];  
427         if(!op) return;
428
429         DEBUGpic16_emitcode (";", " %s Dump operand",prefix);
430         if(IS_SYMOP(op))
431                 DEBUGpic16_emitcode (";", " %s type: SYMBOL",prefix);
432         if(IS_VALOP(op))
433                 DEBUGpic16_emitcode (";", " %s type: VALUE",prefix);
434         if(IS_TYPOP(op))
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);
444         if(IS_SYMOP(op)) {
445                 sprintf(s,"%s (symOperand)",prefix);
446                 pic16_DumpSymbol(s,op->operand.symOperand);
447         }
448
449 }
450
451 void _debugf(char *f, int l, char *frm, ...)
452 {
453   va_list ap;
454   
455     va_start(ap, frm);
456     fprintf(stderr, "%s:%d ", f, l);
457     vfprintf(stderr, frm, ap);
458     va_end(ap);
459 }
460
461
462
463 void gpsimio2_pcop(pCodeOp *pcop)
464 {
465   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_gpsimio2)));
466 }
467
468 void gpsimio2_lit(unsigned char lit)
469 {
470   pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit));
471   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_wreg), pic16_popCopyReg(&pic16_pc_gpsimio2)));
472 }
473
474 void gpsimio2_str(char *buf)
475 {
476   while(*buf) {
477     gpsimio2_lit(*buf);
478     buf++;
479   }
480 }
481
482 void gpsimDebug_StackDump(char *fname, int line, char *info)
483 {
484   pic16_emitpcomment("; gpsim debug stack dump; %s @ %d\tinfo: ", fname, line, info);
485   
486   gpsimio2_str("&c[S:");
487   gpsimio2_str(info);
488   gpsimio2_str("] &h");
489   
490   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr1h),
491                 pic16_popCopyReg(&pic16_pc_gpsimio2)));
492   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr1l),
493                 pic16_popCopyReg(&pic16_pc_gpsimio2)));
494
495   gpsimio2_lit('\n');
496 }
497
498 const char *gptr_fns[4][2] = {
499   { "_gptrget1", "_gptrput1" },
500   { "_gptrget2", "_gptrput2" },
501   { "_gptrget3", "_gptrput3" },
502   { "_gptrget4", "_gptrput4" } };
503
504 extern set *externs;
505   
506 /* generate a call to the generic pointer read/write functions */
507 void pic16_callGenericPointerRW(int rw, int size)
508 {
509   char buf[32];
510   symbol *sym;
511
512     if(size>4) {
513       werror(W_POSSBUG2, __FILE__, __LINE__);
514       abort();
515     }
516
517     strcpy(buf, port->fun_prefix);
518     strcat(buf, gptr_fns[size-1][rw]);
519     
520     pic16_emitpcode (POC_CALL, pic16_popGetWithString (buf));
521     
522     sym = newSymbol( buf, 0 );
523     sym->used++;
524     strcpy(sym->rname, buf);
525     checkAddSym(&externs, sym);
526 }
527
528
529
530 /* check all condition and return appropriate instruction, POC_CPFSGT or POC_CPFFSLT */
531 static int selectCompareOp(resolvedIfx *rIfx, iCode *ifx,
532         operand *result, int offset, int invert_op)
533 {
534   /* add code here */
535   
536   /* check condition, > or < ?? */
537   if(rIfx->condition != 0)invert_op ^= 1;
538   
539   if(ifx && IC_FALSE(ifx))invert_op ^= 1;
540
541   if(!ifx)invert_op ^= 1;
542
543   DEBUGpic16_emitcode("; +++", "%s:%d %s] rIfx->condition= %d, ifx&&IC_FALSE(ifx)= %d, invert_op = %d",
544       __FILE__, __LINE__, __FUNCTION__, rIfx->condition, (ifx && IC_FALSE(ifx)), invert_op);
545   
546   /* do selection */
547   if(!invert_op)return POC_CPFSGT;
548   else return POC_CPFSLT;
549 }
550
551 /* return 1 if function handles compare, 0 otherwise */
552 /* this functions handles special cases like:
553  * reg vs. zero
554  * reg vs. one
555  */
556 int pic16_genCmp_special(operand *left, operand *right, operand *result,
557                     iCode *ifx, resolvedIfx *rIfx, int sign)
558 {
559   int size;
560   int offs=0;
561   symbol *tmplbl;
562   unsigned long lit;
563   int op, cmp_op=0, cond_pre;
564
565     FENTRY;
566     
567     if(!(pic16_options.opt_flags & OF_OPTIMIZE_CMP))return 0;
568
569     size = max(AOP_SIZE(left), AOP_SIZE(right));
570
571     cond_pre = rIfx->condition; // must restore old value on return with 0!!!
572     
573     if(!isAOP_REGlike(left)) {
574       operand *dummy;
575
576         dummy = left;
577         left = right;
578         right = dummy;
579         
580         /* invert comparing operand */
581 //        cmp_op ^= 1;
582         rIfx->condition ^= 1;
583     }
584     
585     
586     if(isAOP_REGlike(left) && isAOP_LIT(right)) {
587       /* comparing register vs. literal */
588       lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
589       
590       
591       if(size == 1) {
592         op = selectCompareOp(rIfx, ifx, result, offs, cmp_op);
593         
594         DEBUGpic16_emitcode("%%", "comparing operand %s, condition: %d", (op==POC_CPFSLT?"POC_CPFSLT":"POC_CPFSGT"), rIfx->condition);
595
596         if(!sign) {
597           /* unsigned compare */
598           switch( lit ) {
599             case 0:
600               if(ifx && IC_FALSE(ifx)) {
601                 tmplbl = newiTempLabel( NULL );
602                 pic16_emitpcode(POC_TSTFSZ, pic16_popGet(AOP(left), 0));
603                 pic16_emitpcode(POC_BRA, pic16_popGetLabel(tmplbl->key));
604                 pic16_emitpcode(POC_BRA, pic16_popGetLabel(rIfx->lbl->key));
605                 pic16_emitpLabel(tmplbl->key);
606
607                 ifx->generated = 1;
608                 return 1;
609               }
610               break;
611           }     /* switch */
612
613         }       /* if(!sign) */
614
615       }         /* if(size==1) */
616
617     }           /* */
618       
619   rIfx->condition = cond_pre;
620   return 0;
621 }