(optionally) push static array initialization down to the ports code generator
[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 static void
163 _pic14_genAssemblerPreamble (FILE * of)
164 {
165   fprintf (of, "\tlist\tp=16c84\n");
166   fprintf (of, "\t__config _wdt_off\n");
167   fprintf (of, "\ninclude \"p16c84.inc\"\n");
168 }
169
170 /* Generate interrupt vector table. */
171 static int
172 _pic14_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
173 {
174   int i;
175
176   if (options.model != MODEL_FLAT24)
177     {
178       /* Let the default code handle it. */
179       return FALSE;
180     }
181
182   fprintf (of, "\t;ajmp\t__sdcc_gsinit_startup\n");
183
184   /* now for the other interrupts */
185   for (i = 0; i < maxInterrupts; i++)
186     {
187       if (interrupts[i])
188         {
189           fprintf (of, "\t;ljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
190         }
191       else
192         {
193           fprintf (of, "\t;reti\n\t.ds\t7\n");
194         }
195     }
196
197   return TRUE;
198 }
199
200 /** $1 is always the basename.
201     $2 is always the output file.
202     $3 varies
203     $l is the list of extra options that should be there somewhere...
204     MUST be terminated with a NULL.
205 */
206 static const char *_linkCmd[] =
207 {
208   "aslink", "-nf", "$1", NULL
209 };
210
211 static const char *_asmCmd[] =
212 {
213   "gpasm", NULL, NULL, NULL
214
215 };
216
217 /* Globals */
218 PORT pic_port =
219 {
220   TARGET_ID_PIC,
221   "pic14",
222   "MCU pic",                    /* Target name */
223   {
224     TRUE,                       /* Emit glue around main */
225     MODEL_SMALL | MODEL_LARGE | MODEL_FLAT24,
226     MODEL_SMALL
227   },
228   {
229     _asmCmd,
230     NULL,
231     NULL,
232         //"-plosgffc",          /* Options with debug */
233         //"-plosgff",           /* Options without debug */
234     0,
235     ".asm"
236   },
237   {
238     _linkCmd,
239     NULL,
240     ".rel"
241   },
242   {
243     _defaultRules
244   },
245   {
246         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
247     1, 2, 2, 4, 1, 2, 1, 1, 4, 4
248         /* TSD - I changed the size of gptr from 3 to 1. However, it should be
249            2 so that we can accomodate the PIC's with 4 register banks (like the
250            16f877)
251          */
252   },
253   {
254     "XSEG    (XDATA)",
255     "STACK   (DATA)",
256     "CSEG    (CODE)",
257     "DSEG    (DATA)",
258     "ISEG    (DATA)",
259     "XSEG    (XDATA)",
260     "BSEG    (BIT)",
261     "RSEG    (DATA)",
262     "GSINIT  (CODE)",
263     "OSEG    (OVR,DATA)",
264     "GSFINAL (CODE)",
265     "HOME        (CODE)",
266     NULL,
267     NULL,
268     1
269   },
270   {
271     +1, 1, 4, 1, 1, 0
272   },
273     /* pic14 has an 8 bit mul */
274   {
275     1, -1
276   },
277   "_",
278   _pic14_init,
279   _pic14_parseOptions,
280   _pic14_finaliseOptions,
281   _pic14_setDefaultOptions,
282   pic14_assignRegisters,
283   _pic14_getRegName,
284   _pic14_keywords,
285   _pic14_genAssemblerPreamble,
286   _pic14_genIVT,
287   _pic14_reset_regparm,
288   _pic14_regparm,
289   NULL,
290   NULL,
291   FALSE,
292   0,                            /* leave lt */
293   0,                            /* leave gt */
294   1,                            /* transform <= to ! > */
295   1,                            /* transform >= to ! < */
296   1,                            /* transform != to !(a == b) */
297   0,                            /* leave == */
298   FALSE,                        /* No array initializer support. */
299   PORT_MAGIC
300 };