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