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 ("z80stdobjdstfilename" , "{dstfilename}{objext}");
314 setMainValue ("z80stdlinkdstfilename", "{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)
336 options.genericPtr = 1; /* default on */
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 "{bindir}{sep}link-{port} -n -c -- {z80bases} -m -j" \
446 " {z80extralibfiles} {z80extralibpaths}" \
447 " {z80outputtypeflag} {z80linkdstfilename}" \
449 " {dstfilename}{objext}" \
453 "{bindir}{sep}as-{port} -plosgff {z80objdstfilename} {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 */