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)
191 /* first we need to create the <filename>.lnk file */
192 sprintf (scratchFileName, "%s.lnk", dstFileName);
193 if (!(lnkfile = fopen (scratchFileName, "w")))
195 werror (E_FILE_OPEN_ERR, scratchFileName);
199 fprintf (lnkfile, "[Objects]\n");
201 fprintf (lnkfile, "%s.o\n", dstFileName);
203 fputStrSet(lnkfile, relFilesSet);
205 fprintf (lnkfile, "\n[Libraries]\n");
206 /* additional libraries if any */
207 fputStrSet(lnkfile, libFilesSet);
209 fprintf (lnkfile, "\n[Output]\n" "%s.gb", dstFileName);
213 buildCmdLine (buffer,port->linker.cmd, dstFileName, NULL, NULL, NULL);
214 /* call the linker */
215 if (my_system (buffer))
217 perror ("Cannot exec linker");
223 _parseOptions (int *pargc, char **argv, int *i)
225 if (argv[*i][0] == '-')
227 if (argv[*i][1] == 'b' && IS_GB)
229 int bank = atoi (argv[*i] + 3);
235 sprintf (buffer, "CODE_%u", bank);
236 gbz80_port.mem.code_name = Safe_strdup (buffer);
240 sprintf (buffer, "DATA_%u", bank);
241 gbz80_port.mem.data_name = Safe_strdup (buffer);
245 else if (!strncmp (argv[*i], "--asm=", 6))
247 if (!strcmp (argv[*i], "--asm=rgbds"))
249 asm_addTree (&_rgbds_gb);
250 gbz80_port.assembler.cmd = _gbz80_rgbasmCmd;
251 gbz80_port.linker.cmd = _gbz80_rgblinkCmd;
252 gbz80_port.linker.do_link = _gbz80_rgblink;
253 _G.asmType = ASM_TYPE_RGBDS;
256 else if (!strcmp (argv[*i], "--asm=asxxxx"))
258 _G.asmType = ASM_TYPE_ASXXXX;
261 else if (!strcmp (argv[*i], "--asm=isas"))
263 asm_addTree (&_isas_gb);
264 /* Munge the function prefix */
265 gbz80_port.fun_prefix = "";
266 _G.asmType = ASM_TYPE_ISAS;
269 else if (!strcmp (argv[*i], "--asm=z80asm"))
271 port->assembler.externGlobal = TRUE;
272 asm_addTree (&_z80asm_z80);
273 _G.asmType = ASM_TYPE_ISAS;
286 if (options.nostdlib == FALSE)
288 setMainValue ("z80libspec", "-l\"{port}.lib\"");
289 setMainValue ("z80crt0", "\"crt0{objext}\"");
293 setMainValue ("z80libspec", "");
294 setMainValue ("z80crt0", "");
297 setMainValue ("z80extralibfiles", (s = joinStrSet(libFilesSet)));
298 Safe_free((void *)s);
299 setMainValue ("z80extralibpaths", (s = joinStrSet(libPathsSet)));
300 Safe_free((void *)s);
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", (s = joinStrSet(relFilesSet)));
317 Safe_free((void *)s);
319 sprintf (buffer, "-b_CODE=0x%04X -b_DATA=0x%04X", options.code_loc, options.data_loc);
320 setMainValue ("z80bases", buffer);
324 _finaliseOptions (void)
326 port->mem.default_local_map = data;
327 port->mem.default_globl_map = data;
328 if (_G.asmType == ASM_TYPE_ASXXXX && IS_GB)
329 asm_addTree (&_asxxxx_gb);
335 _setDefaultOptions (void)
338 options.stackAuto = 1;
339 options.mainreturn = 1;
340 /* first the options part */
341 options.intlong_rent = 1;
342 options.float_rent = 1;
343 options.noRegParams = 1;
344 /* Default code and data locations. */
345 options.code_loc = 0x200;
349 options.data_loc = 0xC000;
353 options.data_loc = 0x8000;
356 optimize.global_cse = 1;
361 optimize.loopInvariant = 1;
362 optimize.loopInduction = 1;
368 policy is the function policy
369 params is the parameter format
374 r is 'r' for reentrant, 's' for static functions
375 s is 'c' for callee saves, 'r' for caller saves
376 p is 'p' for profiling on, 'x' for profiling off
378 rr - reentrant, caller saves
380 A combination of register short names and s to signify stack variables.
382 bds - first two args appear in BC and DE, the rest on the stack
383 s - all arguments are on the stack.
386 _mangleSupportFunctionName(char *original)
390 sprintf(buffer, "%s_rr%s_%s", original,
391 options.profile ? "f" : "x",
392 options.noRegParams ? "s" : "bds"
395 return Safe_strdup(buffer);
399 _getRegName (struct regs *reg)
410 _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
412 sym_link *test = NULL;
420 if ( IS_LITERAL (left))
423 val = OP_VALUE (IC_LEFT (ic));
425 else if ( IS_LITERAL (right))
428 val = OP_VALUE (IC_RIGHT (ic));
435 if ( getSize (test) <= 2)
444 "link-{port} -n -c -- {z80bases} -m -j" \
446 " {z80extralibfiles} {z80extralibpaths}" \
447 " {z80outputtypeflag} \"{linkdstfilename}\"" \
449 " \"{dstfilename}{objext}\"" \
453 "as-{port} -plosgff \"{objdstfilename}\" \"{dstfilename}{asmext}\""
460 "Zilog Z80", /* Target name */
461 NULL, /* Processor name */
464 MODEL_MEDIUM | MODEL_SMALL,
470 "-plosgff", /* Options with debug */
471 "-plosgff", /* Options without debug */
485 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
486 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
510 /* Z80 has no native mul/div commands */
523 0, /* no assembler preamble */
524 NULL, /* no genAssemblerEnd */
525 0, /* no local IVT generation code */
526 0, /* no genXINIT code */
530 _mangleSupportFunctionName,
535 1, /* transform <= to ! > */
536 1, /* transform >= to ! < */
537 1, /* transform != to !(a == b) */
539 TRUE, /* Array initializer support. */
540 0, /* no CSE cost estimation yet */
541 _z80_builtins, /* no builtin functions */
542 GPOINTER, /* treat unqualified pointers as "generic" pointers */
543 1, /* reset labelKey to 1 */
544 1, /* globals & local static allowed */
553 "Gameboy Z80-like", /* Target name */
557 MODEL_MEDIUM | MODEL_SMALL,
563 "-plosgff", /* Options with debug */
564 "-plosgff", /* Options without debug */
567 NULL /* no do_assemble function */
579 /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
580 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
604 /* gbZ80 has no native mul/div commands */
617 0, /* no assembler preamble */
618 NULL, /* no genAssemblerEnd */
619 0, /* no local IVT generation code */
620 0, /* no genXINIT code */
624 _mangleSupportFunctionName,
629 1, /* transform <= to ! > */
630 1, /* transform >= to ! < */
631 1, /* transform != to !(a == b) */
633 TRUE, /* Array initializer support. */
634 0, /* no CSE cost estimation yet */
635 NULL, /* no builtin functions */
636 GPOINTER, /* treat unqualified pointers as "generic" pointers */
637 1, /* reset labelKey to 1 */
638 1, /* globals & local static allowed */