1 /*-------------------------------------------------------------------------
2 main.c - Z80 specific definitions.
4 Michael Hope <michaelh@juju.net.nz> 2001
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
30 static char _z80_defaultRules[] =
33 #include "peeph-z80.rul"
36 static char _gbz80_defaultRules[] =
39 #include "peeph-gbz80.rul"
57 /* determine if we can register a parameter */
62 static char *_keywords[] =
70 extern PORT gbz80_port;
75 static builtins _z80_builtins[] = {
77 { "__builtin_strcpy", "v", 2, {"cg*", "cg*" } },
78 { "__builtin_memcpy", "cg*", 3, {"cg*", "cg*", "ui" } },
80 { NULL , NULL,0, {NULL}}
86 z80_opts.sub = SUB_Z80;
87 asm_addTree (&_asxxxx_z80);
93 z80_opts.sub = SUB_GBZ80;
103 _reg_parm (sym_link * l)
105 if (options.noRegParams)
111 if (_G.regParams == 2)
124 _process_pragma (const char *sz)
126 if (startsWith (sz, "bank="))
129 strcpy (buffer, sz + 5);
131 if (isdigit (buffer[0]))
135 else if (!strcmp (buffer, "BASE"))
137 strcpy (buffer, "HOME");
139 if (isdigit (buffer[0]))
141 /* Arg was a bank number. Handle in an ASM independent
144 strcpy (num, sz + 5);
149 case ASM_TYPE_ASXXXX:
150 sprintf (buffer, "CODE_%s", num);
153 sprintf (buffer, "CODE,BANK[%s]", num);
156 /* PENDING: what to use for ISAS? */
157 sprintf (buffer, "CODE,BANK(%s)", num);
163 gbz80_port.mem.code_name = Safe_strdup (buffer);
164 code->sname = gbz80_port.mem.code_name;
170 static const char *_gbz80_rgbasmCmd[] =
172 "rgbasm", "-o$1.o", "$1.asm", NULL
175 static const char *_gbz80_rgblinkCmd[] =
177 "xlink", "-tg", "-n$1.sym", "-m$1.map", "-zFF", "$1.lnk", NULL
181 _gbz80_rgblink (void)
191 /* first we need to create the <filename>.lnk file */
192 sprintf (scratchFileName, "%s.lnk", sz);
193 if (!(lnkfile = fopen (scratchFileName, "w")))
195 werror (E_FILE_OPEN_ERR, scratchFileName);
199 fprintf (lnkfile, "[Objects]\n");
202 fprintf (lnkfile, "%s.o\n", sz);
204 for (i = 0; i < nrelFiles; i++)
205 fprintf (lnkfile, "%s\n", relFiles[i]);
207 fprintf (lnkfile, "\n[Libraries]\n");
208 /* additional libraries if any */
209 for (i = 0; i < nlibFiles; i++)
210 fprintf (lnkfile, "%s\n", libFiles[i]);
213 fprintf (lnkfile, "\n[Output]\n" "%s.gb", sz);
217 buildCmdLine (buffer,port->linker.cmd, sz, NULL, NULL, NULL);
218 /* call the linker */
219 if (my_system (buffer))
221 perror ("Cannot exec linker");
227 _parseOptions (int *pargc, char **argv, int *i)
229 if (argv[*i][0] == '-')
231 if (argv[*i][1] == 'b' && IS_GB)
233 int bank = atoi (argv[*i] + 3);
239 sprintf (buffer, "CODE_%u", bank);
240 gbz80_port.mem.code_name = Safe_strdup (buffer);
244 sprintf (buffer, "DATA_%u", bank);
245 gbz80_port.mem.data_name = Safe_strdup (buffer);
249 else if (!strncmp (argv[*i], "--asm=", 6))
251 if (!strcmp (argv[*i], "--asm=rgbds"))
253 asm_addTree (&_rgbds_gb);
254 gbz80_port.assembler.cmd = _gbz80_rgbasmCmd;
255 gbz80_port.linker.cmd = _gbz80_rgblinkCmd;
256 gbz80_port.linker.do_link = _gbz80_rgblink;
257 _G.asmType = ASM_TYPE_RGBDS;
260 else if (!strcmp (argv[*i], "--asm=asxxxx"))
262 _G.asmType = ASM_TYPE_ASXXXX;
265 else if (!strcmp (argv[*i], "--asm=isas"))
267 asm_addTree (&_isas_gb);
268 /* Munge the function prefix */
269 gbz80_port.fun_prefix = "";
270 _G.asmType = ASM_TYPE_ISAS;
273 else if (!strcmp (argv[*i], "--asm=z80asm"))
275 port->assembler.externGlobal = TRUE;
276 asm_addTree (&_z80asm_z80);
277 _G.asmType = ASM_TYPE_ISAS;
288 if (options.nostdlib == FALSE)
290 setMainValue ("z80libspec", "-k{libdir}{sep}{port} -l{port}.lib");
291 setMainValue ("z80crt0", "{libdir}{sep}{port}{sep}crt0{objext}");
295 setMainValue ("z80libspec", "");
296 setMainValue ("z80crt0", "");
299 setMainValue ("z80extralibfiles", joinn (libFiles, nlibFiles));
300 setMainValue ("z80extralibpaths", joinn (libPaths, nlibPaths));
304 setMainValue ("z80outputtypeflag", "-z");
305 setMainValue ("z80outext", ".gb");
309 setMainValue ("z80outputtypeflag", "-i");
310 setMainValue ("z80outext", ".ihx");
313 setMainValue ("z80extraobj", joinn (relFiles, nrelFiles));
315 sprintf (buffer, "-b_CODE=0x%04X -b_DATA=0x%04X", options.code_loc, options.data_loc);
316 setMainValue ("z80bases", buffer);
320 _finaliseOptions (void)
322 port->mem.default_local_map = data;
323 port->mem.default_globl_map = data;
324 if (_G.asmType == ASM_TYPE_ASXXXX && IS_GB)
325 asm_addTree (&_asxxxx_gb);
331 _setDefaultOptions (void)
333 options.genericPtr = 1; /* default on */
335 options.stackAuto = 1;
336 options.mainreturn = 1;
337 /* first the options part */
338 options.intlong_rent = 1;
339 options.float_rent = 1;
340 options.noRegParams = 1;
341 /* Default code and data locations. */
342 options.code_loc = 0x200;
346 options.data_loc = 0xC000;
350 options.data_loc = 0x8000;
353 optimize.global_cse = 1;
358 optimize.loopInvariant = 1;
359 optimize.loopInduction = 1;
365 policy is the function policy
366 params is the parameter format
371 r is 'r' for reentrant, 's' for static functions
372 s is 'c' for callee saves, 'r' for caller saves
373 p is 'p' for profiling on, 'x' for profiling off
375 rr - reentrant, caller saves
377 A combination of register short names and s to signify stack variables.
379 bds - first two args appear in BC and DE, the rest on the stack
380 s - all arguments are on the stack.
383 _mangleSupportFunctionName(char *original)
387 sprintf(buffer, "%s_rr%s_%s", original,
388 options.profile ? "f" : "x",
389 options.noRegParams ? "s" : "bds"
392 return Safe_strdup(buffer);
396 _getRegName (struct regs *reg)
407 _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
409 sym_link *test = NULL;
417 if ( IS_LITERAL (left))
420 val = OP_VALUE (IC_LEFT (ic));
422 else if ( IS_LITERAL (right))
425 val = OP_VALUE (IC_RIGHT (ic));
432 if ( getSize (test) <= 2)
441 "{bindir}{sep}link-{port} -n -c -- {z80bases} -m -j" \
443 " {z80extralibfiles} {z80extralibpaths}" \
444 " {z80outputtypeflag} {srcfilename}{z80outext}" \
446 " {srcfilename}{objext}" \
450 "{bindir}{sep}as-{port} -plosgff {srcfilename}{objext} {srcfilename}{asmext}"
457 "Zilog Z80", /* Target name */
460 MODEL_MEDIUM | MODEL_SMALL,
466 "-plosgff", /* Options with debug */
467 "-plosgff", /* Options without debug */
481 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
482 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
506 /* Z80 has no native mul/div commands */
518 0, /* no assembler preamble */
519 NULL, /* no genAssemblerEnd */
520 0, /* no local IVT generation code */
521 0, /* no genXINIT code */
525 _mangleSupportFunctionName,
530 1, /* transform <= to ! > */
531 1, /* transform >= to ! < */
532 1, /* transform != to !(a == b) */
534 TRUE, /* Array initializer support. */
535 0, /* no CSE cost estimation yet */
536 _z80_builtins, /* no builtin functions */
537 GPOINTER, /* treat unqualified pointers as "generic" pointers */
538 1, /* reset labelKey to 1 */
539 1, /* globals & local static allowed */
548 "Gameboy Z80-like", /* Target name */
551 MODEL_MEDIUM | MODEL_SMALL,
557 "-plosgff", /* Options with debug */
558 "-plosgff", /* Options without debug */
561 NULL /* no do_assemble function */
573 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
574 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
598 /* gbZ80 has no native mul/div commands */
610 0, /* no assembler preamble */
611 NULL, /* no genAssemblerEnd */
612 0, /* no local IVT generation code */
613 0, /* no genXINIT code */
617 _mangleSupportFunctionName,
622 1, /* transform <= to ! > */
623 1, /* transform >= to ! < */
624 1, /* transform != to !(a == b) */
626 TRUE, /* Array initializer support. */
627 0, /* no CSE cost estimation yet */
628 NULL, /* no builtin functions */
629 GPOINTER, /* treat unqualified pointers as "generic" pointers */
630 1, /* reset labelKey to 1 */
631 1, /* globals & local static allowed */