* src/pic/glue.h,src/pic16/glue.h: added prototypes
[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 pic16_DumpOpX(FILE *fp, char *prefix, operand *op)
452 {
453   if(!op)return;
454     
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":" ");
459   fprintf(fp, "] ");
460
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);
467 }  
468     
469
470 void _debugf(char *f, int l, char *frm, ...)
471 {
472   va_list ap;
473   
474     va_start(ap, frm);
475     fprintf(stderr, "%s:%d ", f, l);
476     vfprintf(stderr, frm, ap);
477     va_end(ap);
478 }
479
480
481
482 void gpsimio2_pcop(pCodeOp *pcop)
483 {
484   pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_gpsimio2)));
485 }
486
487 void gpsimio2_lit(unsigned char lit)
488 {
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)));
491 }
492
493 void gpsimio2_str(char *buf)
494 {
495   while(*buf) {
496     gpsimio2_lit(*buf);
497     buf++;
498   }
499 }
500
501 void gpsimDebug_StackDump(char *fname, int line, char *info)
502 {
503   pic16_emitpcomment("; gpsim debug stack dump; %s @ %d\tinfo: ", fname, line, info);
504   
505   gpsimio2_str("&c[S:");
506   gpsimio2_str(info);
507   gpsimio2_str("] &h");
508   
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)));
513
514   gpsimio2_lit('\n');
515 }
516
517 const char *gptr_fns[4][2] = {
518   { "_gptrget1", "_gptrput1" },
519   { "_gptrget2", "_gptrput2" },
520   { "_gptrget3", "_gptrput3" },
521   { "_gptrget4", "_gptrput4" } };
522
523 extern set *externs;
524   
525 /* generate a call to the generic pointer read/write functions */
526 void pic16_callGenericPointerRW(int rw, int size)
527 {
528   char buf[32];
529   symbol *sym;
530
531     if(size>4) {
532       werror(W_POSSBUG2, __FILE__, __LINE__);
533       abort();
534     }
535
536     strcpy(buf, port->fun_prefix);
537     strcat(buf, gptr_fns[size-1][rw]);
538     
539     pic16_emitpcode (POC_CALL, pic16_popGetWithString (buf));
540     
541     sym = newSymbol( buf, 0 );
542     sym->used++;
543     strcpy(sym->rname, buf);
544     checkAddSym(&externs, sym);
545 }
546
547
548
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)
552 {
553   /* add code here */
554   
555   /* check condition, > or < ?? */
556   if(rIfx->condition != 0)invert_op ^= 1;
557   
558   if(ifx && IC_FALSE(ifx))invert_op ^= 1;
559
560   if(!ifx)invert_op ^= 1;
561
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);
564   
565   /* do selection */
566   if(!invert_op)return POC_CPFSGT;
567   else return POC_CPFSLT;
568 }
569
570 /* return 1 if function handles compare, 0 otherwise */
571 /* this functions handles special cases like:
572  * reg vs. zero
573  * reg vs. one
574  */
575 int pic16_genCmp_special(operand *left, operand *right, operand *result,
576                     iCode *ifx, resolvedIfx *rIfx, int sign)
577 {
578   int size;
579   int offs=0;
580   symbol *tmplbl;
581   unsigned long lit;
582   int op, cmp_op=0, cond_pre;
583
584     FENTRY;
585     
586     if(!(pic16_options.opt_flags & OF_OPTIMIZE_CMP))return 0;
587
588     size = max(AOP_SIZE(left), AOP_SIZE(right));
589
590     cond_pre = rIfx->condition; // must restore old value on return with 0!!!
591     
592     if(!isAOP_REGlike(left)) {
593       operand *dummy;
594
595         dummy = left;
596         left = right;
597         right = dummy;
598         
599         /* invert comparing operand */
600 //        cmp_op ^= 1;
601         rIfx->condition ^= 1;
602     }
603     
604     
605     if(isAOP_REGlike(left) && isAOP_LIT(right)) {
606       /* comparing register vs. literal */
607       lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
608       
609       
610       if(size == 1) {
611         op = selectCompareOp(rIfx, ifx, result, offs, cmp_op);
612         
613         DEBUGpic16_emitcode("%%", "comparing operand %s, condition: %d", (op==POC_CPFSLT?"POC_CPFSLT":"POC_CPFSGT"), rIfx->condition);
614
615         if(!sign) {
616           /* unsigned compare */
617           switch( lit ) {
618             case 0:
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);
625
626                 ifx->generated = 1;
627                 return 1;
628               }
629               break;
630           }     /* switch */
631
632         }       /* if(!sign) */
633
634       }         /* if(size==1) */
635
636     }           /* */
637       
638   rIfx->condition = cond_pre;
639   return 0;
640 }