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"
44 static OPTION _z80_options[] =
46 { 0, "--callee-saves-bc", &z80_opts.calleeSavesBC, "Force a called function to always save BC" },
63 /* determine if we can register a parameter */
68 static char *_keywords[] =
76 extern PORT gbz80_port;
81 static builtins _z80_builtins[] = {
83 { "__builtin_strcpy", "v", 2, {"cg*", "cg*" } },
84 { "__builtin_memcpy", "cg*", 3, {"cg*", "cg*", "ui" } },
86 { NULL , NULL,0, {NULL}}
92 z80_opts.sub = SUB_Z80;
93 asm_addTree (&_asxxxx_z80);
99 z80_opts.sub = SUB_GBZ80;
109 _reg_parm (sym_link * l)
111 if (options.noRegParams)
117 if (_G.regParams == 2)
130 _process_pragma (const char *sz)
132 if (startsWith (sz, "bank="))
135 strcpy (buffer, sz + 5);
137 if (isdigit (buffer[0]))
141 else if (!strcmp (buffer, "BASE"))
143 strcpy (buffer, "HOME");
145 if (isdigit (buffer[0]))
147 /* Arg was a bank number. Handle in an ASM independent
150 strcpy (num, sz + 5);
155 case ASM_TYPE_ASXXXX:
156 sprintf (buffer, "CODE_%s", num);
159 sprintf (buffer, "CODE,BANK[%s]", num);
162 /* PENDING: what to use for ISAS? */
163 sprintf (buffer, "CODE,BANK(%s)", num);
169 gbz80_port.mem.code_name = Safe_strdup (buffer);
170 code->sname = gbz80_port.mem.code_name;
176 static const char *_gbz80_rgbasmCmd[] =
178 "rgbasm", "-o$1.o", "$1.asm", NULL
181 static const char *_gbz80_rgblinkCmd[] =
183 "xlink", "-tg", "-n$1.sym", "-m$1.map", "-zFF", "$1.lnk", NULL
187 _gbz80_rgblink (void)
197 /* first we need to create the <filename>.lnk file */
198 sprintf (scratchFileName, "%s.lnk", sz);
199 if (!(lnkfile = fopen (scratchFileName, "w")))
201 werror (E_FILE_OPEN_ERR, scratchFileName);
205 fprintf (lnkfile, "[Objects]\n");
208 fprintf (lnkfile, "%s.o\n", sz);
210 for (i = 0; i < nrelFiles; i++)
211 fprintf (lnkfile, "%s\n", relFiles[i]);
213 fprintf (lnkfile, "\n[Libraries]\n");
214 /* additional libraries if any */
215 for (i = 0; i < nlibFiles; i++)
216 fprintf (lnkfile, "%s\n", libFiles[i]);
219 fprintf (lnkfile, "\n[Output]\n" "%s.gb", sz);
223 buildCmdLine (buffer,port->linker.cmd, sz, NULL, NULL, NULL);
224 /* call the linker */
225 if (my_system (buffer))
227 perror ("Cannot exec linker");
233 _parseOptions (int *pargc, char **argv, int *i)
235 if (argv[*i][0] == '-')
237 if (argv[*i][1] == 'b' && IS_GB)
239 int bank = atoi (argv[*i] + 3);
245 sprintf (buffer, "CODE_%u", bank);
246 gbz80_port.mem.code_name = Safe_strdup (buffer);
250 sprintf (buffer, "DATA_%u", bank);
251 gbz80_port.mem.data_name = Safe_strdup (buffer);
255 else if (!strncmp (argv[*i], "--asm=", 6))
257 if (!strcmp (argv[*i], "--asm=rgbds"))
259 asm_addTree (&_rgbds_gb);
260 gbz80_port.assembler.cmd = _gbz80_rgbasmCmd;
261 gbz80_port.linker.cmd = _gbz80_rgblinkCmd;
262 gbz80_port.linker.do_link = _gbz80_rgblink;
263 _G.asmType = ASM_TYPE_RGBDS;
266 else if (!strcmp (argv[*i], "--asm=asxxxx"))
268 _G.asmType = ASM_TYPE_ASXXXX;
271 else if (!strcmp (argv[*i], "--asm=isas"))
273 asm_addTree (&_isas_gb);
274 /* Munge the function prefix */
275 gbz80_port.fun_prefix = "";
276 _G.asmType = ASM_TYPE_ISAS;
279 else if (!strcmp (argv[*i], "--asm=z80asm"))
281 port->assembler.externGlobal = TRUE;
282 asm_addTree (&_z80asm_z80);
283 _G.asmType = ASM_TYPE_ISAS;
294 if (options.nostdlib == FALSE)
296 setMainValue ("z80libspec", "-k{libdir}{sep}{port} -l{port}.lib");
297 setMainValue ("z80crt0", "{libdir}{sep}{port}{sep}crt0{objext}");
301 setMainValue ("z80libspec", "");
302 setMainValue ("z80crt0", "");
305 setMainValue ("z80extralibfiles", joinn (libFiles, nlibFiles));
306 setMainValue ("z80extralibpaths", joinn (libPaths, nlibPaths));
310 setMainValue ("z80outputtypeflag", "-z");
311 setMainValue ("z80outext", ".gb");
315 setMainValue ("z80outputtypeflag", "-i");
316 setMainValue ("z80outext", ".ihx");
319 setMainValue ("z80extraobj", joinn (relFiles, nrelFiles));
321 sprintf (buffer, "-b_CODE=0x%04X -b_DATA=0x%04X", options.code_loc, options.data_loc);
322 setMainValue ("z80bases", buffer);
326 _finaliseOptions (void)
328 port->mem.default_local_map = data;
329 port->mem.default_globl_map = data;
330 if (_G.asmType == ASM_TYPE_ASXXXX && IS_GB)
331 asm_addTree (&_asxxxx_gb);
337 _setDefaultOptions (void)
339 options.genericPtr = 1; /* default on */
341 options.stackAuto = 1;
342 options.mainreturn = 1;
343 /* first the options part */
344 options.intlong_rent = 1;
345 options.float_rent = 1;
346 options.noRegParams = 1;
347 /* Default code and data locations. */
348 options.code_loc = 0x200;
352 options.data_loc = 0xC000;
356 options.data_loc = 0x8000;
359 optimize.global_cse = 1;
364 optimize.loopInvariant = 1;
365 optimize.loopInduction = 1;
371 policy is the function policy
372 params is the parameter format
377 r is 'r' for reentrant, 's' for static functions
378 s is 'c' for callee saves, 'r' for caller saves
379 p is 'p' for profiling on, 'x' for profiling off
381 rr - reentrant, caller saves
383 A combination of register short names and s to signify stack variables.
385 bds - first two args appear in BC and DE, the rest on the stack
386 s - all arguments are on the stack.
389 _mangleSupportFunctionName(char *original)
393 sprintf(buffer, "%s_rr%s_%s", original,
394 options.profile ? "f" : "x",
395 options.noRegParams ? "s" : "bds"
398 return Safe_strdup(buffer);
402 _getRegName (struct regs *reg)
413 _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
415 sym_link *test = NULL;
423 if ( IS_LITERAL (left))
426 val = OP_VALUE (IC_LEFT (ic));
428 else if ( IS_LITERAL (right))
431 val = OP_VALUE (IC_RIGHT (ic));
438 if ( getSize (test) <= 2)
447 "{bindir}{sep}link-{port} -n -c -- {z80bases} -m -j" \
449 " {z80extralibfiles} {z80extralibpaths}" \
450 " {z80outputtypeflag} {srcfilename}{z80outext}" \
452 " {srcfilename}{objext}" \
456 "{bindir}{sep}as-{port} -plosgff {srcfilename}{objext} {srcfilename}{asmext}"
463 "Zilog Z80", /* Target name */
464 NULL, /* Processor name */
467 MODEL_MEDIUM | MODEL_SMALL,
473 "-plosgff", /* Options with debug */
474 "-plosgff", /* Options without debug */
488 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
489 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
513 /* Z80 has no native mul/div commands */
526 0, /* no assembler preamble */
527 NULL, /* no genAssemblerEnd */
528 0, /* no local IVT generation code */
529 0, /* no genXINIT code */
533 _mangleSupportFunctionName,
538 1, /* transform <= to ! > */
539 1, /* transform >= to ! < */
540 1, /* transform != to !(a == b) */
542 TRUE, /* Array initializer support. */
543 0, /* no CSE cost estimation yet */
544 _z80_builtins, /* no builtin functions */
545 GPOINTER, /* treat unqualified pointers as "generic" pointers */
546 1, /* reset labelKey to 1 */
547 1, /* globals & local static allowed */
556 "Gameboy Z80-like", /* Target name */
560 MODEL_MEDIUM | MODEL_SMALL,
566 "-plosgff", /* Options with debug */
567 "-plosgff", /* Options without debug */
570 NULL /* no do_assemble function */
582 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
583 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
607 /* gbZ80 has no native mul/div commands */
620 0, /* no assembler preamble */
621 NULL, /* no genAssemblerEnd */
622 0, /* no local IVT generation code */
623 0, /* no genXINIT code */
627 _mangleSupportFunctionName,
632 1, /* transform <= to ! > */
633 1, /* transform >= to ! < */
634 1, /* transform != to !(a == b) */
636 TRUE, /* Array initializer support. */
637 0, /* no CSE cost estimation yet */
638 NULL, /* no builtin functions */
639 GPOINTER, /* treat unqualified pointers as "generic" pointers */
640 1, /* reset labelKey to 1 */
641 1, /* globals & local static allowed */