* src/SDCCmain.c (parseCmdLine): when sOpt is 'I' add rest in
[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 "gen.h"
58
59 #include "genutils.h"
60
61 #if 1
62 #define pic16_emitcode  DEBUGpic16_emitcode
63 #endif
64
65 #if defined(GEN_Not)
66 /*-----------------------------------------------------------------*/
67 /* pic16_genNot - generate code for ! operation                    */
68 /*-----------------------------------------------------------------*/
69 void pic16_genNot (iCode *ic)
70 {
71   int size;
72   symbol *tlbl;
73
74 /*
75  * result[AOP_CRY,AOP_REG]  = ! left[AOP_CRY, AOP_REG]
76  */
77
78         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
79
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));
84
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));
90                 } else {
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));
94                 }
95                 goto release;
96         }
97
98         size = AOP_SIZE(IC_LEFT(ic));
99 #if 0
100         if(size == 1) {
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));
104                 goto release;
105         }
106 #endif
107
108         pic16_toBoolean( IC_LEFT(ic) );
109         
110         tlbl = newiTempLabel(NULL);
111         emitCLRC;
112         pic16_emitpcode(POC_TSTFSZ, pic16_popCopyReg( &pic16_pc_wreg ));
113         emitSETC;
114         pic16_outBitC( IC_RESULT(ic) );
115
116 release:    
117         /* release the aops */
118         pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
119         pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
120 }
121
122 #endif  /* defined(GEN_Not) */
123
124
125
126 #if defined(GEN_Cpl)
127 /*-----------------------------------------------------------------*/
128 /* pic16_genCpl - generate code for complement                     */
129 /*-----------------------------------------------------------------*/
130 void pic16_genCpl (iCode *ic)
131 {
132   int offset = 0;
133   int size ;
134
135 /*
136  * result[CRY,REG] = ~left[CRY,REG]
137  */
138  
139
140         DEBUGpic16_emitcode ("; ***","%s  %d",__FUNCTION__,__LINE__);
141         /* assign asmOps to operand & result */
142         pic16_aopOp (IC_LEFT(ic),ic,FALSE);
143         pic16_aopOp (IC_RESULT(ic),ic,TRUE);
144         DEBUGpic16_pic16_AopType(__LINE__,IC_LEFT(ic),NULL,IC_RESULT(ic));
145
146         /* if both are in bit space then 
147            a special case */
148         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
149                 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
150
151                 /* FIXME */
152                 pic16_emitcode("mov","c,%s",IC_LEFT(ic)->aop->aopu.aop_dir); 
153                 pic16_emitcode("cpl","c"); 
154                 pic16_emitcode("mov","%s,c",IC_RESULT(ic)->aop->aopu.aop_dir); 
155                 goto release; 
156         } 
157
158         size = AOP_SIZE(IC_RESULT(ic));
159         while (size--) {
160
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 release:
171     /* release the aops */
172     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
173     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
174 }
175 #endif  /* defined(GEN_Cpl) */
176
177
178
179 /*-----------------------------------------------------------------*/
180 /* Helper function to dump operand into comment lines              */
181 /*-----------------------------------------------------------------*/
182
183 void pic16_DumpValue(char *prefix, value *val)
184 {
185 //      char s[INITIAL_INLINEASM];  
186         if(!val) return;
187
188         DEBUGpic16_emitcode (";", " %s Dump value",prefix);
189         DEBUGpic16_emitcode (";", " %s name:%s",prefix,val->name);
190 }
191
192 void pic16_DumpPcodeOp(char *prefix, pCodeOp *pcop)
193 {
194 //      char s[INITIAL_INLINEASM];  
195         if(!pcop) return;
196
197         DEBUGpic16_emitcode (";", " %s Dump pCodeOp",prefix);
198         DEBUGpic16_emitcode (";", " %s name:%s",prefix,pcop->name);
199         if(pcop->type == PO_NONE) {
200                 DEBUGpic16_emitcode (";", " %s type:PO_NONE",prefix);
201         }
202         if(pcop->type == PO_W) {
203                 DEBUGpic16_emitcode (";", " %s type:PO_W",prefix);
204         }
205         if(pcop->type == PO_WREG) {
206                 DEBUGpic16_emitcode (";", " %s type:PO_WREG",prefix);
207         }
208         if(pcop->type == PO_STATUS) {
209                 DEBUGpic16_emitcode (";", " %s type:PO_STATUS",prefix);
210         }
211         if(pcop->type == PO_BSR) {
212                 DEBUGpic16_emitcode (";", " %s type:PO_BSR",prefix);
213         }
214         if(pcop->type == PO_FSR0) {
215                 DEBUGpic16_emitcode (";", " %s type:PO_FSR0",prefix);
216         }
217         if(pcop->type == PO_INDF0) {
218                 DEBUGpic16_emitcode (";", " %s type:PO_INDF0",prefix);
219         }
220         if(pcop->type == PO_INTCON) {
221                 DEBUGpic16_emitcode (";", " %s type:PO_INTCON",prefix);
222         }
223         if(pcop->type == PO_GPR_REGISTER) {
224                 DEBUGpic16_emitcode (";", " %s type:PO_GPR_REGISTER",prefix);
225         }
226         if(pcop->type == PO_GPR_BIT) {
227                 DEBUGpic16_emitcode (";", " %s type:PO_GPR_BIT",prefix);
228         }
229         if(pcop->type == PO_GPR_TEMP) {
230                 DEBUGpic16_emitcode (";", " %s type:PO_GPR_TEMP",prefix);
231         }
232         if(pcop->type == PO_SFR_REGISTER) {
233                 DEBUGpic16_emitcode (";", " %s type:PO_SFR_REGISTER",prefix);
234         }
235         if(pcop->type == PO_PCL) {
236                 DEBUGpic16_emitcode (";", " %s type:PO_PCL",prefix);
237         }
238         if(pcop->type == PO_PCLATH) {
239                 DEBUGpic16_emitcode (";", " %s type:PO_PCLATH",prefix);
240         }
241         if(pcop->type == PO_LITERAL) {
242                 DEBUGpic16_emitcode (";", " %s type:PO_LITERAL",prefix);
243                 DEBUGpic16_emitcode (";", " %s lit:%s",prefix,PCOL(pcop)->lit);
244         }
245         if(pcop->type == PO_REL_ADDR) {
246                 DEBUGpic16_emitcode (";", " %s type:PO_REL_ADDR",prefix);
247         }
248         if(pcop->type == PO_IMMEDIATE) {
249                 DEBUGpic16_emitcode (";", " %s type:PO_IMMEDIATE",prefix);
250         }
251         if(pcop->type == PO_DIR) {
252                 DEBUGpic16_emitcode (";", " %s type:PO_DIR",prefix);
253         }
254         if(pcop->type == PO_CRY) {
255                 DEBUGpic16_emitcode (";", " %s type:PO_CRY",prefix);
256         }
257         if(pcop->type == PO_BIT) {
258                 DEBUGpic16_emitcode (";", " %s type:PO_BIT",prefix);
259         }
260         if(pcop->type == PO_STR) {
261                 DEBUGpic16_emitcode (";", " %s type:PO_STR",prefix);
262         }
263         if(pcop->type == PO_LABEL) {
264                 DEBUGpic16_emitcode (";", " %s type:PO_LABEL",prefix);
265         }
266         if(pcop->type == PO_WILD) {
267                 DEBUGpic16_emitcode (";", " %s type:PO_WILD",prefix);
268         }
269 }
270
271
272
273 void pic16_DumpAop(char *prefix, asmop *aop)
274 {
275         char s[INITIAL_INLINEASM];  
276         if(!aop) return;
277
278         DEBUGpic16_emitcode (";", " %s Dump asmop",prefix);
279         if (aop->type == AOP_LIT)
280         {
281                 DEBUGpic16_emitcode (";", " %s type:AOP_LIT",prefix);
282                 sprintf(s,"%s (aopu.aop_lit)",prefix);
283                 pic16_DumpValue(s,aop->aopu.aop_lit);
284         }
285         if (aop->type == AOP_REG)
286                 DEBUGpic16_emitcode (";", " %s type:AOP_REG",prefix);
287         if (aop->type == AOP_DIR)
288         {
289                 DEBUGpic16_emitcode (";", " %s type:AOP_DIR",prefix);
290                 DEBUGpic16_emitcode (";", " %s aopu.aop_dir:%s",prefix,aop->aopu.aop_dir);
291         }
292         if (aop->type == AOP_DPTR)
293                 DEBUGpic16_emitcode (";", " %s type:AOP_DPTR",prefix);
294         if (aop->type == AOP_DPTR2)
295                 DEBUGpic16_emitcode (";", " %s type:AOP_DPTR2",prefix);
296         if (aop->type == AOP_R0)
297                 DEBUGpic16_emitcode (";", " %s type:AOP_R0",prefix);
298         if (aop->type == AOP_R1)
299                 DEBUGpic16_emitcode (";", " %s type:AOP_R1",prefix);
300         if (aop->type == AOP_STK)
301                 DEBUGpic16_emitcode (";", " %s type:AOP_STK",prefix);
302         if (aop->type == AOP_IMMD)
303         {
304                 DEBUGpic16_emitcode (";", " %s type:AOP_IMMD",prefix);
305                 DEBUGpic16_emitcode (";", " %s aopu.aop_immd:%s",prefix,aop->aopu.aop_immd);
306         }
307         if (aop->type == AOP_STR)
308         {
309                 DEBUGpic16_emitcode (";", " %s type:AOP_STR",prefix);
310                 DEBUGpic16_emitcode (";", " %s aopu.aop_str:%s/%s/%s/%s",prefix,aop->aopu.aop_str[0],
311                                 aop->aopu.aop_str[1],aop->aopu.aop_str[2],aop->aopu.aop_str[3]);
312         }
313         if (aop->type == AOP_CRY)
314                 DEBUGpic16_emitcode (";", " %s type:AOP_CRY",prefix);
315         if (aop->type == AOP_ACC)
316                 DEBUGpic16_emitcode (";", " %s type:AOP_ACC",prefix);
317         if (aop->type == AOP_PCODE)
318         {
319                 DEBUGpic16_emitcode (";", " %s type:AOP_PCODE",prefix);
320                 sprintf(s,"%s (aopu.pcop)",prefix);
321                 pic16_DumpPcodeOp(s,aop->aopu.pcop);
322         }
323
324
325         DEBUGpic16_emitcode (";", " %s coff:%d",prefix,aop->coff);
326         DEBUGpic16_emitcode (";", " %s size:%d",prefix,aop->size);
327         DEBUGpic16_emitcode (";", " %s code:%d",prefix,aop->code);
328         DEBUGpic16_emitcode (";", " %s paged:%d",prefix,aop->paged);
329         DEBUGpic16_emitcode (";", " %s freed:%d",prefix,aop->freed);
330
331 }
332
333 void pic16_DumpSymbol(char *prefix, symbol *sym)
334 {
335         char s[INITIAL_INLINEASM];  
336         if(!sym) return;
337
338         DEBUGpic16_emitcode (";", " %s Dump symbol",prefix);
339         DEBUGpic16_emitcode (";", " %s name:%s",prefix,sym->name);
340         DEBUGpic16_emitcode (";", " %s rname:%s",prefix,sym->rname);
341         DEBUGpic16_emitcode (";", " %s level:%d",prefix,sym->level);
342         DEBUGpic16_emitcode (";", " %s block:%d",prefix,sym->block);
343         DEBUGpic16_emitcode (";", " %s key:%d",prefix,sym->key);
344         DEBUGpic16_emitcode (";", " %s implicit:%d",prefix,sym->implicit);
345         DEBUGpic16_emitcode (";", " %s undefined:%d",prefix,sym->undefined);
346         DEBUGpic16_emitcode (";", " %s _isparm:%d",prefix,sym->_isparm);
347         DEBUGpic16_emitcode (";", " %s ismyparm:%d",prefix,sym->ismyparm);
348         DEBUGpic16_emitcode (";", " %s isitmp:%d",prefix,sym->isitmp);
349         DEBUGpic16_emitcode (";", " %s islbl:%d",prefix,sym->islbl);
350         DEBUGpic16_emitcode (";", " %s isref:%d",prefix,sym->isref);
351         DEBUGpic16_emitcode (";", " %s isind:%d",prefix,sym->isind);
352         DEBUGpic16_emitcode (";", " %s isinvariant:%d",prefix,sym->isinvariant);
353         DEBUGpic16_emitcode (";", " %s cdef:%d",prefix,sym->cdef);
354         DEBUGpic16_emitcode (";", " %s addrtaken:%d",prefix,sym->addrtaken);
355         DEBUGpic16_emitcode (";", " %s isreqv:%d",prefix,sym->isreqv);
356         DEBUGpic16_emitcode (";", " %s udChked:%d",prefix,sym->udChked);
357         DEBUGpic16_emitcode (";", " %s isLiveFcall:%d",prefix,sym->isLiveFcall);
358         DEBUGpic16_emitcode (";", " %s isspilt:%d",prefix,sym->isspilt);
359         DEBUGpic16_emitcode (";", " %s spillA:%d",prefix,sym->spillA);
360         DEBUGpic16_emitcode (";", " %s remat:%d",prefix,sym->remat);
361         DEBUGpic16_emitcode (";", " %s isptr:%d",prefix,sym->isptr);
362         DEBUGpic16_emitcode (";", " %s uptr:%d",prefix,sym->uptr);
363         DEBUGpic16_emitcode (";", " %s isFree:%d",prefix,sym->isFree);
364         DEBUGpic16_emitcode (";", " %s islocal:%d",prefix,sym->islocal);
365         DEBUGpic16_emitcode (";", " %s blockSpil:%d",prefix,sym->blockSpil);
366         DEBUGpic16_emitcode (";", " %s remainSpil:%d",prefix,sym->remainSpil);
367         DEBUGpic16_emitcode (";", " %s stackSpil:%d",prefix,sym->stackSpil);
368         DEBUGpic16_emitcode (";", " %s onStack:%d",prefix,sym->onStack);
369         DEBUGpic16_emitcode (";", " %s iaccess:%d",prefix,sym->iaccess);
370         DEBUGpic16_emitcode (";", " %s ruonly:%d",prefix,sym->ruonly);
371         DEBUGpic16_emitcode (";", " %s spildir:%d",prefix,sym->spildir);
372         DEBUGpic16_emitcode (";", " %s ptrreg:%d",prefix,sym->ptrreg);
373         DEBUGpic16_emitcode (";", " %s noSpilLoc:%d",prefix,sym->noSpilLoc);
374         DEBUGpic16_emitcode (";", " %s isstrlit:%d",prefix,sym->isstrlit);
375         DEBUGpic16_emitcode (";", " %s accuse:%d",prefix,sym->accuse);
376         DEBUGpic16_emitcode (";", " %s dptr:%d",prefix,sym->dptr);
377         DEBUGpic16_emitcode (";", " %s allocreq:%d",prefix,sym->allocreq);
378         DEBUGpic16_emitcode (";", " %s stack:%d",prefix,sym->stack);
379         DEBUGpic16_emitcode (";", " %s xstack:%d",prefix,sym->xstack);
380         DEBUGpic16_emitcode (";", " %s nRegs:%d",prefix,sym->nRegs);
381         DEBUGpic16_emitcode (";", " %s regType:%d",prefix,sym->regType);
382
383         // struct regs !!!
384
385         if(sym->aop)
386         {
387                 sprintf(s,"%s (aop)",prefix);
388                 pic16_DumpAop(s,sym->aop);
389         } else {
390                 DEBUGpic16_emitcode (";", " %s aop:NULL",prefix);
391         }
392 }
393
394 void pic16_DumpOp(char *prefix, operand *op)
395 {
396         char s[INITIAL_INLINEASM];  
397         if(!op) return;
398
399         DEBUGpic16_emitcode (";", " %s Dump operand",prefix);
400         if(IS_SYMOP(op))
401                 DEBUGpic16_emitcode (";", " %s type: SYMBOL",prefix);
402         if(IS_VALOP(op))
403                 DEBUGpic16_emitcode (";", " %s type: VALUE",prefix);
404         if(IS_TYPOP(op))
405                 DEBUGpic16_emitcode (";", " %s type: TYPE",prefix);
406         DEBUGpic16_emitcode (";", " %s isaddr:%d",prefix,op->isaddr);
407         DEBUGpic16_emitcode (";", " %s isvolatile:%d",prefix,op->isvolatile);
408         DEBUGpic16_emitcode (";" ," %s isGlobal:%d",prefix,op->isGlobal);
409         DEBUGpic16_emitcode (";", " %s isPtr:%d",prefix,op->isPtr);
410         DEBUGpic16_emitcode (";", " %s isGptr:%d",prefix,op->isGptr);
411         DEBUGpic16_emitcode (";", " %s isParm:%d",prefix,op->isParm);
412         DEBUGpic16_emitcode (";", " %s isLiteral:%d",prefix,op->isLiteral);
413         DEBUGpic16_emitcode (";", " %s key:%d",prefix,op->key);
414         if(IS_SYMOP(op)) {
415                 sprintf(s,"%s (symOperand)",prefix);
416                 pic16_DumpSymbol(s,op->operand.symOperand);
417         }
418
419 }