1 /*-------------------------------------------------------------------------
2 genutils.c - source file for code generation for pic16
3 code generation utility functions
5 Created by Vangelis Rokas (vrokas@otenet.gr) [Nov-2003]
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)
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
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.
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.
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!
34 000123 mlh Moved aopLiteral to SDCCglue.c to help the split
35 Made everything static
36 -------------------------------------------------------------------------*/
38 /**********************************************************
39 * Here is a list with completed genXXXXX functions
50 #include "SDCCglobl.h"
54 #include "SDCCpeeph.h"
62 #define pic16_emitcode DEBUGpic16_emitcode
66 /*-----------------------------------------------------------------*/
67 /* pic16_genNot - generate code for ! operation */
68 /*-----------------------------------------------------------------*/
69 void pic16_genNot (iCode *ic)
75 * result[AOP_CRY,AOP_REG] = ! left[AOP_CRY, AOP_REG]
80 /* assign asmOps to operand & result */
81 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
82 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
83 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
85 /* if in bit space then a special case */
86 if (AOP_TYPE(IC_LEFT(ic)) == AOP_CRY) {
87 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY) {
88 pic16_emitpcode(POC_MOVLW,pic16_popGet(AOP(IC_LEFT(ic)),0));
89 pic16_emitpcode(POC_XORWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
91 pic16_emitpcode(POC_CLRF,pic16_popGet(AOP(IC_RESULT(ic)),0));
92 pic16_emitpcode(POC_BTFSS,pic16_popGet(AOP(IC_LEFT(ic)),0));
93 pic16_emitpcode(POC_INCF,pic16_popGet(AOP(IC_RESULT(ic)),0));
98 size = AOP_SIZE(IC_LEFT(ic));
101 pic16_emitpcode(POC_COMFW,pic16_popGet(AOP(IC_LEFT(ic)),0));
102 pic16_emitpcode(POC_ANDLW,pic16_popGetLit(1));
103 pic16_emitpcode(POC_MOVWF,pic16_popGet(AOP(IC_RESULT(ic)),0));
108 pic16_toBoolean( IC_LEFT(ic) );
110 pic16_emitpcode(POC_TSTFSZ, pic16_popCopyReg( &pic16_pc_wreg ));
112 pic16_outBitC( IC_RESULT(ic) );
115 /* release the aops */
116 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
117 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
120 #endif /* defined(GEN_Not) */
125 /*-----------------------------------------------------------------*/
126 /* pic16_genCpl - generate code for complement */
127 /*-----------------------------------------------------------------*/
128 void pic16_genCpl (iCode *ic)
134 * result[CRY,REG] = ~left[CRY,REG]
138 DEBUGpic16_emitcode ("; ***","%s %d",__FUNCTION__,__LINE__);
139 /* assign asmOps to operand & result */
140 pic16_aopOp (IC_LEFT(ic),ic,FALSE);
141 pic16_aopOp (IC_RESULT(ic),ic,TRUE);
142 DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
144 /* if both are in bit space then
146 if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY
147 && AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) {
150 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir);
151 pic16_emitcode("cpl","c");
152 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir);
156 size = AOP_SIZE(IC_RESULT(ic));
158 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
159 pic16_emitpcode(POC_COMF, pic16_popGet(AOP(IC_LEFT(ic)), offset));
161 pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
162 pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
168 /* release the aops */
169 pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
170 pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
172 #endif /* defined(GEN_Cpl) */
176 /*-----------------------------------------------------------------*/
177 /* Helper function to dump operand into comment lines */
178 /*-----------------------------------------------------------------*/
180 void pic16_DumpValue(char *prefix, value *val)
182 // char s[INITIAL_INLINEASM];
185 DEBUGpic16_emitcode (";", " %s Dump value",prefix);
186 DEBUGpic16_emitcode (";", " %s name:%s",prefix,val->name);
189 void pic16_DumpPcodeOp(char *prefix, pCodeOp *pcop)
191 // char s[INITIAL_INLINEASM];
194 DEBUGpic16_emitcode (";", " %s Dump pCodeOp",prefix);
195 DEBUGpic16_emitcode (";", " %s name:%s",prefix,pcop->name);
196 if(pcop->type == PO_NONE) {
197 DEBUGpic16_emitcode (";", " %s type:PO_NONE",prefix);
199 if(pcop->type == PO_W) {
200 DEBUGpic16_emitcode (";", " %s type:PO_W",prefix);
202 if(pcop->type == PO_WREG) {
203 DEBUGpic16_emitcode (";", " %s type:PO_WREG",prefix);
205 if(pcop->type == PO_STATUS) {
206 DEBUGpic16_emitcode (";", " %s type:PO_STATUS",prefix);
208 if(pcop->type == PO_BSR) {
209 DEBUGpic16_emitcode (";", " %s type:PO_BSR",prefix);
211 if(pcop->type == PO_FSR0) {
212 DEBUGpic16_emitcode (";", " %s type:PO_FSR0",prefix);
214 if(pcop->type == PO_INDF0) {
215 DEBUGpic16_emitcode (";", " %s type:PO_INDF0",prefix);
217 if(pcop->type == PO_INTCON) {
218 DEBUGpic16_emitcode (";", " %s type:PO_INTCON",prefix);
220 if(pcop->type == PO_GPR_REGISTER) {
221 DEBUGpic16_emitcode (";", " %s type:PO_GPR_REGISTER",prefix);
223 if(pcop->type == PO_GPR_BIT) {
224 DEBUGpic16_emitcode (";", " %s type:PO_GPR_BIT",prefix);
226 if(pcop->type == PO_GPR_TEMP) {
227 DEBUGpic16_emitcode (";", " %s type:PO_GPR_TEMP",prefix);
229 if(pcop->type == PO_SFR_REGISTER) {
230 DEBUGpic16_emitcode (";", " %s type:PO_SFR_REGISTER",prefix);
232 if(pcop->type == PO_PCL) {
233 DEBUGpic16_emitcode (";", " %s type:PO_PCL",prefix);
235 if(pcop->type == PO_PCLATH) {
236 DEBUGpic16_emitcode (";", " %s type:PO_PCLATH",prefix);
238 if(pcop->type == PO_LITERAL) {
239 DEBUGpic16_emitcode (";", " %s type:PO_LITERAL",prefix);
240 DEBUGpic16_emitcode (";", " %s lit:%s",prefix,PCOL(pcop)->lit);
242 if(pcop->type == PO_REL_ADDR) {
243 DEBUGpic16_emitcode (";", " %s type:PO_REL_ADDR",prefix);
245 if(pcop->type == PO_IMMEDIATE) {
246 DEBUGpic16_emitcode (";", " %s type:PO_IMMEDIATE",prefix);
248 if(pcop->type == PO_DIR) {
249 DEBUGpic16_emitcode (";", " %s type:PO_DIR",prefix);
251 if(pcop->type == PO_CRY) {
252 DEBUGpic16_emitcode (";", " %s type:PO_CRY",prefix);
254 if(pcop->type == PO_BIT) {
255 DEBUGpic16_emitcode (";", " %s type:PO_BIT",prefix);
257 if(pcop->type == PO_STR) {
258 DEBUGpic16_emitcode (";", " %s type:PO_STR",prefix);
260 if(pcop->type == PO_LABEL) {
261 DEBUGpic16_emitcode (";", " %s type:PO_LABEL",prefix);
263 if(pcop->type == PO_WILD) {
264 DEBUGpic16_emitcode (";", " %s type:PO_WILD",prefix);
270 void pic16_DumpAop(char *prefix, asmop *aop)
272 char s[INITIAL_INLINEASM];
275 DEBUGpic16_emitcode (";", " %s Dump asmop",prefix);
276 if (aop->type == AOP_LIT)
278 DEBUGpic16_emitcode (";", " %s type:AOP_LIT",prefix);
279 sprintf(s,"%s (aopu.aop_lit)",prefix);
280 pic16_DumpValue(s,aop->aopu.aop_lit);
282 if (aop->type == AOP_REG)
283 DEBUGpic16_emitcode (";", " %s type:AOP_REG",prefix);
284 if (aop->type == AOP_DIR)
286 DEBUGpic16_emitcode (";", " %s type:AOP_DIR",prefix);
287 DEBUGpic16_emitcode (";", " %s aopu.aop_dir:%s",prefix,aop->aopu.aop_dir);
289 if (aop->type == AOP_DPTR)
290 DEBUGpic16_emitcode (";", " %s type:AOP_DPTR",prefix);
291 if (aop->type == AOP_DPTR2)
292 DEBUGpic16_emitcode (";", " %s type:AOP_DPTR2",prefix);
293 if (aop->type == AOP_R0)
294 DEBUGpic16_emitcode (";", " %s type:AOP_R0",prefix);
295 if (aop->type == AOP_R1)
296 DEBUGpic16_emitcode (";", " %s type:AOP_R1",prefix);
297 if (aop->type == AOP_STK)
298 DEBUGpic16_emitcode (";", " %s type:AOP_STK",prefix);
299 if (aop->type == AOP_STA)
300 DEBUGpic16_emitcode (";", " %s type:AOP_STA",prefix);
301 if (aop->type == AOP_IMMD)
303 DEBUGpic16_emitcode (";", " %s type:AOP_IMMD",prefix);
304 DEBUGpic16_emitcode (";", " %s aopu.aop_immd:%s",prefix,aop->aopu.aop_immd);
306 if (aop->type == AOP_STR)
308 DEBUGpic16_emitcode (";", " %s type:AOP_STR",prefix);
309 DEBUGpic16_emitcode (";", " %s aopu.aop_str:%s/%s/%s/%s",prefix,aop->aopu.aop_str[0],
310 aop->aopu.aop_str[1],aop->aopu.aop_str[2],aop->aopu.aop_str[3]);
312 if (aop->type == AOP_CRY)
313 DEBUGpic16_emitcode (";", " %s type:AOP_CRY",prefix);
314 if (aop->type == AOP_ACC)
315 DEBUGpic16_emitcode (";", " %s type:AOP_ACC",prefix);
316 if (aop->type == AOP_PCODE)
318 DEBUGpic16_emitcode (";", " %s type:AOP_PCODE",prefix);
319 sprintf(s,"%s (aopu.pcop)",prefix);
320 pic16_DumpPcodeOp(s,aop->aopu.pcop);
324 DEBUGpic16_emitcode (";", " %s coff:%d",prefix,aop->coff);
325 DEBUGpic16_emitcode (";", " %s size:%d",prefix,aop->size);
326 DEBUGpic16_emitcode (";", " %s code:%d",prefix,aop->code);
327 DEBUGpic16_emitcode (";", " %s paged:%d",prefix,aop->paged);
328 DEBUGpic16_emitcode (";", " %s freed:%d",prefix,aop->freed);
332 void pic16_DumpSymbol(char *prefix, symbol *sym)
334 char s[INITIAL_INLINEASM];
337 DEBUGpic16_emitcode (";", " %s Dump symbol",prefix);
338 DEBUGpic16_emitcode (";", " %s name:%s",prefix,sym->name);
339 DEBUGpic16_emitcode (";", " %s rname:%s",prefix,sym->rname);
340 DEBUGpic16_emitcode (";", " %s level:%d",prefix,sym->level);
341 DEBUGpic16_emitcode (";", " %s block:%d",prefix,sym->block);
342 DEBUGpic16_emitcode (";", " %s key:%d",prefix,sym->key);
343 DEBUGpic16_emitcode (";", " %s implicit:%d",prefix,sym->implicit);
344 DEBUGpic16_emitcode (";", " %s undefined:%d",prefix,sym->undefined);
345 DEBUGpic16_emitcode (";", " %s _isparm:%d",prefix,sym->_isparm);
346 DEBUGpic16_emitcode (";", " %s ismyparm:%d",prefix,sym->ismyparm);
347 DEBUGpic16_emitcode (";", " %s isitmp:%d",prefix,sym->isitmp);
348 DEBUGpic16_emitcode (";", " %s islbl:%d",prefix,sym->islbl);
349 DEBUGpic16_emitcode (";", " %s isref:%d",prefix,sym->isref);
350 DEBUGpic16_emitcode (";", " %s isind:%d",prefix,sym->isind);
351 DEBUGpic16_emitcode (";", " %s isinvariant:%d",prefix,sym->isinvariant);
352 DEBUGpic16_emitcode (";", " %s cdef:%d",prefix,sym->cdef);
353 DEBUGpic16_emitcode (";", " %s addrtaken:%d",prefix,sym->addrtaken);
354 DEBUGpic16_emitcode (";", " %s isreqv:%d",prefix,sym->isreqv);
355 DEBUGpic16_emitcode (";", " %s udChked:%d",prefix,sym->udChked);
356 DEBUGpic16_emitcode (";", " %s isLiveFcall:%d",prefix,sym->isLiveFcall);
357 DEBUGpic16_emitcode (";", " %s isspilt:%d",prefix,sym->isspilt);
358 DEBUGpic16_emitcode (";", " %s spillA:%d",prefix,sym->spillA);
359 DEBUGpic16_emitcode (";", " %s remat:%d",prefix,sym->remat);
360 DEBUGpic16_emitcode (";", " %s isptr:%d",prefix,sym->isptr);
361 DEBUGpic16_emitcode (";", " %s uptr:%d",prefix,sym->uptr);
362 DEBUGpic16_emitcode (";", " %s isFree:%d",prefix,sym->isFree);
363 DEBUGpic16_emitcode (";", " %s islocal:%d",prefix,sym->islocal);
364 DEBUGpic16_emitcode (";", " %s blockSpil:%d",prefix,sym->blockSpil);
365 DEBUGpic16_emitcode (";", " %s remainSpil:%d",prefix,sym->remainSpil);
366 DEBUGpic16_emitcode (";", " %s stackSpil:%d",prefix,sym->stackSpil);
367 DEBUGpic16_emitcode (";", " %s onStack:%d",prefix,sym->onStack);
368 DEBUGpic16_emitcode (";", " %s iaccess:%d",prefix,sym->iaccess);
369 DEBUGpic16_emitcode (";", " %s ruonly:%d",prefix,sym->ruonly);
370 DEBUGpic16_emitcode (";", " %s spildir:%d",prefix,sym->spildir);
371 DEBUGpic16_emitcode (";", " %s ptrreg:%d",prefix,sym->ptrreg);
372 DEBUGpic16_emitcode (";", " %s noSpilLoc:%d",prefix,sym->noSpilLoc);
373 DEBUGpic16_emitcode (";", " %s isstrlit:%d",prefix,sym->isstrlit);
374 DEBUGpic16_emitcode (";", " %s accuse:%d",prefix,sym->accuse);
375 DEBUGpic16_emitcode (";", " %s dptr:%d",prefix,sym->dptr);
376 DEBUGpic16_emitcode (";", " %s allocreq:%d",prefix,sym->allocreq);
377 DEBUGpic16_emitcode (";", " %s stack:%d",prefix,sym->stack);
378 DEBUGpic16_emitcode (";", " %s xstack:%d",prefix,sym->xstack);
379 DEBUGpic16_emitcode (";", " %s nRegs:%d",prefix,sym->nRegs);
380 DEBUGpic16_emitcode (";", " %s regType:%d",prefix,sym->regType);
386 sprintf(s,"%s (aop)",prefix);
387 pic16_DumpAop(s,sym->aop);
389 DEBUGpic16_emitcode (";", " %s aop:NULL",prefix);
393 void pic16_DumpOp(char *prefix, operand *op)
395 char s[INITIAL_INLINEASM];
398 DEBUGpic16_emitcode (";", " %s Dump operand",prefix);
400 DEBUGpic16_emitcode (";", " %s type: SYMBOL",prefix);
402 DEBUGpic16_emitcode (";", " %s type: VALUE",prefix);
404 DEBUGpic16_emitcode (";", " %s type: TYPE",prefix);
405 DEBUGpic16_emitcode (";", " %s isaddr:%d",prefix,op->isaddr);
406 DEBUGpic16_emitcode (";", " %s isvolatile:%d",prefix,op->isvolatile);
407 DEBUGpic16_emitcode (";" ," %s isGlobal:%d",prefix,op->isGlobal);
408 DEBUGpic16_emitcode (";", " %s isPtr:%d",prefix,op->isPtr);
409 DEBUGpic16_emitcode (";", " %s isGptr:%d",prefix,op->isGptr);
410 DEBUGpic16_emitcode (";", " %s isParm:%d",prefix,op->isParm);
411 DEBUGpic16_emitcode (";", " %s isLiteral:%d",prefix,op->isLiteral);
412 DEBUGpic16_emitcode (";", " %s key:%d",prefix,op->key);
414 sprintf(s,"%s (symOperand)",prefix);
415 pic16_DumpSymbol(s,op->operand.symOperand);
420 void _debugf(char *f, int l, char *frm, ...)
425 fprintf(stderr, "%s:%d ", f, l);
426 vfprintf(stderr, frm, ap);
432 void gpsimio2_pcop(pCodeOp *pcop)
434 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pcop, pic16_popCopyReg(&pic16_pc_gpsimio2)));
437 void gpsimio2_lit(unsigned char lit)
439 pic16_emitpcode(POC_MOVLW, pic16_popGetLit(lit));
440 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_wreg), pic16_popCopyReg(&pic16_pc_gpsimio2)));
443 void gpsimio2_str(char *buf)
451 void gpsimDebug_StackDump(char *fname, int line, char *info)
453 pic16_emitpcomment("; gpsim debug stack dump; %s @ %d\tinfo: ", fname, line, info);
455 gpsimio2_str("&c[S:");
457 gpsimio2_str("] &h");
459 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr1h),
460 pic16_popCopyReg(&pic16_pc_gpsimio2)));
461 pic16_emitpcode(POC_MOVFF, pic16_popGet2p(pic16_popCopyReg(&pic16_pc_fsr1l),
462 pic16_popCopyReg(&pic16_pc_gpsimio2)));