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