Replaced cast (void **) with (void *) to avoid gcc 3 warning:
[fw/sdcc] / src / xa51 / main.c
1 /* @file main.c
2    xa51 specific general functions.
3 */
4
5 #include "common.h"
6 #include "main.h"
7 #include "ralloc.h"
8 #include "gen.h"
9
10 static char _defaultRules[] =
11 {
12 #include "peeph.rul"
13 };
14
15 /* list of key words used by xa51 */
16 static char *_xa51_keywords[] =
17 {
18   "at",
19   "bit",
20   "code",
21   "critical",
22   "data",
23   "far",
24   //"idata",
25   "interrupt",
26   "near",
27   //"pdata",
28   "reentrant",
29   "sfr",
30   "sbit",
31   "using",
32   "xdata",
33   //"_data",
34   //"_code",
35   //"_generic",
36   //"_near",
37   //"_xdata",
38   //"_pdata",
39   //"_idata",
40   "_naked",
41   //"_overlay",
42   NULL
43 };
44
45 /* rewinds declared in asm.c, function printCLine().
46  * Currently commented out.
47  *
48  * extern int rewinds;
49  */
50 void   _xa51_genAssemblerEnd (FILE * of)
51 {
52   //fprintf (stderr, "Did %d rewind%c for c-line in asm comments\n", rewinds,
53   //rewinds==1 ? '\0' : 's');
54 }
55
56 void xa51_assignRegisters (eBBlock ** ebbs, int count);
57
58 static int regParmFlg = 0;      /* determine if we can register a parameter */
59
60 static void
61 _xa51_init (void)
62 {
63   asm_addTree (&asm_xa_asm_mapping);
64 }
65
66 static void
67 _xa51_reset_regparm ()
68 {
69   regParmFlg = 0;
70 }
71
72 static int
73 _xa51_regparm (sym_link * l)
74 {
75   return 0; // for now
76   /* for this processor it is simple
77      can pass only the first parameter in a register */
78   if (regParmFlg)
79     return 0;
80
81   regParmFlg = 1;
82   return 1;
83 }
84
85 static bool
86 _xa51_parseOptions (int *pargc, char **argv, int *i)
87 {
88   /* TODO: allow port-specific command line options to specify
89    * segment names here.
90    */
91   return FALSE;
92 }
93
94 static void
95 _xa51_finaliseOptions (void)
96 {
97   fprintf (stderr, "*** WARNING *** The XA51 port isn't yet complete\n");
98   port->mem.default_local_map = istack;
99   port->mem.default_globl_map = xdata;
100   if (options.model!=MODEL_PAGE0) {
101     fprintf (stderr, "-mxa51 only supports --model-page0\n");
102     exit (1);
103   }
104 }
105
106 static void
107 _xa51_setDefaultOptions (void)
108 {
109   options.stackAuto=1;
110   options.intlong_rent=1;
111   options.float_rent=1;
112   options.stack_loc=0x100;
113   options.data_loc=0;
114 }
115
116 static const char *
117 _xa51_getRegName (struct regs *reg)
118 {
119   if (reg)
120     return reg->name;
121   return "err";
122 }
123
124 /* Generate interrupt vector table. */
125 static int
126 _xa51_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
127 {
128   return TRUE;
129 }
130
131 /* Generate code to copy XINIT to XISEG */
132 static void _xa51_genXINIT (FILE * of) {
133   fprintf (of, ";       _xa51_genXINIT() start\n");
134   fprintf (of, "        mov     r0,#l_XINIT\n");
135   fprintf (of, "        beq     00002$\n");
136   fprintf (of, "        mov     r1,#s_XINIT\n");
137   fprintf (of, "        mov     r2,#s_XISEG\n");
138   fprintf (of, "00001$: movc    r3l,[r1+]\n");
139   fprintf (of, "        mov     [r2+],r3l\n");
140   fprintf (of, "        djnz    r0,00001$\n");
141   fprintf (of, "00002$:\n");
142   fprintf (of, ";       _xa51_genXINIT() end\n");
143 }
144
145 static void
146 _xa51_genAssemblerPreamble (FILE * of)
147 {
148   symbol *mainExists=newSymbol("main", 0);
149   mainExists->block=0;
150
151   if ((mainExists=findSymWithLevel(SymbolTab, mainExists))) {
152     fprintf (of, "\t.area GSINIT\t(CODE)\n");
153     fprintf (of, "__interrupt_vect:\n");
154     fprintf (of, "\t.dw\t0x8f00\n");
155     fprintf (of, "\t.dw\t__sdcc_gsinit_startup\n");
156     fprintf (of, "\n");
157     fprintf (of, "__sdcc_gsinit_startup:\n");
158     fprintf (of, ";\tmov.b\t_SCR,#0x01\t; page zero mode\n");
159     fprintf (of, "\t.db 0x96,0x48,0x40,0x01\n");
160     fprintf (of, "\tmov\tr7,#0x%04x\n", options.stack_loc);
161     fprintf (of, "\tcall\t_external_startup\n");
162     _xa51_genXINIT(of);
163     fprintf (of, "\t.area CSEG\t(CODE)\n");
164     fprintf (of, "\tcall\t_main\n");
165     fprintf (of, "\treset\t;main should not return\n");
166   }
167 }
168
169 /* dummy linker for now */
170 void xa_link(void) {
171 }
172
173 /* Do CSE estimation */
174 static bool cseCostEstimation (iCode *ic, iCode *pdic)
175 {
176     operand *result = IC_RESULT(ic);
177     sym_link *result_type = operandType(result);
178
179     /* if it is a pointer then return ok for now */
180     if (IC_RESULT(ic) && IS_PTR(result_type)) return 1;
181     
182     /* if bitwise | add & subtract then no since xa51 is pretty good at it 
183        so we will cse only if they are local (i.e. both ic & pdic belong to
184        the same basic block */
185     if (IS_BITWISE_OP(ic) || ic->op == '+' || ic->op == '-') {
186         /* then if they are the same Basic block then ok */
187         if (ic->eBBlockNum == pdic->eBBlockNum) return 1;
188         else return 0;
189     }
190         
191     /* for others it is cheaper to do the cse */
192     return 1;
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   "xa_link", "", "\"$1\"", NULL
204 };
205
206 /* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */
207 static const char *_asmCmd[] =
208 {
209   "xa_rasm", "$l", "$3", "\"$1.asm\"", NULL
210 };
211
212 /* Globals */
213 PORT xa51_port =
214 {
215   TARGET_ID_XA51,
216   "xa51",
217   "MCU 80C51XA",                /* Target name */
218   NULL,                         /* Processor name */
219   {
220     glue,
221     FALSE,                      /* Emit glue around main */
222     MODEL_PAGE0,
223     MODEL_PAGE0
224   },
225   {
226     _asmCmd,
227     NULL,
228     "",                         /* Options with debug */
229     "",                         /* Options without debug */
230     0,
231     ".asm",
232     NULL                        /* no do_assemble function */
233   },
234   {
235     _linkCmd,
236     NULL,
237     NULL,
238     ".rel"
239   },
240   {
241     _defaultRules
242   },
243   {
244         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
245     1, 2, 2, 4, 2, 2, 3, 1, 4, 4
246   },
247   {
248     "XSEG    (XDATA)",
249     "STACK   (XDATA)",
250     "CSEG    (CODE)",
251     "DSEG    (DATA)",
252     NULL, //"ISEG    (DATA)",
253     "XSEG    (XDATA)",
254     "BSEG    (BIT)",
255     NULL, //"RSEG    (DATA)",
256     "GSINIT  (CODE)",
257     NULL, //"OSEG    (OVR,XDATA)",
258     "GSFINAL (CODE)",
259     "HOME    (CODE)",
260     "XISEG   (XDATA)", // initialized xdata
261     "XINIT   (CODE)", // a code copy of xiseg
262     NULL, // default local map
263     NULL, // default global map
264     1
265   },
266   { NULL, NULL },
267   {
268     -1, // stack grows down
269     0, // bank overhead NUY
270     4, // isr overhead, page zero mode
271     2, // function call overhead, page zero mode
272     0, // reentrant overhead NUY
273     0 // banked overhead NUY
274   },
275     /* xa51 has an 16 bit mul */
276   {
277     2, -2
278   },
279   "_",
280   _xa51_init,
281   _xa51_parseOptions,
282   NULL,
283   _xa51_finaliseOptions,
284   _xa51_setDefaultOptions,
285   xa51_assignRegisters,
286   _xa51_getRegName,
287   _xa51_keywords,
288   _xa51_genAssemblerPreamble,
289   _xa51_genAssemblerEnd,
290   _xa51_genIVT,
291   _xa51_genXINIT,
292   _xa51_reset_regparm,
293   _xa51_regparm,
294   NULL, // process_pragma()
295   NULL, // getMangledFunctionName()
296   NULL, // hasNativeMulFor()
297   TRUE, // use_dw_for_init
298   TRUE,                         /* little endian */
299   0,                            /* leave lt */
300   0,                            /* leave gt */
301   1,                            /* transform <= to ! > */
302   1,                            /* transform >= to ! < */
303   1,                            /* transform != to !(a == b) */
304   0,                            /* leave == */
305   FALSE,                        /* No array initializer support. */
306   cseCostEstimation,
307   NULL,                         /* no builtin functions */
308   GPOINTER,                     /* treat unqualified pointers as "generic" pointers */
309   1,                            /* reset labelKey to 1 */
310   1,                            /* globals & local static allowed */
311   PORT_MAGIC
312 };