Beautified (indented) compiler source according to gnu coding style
[fw/sdcc] / src / ds390 / main.c
1 /** @file main.c
2     ds390 specific general functions.
3
4     Note that mlh prepended _ds390_ 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 *_ds390_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 ds390_assignRegisters (eBBlock ** ebbs, int count);
47
48 static int regParmFlg = 0;      /* determine if we can register a parameter */
49
50 static void
51 _ds390_init (void)
52 {
53   asm_addTree (&asm_asxxxx_mapping);
54 }
55
56 static void
57 _ds390_reset_regparm ()
58 {
59   regParmFlg = 0;
60 }
61
62 static int
63 _ds390_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 _ds390_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 _ds390_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       fprintf (stderr,
92                "*** warning: ds390 port only supports the flat24 model.\n");
93       options.model = MODEL_FLAT24;
94     }
95   port->s.fptr_size = 3;
96   port->s.gptr_size = 4;
97   port->stack.isr_overhead++;   /* Will save dpx on ISR entry. */
98 #if 1
99   port->stack.call_overhead++;  /* This acounts for the extra byte 
100                                  * of return addres on the stack.
101                                  * but is ugly. There must be a 
102                                  * better way.
103                                  */
104 #endif
105
106   if (options.model)
107     {
108       port->mem.default_local_map = xdata;
109       port->mem.default_globl_map = xdata;
110     }
111   else
112     {
113       port->mem.default_local_map = data;
114       port->mem.default_globl_map = data;
115     }
116
117   if (options.stack10bit)
118     {
119       if (options.model != MODEL_FLAT24)
120         {
121           fprintf (stderr,
122                    "*** warning: 10 bit stack mode is only supported in flat24 model.\n");
123           fprintf (stderr, "\t10 bit stack mode disabled.\n");
124           options.stack10bit = 0;
125         }
126       else
127         {
128           /* Fixup the memory map for the stack; it is now in
129            * far space and requires a FPOINTER to access it.
130            */
131           istack->fmap = 1;
132           istack->ptrType = FPOINTER;
133         }
134     }
135 }
136
137 static void
138 _ds390_setDefaultOptions (void)
139 {
140 }
141
142 static const char *
143 _ds390_getRegName (struct regs *reg)
144 {
145   if (reg)
146     return reg->name;
147   return "err";
148 }
149
150 static void
151 _ds390_genAssemblerPreamble (FILE * of)
152 {
153   if (options.model == MODEL_FLAT24)
154     {
155       fputs (".flat24 on\t\t; 24 bit flat addressing\n", of);
156       fputs ("dpx = 0x93\t\t; dpx register unknown to assembler\n", of);
157       fputs ("dps = 0x86\t\t; dps register unknown to assembler\n", of);
158       fputs ("dpl1 = 0x84\t\t; dpl1 register unknown to assembler\n", of);
159       fputs ("dph1 = 0x85\t\t; dph1 register unknown to assembler\n", of);
160       fputs ("dpx1 = 0x95\t\t; dpx1 register unknown to assembler\n", of);
161       fputs ("ap = 0x9C\t\t; ap register unknown to assembler\n", of);
162     }
163 }
164
165 /* Generate interrupt vector table. */
166 static int
167 _ds390_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
168 {
169   int i;
170
171   if (options.model != MODEL_FLAT24)
172     {
173       /* Let the default code handle it. */
174       return FALSE;
175     }
176
177   fprintf (of, "\tajmp\t__sdcc_gsinit_startup\n");
178
179   /* now for the other interrupts */
180   for (i = 0; i < maxInterrupts; i++)
181     {
182       if (interrupts[i])
183         {
184           fprintf (of, "\tljmp\t%s\n\t.ds\t4\n", interrupts[i]->rname);
185         }
186       else
187         {
188           fprintf (of, "\treti\n\t.ds\t7\n");
189         }
190     }
191
192   return TRUE;
193 }
194
195 /** $1 is always the basename.
196     $2 is always the output file.
197     $3 varies
198     $l is the list of extra options that should be there somewhere...
199     MUST be terminated with a NULL.
200 */
201 static const char *_linkCmd[] =
202 {
203   "aslink", "-nf", "$1", NULL
204 };
205
206 static const char *_asmCmd[] =
207 {
208   "asx8051", "-plosgff", "$1.asm", NULL
209 };
210
211 /* Globals */
212 PORT ds390_port =
213 {
214   "ds390",
215   "DS80C390",                   /* Target name */
216   {
217     TRUE,                       /* Emit glue around main */
218     MODEL_SMALL | MODEL_LARGE | MODEL_FLAT24,
219     MODEL_SMALL
220   },
221   {
222     _asmCmd,
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, 3, 1, 4, 4
238   },
239   {
240     "XSEG    (XDATA)",
241     "STACK   (DATA)",
242     "CSEG    (CODE)",
243     "DSEG    (DATA)",
244     "ISEG    (DATA)",
245     "XSEG    (XDATA)",
246     "BSEG    (BIT)",
247     "RSEG    (DATA)",
248     "GSINIT  (CODE)",
249     "OSEG    (OVR,DATA)",
250     "GSFINAL (CODE)",
251     "HOME        (CODE)",
252     NULL,
253     NULL,
254     1
255   },
256   {
257     +1, 1, 4, 1, 1, 0
258   },
259     /* ds390 has an 8 bit mul */
260   {
261     1, 0
262   },
263   "_",
264   _ds390_init,
265   _ds390_parseOptions,
266   _ds390_finaliseOptions,
267   _ds390_setDefaultOptions,
268   ds390_assignRegisters,
269   _ds390_getRegName,
270   _ds390_keywords,
271   _ds390_genAssemblerPreamble,
272   _ds390_genIVT,
273   _ds390_reset_regparm,
274   _ds390_regparm,
275   NULL,
276   FALSE,
277   0,                            /* leave lt */
278   0,                            /* leave gt */
279   1,                            /* transform <= to ! > */
280   1,                            /* transform >= to ! < */
281   1,                            /* transform != to !(a == b) */
282   0,                            /* leave == */
283   PORT_MAGIC
284 };