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)
192 /* first we need to create the <filename>.lnk file */
193 sprintf (scratchFileName, "%s.lnk", dstFileName);
194 if (!(lnkfile = fopen (scratchFileName, "w")))
196 werror (E_FILE_OPEN_ERR, scratchFileName);
200 fprintf (lnkfile, "[Objects]\n");
202 fprintf (lnkfile, "%s.o\n", dstFileName);
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", dstFileName);
217 buildCmdLine (buffer,port->linker.cmd, dstFileName, 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 ("stdobjdstfilename" , "{dstfilename}{objext}");
314 setMainValue ("stdlinkdstfilename", "{dstfilename}{z80outext}");
316 setMainValue ("z80extraobj", joinn (relFiles, nrelFiles));
318 sprintf (buffer, "-b_CODE=0x%04X -b_DATA=0x%04X", options.code_loc, options.data_loc);
319 setMainValue ("z80bases", buffer);
323 _finaliseOptions (void)
325 port->mem.default_local_map = data;
326 port->mem.default_globl_map = data;
327 if (_G.asmType == ASM_TYPE_ASXXXX && IS_GB)
328 asm_addTree (&_asxxxx_gb);
334 _setDefaultOptions (void)
337 options.stackAuto = 1;
338 options.mainreturn = 1;
339 /* first the options part */
340 options.intlong_rent = 1;
341 options.float_rent = 1;
342 options.noRegParams = 1;
343 /* Default code and data locations. */
344 options.code_loc = 0x200;
348 options.data_loc = 0xC000;
352 options.data_loc = 0x8000;
355 optimize.global_cse = 1;
360 optimize.loopInvariant = 1;
361 optimize.loopInduction = 1;
367 policy is the function policy
368 params is the parameter format
373 r is 'r' for reentrant, 's' for static functions
374 s is 'c' for callee saves, 'r' for caller saves
375 p is 'p' for profiling on, 'x' for profiling off
377 rr - reentrant, caller saves
379 A combination of register short names and s to signify stack variables.
381 bds - first two args appear in BC and DE, the rest on the stack
382 s - all arguments are on the stack.
385 _mangleSupportFunctionName(char *original)
389 sprintf(buffer, "%s_rr%s_%s", original,
390 options.profile ? "f" : "x",
391 options.noRegParams ? "s" : "bds"
394 return Safe_strdup(buffer);
398 _getRegName (struct regs *reg)
409 _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
411 sym_link *test = NULL;
419 if ( IS_LITERAL (left))
422 val = OP_VALUE (IC_LEFT (ic));
424 else if ( IS_LITERAL (right))
427 val = OP_VALUE (IC_RIGHT (ic));
434 if ( getSize (test) <= 2)
443 "{bindir}{sep}link-{port} -n -c -- {z80bases} -m -j" \
445 " {z80extralibfiles} {z80extralibpaths}" \
446 " {z80outputtypeflag} {linkdstfilename}" \
448 " {dstfilename}{objext}" \
452 "{bindir}{sep}as-{port} -plosgff {objdstfilename} {dstfilename}{asmext}"
459 "Zilog Z80", /* Target name */
460 NULL, /* Processor name */
463 MODEL_MEDIUM | MODEL_SMALL,
469 "-plosgff", /* Options with debug */
470 "-plosgff", /* Options without debug */
484 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
485 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
509 /* Z80 has no native mul/div commands */
522 0, /* no assembler preamble */
523 NULL, /* no genAssemblerEnd */
524 0, /* no local IVT generation code */
525 0, /* no genXINIT code */
529 _mangleSupportFunctionName,
534 1, /* transform <= to ! > */
535 1, /* transform >= to ! < */
536 1, /* transform != to !(a == b) */
538 TRUE, /* Array initializer support. */
539 0, /* no CSE cost estimation yet */
540 _z80_builtins, /* no builtin functions */
541 GPOINTER, /* treat unqualified pointers as "generic" pointers */
542 1, /* reset labelKey to 1 */
543 1, /* globals & local static allowed */
552 "Gameboy Z80-like", /* Target name */
556 MODEL_MEDIUM | MODEL_SMALL,
562 "-plosgff", /* Options with debug */
563 "-plosgff", /* Options without debug */
566 NULL /* no do_assemble function */
578 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
579 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
603 /* gbZ80 has no native mul/div commands */
616 0, /* no assembler preamble */
617 NULL, /* no genAssemblerEnd */
618 0, /* no local IVT generation code */
619 0, /* no genXINIT code */
623 _mangleSupportFunctionName,
628 1, /* transform <= to ! > */
629 1, /* transform >= to ! < */
630 1, /* transform != to !(a == b) */
632 TRUE, /* Array initializer support. */
633 0, /* no CSE cost estimation yet */
634 NULL, /* no builtin functions */
635 GPOINTER, /* treat unqualified pointers as "generic" pointers */
636 1, /* reset labelKey to 1 */
637 1, /* globals & local static allowed */