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