Beautified (indented) compiler source according to gnu coding style
[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   /* Hack-o-matic: if we are using the flat24 model,
87    * adjust pointer sizes.
88    */
89   if (options.model == MODEL_FLAT24)
90     {
91
92       fprintf (stderr, "*** WARNING: you should use the '-mds390' option "
93                "for DS80C390 support. This code generator is "
94                "badly out of date and probably broken.\n");
95
96       port->s.fptr_size = 3;
97       port->s.gptr_size = 4;
98       port->stack.isr_overhead++;       /* Will save dpx on ISR entry. */
99 #if 1
100       port->stack.call_overhead++;      /* This acounts for the extra byte 
101                                          * of return addres on the stack.
102                                          * but is ugly. There must be a 
103                                          * better way.
104                                          */
105 #endif
106       fReturn = fReturn390;
107       fReturnSize = 5;
108     }
109
110   if (options.model == MODEL_LARGE)
111     {
112       port->mem.default_local_map = xdata;
113       port->mem.default_globl_map = xdata;
114     }
115   else
116     {
117       port->mem.default_local_map = data;
118       port->mem.default_globl_map = data;
119     }
120
121   if (options.stack10bit)
122     {
123       if (options.model != MODEL_FLAT24)
124         {
125           fprintf (stderr,
126                    "*** warning: 10 bit stack mode is only supported in flat24 model.\n");
127           fprintf (stderr, "\t10 bit stack mode disabled.\n");
128           options.stack10bit = 0;
129         }
130       else
131         {
132           /* Fixup the memory map for the stack; it is now in
133            * far space and requires a FPOINTER to access it.
134            */
135           istack->fmap = 1;
136           istack->ptrType = FPOINTER;
137         }
138     }
139 }
140
141 static void
142 _pic14_setDefaultOptions (void)
143 {
144 }
145
146 static const char *
147 _pic14_getRegName (struct regs *reg)
148 {
149   if (reg)
150     return reg->name;
151   return "err";
152 }
153
154 static void
155 _pic14_genAssemblerPreamble (FILE * of)
156 {
157   fprintf (of, "\tlist\tp=16c84\n");
158   fprintf (of, "\t__config _wdt_off\n");
159   fprintf (of, "\ninclude \"p16c84.inc\"\n");
160 }
161
162 /* Generate interrupt vector table. */
163 static int
164 _pic14_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
165 {
166   int i;
167
168   if (options.model != MODEL_FLAT24)
169     {
170       /* Let the default code handle it. */
171       return FALSE;
172     }
173
174   fprintf (of, "\t;ajmp\t__sdcc_gsinit_startup\n");
175
176   /* now for the other interrupts */
177   for (i = 0; i < maxInterrupts; i++)
178     {
179       if (interrupts[i])
180         {
181           fprintf (of, "\t;ljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
182         }
183       else
184         {
185           fprintf (of, "\t;reti\n\t.ds\t7\n");
186         }
187     }
188
189   return TRUE;
190 }
191
192 /** $1 is always the basename.
193     $2 is always the output file.
194     $3 varies
195     $l is the list of extra options that should be there somewhere...
196     MUST be terminated with a NULL.
197 */
198 static const char *_linkCmd[] =
199 {
200   "aslink", "-nf", "$1", NULL
201 };
202
203 static const char *_asmCmd[] =
204 {
205   "gpasm", NULL, NULL, NULL
206
207 };
208
209 /* Globals */
210 PORT pic14_port =
211 {
212   "pic14",
213   "MCU pic",                    /* Target name */
214   {
215     TRUE,                       /* Emit glue around main */
216     MODEL_SMALL | MODEL_LARGE | MODEL_FLAT24,
217     MODEL_SMALL
218   },
219   {
220     _asmCmd,
221     NULL,
222     NULL,
223         //"-plosgffc",          /* Options with debug */
224         //"-plosgff",           /* Options without debug */
225     0
226   },
227   {
228     _linkCmd,
229     NULL,
230     ".rel"
231   },
232   {
233     _defaultRules
234   },
235   {
236         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
237     1, 1, 2, 4, 1, 2, 1, 1, 4, 4
238         /* TSD - I changed the size of gptr from 3 to 1. However, it should be
239            2 so that we can accomodate the PIC's with 4 register banks (like the
240            16f877)
241          */
242   },
243   {
244     "XSEG    (XDATA)",
245     "STACK   (DATA)",
246     "CSEG    (CODE)",
247     "DSEG    (DATA)",
248     "ISEG    (DATA)",
249     "XSEG    (XDATA)",
250     "BSEG    (BIT)",
251     "RSEG    (DATA)",
252     "GSINIT  (CODE)",
253     "OSEG    (OVR,DATA)",
254     "GSFINAL (CODE)",
255     "HOME        (CODE)",
256     NULL,
257     NULL,
258     1
259   },
260   {
261     +1, 1, 4, 1, 1, 0
262   },
263     /* pic14 has an 8 bit mul */
264   {
265     1, 0
266   },
267   "_",
268   _pic14_init,
269   _pic14_parseOptions,
270   _pic14_finaliseOptions,
271   _pic14_setDefaultOptions,
272   pic14_assignRegisters,
273   _pic14_getRegName,
274   _pic14_keywords,
275   _pic14_genAssemblerPreamble,
276   _pic14_genIVT,
277   _pic14_reset_regparm,
278   _pic14_regparm,
279   NULL,
280   FALSE,
281   0,                            /* leave lt */
282   0,                            /* leave gt */
283   1,                            /* transform <= to ! > */
284   1,                            /* transform >= to ! < */
285   1,                            /* transform != to !(a == b) */
286   0,                            /* leave == */
287   PORT_MAGIC
288 };