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