Fixed several pointer related bugs in the PIC port
[fw/sdcc] / src / pic / main.c
1 /** @file main.c
2     pic14 specific general functions.
3
4     Note that mlh prepended _pic14_ on the static functions.  Makes
5     it easier to set a breakpoint using the debugger.
6 */
7 #include "common.h"
8 #include "main.h"
9 #include "ralloc.h"
10 #include "device.h"
11 //#include "gen.h"
12
13
14 static char _defaultRules[] =
15 {
16 #include "peeph.rul"
17 };
18
19 /* list of key words used by msc51 */
20 static char *_pic14_keywords[] =
21 {
22   "at",
23   "bit",
24   "code",
25   "critical",
26   "data",
27   "far",
28   "idata",
29   "interrupt",
30   "near",
31   "pdata",
32   "reentrant",
33   "sfr",
34   "sbit",
35   "using",
36   "xdata",
37   "_data",
38   "_code",
39   "_generic",
40   "_near",
41   "_xdata",
42   "_pdata",
43   "_idata",
44   NULL
45 };
46
47 void  pCodeInitRegisters(void);
48
49 void pic14_assignRegisters (eBBlock ** ebbs, int count);
50
51 static int regParmFlg = 0;      /* determine if we can register a parameter */
52
53 static void
54 _pic14_init (void)
55 {
56   asm_addTree (&asm_asxxxx_mapping);
57   pCodeInitRegisters();
58 }
59
60 static void
61 _pic14_reset_regparm ()
62 {
63   regParmFlg = 0;
64 }
65
66 static int
67 _pic14_regparm (sym_link * l)
68 {
69   /* for this processor it is simple
70      can pass only the first parameter in a register */
71   //if (regParmFlg)
72   //  return 0;
73
74   regParmFlg++;// = 1;
75   return 1;
76 }
77
78 static bool
79 _pic14_parseOptions (int *pargc, char **argv, int *i)
80 {
81   /* TODO: allow port-specific command line options to specify
82    * segment names here.
83    */
84   return FALSE;
85 }
86
87 static void
88 _pic14_finaliseOptions (void)
89 {
90
91       port->mem.default_local_map = data;
92       port->mem.default_globl_map = data;
93 #if 0
94   /* Hack-o-matic: if we are using the flat24 model,
95    * adjust pointer sizes.
96    */
97   if (options.model == MODEL_FLAT24)
98     {
99
100       fprintf (stderr, "*** WARNING: you should use the '-mds390' option "
101                "for DS80C390 support. This code generator is "
102                "badly out of date and probably broken.\n");
103
104       port->s.fptr_size = 3;
105       port->s.gptr_size = 4;
106       port->stack.isr_overhead++;       /* Will save dpx on ISR entry. */
107 #if 1
108       port->stack.call_overhead++;      /* This acounts for the extra byte 
109                                          * of return addres on the stack.
110                                          * but is ugly. There must be a 
111                                          * better way.
112                                          */
113 #endif
114       fReturn = fReturn390;
115       fReturnSize = 5;
116     }
117
118   if (options.model == MODEL_LARGE)
119     {
120       port->mem.default_local_map = xdata;
121       port->mem.default_globl_map = xdata;
122     }
123   else
124     {
125       port->mem.default_local_map = data;
126       port->mem.default_globl_map = data;
127     }
128
129   if (options.stack10bit)
130     {
131       if (options.model != MODEL_FLAT24)
132         {
133           fprintf (stderr,
134                    "*** warning: 10 bit stack mode is only supported in flat24 model.\n");
135           fprintf (stderr, "\t10 bit stack mode disabled.\n");
136           options.stack10bit = 0;
137         }
138       else
139         {
140           /* Fixup the memory map for the stack; it is now in
141            * far space and requires a FPOINTER to access it.
142            */
143           istack->fmap = 1;
144           istack->ptrType = FPOINTER;
145         }
146     }
147 #endif
148 }
149
150 static void
151 _pic14_setDefaultOptions (void)
152 {
153 }
154
155 static const char *
156 _pic14_getRegName (struct regs *reg)
157 {
158   if (reg)
159     return reg->name;
160   return "err";
161 }
162
163 extern char *processor_base_name(void);
164
165 static void
166 _pic14_genAssemblerPreamble (FILE * of)
167 {
168   char * name = processor_base_name();
169
170   if(!name) {
171
172     name = "p16f877";
173     fprintf(stderr,"WARNING: No Pic has been selected, defaulting to %s\n",name);
174   }
175
176   fprintf (of, "\tlist\tp=%s\n",&name[1]);
177   fprintf (of, "\t__CONFIG 0x%x\n",getConfigWord(0x2007));
178   fprintf (of, "\ninclude \"%s.inc\"\n",name);
179 }
180
181 /* Generate interrupt vector table. */
182 static int
183 _pic14_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
184 {
185   int i;
186
187   if (options.model != MODEL_FLAT24)
188     {
189       /* Let the default code handle it. */
190       return FALSE;
191     }
192
193   fprintf (of, "\t;ajmp\t__sdcc_gsinit_startup\n");
194
195   /* now for the other interrupts */
196   for (i = 0; i < maxInterrupts; i++)
197     {
198       if (interrupts[i])
199         {
200           fprintf (of, "\t;ljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
201         }
202       else
203         {
204           fprintf (of, "\t;reti\n\t.ds\t7\n");
205         }
206     }
207
208   return TRUE;
209 }
210
211 static bool
212 _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
213 {
214   sym_link *test = NULL;
215   value *val;
216
217   fprintf(stderr,"checking for native mult\n");
218
219   if ( ic->op != '*')
220     {
221       return FALSE;
222     }
223
224   return TRUE;
225 /*
226   if ( IS_LITERAL (left))
227     {
228       fprintf(stderr,"left is lit\n");
229       test = left;
230       val = OP_VALUE (IC_LEFT (ic));
231     }
232   else if ( IS_LITERAL (right))
233     {
234       fprintf(stderr,"right is lit\n");
235       test = left;
236       val = OP_VALUE (IC_RIGHT (ic));
237     }
238   else
239     {
240       fprintf(stderr,"oops, neither is lit so no\n");
241       return FALSE;
242     }
243
244   if ( getSize (test) <= 2)
245     {
246       fprintf(stderr,"yep\n");
247       return TRUE;
248     }
249   fprintf(stderr,"nope\n");
250
251   return FALSE;
252 */
253 }
254
255 /** $1 is always the basename.
256     $2 is always the output file.
257     $3 varies
258     $l is the list of extra options that should be there somewhere...
259     MUST be terminated with a NULL.
260 */
261 static const char *_linkCmd[] =
262 {
263   "aslink", "-nf", "$1", NULL
264 };
265
266 /* Sigh. This really is not good. For now, I recommend:
267  * sdcc -S -mpic14 file.c
268  * the -S option does not compile or link
269  */
270 static const char *_asmCmd[] =
271 {
272   "gpasm", "-c  -I /usr/local/share/gpasm/header", "$1.asm", NULL
273
274 };
275
276 /* Globals */
277 PORT pic_port =
278 {
279   TARGET_ID_PIC,
280   "pic14",
281   "MCU pic",                    /* Target name */
282   "p16f877",                    /* Processor */
283   {
284     TRUE,                       /* Emit glue around main */
285     MODEL_SMALL | MODEL_LARGE | MODEL_FLAT24,
286     MODEL_SMALL
287   },
288   {
289     _asmCmd,
290     NULL,
291     NULL,
292     NULL,
293         //"-plosgffc",          /* Options with debug */
294         //"-plosgff",           /* Options without debug */
295     0,
296     ".asm",
297     NULL                        /* no do_assemble function */
298   },
299   {
300     _linkCmd,
301     NULL,
302     NULL,
303     ".rel"
304   },
305   {
306     _defaultRules
307   },
308   {
309         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
310     1, 2, 2, 4, 1, 2, 2, 1, 4, 4
311         /* TSD - I changed the size of gptr from 3 to 1. However, it should be
312            2 so that we can accomodate the PIC's with 4 register banks (like the
313            16f877)
314          */
315   },
316   {
317     "XSEG    (XDATA)",
318     "STACK   (DATA)",
319     "CSEG    (CODE)",
320     "DSEG    (DATA)",
321     "ISEG    (DATA)",
322     "XSEG    (XDATA)",
323     "BSEG    (BIT)",
324     "RSEG    (DATA)",
325     "GSINIT  (CODE)",
326     "OSEG    (OVR,DATA)",
327     "GSFINAL (CODE)",
328     "HOME        (CODE)",
329     NULL, // xidata
330     NULL, // xinit
331     NULL,
332     NULL,
333     1        // code is read only
334   },
335   {
336     +1, 1, 4, 1, 1, 0
337   },
338     /* pic14 has an 8 bit mul */
339   {
340     1, -1
341   },
342   "_",
343   _pic14_init,
344   _pic14_parseOptions,
345   NULL,
346   _pic14_finaliseOptions,
347   _pic14_setDefaultOptions,
348   pic14_assignRegisters,
349   _pic14_getRegName,
350   _pic14_keywords,
351   _pic14_genAssemblerPreamble,
352   NULL,                         /* no genAssemblerEnd */
353   _pic14_genIVT,
354   NULL, // _pic14_genXINIT
355   _pic14_reset_regparm,
356   _pic14_regparm,
357   NULL,
358   NULL,
359   _hasNativeMulFor,
360   FALSE,
361   0,                            /* leave lt */
362   0,                            /* leave gt */
363   1,                            /* transform <= to ! > */
364   1,                            /* transform >= to ! < */
365   1,                            /* transform != to !(a == b) */
366   0,                            /* leave == */
367   FALSE,                        /* No array initializer support. */
368   0,                            /* no CSE cost estimation yet */
369   NULL,                         /* no builtin functions */
370   GPOINTER,                     /* treat unqualified pointers as "generic" pointers */
371   1,                            /* reset labelKey to 1 */
372   1,                            /* globals & local static allowed */
373   PORT_MAGIC
374 };