From: michaelh Date: Wed, 16 Feb 2000 04:20:26 +0000 (+0000) Subject: * Added support for the gb. X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=1e1d089aeaef38c6c55092486af1d38aa30a7a9d;p=fw%2Fsdcc * Added support for the gb. git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@107 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/src/SDCCmain.c b/src/SDCCmain.c index 65ddc3c4..2ad90c4c 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -123,12 +123,14 @@ static const char *_preCmd[] = { extern PORT mcs51_port; extern PORT z80_port; +extern PORT gbz80_port; PORT *port; static PORT *_ports[] = { &mcs51_port, - &z80_port + &z80_port, + &gbz80_port }; #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0])) @@ -1208,6 +1210,10 @@ int main ( int argc, char **argv , char **envp) /*printVersionInfo ();*/ _findPort(argc, argv); + /* Initalise the port. */ + if (port->init) + port->init(); + setDefaultOptions(); parseCmdLine(argc,argv); @@ -1216,6 +1222,7 @@ int main ( int argc, char **argv , char **envp) printUsage(); exit(0); } + if (srcFileName) preProcess(envp) ; diff --git a/src/mcs51/main.c b/src/mcs51/main.c index 5276dd14..3723fed3 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -174,6 +174,7 @@ PORT mcs51_port = { { 1 }, + NULL, _mcs51_parseOptions, _mcs51_finaliseOptions, _mcs51_setDefaultOptions, diff --git a/src/port.h b/src/port.h index 30c1e9e5..76ebfbd6 100644 --- a/src/port.h +++ b/src/port.h @@ -83,6 +83,11 @@ typedef struct { int nativebelow; } muldiv; + /** Called once the processor target has been selected. + First chance to initalise and set any port specific varibles. + 'port' is set before calling this. May be NULL. + */ + void (*init)(void); /** Parses one option + its arguments */ bool (*parseOption)(int *pargc, char **argv, int *i); /** Called after all the options have been parsed. */ @@ -114,4 +119,3 @@ typedef struct { extern PORT *port; #endif - diff --git a/src/z80/Makefile b/src/z80/Makefile index 2f6ef6e3..18b79f2f 100644 --- a/src/z80/Makefile +++ b/src/z80/Makefile @@ -2,7 +2,7 @@ PRJDIR = ../.. include $(PRJDIR)/Makefile.common -OBJ = gen.o ralloc.o main.o +OBJ = gen.o ralloc.o main.o gbz80.o LIB = port.a CFLAGS = -ggdb -Wall diff --git a/src/z80/gbz80.c b/src/z80/gbz80.c new file mode 100644 index 00000000..e64785be --- /dev/null +++ b/src/z80/gbz80.c @@ -0,0 +1,119 @@ +/** @file z80/gbz80.c + Extra bits ontop of the z80 port to target the Gameboy's Z80 like + processor. + + Michael Hope 2000 +*/ + +#include "z80.h" + +static char _defaultRules[] = +{ +#include "peeph.rul" +}; + +static char *_gbz80_keywords[] = { NULL }; + +static bool _gbz80_parseOptions(int *pargc, char **argv, int *i) +{ + return FALSE; +} + +static void _gbz80_init(void) +{ + z80_opts.sub = SUB_GBZ80; +} + +static void _gbz80_finaliseOptions(void) +{ +} + +static void _gbz80_setDefaultOptions(void) +{ + options.genericPtr = 1; /* default on */ + options.nopeep = 0; + options.stackAuto = 1; + options.mainreturn = 1; + options.noregparms = 1; + /* first the options part */ + options.intlong_rent = 1; + + optimize.global_cse = 1; + optimize.label1 = 1; + optimize.label2 = 1; + optimize.label3 = 1; + optimize.label4 = 1; + optimize.loopInvariant = 1; + optimize.loopInduction = 0; +} + +static const char *_gbz80_getRegName(struct regs *reg) +{ + if (reg) + 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 *_linkCmd[] = { + "link-gb", "-nf", "$1", NULL +}; + +static const char *_asmCmd[] = { + "as-gb", "-plosgff", "$1.o", "$1.asm", NULL +}; + +/* Globals */ +PORT gbz80_port = { + "gbz80", + "Gameboy Z80-like", /* Target name */ + { + _asmCmd, + "-plosgff", /* Options with debug */ + "-plosgff", /* Options without debug */ + }, + { + _linkCmd + }, + { + _defaultRules + }, + { + /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */ + 1, 1, 2, 4, 2, 2, 2, 1, 4, 4 + }, + { + "_XSEG", + "_STACK", + "_CODE", + "_DATA", + "_ISEG", + "_XSEG", + "_BSEG", + "_RSEG", + "_GSINIT", + "_OVERLAY" + }, + { + -1, 0, 0, 4, 0 + }, + /* Z80 has no native mul/div commands */ + { + 0 + }, + _gbz80_init, + _gbz80_parseOptions, + _gbz80_finaliseOptions, + _gbz80_setDefaultOptions, + z80_assignRegisters, + _gbz80_getRegName, + _gbz80_keywords, + 0, /* no assembler preamble */ + 0, /* no local IVT generation code */ +}; diff --git a/src/z80/gen.c b/src/z80/gen.c index 50154dd3..9e325cd5 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -45,30 +45,15 @@ #include #include #include -#include "SDCCglobl.h" #ifdef HAVE_SYS_ISA_DEFS_H #include #endif -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCloop.h" -#include "SDCCcse.h" -#include "SDCCcflow.h" -#include "SDCCdflow.h" -#include "SDCClrange.h" -#include "ralloc.h" -#include "gen.h" +#include "z80.h" #include "SDCCpeeph.h" -#include "SDCCglue.h" /* drdani Jan 30 2000 */ +#include "gen.h" +#include "SDCCglue.h" /* this is the down and dirty file with all kinds of kludgy & hacky stuff. This is what it is all about CODE GENERATION for a specific MCU. @@ -77,7 +62,11 @@ static char *zero = "#0x00"; static char *one = "#0x01"; static char *spname ; -static char *fReturn[] = {"l", "h", "e", "d" }; +static char *_z80_return[] = {"l", "h", "e", "d" }; +static char *_gbz80_return[] = { "e", "d", "l", "h" }; +static char **_fReturn; +static char **_fTmp; + static char *accUse[] = {"a" }; short rbank = -1; short accInUse = 0 ; @@ -106,6 +95,8 @@ unsigned char SRMask[] = {0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00}; static int _lastStack = 0; +static int _pushed = 0; +static int _spoffset; #define LSB 0 #define MSB16 1 @@ -258,10 +249,22 @@ static asmop *aopForSym (iCode *ic,symbol *sym,bool result) return aop; } + if (IS_GB) { + /* if it is in direct space */ + if (IN_DIRSPACE(space)) { + sym->aop = aop = newAsmop (AOP_DIR); + aop->aopu.aop_dir = sym->rname ; + aop->size = getSize(sym->type); + emitcode("", "; AOP_DIR for %s", sym->rname); + return aop; + } + } + /* only remaining is far space */ /* in which case DPTR gets the address */ sym->aop = aop = newAsmop(AOP_IY); - emitcode ("ld","iy,#%s", sym->rname); + if (!IS_GB) + emitcode ("ld","iy,#%s ; a", sym->rname); aop->size = getSize(sym->type); aop->aopu.aop_dir = sym->rname; @@ -484,7 +487,7 @@ static void aopOp (operand *op, iCode *ic, bool result) aop = op->aop = sym->aop = newAsmop(AOP_STR); aop->size = getSize(sym->type); for ( i = 0 ; i < 4 ; i++ ) - aop->aopu.aop_str[i] = fReturn[i]; + aop->aopu.aop_str[i] = "xx"; /*_fReturn[i];*/ return; } @@ -612,8 +615,8 @@ static char *aopGet (asmop *aop, int offset, bool bit16) return rs; case AOP_DIR: - assert(0); - emitcode("ld", "a,(%s+%d)", aop->aopu.aop_dir, offset); + assert(IS_GB); + emitcode("ld", "a,(%s+%d) ; x", aop->aopu.aop_dir, offset); sprintf(s, "a"); ALLOC_ATOMIC(rs,strlen(s)+1); strcpy(rs,s); @@ -629,7 +632,16 @@ static char *aopGet (asmop *aop, int offset, bool bit16) return rs; case AOP_STK: - sprintf(s,"%d(ix) ; %u", aop->aopu.aop_stk+offset, offset); + if (IS_GB) { + /* We cant really optimise this as we cant afford to + change the flags. + */ + emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset); + sprintf(s, "(hl)"); + } + else { + sprintf(s,"%d(ix) ; %u", aop->aopu.aop_stk+offset, offset); + } ALLOC_ATOMIC(rs,strlen(s)+1); strcpy(rs,s); return rs; @@ -690,8 +702,6 @@ bool canAssignToPtr(char *s) /*-----------------------------------------------------------------*/ static void aopPut (asmop *aop, char *s, int offset) { - char *d = buffer ; - if (aop->size && offset > ( aop->size - 1)) { werror(E_INTERNAL_ERROR,__FILE__,__LINE__, "aopPut got offset > aop->size"); @@ -702,10 +712,10 @@ static void aopPut (asmop *aop, char *s, int offset) /* depending on where it is ofcourse */ switch (aop->type) { case AOP_DIR: - assert(0); /* Direct. Hmmm. */ + assert(IS_GB); emitcode("ld", "a,%s", s); - emitcode("ld", "(%s+%d),a", d, offset); + emitcode("ld", "(%s+%d),a", aop->aopu.aop_dir, offset); break; case AOP_REG: @@ -717,6 +727,7 @@ static void aopPut (asmop *aop, char *s, int offset) break; case AOP_IY: + assert(!IS_GB); if (!canAssignToPtr(s)) { emitcode("ld", "a,%s", s); emitcode("ld", "%d(iy),a", offset); @@ -726,12 +737,27 @@ static void aopPut (asmop *aop, char *s, int offset) break; case AOP_STK: - if (!canAssignToPtr(s)) { - emitcode("ld", "a,%s", s); - emitcode("ld", "%d(ix),a", aop->aopu.aop_stk+offset); + if (IS_GB) { + if (!strcmp("(hl)", s)) { + emitcode("ld", "a,(hl)"); + s = "a"; + } + emitcode("lda", "hl,%d+%d+%d(sp)", aop->aopu.aop_stk+offset, _pushed, _spoffset); + if (!canAssignToPtr(s)) { + emitcode("ld", "a,%s", s); + emitcode("ld", "(hl),a"); + } + else + emitcode("ld", "(hl),%s", s); + } + else { + if (!canAssignToPtr(s)) { + emitcode("ld", "a,%s", s); + emitcode("ld", "%d(ix),a", aop->aopu.aop_stk+offset); + } + else + emitcode("ld", "%d(ix),%s", aop->aopu.aop_stk+offset, s); } - else - emitcode("ld", "%d(ix),%s", aop->aopu.aop_stk+offset, s); break; case AOP_CRY: @@ -989,6 +1015,15 @@ release: freeAsmop(IC_RESULT(ic),NULL,ic); } +static bool requiresHL(asmop *aop) +{ + switch (aop->type) { + case AOP_STK: + return TRUE; + default: + return FALSE; + } +} /*-----------------------------------------------------------------*/ /* assignResultValue - */ @@ -997,12 +1032,28 @@ void assignResultValue(operand * oper) { int offset = 0; int size = AOP_SIZE(oper); + + assert(size <= 2); + while (size--) { - aopPut(AOP(oper),fReturn[offset],offset); + aopPut(AOP(oper),_fReturn[offset],offset); offset++; } } +static void fetchHL(asmop *aop) +{ + if (IS_GB && requiresHL(aop)) { + emitcode("ld", "a,%s", aopGet(aop, 0, FALSE)); + emitcode("ld", "h,%s", aopGet(aop, 1, FALSE)); + emitcode("ld", "l,a"); + } + else { + emitcode("ld", "l,%s", aopGet(aop, 0, FALSE)); + emitcode("ld", "h,%s", aopGet(aop, 1, FALSE)); + } +} + /*-----------------------------------------------------------------*/ /* genIpush - genrate code for pushing this gets a little complex */ /*-----------------------------------------------------------------*/ @@ -1024,6 +1075,7 @@ static void genIpush (iCode *ic) /* push it on the stack */ if (isPair(AOP(IC_LEFT(ic)))) { emitcode("push", getPairName(AOP(IC_LEFT(ic)))); + _pushed += 2; } else { offset = size; @@ -1033,6 +1085,7 @@ static void genIpush (iCode *ic) emitcode("ld", "a,%s", l); emitcode("push", "af"); emitcode("inc", "sp"); + _pushed++; } } return ; @@ -1047,6 +1100,7 @@ static void genIpush (iCode *ic) size = AOP_SIZE(IC_LEFT(ic)); if (isPair(AOP(IC_LEFT(ic)))) { + _pushed+=2; emitcode("push", "%s", getPairName(AOP(IC_LEFT(ic)))); } else { @@ -1055,12 +1109,13 @@ static void genIpush (iCode *ic) if (s) { emitcode("ld", "hl,%s", s); emitcode("push", "hl"); + _pushed+=2; } else { /* Optimise here - load into HL then push HL */ - emitcode("ld", "l,%s", aopGet(AOP(IC_LEFT(ic)), 0, FALSE)); - emitcode("ld", "h,%s", aopGet(AOP(IC_LEFT(ic)), 1, FALSE)); + fetchHL(AOP(IC_LEFT(ic))); emitcode("push", "hl"); + _pushed += 2; } goto release; } @@ -1070,6 +1125,7 @@ static void genIpush (iCode *ic) emitcode("ld", "a,%s", l); emitcode("push", "af"); emitcode("inc", "sp"); + _pushed++; } } release: @@ -1126,9 +1182,9 @@ static void emitCall (iCode *ic, bool ispcall) while (size--) { char *l = aopGet(AOP(IC_LEFT(sic)),offset, FALSE); - if (strcmp(l,fReturn[offset])) + if (strcmp(l, _fReturn[offset])) emitcode("ld","%s,%s", - fReturn[offset], + _fReturn[offset], l); offset++; } @@ -1176,6 +1232,7 @@ static void emitCall (iCode *ic, bool ispcall) /* adjust the stack for parameters if required */ if (IC_LEFT(ic)->parmBytes) { int i = IC_LEFT(ic)->parmBytes; + _pushed -= i; if (i>6) { emitcode("ld", "hl,#%d", i); emitcode("add", "hl,sp"); @@ -1258,11 +1315,13 @@ static void genFunction (iCode *ic) /* PENDING: callee-save etc */ /* adjust the stack for the function */ - emitcode("push", "de"); emitcode("push", "bc"); - emitcode("push", "ix"); - emitcode("ld", "ix,#0"); - emitcode("add", "ix,sp"); + if (!IS_GB) { + emitcode("push", "de"); + emitcode("push", "ix"); + emitcode("ld", "ix,#0"); + emitcode("add", "ix,sp"); + } _lastStack = sym->stack; @@ -1270,7 +1329,8 @@ static void genFunction (iCode *ic) emitcode("ld", "hl,#-%d", sym->stack); emitcode("add", "hl,sp"); emitcode("ld", "sp,hl"); - } + } + _spoffset = sym->stack; } /*-----------------------------------------------------------------*/ @@ -1301,10 +1361,12 @@ static void genEndFunction (iCode *ic) emitcode("","XG$%s$0$0 ==.",currFunc->name); debugLine = 0; } - emitcode("ld", "sp,ix"); - emitcode("pop", "ix"); + if (!IS_GB) { + emitcode("ld", "sp,ix"); + emitcode("pop", "ix"); + emitcode("pop", "de"); + } emitcode("pop", "bc"); - emitcode("pop", "de"); emitcode("ret", ""); } @@ -1337,8 +1399,8 @@ static void genRet (iCode *ic) while (size--) { l = aopGet(AOP(IC_LEFT(ic)),offset, FALSE); - if (strcmp(fReturn[offset],l)) - emitcode("ld","%s,%s",fReturn[offset++],l); + if (strcmp(_fReturn[offset],l)) + emitcode("ld","%s,%s", _fReturn[offset++],l); } } freeAsmop (IC_LEFT(ic),NULL,ic); @@ -1855,25 +1917,25 @@ static void genCmp (operand *left,operand *right, if (AOP_TYPE(left) == AOP_LIT){ unsigned long lit = (unsigned long) floatFromVal(AOP(left)->aopu.aop_lit); - emitcode("ld", "l,#0x%02x", + emitcode("ld", "%s,#0x%02x", _fTmp[0], 0x80 ^ (unsigned int)((lit >> ((size-1)*8)) & 0x0FFL)); } else { emitcode("ld", "a,%s", aopGet(AOP(left), size-1, FALSE)); emitcode("xor", "a,#0x80"); - emitcode("ld", "l,a"); + emitcode("ld", "%s,a", _fTmp[0]); fDidXor = TRUE; } if (AOP_TYPE(right) == AOP_LIT) { unsigned long lit = (unsigned long) floatFromVal(AOP(right)->aopu.aop_lit); - emitcode("ld", "h,#0x%02x", + emitcode("ld", "%s,#0x%02x", _fTmp[1], 0x80 ^ (unsigned int)((lit >> ((size-1)*8)) & 0x0FFL)); } else { emitcode("ld", "a,%s", aopGet(AOP(right), size-1, FALSE)); emitcode("xor", "a,#0x80"); - emitcode("ld", "h,a"); + emitcode("ld", "%s,a", _fTmp[1]); fDidXor = TRUE; } if (!fDidXor) @@ -1887,8 +1949,8 @@ static void genCmp (operand *left,operand *right, if (!sign || size) MOVA(aopGet(AOP(left),offset,FALSE)); if (sign && size == 0) { - emitcode("ld", "a,l"); - emitcode("sbc", "a,h"); + emitcode("ld", "a,%s", _fTmp[0]); + emitcode("sbc", "a,%s", _fTmp[1]); } else { /* Subtract through, propagating the carry */ @@ -3230,9 +3292,7 @@ static void genGenPointerGet (operand *left, if (AOP_TYPE(left) == AOP_IMMD) emitcode("ld","hl,%s",aopGet(AOP(left),0,TRUE)); else { /* we need to get it byte by byte */ - - emitcode("ld", "l,%s", aopGet(AOP(left), 0, FALSE)); - emitcode("ld", "h,%s", aopGet(AOP(left), 1, FALSE)); + fetchHL(AOP(left)); } /* so iy now contains the address */ freeAsmop(left,NULL,ic); @@ -3322,8 +3382,7 @@ static void genGenPointerSet (operand *right, } else { /* we need to get it byte by byte */ /* PENDING: do this better */ - emitcode("ld", "l,%s", aopGet(AOP(result), 0, FALSE)); - emitcode("ld", "h,%s", aopGet(AOP(result), 1, FALSE)); + fetchHL(AOP(result)); } } /* so hl know contains the address */ @@ -3425,19 +3484,29 @@ static void genAddrOf (iCode *ic) variable */ if (sym->onStack) { /* if it has an offset then we need to compute it */ - emitcode("push", "de"); - emitcode("push", "ix"); - emitcode("pop", "hl"); - emitcode("ld", "de,#%d", sym->stack); - emitcode("add", "hl,de"); - emitcode("pop", "de"); + if (IS_GB) { + emitcode("lda", "hl,%d(sp)", sym->stack); + emitcode("ld", "d,h"); + emitcode("ld", "e,l"); + aopPut(AOP(IC_RESULT(ic)), "e", 0); + aopPut(AOP(IC_RESULT(ic)), "d", 1); + goto end; + } + else { + emitcode("push", "de"); + emitcode("push", "ix"); + emitcode("pop", "hl"); + emitcode("ld", "de,#%d", sym->stack); + emitcode("add", "hl,de"); + emitcode("pop", "de"); + } } else { emitcode("ld", "hl,#%s", sym->rname); } aopPut(AOP(IC_RESULT(ic)), "l", 0); aopPut(AOP(IC_RESULT(ic)), "h", 1); - +end: freeAsmop(IC_RESULT(ic),NULL,ic); } @@ -3536,7 +3605,8 @@ static void genJumpTab (iCode *ic) /* get the condition into accumulator */ l = aopGet(AOP(IC_JTCOND(ic)),0,FALSE); MOVA(l); - emitcode("push", "de"); + if (!IS_GB) + emitcode("push", "de"); emitcode("ld", "e,%s", l); emitcode("ld", "d,#0"); jtab = newiTempLabel(NULL); @@ -3544,7 +3614,8 @@ static void genJumpTab (iCode *ic) emitcode("add", "hl,de"); emitcode("add", "hl,de"); freeAsmop(IC_JTCOND(ic),NULL,ic); - emitcode("pop", "de"); + if (!IS_GB) + emitcode("pop", "de"); emitcode("jp", "(hl)"); emitcode("","%05d$:",jtab->key+100); /* now generate the jump labels */ @@ -3594,10 +3665,13 @@ static void genCast (iCode *ic) goto release; } + /* PENDING: should be OK. */ +#if 0 /* if the result is of type pointer */ if (IS_PTR(ctype)) { assert(0); } +#endif /* so we now know that the size of destination is greater than the size of the source */ @@ -3661,6 +3735,16 @@ void genZ80Code (iCode *lic) iCode *ic; int cln = 0; + /* HACK */ + if (IS_GB) { + _fReturn = _gbz80_return; + _fTmp = _gbz80_return; + } + else { + _fReturn = _z80_return; + _fTmp = _z80_return; + } + lineHead = lineCurr = NULL; /* if debug information required */ diff --git a/src/z80/main.c b/src/z80/main.c index 27026e49..f59edf61 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -1,14 +1,18 @@ -#include "common.h" -#include "ralloc.h" +#include "z80.h" static char _defaultRules[] = { #include "peeph.rul" }; +Z80_OPTS z80_opts; + static char *_z80_keywords[] = { NULL }; -void z80_assignRegisters (eBBlock **ebbs, int count); +static void _z80_init(void) +{ + z80_opts.sub = SUB_Z80; +} static bool _z80_parseOptions(int *pargc, char **argv, int *i) { @@ -98,6 +102,7 @@ PORT z80_port = { { 0 }, + _z80_init, _z80_parseOptions, _z80_finaliseOptions, _z80_setDefaultOptions, diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index 1e651850..54e34049 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -42,24 +42,7 @@ software-hoarding! */ -#include -#include -#include "SDCCglobl.h" -#include "SDCCast.h" -#include "SDCCmem.h" -#include "SDCCy.h" -#include "SDCChasht.h" -#include "SDCCbitv.h" -#include "SDCCset.h" -#include "SDCCicode.h" -#include "SDCClabel.h" -#include "SDCCBBlock.h" -#include "SDCCloop.h" -#include "SDCCcse.h" -#include "SDCCcflow.h" -#include "SDCCdflow.h" -#include "SDCClrange.h" -#include "ralloc.h" +#include "z80.h" /*-----------------------------------------------------------------*/ /* At this point we start getting processor specific although */ @@ -80,12 +63,18 @@ int ptrRegReq = 0; /* one byte pointer register required */ bitVect *funcrUsed = NULL; /* registers used in a function */ int stackExtend = 0; int dataExtend = 0; +int _nRegs; /** Set to help debug register pressure related problems */ #define DEBUG_FAKE_EXTRA_REGS 0 -static regs regsZ80[] = -{ +static regs _gbz80_regs[] = { + { REG_GPR, C_IDX , "b", 1 }, + { REG_GPR, B_IDX , "c", 1 }, + { REG_CND, CND_IDX, "c", 1} +}; + +static regs _z80_regs[] = { { REG_GPR, C_IDX , "c", 1 }, { REG_GPR, B_IDX , "b", 1 }, { REG_GPR, E_IDX , "e", 1 }, @@ -105,8 +94,11 @@ static regs regsZ80[] = { REG_CND, CND_IDX, "c", 1} }; +regs *regsZ80; + /** Number of usable registers (all but C) */ -#define MAX_REGS ((sizeof(regsZ80)/sizeof(regs))-1) +#define Z80_MAX_REGS ((sizeof(_z80_regs)/sizeof(_z80_regs[0]))-1) +#define GBZ80_MAX_REGS ((sizeof(_gbz80_regs)/sizeof(_gbz80_regs[0]))-1) static void spillThis (symbol *); @@ -120,7 +112,7 @@ static regs *allocReg (short type) { int i; - for ( i = 0 ; i < MAX_REGS ; i++ ) { + for ( i = 0 ; i < _nRegs ; i++ ) { /* For now we allocate from any free */ if (regsZ80[i].isFree ) { regsZ80[i].isFree = 0; @@ -139,7 +131,7 @@ regs *regWithIdx (int idx) { int i; - for (i=0;i < MAX_REGS;i++) + for (i=0;i < _nRegs;i++) if (regsZ80[i].rIdx == idx) return ®sZ80[i]; @@ -164,7 +156,7 @@ static int nFreeRegs (int type) int i; int nfr=0; - for (i = 0 ; i < MAX_REGS; i++ ) { + for (i = 0 ; i < _nRegs; i++ ) { /* For now only one reg type */ if (regsZ80[i].isFree) nfr++; @@ -867,7 +859,7 @@ bool tryAllocatingRegPair(symbol *sym) { int i; assert(sym->nRegs == 2); - for ( i = 0 ; i < MAX_REGS ; i+=2 ) { + for ( i = 0 ; i < _nRegs ; i+=2 ) { if ((regsZ80[i].isFree)&&(regsZ80[i+1].isFree)) { regsZ80[i].isFree = 0; sym->regs[0] = ®sZ80[i]; @@ -1037,7 +1029,7 @@ bitVect *rUmaskForOp (operand *op) if (sym->isspilt || !sym->nRegs) return NULL; - rumask = newBitVect(MAX_REGS); + rumask = newBitVect(_nRegs); for (j = 0; j < sym->nRegs; j++) { rumask = bitVectSetBit(rumask, @@ -1051,7 +1043,7 @@ bitVect *rUmaskForOp (operand *op) */ bitVect *regsUsedIniCode (iCode *ic) { - bitVect *rmask = newBitVect(MAX_REGS); + bitVect *rmask = newBitVect(_nRegs); /* do the special cases first */ if (ic->op == IFX ) { @@ -1117,7 +1109,7 @@ static void createRegMask (eBBlock **ebbs, int count) /* now create the register mask for those registers that are in use : this is a super set of ic->rUsed */ - ic->rMask = newBitVect(MAX_REGS+1); + ic->rMask = newBitVect(_nRegs+1); /* for all live Ranges alive at this point */ for (j = 1; j < ic->rlive->size; j++ ) { @@ -1234,7 +1226,7 @@ static void freeAllRegs() { int i; - for (i=0;i< MAX_REGS;i++ ) + for (i=0;i< _nRegs;i++ ) regsZ80[i].isFree = 1; } @@ -2047,25 +2039,27 @@ static void packRegisters (eBBlock *ebp) packRegsForOneuse (ic,IC_LEFT(ic),ebp); #endif - /* if pointer set & left has a size more than + if (!IS_GB) { + /* if pointer set & left has a size more than one and right is not in far space */ - if (POINTER_SET(ic) && - /* MLH: no such thing. - !isOperandInFarSpace(IC_RIGHT(ic)) && */ - !OP_SYMBOL(IC_RESULT(ic))->remat && - !IS_OP_RUONLY(IC_RIGHT(ic)) && - getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 ) - - packRegsForOneuse (ic,IC_RESULT(ic),ebp); - - /* if pointer get */ - if (POINTER_GET(ic) && - /* MLH: dont have far space - !isOperandInFarSpace(IC_RESULT(ic))&& */ - !OP_SYMBOL(IC_LEFT(ic))->remat && - !IS_OP_RUONLY(IC_RESULT(ic)) && - getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 ) - packRegsForOneuse (ic,IC_LEFT(ic),ebp); + if (POINTER_SET(ic) && + /* MLH: no such thing. + !isOperandInFarSpace(IC_RIGHT(ic)) && */ + !OP_SYMBOL(IC_RESULT(ic))->remat && + !IS_OP_RUONLY(IC_RIGHT(ic)) && + getSize(aggrToPtr(operandType(IC_RESULT(ic)),FALSE)) > 1 ) + + packRegsForOneuse (ic,IC_RESULT(ic),ebp); + + /* if pointer get */ + if (POINTER_GET(ic) && + /* MLH: dont have far space + !isOperandInFarSpace(IC_RESULT(ic))&& */ + !OP_SYMBOL(IC_LEFT(ic))->remat && + !IS_OP_RUONLY(IC_RESULT(ic)) && + getSize(aggrToPtr(operandType(IC_LEFT(ic)),FALSE)) > 1 ) + packRegsForOneuse (ic,IC_LEFT(ic),ebp); + } /* pack registers for accumulator use, when the result of an arithmetic or bit wise operation has only one use, that use is @@ -2106,6 +2100,16 @@ void z80_assignRegisters (eBBlock **ebbs, int count) setToNull((void *)&funcrUsed); ptrRegReq = stackExtend = dataExtend = 0; + if (IS_GB) { + /* DE is required for the code gen. */ + _nRegs = GBZ80_MAX_REGS; + regsZ80 = _gbz80_regs; + } + else { + _nRegs = Z80_MAX_REGS; + regsZ80 = _z80_regs; + } + /* change assignments this will remove some live ranges reducing some register pressure */ for (i = 0 ; i < count ;i++ ) diff --git a/src/z80/ralloc.h b/src/z80/ralloc.h index d3af0525..c798aca7 100644 --- a/src/z80/ralloc.h +++ b/src/z80/ralloc.h @@ -60,9 +60,11 @@ typedef struct regs unsigned isFree :1; /* is currently unassigned */ } regs; -extern regs regsZ80[]; +extern regs *regsZ80; void assignRegisters (eBBlock **, int ); regs *regWithIdx (int); +void z80_assignRegisters (eBBlock **ebbs, int count); + #endif diff --git a/src/z80/z80.h b/src/z80/z80.h new file mode 100644 index 00000000..5fa505f2 --- /dev/null +++ b/src/z80/z80.h @@ -0,0 +1,19 @@ +/** @file z80/z80.h + Common definitions between the z80 and gbz80 parts. +*/ +#include "common.h" +#include "ralloc.h" + +typedef enum { + SUB_Z80, + SUB_GBZ80 +} Z80_SUB_PORT; + +typedef struct { + Z80_SUB_PORT sub; +} Z80_OPTS; + +extern Z80_OPTS z80_opts; + +#define IS_GB (z80_opts.sub == SUB_GBZ80) +