* Added support for the gb.
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 16 Feb 2000 04:20:26 +0000 (04:20 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Wed, 16 Feb 2000 04:20:26 +0000 (04:20 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@107 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/SDCCmain.c
src/mcs51/main.c
src/port.h
src/z80/Makefile
src/z80/gbz80.c [new file with mode: 0644]
src/z80/gen.c
src/z80/main.c
src/z80/ralloc.c
src/z80/ralloc.h
src/z80/z80.h [new file with mode: 0644]

index 65ddc3c4b582a5d4274b18838a3e2c7ea318223d..2ad90c4ca9e5305f129d991b2c8092423f069c5d 100644 (file)
@@ -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) ;
index 5276dd148782829ca12f3aad919fd1a3ddfa625b..3723fed344ca466c1f334e8a5474fe1a6e2c6bde 100644 (file)
@@ -174,6 +174,7 @@ PORT mcs51_port = {
     {
        1
     },
+    NULL,
     _mcs51_parseOptions,
     _mcs51_finaliseOptions,
     _mcs51_setDefaultOptions,
index 30c1e9e5c6a9a3a9958757b14c15c05107ca84ad..76ebfbd62606a1254a60c9cf785e621f291fd44f 100644 (file)
@@ -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
-
index 2f6ef6e31d8491b41d05824fd21a158cb167e2f4..18b79f2f1ba16f3e6a4773e219802d755526dedc 100644 (file)
@@ -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 (file)
index 0000000..e64785b
--- /dev/null
@@ -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 <michaelh@earthling.net> 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 */
+};
index 50154dd37d24a95040269d4bbeb7db19265efc1c..9e325cd561c582f97a4f5a017eaea92cb60de633 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include "SDCCglobl.h"
 
 #ifdef HAVE_SYS_ISA_DEFS_H
 #include <sys/isa_defs.h>
 #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.
 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 */
index 27026e499c5646c4edf9243145b4069ff409730a..f59edf6126d1e4806607480653b44ce0211d808f 100644 (file)
@@ -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,
index 1e651850cf0cd6a62d0b81e40e026dfbf5b42e86..54e34049b2e5c8b1e9ffa58aa6738dc563706780 100644 (file)
     software-hoarding!  
 */
 
-#include <stdio.h>
-#include <stdlib.h>
-#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 &regsZ80[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] = &regsZ80[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++ )
index d3af0525f6b4e304551d544d14876dbe549a25b4..c798aca71a06f178a6b0ab2990a8b0f1a558bd3b 100644 (file)
@@ -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 (file)
index 0000000..5fa505f
--- /dev/null
@@ -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)
+