+2001-12-23 Michael Hope <michaelh@juju.net.nz>
+
+ * src/z80/mappings.i: Added z80asm support.
+
+ * src/z80/main.c: Added z80asm support on --asm=z80asm
+
+ * src/z80/gen.c: Fixed asm portability issues.
+
+ * src/asm.c (tvsprintf): Removed old code, added 'N' for function name. For extern support.
+
+ * src/SDCCglue.c (printExterns): Added global/extern split.
+
2001-12-17 Bernhard Held <bernhard@bernhardheld.de>
* support/regression/Makefile: added test for mcs51 model large
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
-------------------------------------------------------------------------*/
-#include "string.h"
+#include <string.h>
#define NULL (void *)0
char * strpbrk (
/* if extern then add it into the extern list */
if (IS_EXTERN (sym->etype))
{
- addSetHead (&externs, sym);
+ addSetHead (&externs, sym);
continue;
}
/* if it is not static add it to the public
table */
if (!IS_STATIC (sym->etype))
- addSetHead (&publics, sym);
+ {
+ addSetHead (&publics, sym);
+ }
/* print extra debug info if required */
if (options.debug) {
for (sym = setFirstItem (externs); sym;
sym = setNextItem (externs))
- tfprintf (afile, "\t!global\n", sym->rname);
+ tfprintf (afile, "\t!extern\n", sym->rname);
}
/*-----------------------------------------------------------------*/
and addPublics allowed then add it to the public set */
if ((sym->_isparm && !IS_REGPARM (sym->etype))
&& !IS_STATIC (sym->etype))
- addSetHead (&publics, sym);
+ {
+ addSetHead (&publics, sym);
+ }
/* if extern then do nothing or is a function
then do nothing */
return shash_find (_h, szKey);
}
-#if 0
-static void
-_iprintf (char *pInto, const char *sz, va_list * pap)
-{
- char format[MAX_TOKEN_LEN];
- char *pStart = pInto;
- static int count;
-
- while (*sz)
- {
- if (*sz == '%')
- {
- switch (*++sz)
- {
- /* See if it's a special emitter */
- case 'r':
- wassert (0);
- break;
- /* Name of the code segment */
- case 'C':
- strcpy (pInto, CODE_NAME);
- pInto = pStart + strlen (pStart);
- sz++;
- break;
- case 'F':
- strcpy (pInto, srcFileName);
- pInto = pStart + strlen (pStart);
- sz++;
- break;
- case 'I':
- sprintf (pInto, "%u", ++count);
- pInto = pStart + strlen (pStart);
- sz++;
- break;
- default:
- {
- /* Scan out the arg and pass it on to sprintf */
- char *p = format;
- *p++ = '%';
- while (isdigit (*sz))
- *p++ = *sz++;
- *p++ = *sz++;
- *p = '\0';
- vsprintf (pInto, format, *pap);
- /* PENDING: Assume that the arg length was an int */
- (void) va_arg (*pap, int);
- }
- }
- pInto = pStart + strlen (pStart);
- }
- else
- {
- *pInto++ = *sz++;
- }
- }
- *pInto = '\0';
-}
-
-void
-tvsprintf (char *buffer, const char *sz, va_list ap)
-{
- char *pInto = buffer;
- char *p;
- char token[MAX_TOKEN_LEN];
-
- buffer[0] = '\0';
-
- while (*sz)
- {
- if (*sz == '!')
- {
- /* Start of a token. Search until the first
- [non alplha, *] and call it a token. */
- const char *t;
- p = token;
- sz++;
- while (isalpha (*sz) || *sz == '*')
- {
- *p++ = *sz++;
- }
- *p = '\0';
- /* Now find the token in the token list */
- if ((t = _findMapping (token)))
- {
- printf ("tvsprintf: found token \"%s\" to \"%s\"\n", token, t);
- _iprintf (pInto, t, &ap);
- pInto = buffer + strlen (buffer);
- }
- else
- {
- fprintf (stderr, "Cant find token \"%s\"\n", token);
- wassert (0);
- }
- }
- else if (*sz == '%')
- {
- p = token;
- *p++ = *sz++;
- while (!isalpha (*sz))
- {
- *p++ = *sz++;
- }
- *p++ = *sz++;
- *p = '\0';
- vsprintf (pInto, token, ap);
- pInto = buffer + strlen (buffer);
- (void) va_arg (ap, int);
- }
- else
- {
- *pInto++ = *sz++;
- }
- }
- *pInto = '\0';
-}
-#else
// Append a string onto another, and update the pointer to the end of
// the new string.
static char *
// Supports:
// !tokens
- // %[CIF] - special formats with no argument (ie list isnt touched)
+ // %[CIFN] - special formats with no argument (ie list isnt touched)
// All of the system formats
// This is acheived by expanding the tokens and zero arg formats into
// one big format string, which is passed to the native printf.
static int count;
- char newformat[INITIAL_INLINEASM];
- char *pInto = newformat;
+ char noTokens[INITIAL_INLINEASM];
+ char newFormat[INITIAL_INLINEASM];
+ char *pInto = noTokens;
char *p;
char token[MAX_TOKEN_LEN];
const char *sz = format;
// NULL terminate it to let strlen work.
*pInto = '\0';
+ /* First pass: expand all of the macros */
while (*sz)
{
if (*sz == '!')
/* Now find the token in the token list */
if ((t = _findMapping (token)))
{
- pInto = _appendAt (pInto, newformat, t);
+ pInto = _appendAt (pInto, noTokens, t);
}
else
{
wassert (0);
}
}
- else if (*sz == '%')
+ else
+ {
+ *pInto++ = *sz++;
+ }
+ }
+
+ *pInto = '\0';
+
+ /* Second pass: Expand any macros that we own */
+ sz = noTokens;
+ pInto = newFormat;
+
+ while (*sz)
+ {
+ if (*sz == '%')
{
// See if its one that we handle.
sz++;
{
case 'C':
// Code segment name.
- pInto = _appendAt (pInto, newformat, CODE_NAME);
+ pInto = _appendAt (pInto, newFormat, CODE_NAME);
+ sz++;
break;
case 'F':
// Source file name.
- pInto = _appendAt (pInto, newformat, srcFileName);
+ pInto = _appendAt (pInto, newFormat, srcFileName);
+ sz++;
break;
+ case 'N':
+ // Current function name.
+ pInto = _appendAt (pInto, newFormat, currFunc->rname);
+ sz++;
+ break;
case 'I':
{
// Unique ID.
char id[20];
sprintf (id, "%u", ++count);
- pInto = _appendAt (pInto, newformat, id);
+ pInto = _appendAt (pInto, newFormat, id);
+ sz++;
break;
}
default:
*pInto++ = *sz++;
}
}
+
*pInto = '\0';
// Now do the actual printing
- vsprintf (buffer, newformat, ap);
+ vsprintf (buffer, newFormat, ap);
}
-#endif
void
tfprintf (FILE * fp, const char *szFormat,...)
{"msbimmeds", "#>%s"},
{"module", ".file \"%s.c\""},
{"global", ".globl %s"},
+ {"extern", ".globl %s"},
{"fileprelude", ""},
{"functionheader",
"; ---------------------------------\n"
/* if bit variable */
if (!aop->aopu.aop_dir)
{
- emit2 ("ld a,#0");
+ emit2 ("ld a,!zero");
emit2 ("rla");
}
else
spillCached ();
if (i > 8)
{
- emit2 ("ld iy,#%d", i);
+ emit2 ("ld iy,!immedword", i);
emit2 ("add iy,sp");
emit2 ("ld sp,iy");
}
/* Create the function header */
emit2 ("!functionheader", sym->name);
- /* PENDING: portability. */
- emit2 ("__%s_start:", sym->rname);
+ sprintf (buffer, "%s_start", sym->rname);
+ emit2 ("!labeldef", buffer);
emit2 ("!functionlabeldef", sym->rname);
if (options.profile)
/* Both baned and non-banked just ret */
emit2 ("ret");
- /* PENDING: portability. */
- emit2 ("__%s_end:", sym->rname);
+ sprintf (buffer, "%s_end", sym->rname);
+ emit2 ("!labeldef", buffer);
}
_G.flushStatics = 1;
_G.stack.pushed = 0;
if (isPair (AOP (IC_RIGHT (ic))) && AOP_TYPE (IC_LEFT (ic)) == AOP_IMMD && getPairId (AOP (IC_RIGHT (ic))) != PAIR_HL)
{
fetchPair (PAIR_HL, AOP (IC_LEFT (ic)));
- emit2 ("add hl,%s ; 2", getPairName (AOP (IC_RIGHT (ic))));
+ emit2 ("add hl,%s", getPairName (AOP (IC_RIGHT (ic))));
spillCached();
commitPair ( AOP (IC_RESULT (ic)), PAIR_HL);
goto release;
// Save the flags
emit2 ("push af");
emit2 ("ld a,(de)");
- emit2 ("xor #0x80");
+ emit2 ("xor !immedbyte", 0x80);
emit2 ("ld e,a");
emit2 ("ld a,(hl)");
- emit2 ("xor #0x80");
+ emit2 ("xor !immedbyte", 0x80);
emit2 ("ld d,a");
emit2 ("pop af");
emit2 ("ld a,e");
// Save the flags
emit2 ("push af");
emit2 ("ld a,(hl)");
- emit2 ("xor #0x80");
+ emit2 ("xor !immedbyte", 0x80);
emit2 ("ld l,a");
emit2 ("ld a,%d(iy)", offset);
- emit2 ("xor #0x80");
+ emit2 ("xor !immedbyte", 0x80);
emit2 ("ld h,a");
emit2 ("pop af");
emit2 ("ld a,l");
{
/* if it has an offset then we need to compute it */
if (sym->stack > 0)
- emit2 ("ld hl,#%d+%d+%d+%d", sym->stack, _G.stack.pushed, _G.stack.offset, _G.stack.param_offset);
+ emit2 ("ld hl,!immedword", sym->stack + _G.stack.pushed + _G.stack.offset + _G.stack.param_offset);
else
- emit2 ("ld hl,#%d+%d+%d", sym->stack, _G.stack.pushed, _G.stack.offset);
+ emit2 ("ld hl,!immedword", sym->stack + _G.stack.pushed + _G.stack.offset);
emit2 ("add hl,sp");
}
else
{
- emit2 ("ld hl,#%s", sym->rname);
+ emit2 ("ld hl,!hashedstr", sym->rname);
}
commitPair (AOP (IC_RESULT (ic)), PAIR_HL);
}
/* Yes, worthwhile. */
/* Commit whatever was in the buffer. */
_rleCommit(self);
- emit2(".db -%u,0x%02X", self->runLen, self->last);
+ emit2("!db !immed-%u,!immedbyte", self->runLen, self->last);
}
else
{
/* Commit whatever was in the buffer. */
_rleCommit(self);
- emit2 (".db -%u,0x%02X", self->runLen, self->last);
+ emit2 ("!db !immed-%u,!immedbyte", self->runLen, self->last);
self->runLen = 0;
}
self->runLen++;
/* Must be first */
ASM_TYPE_ASXXXX,
ASM_TYPE_RGBDS,
- ASM_TYPE_ISAS
+ ASM_TYPE_ISAS,
+ ASM_TYPE_Z80ASM
}
ASM_TYPE;
_G.asmType = ASM_TYPE_ISAS;
return TRUE;
}
+ else if (!strcmp (argv[*i], "--asm=z80asm"))
+ {
+ port->assembler.externGlobal = TRUE;
+ asm_addTree (&_z80asm_z80);
+ _G.asmType = ASM_TYPE_ISAS;
+ return TRUE;
+ }
}
}
return FALSE;
"\tadd\tix,sp\n"
"\tld\thl,#-%d\n"
"\tadd\thl,sp\n"
- "\tld\tsp,hl\n"
+ "\tld\tsp,hl"
},
{ "leave",
- "pop\tix\n"
+ "pop\tix"
},
{ "leavex",
"ld sp,ix\n"
- "\tpop\tix\n"
+ "\tpop\tix"
},
{ "pusha",
"push af\n"
static const ASM_MAPPING _rgbds_mapping[] = {
{ "global", "GLOBAL %s" },
+ { "extern", "GLOBAL %s" },
{ "slabeldef", "%s:" },
{ "labeldef", "%s:" },
{ "tlabeldef", ".l%05d:" },
static const ASM_MAPPING _isas_mapping[] = {
{ "global", "GLOBAL %s" },
+ { "extern", "GLOBAL %s" },
{ "slabeldef", "%s:" },
{ "labeldef", "%s:" },
{ "tlabeldef", "?l%05d:" },
{ NULL, NULL }
};
+static const ASM_MAPPING _z80asm_mapping[] = {
+ { "global", "XDEF %s" },
+ { "extern", "XREF %s" },
+ { "slabeldef", "\n.%s" },
+ { "labeldef", "\n.%s" },
+ { "tlabeldef", "\n.l%N%05d" },
+ { "tlabel", "l%N%05d" },
+ { "fileprelude",
+ "; Generated using the z80asm/z88 tokens.\n"
+ "\tXREF __muluchar_rrx_s\n"
+ "\tXREF __mulschar_rrx_s\n"
+ "\tXREF __mulsint_rrx_s\n"
+ "\tXREF __muluint_rrx_s\n"
+ "\tXREF __mululong_rrx_s\n"
+ "\tXREF __mulslong_rrx_s\n"
+ "\tXREF __divuchar_rrx_s\n"
+ "\tXREF __divschar_rrx_s\n"
+ "\tXREF __divsint_rrx_s\n"
+ "\tXREF __divuint_rrx_s\n"
+ "\tXREF __divulong_rrx_s\n"
+ "\tXREF __divslong_rrx_s\n"
+ "\tXREF __rrulong_rrx_s\n"
+ "\tXREF __rrslong_rrx_s\n"
+ "\tXREF __rlulong_rrx_s\n"
+ "\tXREF __rlslong_rrx_s\n"
+ },
+ { "functionheader",
+ "; ---------------------------------\n"
+ "; Function %s\n"
+ "; ---------------------------------"
+ },
+ { "functionlabeldef", ".%s" },
+ { "zero", "$00" },
+ { "one", "$01" },
+ { "ascii", "DEFM \"%s\"" },
+ { "ds", "DEFS %d" },
+ { "db", "DEFB" },
+ { "dbs", "DEFB %s" },
+ { "dw", "DEFW" },
+ { "dws", "DEFB %s" },
+ { "immed", "" },
+ { "constbyte", "$%02X" },
+ { "constword", "$%04X" },
+ { "immedword", "$%04X" },
+ { "immedbyte", "$%02X" },
+ { "hashedstr", "%s" },
+ { "lsbimmeds", "%s & $FF" },
+ { "msbimmeds", "%s / 256" },
+
+ { "bankimmeds", "BANK(%s)" },
+ { "module", "MODULE %s" },
+ { "area", "; Area %s" },
+ { "areadata", "; Aread BSS" },
+ { "areacode", "; Area CODE" },
+ { "areahome", "; Area HOME" },
+ { NULL, NULL }
+};
+
+static const ASM_MAPPING _z80asm_z80_mapping[] = {
+ { "*ixx", "(ix%+d)" },
+ { "*iyx", "(iy%+d)" },
+ { "*hl", "(hl)" },
+ { "di", "di" },
+ { "ldahli",
+ "ld a,(hl)\n"
+ "\tinc\thl" },
+ { "ldahlsp",
+ "ld hl,%d\n"
+ "\tadd\thl,sp" },
+ { "ldaspsp",
+ "ld hl,%d\n"
+ "\tadd\thl,sp\n"
+ "\tld\tsp,hl" },
+ { "*pair", "(%s)" },
+ { "shortjp", "jp" },
+ { "enter",
+ "push\tix\n"
+ "\tld\tix,0\n"
+ "\tadd\tix,sp" },
+ { "enterx",
+ "push\tix\n"
+ "\tld\tix,0\n"
+ "\tadd\tix,sp\n"
+ "\tld\thl,-%d\n"
+ "\tadd\thl,sp\n"
+ "\tld\tsp,hl"
+ },
+ { "leave",
+ "pop\tix"
+ },
+ { "leavex",
+ "ld sp,ix\n"
+ "\tpop\tix"
+ },
+ { "pusha",
+ "push af\n"
+ "\tpush\tbc\n"
+ "\tpush\tde\n"
+ "\tpush\thl"
+ },
+ { "adjustsp", "lda sp,(sp%+d)" },
+ { "profileenter",
+ "ld a,3\n"
+ "\trst\t$08"
+ },
+ { "profileexit",
+ "ld a,4\n"
+ "\trst\t$08"
+ },
+ { NULL, NULL }
+};
+
static const ASM_MAPPINGS _isas = {
NULL,
_isas_mapping
&asm_asxxxx_mapping,
_asxxxx_z80_mapping
};
+
+static const ASM_MAPPINGS _z80asm = {
+ NULL,
+ _z80asm_mapping
+};
+
+const ASM_MAPPINGS _z80asm_z80 = {
+ &_z80asm,
+ _z80asm_z80_mapping
+};