+/*-------------------------------------------------------------------------
+ main.c - Z80 specific definitions.
+
+ Michael Hope <michaelh@juju.net.nz> 2001
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ In other words, you are welcome to use, share and improve this program.
+ You are forbidden to forbid anyone else to use, share and improve
+ what you give them. Help stamp out software-hoarding!
+-------------------------------------------------------------------------*/
+
#include "z80.h"
#include "MySystem.h"
#include "BuildCmd.h"
+#include "SDCCutil.h"
static char _z80_defaultRules[] =
{
static struct
{
ASM_TYPE asmType;
+ /* determine if we can register a parameter */
+ int regParams;
}
_G;
z80_opts.sub = SUB_GBZ80;
}
-static int regParmFlg = 0; /* determine if we can register a parameter */
-
static void
_reset_regparm ()
{
- regParmFlg = 0;
+ _G.regParams = 0;
}
static int
_reg_parm (sym_link * l)
{
- if (regParmFlg == 2)
- return 0;
-
- regParmFlg++;
- return 1;
-}
-
-static bool
-_startsWith (const char *sz, const char *key)
-{
- return !strncmp (sz, key, strlen (key));
-}
-
-static void
-_chomp (char *sz)
-{
- char *nl;
- while ((nl = strrchr (sz, '\n')))
- *nl = '\0';
+ if (options.noRegParams)
+ {
+ return FALSE;
+ }
+ else
+ {
+ if (_G.regParams == 2)
+ {
+ return FALSE;
+ }
+ else
+ {
+ _G.regParams++;
+ return TRUE;
+ }
+ }
}
static int
_process_pragma (const char *sz)
{
- if (_startsWith (sz, "bank="))
+ if (startsWith (sz, "bank="))
{
char buffer[128];
strcpy (buffer, sz + 5);
- _chomp (buffer);
+ chomp (buffer);
if (isdigit (buffer[0]))
{
way. */
char num[128];
strcpy (num, sz + 5);
- _chomp (num);
+ chomp (num);
switch (_G.asmType)
{
wassert (0);
}
}
- gbz80_port.mem.code_name = gc_strdup (buffer);
+ gbz80_port.mem.code_name = Safe_strdup (buffer);
code->sname = gbz80_port.mem.code_name;
return 0;
}
sz = "a";
/* first we need to create the <filename>.lnk file */
- sprintf (buffer, "%s.lnk", sz);
- if (!(lnkfile = fopen (buffer, "w")))
+ sprintf (scratchFileName, "%s.lnk", sz);
+ if (!(lnkfile = fopen (scratchFileName, "w")))
{
- werror (E_FILE_OPEN_ERR, buffer);
+ werror (E_FILE_OPEN_ERR, scratchFileName);
exit (1);
}
case 'o':
/* ROM bank */
sprintf (buffer, "CODE_%u", bank);
- gbz80_port.mem.code_name = gc_strdup (buffer);
+ gbz80_port.mem.code_name = Safe_strdup (buffer);
return TRUE;
case 'a':
/* RAM bank */
sprintf (buffer, "DATA_%u", bank);
- gbz80_port.mem.data_name = gc_strdup (buffer);
+ gbz80_port.mem.data_name = Safe_strdup (buffer);
return TRUE;
}
}
return FALSE;
}
+static void
+_setValues(void)
+{
+ if (options.nostdlib == FALSE)
+ {
+ setMainValue ("z80libspec", "-k{libdir}{sep}{port} -l{port}.lib");
+ setMainValue ("z80crt0", "{libdir}{sep}{port}{sep}crt0{objext}");
+ }
+ else
+ {
+ setMainValue ("z80libspec", "");
+ setMainValue ("z80crt0", "");
+ }
+
+ setMainValue ("z80extralibfiles", joinn (libFiles, nlibFiles));
+ setMainValue ("z80extralibpaths", joinn (libPaths, nlibPaths));
+
+ if (IS_GB)
+ {
+ setMainValue ("z80outputtypeflag", "-z");
+ setMainValue ("z80outext", ".gb");
+ }
+ else
+ {
+ setMainValue ("z80outputtypeflag", "-i");
+ setMainValue ("z80outext", ".ihx");
+ }
+
+ setMainValue ("z80extraobj", joinn (relFiles, nrelFiles));
+
+ sprintf (buffer, "-b_CODE=0x%04X -b_DATA=0x%04X", options.code_loc, options.data_loc);
+ setMainValue ("z80bases", buffer);
+}
+
static void
_finaliseOptions (void)
{
port->mem.default_globl_map = data;
if (_G.asmType == ASM_TYPE_ASXXXX && IS_GB)
asm_addTree (&_asxxxx_gb);
+
+ _setValues();
}
static void
options.nopeep = 0;
options.stackAuto = 1;
options.mainreturn = 1;
- options.nodebug = 1;
/* first the options part */
options.intlong_rent = 1;
+ options.noRegParams = 1;
+ /* Default code and data locations. */
+ options.code_loc = 0x200;
+
+ if (IS_GB)
+ {
+ options.data_loc = 0xC000;
+ }
+ else
+ {
+ options.data_loc = 0x8000;
+ }
optimize.global_cse = 1;
optimize.label1 = 1;
optimize.label3 = 1;
optimize.label4 = 1;
optimize.loopInvariant = 1;
- optimize.loopInduction = 0;
+ optimize.loopInduction = 1;
+}
+
+/* Mangaling format:
+ _fun_policy_params
+ where:
+ policy is the function policy
+ params is the parameter format
+
+ policy format:
+ rsp
+ where:
+ r is 'r' for reentrant, 's' for static functions
+ s is 'c' for callee saves, 'r' for caller saves
+ p is 'p' for profiling on, 'x' for profiling off
+ examples:
+ rr - reentrant, caller saves
+ params format:
+ A combination of register short names and s to signify stack variables.
+ examples:
+ bds - first two args appear in BC and DE, the rest on the stack
+ s - all arguments are on the stack.
+*/
+static char *
+_mangleSupportFunctionName(char *original)
+{
+ char buffer[128];
+
+ sprintf(buffer, "%s_rr%s_%s", original,
+ options.profile ? "f" : "x",
+ options.noRegParams ? "s" : "bds"
+ );
+
+ return Safe_strdup(buffer);
}
static const char *
_getRegName (struct regs *reg)
{
if (reg)
- return reg->name;
+ {
+ return reg->name;
+ }
assert (0);
return "err";
}
-/** $1 is always the basename.
- $2 is always the output file.
- $3 varies
- $l is the list of extra options that should be there somewhere...
- MUST be terminated with a NULL.
-*/
-static const char *_z80_linkCmd[] =
+static bool
+_hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
{
- "link-z80", "-nf", "$1", NULL
-};
+ sym_link *test = NULL;
+ value *val;
-static const char *_z80_asmCmd[] =
-{
- "as-z80", "-plosgff", "$1.o", "$1.asm", NULL
-};
+ if ( ic->op != '*')
+ {
+ return FALSE;
+ }
-/** $1 is always the basename.
- $2 is always the output file.
- $3 varies
- $l is the list of extra options that should be there somewhere...
- MUST be terminated with a NULL.
-*/
-static const char *_gbz80_linkCmd[] =
-{
- "link-gbz80", "-nf", "$1", NULL
-};
+ if ( IS_LITERAL (left))
+ {
+ test = left;
+ val = OP_VALUE (IC_LEFT (ic));
+ }
+ else if ( IS_LITERAL (right))
+ {
+ test = left;
+ val = OP_VALUE (IC_RIGHT (ic));
+ }
+ else
+ {
+ return FALSE;
+ }
-static const char *_gbz80_asmCmd[] =
-{
- "as-gbz80", "-plosgff", "$1.o", "$1.asm", NULL
-};
+ if ( getSize (test) <= 2)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+#define LINKCMD \
+ "{bindir}{sep}link-{port} -n -c -- {z80bases} -m -j" \
+ " {z80libspec}" \
+ " {z80extralibfiles} {z80extralibpaths}" \
+ " {z80outputtypeflag} {srcfilename}{z80outext}" \
+ " {z80crt0}" \
+ " {srcfilename}{objext}" \
+ " {z80extraobj}"
+
+#define ASMCMD \
+ "{bindir}{sep}as-{port} -plosgff {srcfilename}{objext} {srcfilename}{asmext}"
/* Globals */
PORT z80_port =
MODEL_SMALL
},
{
- _z80_asmCmd,
+ NULL,
+ ASMCMD,
"-plosgff", /* Options with debug */
"-plosgff", /* Options without debug */
0,
".asm"
},
{
- _z80_linkCmd,
+ NULL,
+ LINKCMD,
NULL,
".o"
},
},
{
/* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
- 1, 1, 2, 4, 2, 2, 2, 1, 4, 4
+ 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
},
{
"XSEG",
_reset_regparm,
_reg_parm,
_process_pragma,
+ _mangleSupportFunctionName,
+ _hasNativeMulFor,
TRUE,
0, /* leave lt */
0, /* leave gt */
1, /* transform >= to ! < */
1, /* transform != to !(a == b) */
0, /* leave == */
+ TRUE, /* Array initializer support. */
PORT_MAGIC
};
MODEL_SMALL
},
{
- _gbz80_asmCmd,
+ NULL,
+ ASMCMD,
"-plosgff", /* Options with debug */
"-plosgff", /* Options without debug */
- 1
+ 0,
+ ".asm"
},
{
- _gbz80_linkCmd,
+ NULL,
+ LINKCMD,
NULL,
".o"
},
_gbz80_defaultRules
},
{
- /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
- 1, 1, 2, 4, 2, 2, 2, 1, 4, 4
+ /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
+ 1, 2, 2, 4, 2, 2, 2, 1, 4, 4
},
{
"XSEG",
_reset_regparm,
_reg_parm,
_process_pragma,
+ _mangleSupportFunctionName,
+ _hasNativeMulFor,
TRUE,
0, /* leave lt */
0, /* leave gt */
1, /* transform >= to ! < */
1, /* transform != to !(a == b) */
0, /* leave == */
+ FALSE, /* No array initializer support. */
PORT_MAGIC
};