xa51 update
[fw/sdcc] / src / xa51 / main.c
1 /** @file main.c
2     xa51 specific general functions.
3
4     Note that mlh prepended _xa51_ 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 xa51 */
18 static char *_xa51_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   "_naked",
43   "_overlay",
44   NULL
45 };
46
47
48 void xa51_assignRegisters (eBBlock ** ebbs, int count);
49
50 static int regParmFlg = 0;      /* determine if we can register a parameter */
51
52 static void
53 _xa51_init (void)
54 {
55   asm_addTree (&asm_asxxxx_mapping);
56 }
57
58 static void
59 _xa51_reset_regparm ()
60 {
61   regParmFlg = 0;
62 }
63
64 static int
65 _xa51_regparm (sym_link * l)
66 {
67   return 0; // for now
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 _xa51_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 _xa51_finaliseOptions (void)
88 {
89   port->mem.default_local_map = istack;
90   port->mem.default_globl_map = xdata;
91 }
92
93 static void
94 _xa51_setDefaultOptions (void)
95 {
96   options.stackAuto=1;
97   options.intlong_rent=1;
98   options.float_rent=1;
99 }
100
101 static const char *
102 _xa51_getRegName (struct regs *reg)
103 {
104   if (reg)
105     return reg->name;
106   return "err";
107 }
108
109 static void
110 _xa51_genAssemblerPreamble (FILE * of)
111 {
112 }
113
114 /* Generate interrupt vector table. */
115 static int
116 _xa51_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts)
117 {
118   return FALSE;
119 }
120
121 /* Generate code to copy XINIT to XISEG */
122 static void _xa51_genXINIT (FILE * of) {
123   fprintf (of, ";       _xa51_genXINIT() start\n");
124   fprintf (of, "        mov     a,#l_XINIT\n");
125   fprintf (of, "        orl     a,#l_XINIT>>8\n");
126   fprintf (of, "        jz      00003$\n");
127   fprintf (of, "        mov     a,#s_XINIT\n");
128   fprintf (of, "        add     a,#l_XINIT\n");
129   fprintf (of, "        mov     r1,a\n");
130   fprintf (of, "        mov     a,#s_XINIT>>8\n");
131   fprintf (of, "        addc    a,#l_XINIT>>8\n");
132   fprintf (of, "        mov     r2,a\n");
133   fprintf (of, "        mov     dptr,#s_XINIT\n");
134   fprintf (of, "        mov     r0,#s_XISEG\n");
135   fprintf (of, "        mov     p2,#(s_XISEG >> 8)\n");
136   fprintf (of, "00001$: clr     a\n");
137   fprintf (of, "        movc    a,@a+dptr\n");
138   fprintf (of, "        movx    @r0,a\n");
139   fprintf (of, "        inc     dptr\n");
140   fprintf (of, "        inc     r0\n");
141   fprintf (of, "        cjne    r0,#0,00002$\n");
142   fprintf (of, "        inc     p2\n");
143   fprintf (of, "00002$: mov     a,dpl\n");
144   fprintf (of, "        cjne    a,ar1,00001$\n");
145   fprintf (of, "        mov     a,dph\n");
146   fprintf (of, "        cjne    a,ar2,00001$\n");
147   fprintf (of, "        mov     p2,#0xFF\n");
148   fprintf (of, "00003$:\n");
149   fprintf (of, ";       _xa51_genXINIT() end\n");
150 }
151
152
153 /* Do CSE estimation */
154 static bool cseCostEstimation (iCode *ic, iCode *pdic)
155 {
156     operand *result = IC_RESULT(ic);
157     sym_link *result_type = operandType(result);
158
159     /* if it is a pointer then return ok for now */
160     if (IC_RESULT(ic) && IS_PTR(result_type)) return 1;
161     
162     /* if bitwise | add & subtract then no since xa51 is pretty good at it 
163        so we will cse only if they are local (i.e. both ic & pdic belong to
164        the same basic block */
165     if (IS_BITWISE_OP(ic) || ic->op == '+' || ic->op == '-') {
166         /* then if they are the same Basic block then ok */
167         if (ic->eBBlockNum == pdic->eBBlockNum) return 1;
168         else return 0;
169     }
170         
171     /* for others it is cheaper to do the cse */
172     return 1;
173 }
174
175 /** $1 is always the basename.
176     $2 is always the output file.
177     $3 varies
178     $l is the list of extra options that should be there somewhere...
179     MUST be terminated with a NULL.
180 */
181 static const char *_linkCmd[] =
182 {
183   "{bindir}{sep}aslink", "-nf", "$1", NULL
184 };
185
186 /* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */
187 static const char *_asmCmd[] =
188 {
189   "xa_asm", "$l", "$3", "$1.asm", NULL
190 };
191
192 /* Globals */
193 PORT xa51_port =
194 {
195   TARGET_ID_XA51,
196   "xa51",
197   "MCU 80C51XA",                /* Target name */
198   {
199     TRUE,                       /* Emit glue around main */
200     MODEL_LARGE,
201     MODEL_LARGE
202   },
203   {
204     _asmCmd,
205     NULL,
206     "-plosgffc",                /* Options with debug */
207     "-plosgff",                 /* Options without debug */
208     0,
209     ".asm",
210     NULL                        /* no do_assemble function */
211   },
212   {
213     _linkCmd,
214     NULL,
215     NULL,
216     ".rel"
217   },
218   {
219     _defaultRules
220   },
221   {
222         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
223     1, 2, 2, 4, 2, 2, 3, 1, 4, 4
224   },
225   {
226     "XSEG    (XDATA)",
227     "STACK   (DATA)",
228     "CSEG    (CODE)",
229     "DSEG    (DATA)",
230     "ISEG    (DATA)",
231     "XSEG    (XDATA)",
232     "BSEG    (BIT)",
233     "RSEG    (DATA)",
234     "GSINIT  (CODE)",
235     "OSEG    (OVR,DATA)",
236     "GSFINAL (CODE)",
237     "HOME    (CODE)",
238     "XISEG   (XDATA)", // initialized xdata
239     "XINIT   (CODE)", // a code copy of xiseg
240     NULL, // default local map
241     NULL, // default global map
242     1
243   },
244   {
245     -1, // stack grows down
246     0, // bank overhead NUY
247     6, // isr overhead
248     4, // function call overhead
249     0, // reentrant overhead NUY
250     0 // banked overhead NUY
251   },
252     /* xa51 has an 16 bit mul */
253   {
254     2, -2
255   },
256   "_",
257   _xa51_init,
258   _xa51_parseOptions,
259   _xa51_finaliseOptions,
260   _xa51_setDefaultOptions,
261   xa51_assignRegisters,
262   _xa51_getRegName,
263   _xa51_keywords,
264   _xa51_genAssemblerPreamble,
265   NULL,                         /* no genAssemblerEnd */
266   _xa51_genIVT,
267   _xa51_genXINIT,
268   _xa51_reset_regparm,
269   _xa51_regparm,
270   NULL,
271   NULL,
272   NULL,
273   FALSE,
274   0,                            /* leave lt */
275   0,                            /* leave gt */
276   1,                            /* transform <= to ! > */
277   1,                            /* transform >= to ! < */
278   1,                            /* transform != to !(a == b) */
279   0,                            /* leave == */
280   FALSE,                        /* No array initializer support. */
281   cseCostEstimation,
282   NULL,                         /* no builtin functions */
283   GPOINTER,                     /* treat unqualified pointers as "generic" pointers */
284   1,                            /* reset labelKey to 1 */
285   1,                            /* globals & local static allowed */
286   PORT_MAGIC
287 };