pCode - register allocation, flow analysis, and peephole.
[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 static char _defaultRules[] =
13 {
14 #include "peeph.rul"
15 };
16
17 /* list of key words used by msc51 */
18 static char *_pic14_keywords[] =
19 {
20   "at",
21   "bit",
22   "code",
23   "critical",
24   "data",
25   "far",
26   "idata",
27   "interrupt",
28   "near",
29   "pdata",
30   "reentrant",
31   "sfr",
32   "sbit",
33   "using",
34   "xdata",
35   "_data",
36   "_code",
37   "_generic",
38   "_near",
39   "_xdata",
40   "_pdata",
41   "_idata",
42   NULL
43 };
44
45
46 void pic14_assignRegisters (eBBlock ** ebbs, int count);
47
48 static int regParmFlg = 0;      /* determine if we can register a parameter */
49
50 static void
51 _pic14_init (void)
52 {
53   asm_addTree (&asm_asxxxx_mapping);
54 }
55
56 static void
57 _pic14_reset_regparm ()
58 {
59   regParmFlg = 0;
60 }
61
62 static int
63 _pic14_regparm (sym_link * l)
64 {
65   /* for this processor it is simple
66      can pass only the first parameter in a register */
67   if (regParmFlg)
68     return 0;
69
70   regParmFlg = 1;
71   return 1;
72 }
73
74 static bool
75 _pic14_parseOptions (int *pargc, char **argv, int *i)
76 {
77   /* TODO: allow port-specific command line options to specify
78    * segment names here.
79    */
80   return FALSE;
81 }
82
83 static void
84 _pic14_finaliseOptions (void)
85 {
86
87       port->mem.default_local_map = data;
88       port->mem.default_globl_map = data;
89 #if 0
90   /* Hack-o-matic: if we are using the flat24 model,
91    * adjust pointer sizes.
92    */
93   if (options.model == MODEL_FLAT24)
94     {
95
96       fprintf (stderr, "*** WARNING: you should use the '-mds390' option "
97                "for DS80C390 support. This code generator is "
98                "badly out of date and probably broken.\n");
99
100       port->s.fptr_size = 3;
101       port->s.gptr_size = 4;
102       port->stack.isr_overhead++;       /* Will save dpx on ISR entry. */
103 #if 1
104       port->stack.call_overhead++;      /* This acounts for the extra byte 
105                                          * of return addres on the stack.
106                                          * but is ugly. There must be a 
107                                          * better way.
108                                          */
109 #endif
110       fReturn = fReturn390;
111       fReturnSize = 5;
112     }
113
114   if (options.model == MODEL_LARGE)
115     {
116       port->mem.default_local_map = xdata;
117       port->mem.default_globl_map = xdata;
118     }
119   else
120     {
121       port->mem.default_local_map = data;
122       port->mem.default_globl_map = data;
123     }
124
125   if (options.stack10bit)
126     {
127       if (options.model != MODEL_FLAT24)
128         {
129           fprintf (stderr,
130                    "*** warning: 10 bit stack mode is only supported in flat24 model.\n");
131           fprintf (stderr, "\t10 bit stack mode disabled.\n");
132           options.stack10bit = 0;
133         }
134       else
135         {
136           /* Fixup the memory map for the stack; it is now in
137            * far space and requires a FPOINTER to access it.
138            */
139           istack->fmap = 1;
140           istack->ptrType = FPOINTER;
141         }
142     }
143 #endif
144 }
145
146 static void
147 _pic14_setDefaultOptions (void)
148 {
149 }
150
151 static const char *
152 _pic14_getRegName (struct regs *reg)
153 {
154   if (reg)
155     return reg->name;
156   return "err";
157 }
158
159 static void
160 _pic14_genAssemblerPreamble (FILE * of)
161 {
162   fprintf (of, "\tlist\tp=16c84\n");
163   fprintf (of, "\t__config _wdt_off\n");
164   fprintf (of, "\ninclude \"p16c84.inc\"\n");
165 }
166
167 /* Generate interrupt vector table. */
168 static int
169 _pic14_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
170 {
171   int i;
172
173   if (options.model != MODEL_FLAT24)
174     {
175       /* Let the default code handle it. */
176       return FALSE;
177     }
178
179   fprintf (of, "\t;ajmp\t__sdcc_gsinit_startup\n");
180
181   /* now for the other interrupts */
182   for (i = 0; i < maxInterrupts; i++)
183     {
184       if (interrupts[i])
185         {
186           fprintf (of, "\t;ljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
187         }
188       else
189         {
190           fprintf (of, "\t;reti\n\t.ds\t7\n");
191         }
192     }
193
194   return TRUE;
195 }
196
197 /** $1 is always the basename.
198     $2 is always the output file.
199     $3 varies
200     $l is the list of extra options that should be there somewhere...
201     MUST be terminated with a NULL.
202 */
203 static const char *_linkCmd[] =
204 {
205   "aslink", "-nf", "$1", NULL
206 };
207
208 static const char *_asmCmd[] =
209 {
210   "gpasm", NULL, NULL, NULL
211
212 };
213
214 /* Globals */
215 PORT pic_port =
216 {
217   TARGET_ID_PIC,
218   "pic14",
219   "MCU pic",                    /* Target name */
220   {
221     TRUE,                       /* Emit glue around main */
222     MODEL_SMALL | MODEL_LARGE | MODEL_FLAT24,
223     MODEL_SMALL
224   },
225   {
226     _asmCmd,
227     NULL,
228     NULL,
229         //"-plosgffc",          /* Options with debug */
230         //"-plosgff",           /* Options without debug */
231     0
232   },
233   {
234     _linkCmd,
235     NULL,
236     ".rel"
237   },
238   {
239     _defaultRules
240   },
241   {
242         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
243     1, 1, 2, 4, 1, 2, 1, 1, 4, 4
244         /* TSD - I changed the size of gptr from 3 to 1. However, it should be
245            2 so that we can accomodate the PIC's with 4 register banks (like the
246            16f877)
247          */
248   },
249   {
250     "XSEG    (XDATA)",
251     "STACK   (DATA)",
252     "CSEG    (CODE)",
253     "DSEG    (DATA)",
254     "ISEG    (DATA)",
255     "XSEG    (XDATA)",
256     "BSEG    (BIT)",
257     "RSEG    (DATA)",
258     "GSINIT  (CODE)",
259     "OSEG    (OVR,DATA)",
260     "GSFINAL (CODE)",
261     "HOME        (CODE)",
262     NULL,
263     NULL,
264     1
265   },
266   {
267     +1, 1, 4, 1, 1, 0
268   },
269     /* pic14 has an 8 bit mul */
270   {
271     1, 0
272   },
273   "_",
274   _pic14_init,
275   _pic14_parseOptions,
276   _pic14_finaliseOptions,
277   _pic14_setDefaultOptions,
278   pic14_assignRegisters,
279   _pic14_getRegName,
280   _pic14_keywords,
281   _pic14_genAssemblerPreamble,
282   _pic14_genIVT,
283   _pic14_reset_regparm,
284   _pic14_regparm,
285   NULL,
286   FALSE,
287   0,                            /* leave lt */
288   0,                            /* leave gt */
289   1,                            /* transform <= to ! > */
290   1,                            /* transform >= to ! < */
291   1,                            /* transform != to !(a == b) */
292   0,                            /* leave == */
293   PORT_MAGIC
294 };