* .version: bumped version number to 2.4.5
[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         emitSETC;
110         pic16_emitpcode(POC_TSTFSZ, pic16_popCopyReg( &pic16_pc_wreg ));
111         emitCLRC;
112         pic16_outBitC( IC_RESULT(ic) );
113
114 release:    
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);
118 }
119
120 #endif  /* defined(GEN_Not) */
121
122
123
124 #if defined(GEN_Cpl)
125 /*-----------------------------------------------------------------*/
126 /* pic16_genCpl - generate code for complement                     */
127 /*-----------------------------------------------------------------*/
128 void pic16_genCpl (iCode *ic)
129 {
130   int offset = 0;
131   int size ;
132
133 /*
134  * result[CRY,REG] = ~left[CRY,REG]
135  */
136  
137
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));
143
144         /* if both are in bit space then 
145            a special case */
146         if (AOP_TYPE(IC_RESULT(ic)) == AOP_CRY &&
147                 AOP_TYPE(IC_LEFT(ic)) == AOP_CRY ) { 
148
149                 /* FIXME */
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); 
153                 goto release; 
154         } 
155
156         size = AOP_SIZE(IC_RESULT(ic));
157         while (size--) {
158
159                 if (pic16_sameRegs(AOP(IC_LEFT(ic)), AOP(IC_RESULT(ic))) ) {
160                         pic16_emitpcode(POC_COMF,  pic16_popGet(AOP(IC_LEFT(ic)), offset));
161                 } else {
162                         pic16_emitpcode(POC_COMFW, pic16_popGet(AOP(IC_LEFT(ic)),offset));
163                         pic16_emitpcode(POC_MOVWF, pic16_popGet(AOP(IC_RESULT(ic)),offset));
164                 }
165                 offset++;
166         }
167
168 release:
169     /* release the aops */
170     pic16_freeAsmop(IC_LEFT(ic),NULL,ic,(RESULTONSTACK(ic) ? 0 : 1));
171     pic16_freeAsmop(IC_RESULT(ic),NULL,ic,TRUE);
172 }
173 #endif  /* defined(GEN_Cpl) */
174
175
176
177 /*-----------------------------------------------------------------*/
178 /* Helper function to dump operand into comment lines              */
179 /*-----------------------------------------------------------------*/
180
181 void pic16_DumpValue(char *prefix, value *val)
182 {
183 //      char s[INITIAL_INLINEASM];  
184         if(!val) return;
185
186         DEBUGpic16_emitcode (";", " %s Dump value",prefix);
187         DEBUGpic16_emitcode (";", " %s name:%s",prefix,val->name);
188 }
189
190 void pic16_DumpPcodeOp(char *prefix, pCodeOp *pcop)
191 {
192 //      char s[INITIAL_INLINEASM];  
193         if(!pcop) return;
194
195         DEBUGpic16_emitcode (";", " %s Dump pCodeOp",prefix);
196         DEBUGpic16_emitcode (";", " %s name:%s",prefix,pcop->name);
197         if(pcop->type == PO_NONE) {
198                 DEBUGpic16_emitcode (";", " %s type:PO_NONE",prefix);
199         }
200         if(pcop->type == PO_W) {
201                 DEBUGpic16_emitcode (";", " %s type:PO_W",prefix);
202         }
203         if(pcop->type == PO_WREG) {
204                 DEBUGpic16_emitcode (";", " %s type:PO_WREG",prefix);
205         }
206         if(pcop->type == PO_STATUS) {
207                 DEBUGpic16_emitcode (";", " %s type:PO_STATUS",prefix);
208         }
209         if(pcop->type == PO_BSR) {
210                 DEBUGpic16_emitcode (";", " %s type:PO_BSR",prefix);
211         }
212         if(pcop->type == PO_FSR0) {
213                 DEBUGpic16_emitcode (";", " %s type:PO_FSR0",prefix);
214         }
215         if(pcop->type == PO_INDF0) {
216                 DEBUGpic16_emitcode (";", " %s type:PO_INDF0",prefix);
217         }
218         if(pcop->type == PO_INTCON) {
219                 DEBUGpic16_emitcode (";", " %s type:PO_INTCON",prefix);
220         }
221         if(pcop->type == PO_GPR_REGISTER) {
222                 DEBUGpic16_emitcode (";", " %s type:PO_GPR_REGISTER",prefix);
223         }
224         if(pcop->type == PO_GPR_BIT) {
225                 DEBUGpic16_emitcode (";", " %s type:PO_GPR_BIT",prefix);
226         }
227         if(pcop->type == PO_GPR_TEMP) {
228                 DEBUGpic16_emitcode (";", " %s type:PO_GPR_TEMP",prefix);
229         }
230         if(pcop->type == PO_SFR_REGISTER) {
231                 DEBUGpic16_emitcode (";", " %s type:PO_SFR_REGISTER",prefix);
232         }
233         if(pcop->type == PO_PCL) {
234                 DEBUGpic16_emitcode (";", " %s type:PO_PCL",prefix);
235         }
236         if(pcop->type == PO_PCLATH) {
237                 DEBUGpic16_emitcode (";", " %s type:PO_PCLATH",prefix);
238         }
239         if(pcop->type == PO_LITERAL) {
240                 DEBUGpic16_emitcode (";", " %s type:PO_LITERAL",prefix);
241                 DEBUGpic16_emitcode (";", " %s lit:%s",prefix,PCOL(pcop)->lit);
242         }
243         if(pcop->type == PO_REL_ADDR) {
244                 DEBUGpic16_emitcode (";", " %s type:PO_REL_ADDR",prefix);
245         }
246         if(pcop->type == PO_IMMEDIATE) {
247                 DEBUGpic16_emitcode (";", " %s type:PO_IMMEDIATE",prefix);
248         }
249         if(pcop->type == PO_DIR) {
250                 DEBUGpic16_emitcode (";", " %s type:PO_DIR",prefix);
251         }
252         if(pcop->type == PO_CRY) {
253                 DEBUGpic16_emitcode (";", " %s type:PO_CRY",prefix);
254         }
255         if(pcop->type == PO_BIT) {
256                 DEBUGpic16_emitcode (";", " %s type:PO_BIT",prefix);
257         }
258         if(pcop->type == PO_STR) {
259                 DEBUGpic16_emitcode (";", " %s type:PO_STR",prefix);
260         }
261         if(pcop->type == PO_LABEL) {
262                 DEBUGpic16_emitcode (";", " %s type:PO_LABEL",prefix);
263         }
264         if(pcop->type == PO_WILD) {
265                 DEBUGpic16_emitcode (";", " %s type:PO_WILD",prefix);
266         }
267 }
268
269
270
271 void pic16_DumpAop(char *prefix, asmop *aop)
272 {
273         char s[INITIAL_INLINEASM];  
274         if(!aop) return;
275
276         DEBUGpic16_emitcode (";", " %s Dump asmop",prefix);
277         if (aop->type == AOP_LIT)
278         {
279                 DEBUGpic16_emitcode (";", " %s type:AOP_LIT",prefix);
280                 sprintf(s,"%s (aopu.aop_lit)",prefix);
281                 pic16_DumpValue(s,aop->aopu.aop_lit);
282         }
283         if (aop->type == AOP_REG)
284                 DEBUGpic16_emitcode (";", " %s type:AOP_REG",prefix);
285         if (aop->type == AOP_DIR)
286         {
287                 DEBUGpic16_emitcode (";", " %s type:AOP_DIR",prefix);
288                 DEBUGpic16_emitcode (";", " %s aopu.aop_dir:%s",prefix,aop->aopu.aop_dir);
289         }
290         if (aop->type == AOP_DPTR)
291                 DEBUGpic16_emitcode (";", " %s type:AOP_DPTR",prefix);
292         if (aop->type == AOP_DPTR2)
293                 DEBUGpic16_emitcode (";", " %s type:AOP_DPTR2",prefix);
294         if (aop->type == AOP_R0)
295                 DEBUGpic16_emitcode (";", " %s type:AOP_R0",prefix);
296         if (aop->type == AOP_R1)
297                 DEBUGpic16_emitcode (";", " %s type:AOP_R1",prefix);
298         if (aop->type == AOP_STK)
299                 DEBUGpic16_emitcode (";", " %s type:AOP_STK",prefix);
300         if (aop->type == AOP_STA)
301                 DEBUGpic16_emitcode (";", " %s type:AOP_STA",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 }