Merged changes between gbdk-293 and main
[fw/sdcc] / src / z80 / main.c
1 #include "z80.h"
2
3 static char _z80_defaultRules[] =
4 {
5 #include "peeph.rul"
6 #include "peeph-z80.rul"
7 };
8
9 static char _gbz80_defaultRules[] =
10 {
11 #include "peeph.rul"
12 #include "peeph-gbz80.rul"
13 };
14
15 Z80_OPTS z80_opts;
16
17 static struct {
18     bool fsetAsmType;
19 } _G;
20
21 static char *_keywords[] = { NULL };
22
23 extern PORT gbz80_port;
24 extern PORT z80_port;
25
26 #include "mappings.i"
27
28 static void _z80_init(void)
29 {
30     z80_opts.sub = SUB_Z80;
31     asm_addTree(&_asxxxx_z80);
32 }
33
34 static void _gbz80_init(void)
35 {
36     z80_opts.sub = SUB_GBZ80;
37 }
38
39 static int regParmFlg = 0; /* determine if we can register a parameter */
40
41 static void _reset_regparm()
42 {
43     regParmFlg = 0;
44 }
45
46 static int _reg_parm(link *l)
47 {
48         /* for this processor it is simple
49        can pass only the first parameter in a register */
50     if (regParmFlg)
51         return 0;
52
53     regParmFlg = 1;
54     return 1;
55
56 }
57
58 static int _process_pragma(const char *sz)
59 {
60     printf("Got pragma \"%s\"\n", sz);
61     return 1;
62 }
63
64 static bool _parseOptions(int *pargc, char **argv, int *i)
65 {
66     if (argv[*i][0] == '-') {
67         if (argv[*i][1] == 'b' && IS_GB) {
68             int bank = atoi(argv[*i] + 3);
69             char buffer[128];
70             switch (argv[*i][2]) {
71             case 'o':
72                 /* ROM bank */
73                 sprintf(buffer, "_CODE_%u", bank);
74                 gbz80_port.mem.code_name = gc_strdup(buffer);
75                 return TRUE;
76             case 'a':
77                 /* RAM bank */
78                 sprintf(buffer, "_DATA_%u", bank);
79                 gbz80_port.mem.data_name = gc_strdup(buffer);
80                 return TRUE;
81             }
82         }
83         else if (!strncmp(argv[*i], "--asm=", 6)) {
84             if (!strcmp(argv[*i], "--asm=rgbds")) {
85                 asm_addTree(&_rgbds_gb);
86                 _G.fsetAsmType = TRUE;
87                 return TRUE;
88             }
89             else if (!strcmp(argv[*i], "--asm=asxxxx")) {
90                 asm_addTree(&_asxxxx_gb);
91                 _G.fsetAsmType = TRUE;
92                 return TRUE;
93             }
94             else if (!strcmp(argv[*i], "--asm=isas")) {
95                 asm_addTree(&_isas_gb);
96                 /* Munge the function prefix */
97                 gbz80_port.fun_prefix = "";
98                 _G.fsetAsmType = TRUE;
99                 return TRUE;
100             }
101         }
102     }
103     return FALSE;
104 }
105
106 static void _finaliseOptions(void)
107 {
108     port->mem.default_local_map = data;
109     port->mem.default_globl_map = data;
110     if (!_G.fsetAsmType && IS_GB)
111         asm_addTree(&_asxxxx_gb);
112 }
113
114 static void _setDefaultOptions(void)
115 {    
116     options.genericPtr = 1;   /* default on */
117     options.nopeep    = 0;
118     options.stackAuto = 1;
119     options.mainreturn = 1;
120     options.noregparms = 1;
121     options.nodebug = 1;
122     /* first the options part */
123     options.intlong_rent = 1;
124
125     optimize.global_cse = 1;    
126     optimize.label1 = 1;
127     optimize.label2 = 1;
128     optimize.label3 = 1;
129     optimize.label4 = 1;    
130     optimize.loopInvariant = 1;
131     optimize.loopInduction = 0;
132 }
133
134 static const char *_getRegName(struct regs *reg)
135 {
136     if (reg)
137         return reg->name;
138     assert(0);
139     return "err";
140 }
141
142 /** $1 is always the basename.
143     $2 is always the output file.
144     $3 varies
145     $l is the list of extra options that should be there somewhere...
146     MUST be terminated with a NULL.
147 */
148 static const char *_z80_linkCmd[] = {
149     "link-z80", "-nf", "$1", NULL
150 };
151
152 static const char *_z80_asmCmd[] = {
153     "as-z80", "-plosgff", "$1.o", "$1.asm", NULL
154 };
155
156 /** $1 is always the basename.
157     $2 is always the output file.
158     $3 varies
159     $l is the list of extra options that should be there somewhere...
160     MUST be terminated with a NULL.
161 */
162 static const char *_gbz80_linkCmd[] = {
163     "link-gbz80", "-nf", "$1", NULL
164 };
165
166 static const char *_gbz80_asmCmd[] = {
167     "as-gbz80", "-plosgff", "$1.o", "$1.asm", NULL
168 };
169
170 /* Globals */
171 PORT z80_port = {
172     "z80",
173     "Zilog Z80",                /* Target name */
174     {
175         FALSE,
176     },
177     {   
178         _z80_asmCmd,
179         "-plosgff",             /* Options with debug */
180         "-plosgff",             /* Options without debug */
181     },
182     {
183         _z80_linkCmd
184     },
185     {
186         _z80_defaultRules
187     },
188     {
189         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
190         1, 1, 2, 4, 2, 2, 2, 1, 4, 4
191     },
192     {
193         "_XSEG",
194         "_STACK",
195         "_CODE",
196         "_DATA",
197         "_ISEG",
198         "_XSEG",
199         "_BSEG",
200         "_RSEG",
201         "_GSINIT",
202         "_OVERLAY",
203         "_GSFINAL",
204         NULL,
205         NULL,
206         1
207     },
208     { 
209         -1, 0, 0, 8, 0
210     },
211     /* Z80 has no native mul/div commands */
212     {  
213         0
214     },
215     "_",
216     _z80_init,
217     _parseOptions,
218     _finaliseOptions,
219     _setDefaultOptions,
220     z80_assignRegisters,
221     _getRegName,
222     _keywords,
223     0,  /* no assembler preamble */
224     0,  /* no local IVT generation code */
225     _reset_regparm,
226     _reg_parm
227 };
228
229 /* Globals */
230 PORT gbz80_port = {
231     "gbz80",
232     "Gameboy Z80-like",         /* Target name */
233     {
234         FALSE,
235     },
236     {   
237         _gbz80_asmCmd,
238         "-plosgff",             /* Options with debug */
239         "-plosgff",             /* Options without debug */
240     },
241     {
242         _gbz80_linkCmd
243     },
244     {
245         _gbz80_defaultRules
246     },
247     {
248         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
249         1, 1, 2, 4, 2, 2, 2, 1, 4, 4
250     },
251     {
252         "_XSEG",
253         "_STACK",
254         "_CODE",
255         "_DATA",
256         "_ISEG",
257         "_XSEG",
258         "_BSEG",
259         "_RSEG",
260         "_GSINIT",
261         "_OVERLAY",
262         "_GSFINAL",
263         NULL,
264         NULL,
265         1
266     },
267     { 
268         -1, 0, 0, 4, 0
269     },
270     /* gbZ80 has no native mul/div commands */
271     {  
272         0
273     },
274     "_",
275     _gbz80_init,
276     _parseOptions,
277     _finaliseOptions,
278     _setDefaultOptions,
279     z80_assignRegisters,
280     _getRegName,
281     _keywords,
282     0,  /* no assembler preamble */
283     0,  /* no local IVT generation code */
284     _reset_regparm,
285     _reg_parm,
286     _process_pragma
287 };