Merged gbdk-294 branch
authormichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 21 May 2000 02:34:30 +0000 (02:34 +0000)
committermichaelh <michaelh@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Sun, 21 May 2000 02:34:30 +0000 (02:34 +0000)
git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@254 4a8a32a2-be11-0410-ad9d-d568d2c75423

src/SDCCglue.c
src/SDCCsymt.h
src/z80/gen.c
src/z80/gen.h
src/z80/main.c
src/z80/mappings.i
src/z80/ralloc.c
src/z80/z80.h

index 31ebf5b94868cae645376ba620bd58a5bf646995..1a3c51584b852c777dcf462cdc5b3a2404a5d3a0 100644 (file)
@@ -357,6 +357,7 @@ void printChar (FILE * ofile, char *s, int plen)
        if (p != buf) {
            *p = '\0';
            tfprintf(ofile, "\t!ascii\n", buf);
+           p = buf;
        }
        
        if (len > 60)
index f97f554b444de8815cdea8eb28d0bf0d3878ce2b..517c49e7735788c4e0e01533cf0f22ebc9e2ed0c 100644 (file)
@@ -201,9 +201,13 @@ typedef struct symbol {
     unsigned onStack    :1      ;  /* this symbol allocated on the stack */
     unsigned iaccess    :1      ;  /* indirect access      */
     unsigned ruonly     :1      ;  /* used in return statement only */
-    unsigned accuse     :1      ;  /* can be left in the accumulator */
     unsigned spildir    :1      ;  /* spilt in direct space */
     unsigned ptrreg     :1      ;  /* this symbol assigned to a ptr reg */
+    unsigned accuse             ;  /* can be left in the accumulator
+                                     On the Z80 accuse is devided into
+                                     ACCUSE_A and ACCUSE_HL as the idea
+                                     is quite similar.
+                                  */
 
     int      stack              ;  /* offset on stack      */
     int      xstack             ;  /* offset on xternal stack */
index 8d97b83b5854114ed1a0e8fabebe74f828f8638c..a257244c02d372782576cce1c1eff9edee30180e 100644 (file)
@@ -71,6 +71,7 @@ static char **_fTmp;
 static char zero[20];
 
 static char *accUse[] = {"a" };
+static char *hlUse[] = { "l", "h" };
 short rbank = -1;
 short accInUse = 0 ;
 short inLine = 0;
@@ -595,11 +596,22 @@ static void aopOp (operand *op, iCode *ic, bool result, bool requires_a)
 
        if (sym->accuse) {
            int i;
-            aop = op->aop = sym->aop = newAsmop(AOP_ACC);
-            aop->size = getSize(sym->type);
-            for ( i = 0 ; i < 2 ; i++ )
-                aop->aopu.aop_str[i] = accUse[i];
-            return;  
+           if (sym->accuse == ACCUSE_A) {
+               aop = op->aop = sym->aop = newAsmop(AOP_ACC);
+               aop->size = getSize(sym->type);
+               for ( i = 0 ; i < 2 ; i++ )
+                   aop->aopu.aop_str[i] = accUse[i];
+           }
+           else if (sym->accuse == ACCUSE_HL) {
+               wassert(!IS_GB);
+               aop = op->aop = sym->aop = newAsmop(AOP_HLREG);
+               aop->size = getSize(sym->type);
+               for ( i = 0 ; i < 2 ; i++ )
+                   aop->aopu.aop_str[i] = hlUse[i];
+           }
+           else
+               wassert(0);
+           return;
        }
 
         if (sym->ruonly ) {
@@ -826,6 +838,13 @@ static void fetchPairLong(PAIR_ID pairId, asmop *aop, int offset)
            emit2("ld h,!*hl");
            emit2("ld l,a");
        }
+       else if (IS_Z80 && aop->type == AOP_IY) {
+           /* Instead of fetching relative to IY, just grab directly
+              from the address IY refers to */
+           char *l = aopGetLitWordLong(aop, offset, FALSE);
+           wassert(l);
+           emit2("ld %s,(%s)", _pairs[pairId].name, l);
+       }
        else {
            emitcode("ld", "%s,%s", _pairs[pairId].l, aopGet(aop, offset, FALSE));
            emitcode("ld", "%s,%s", _pairs[pairId].h, aopGet(aop, offset+1, FALSE));
@@ -852,6 +871,8 @@ static void setupPair(PAIR_ID pairId, asmop *aop, int offset)
 
     switch (aop->type) {
     case AOP_IY:
+       fetchLitPair(pairId, aop, 0);
+       break;
     case AOP_HL:
        fetchLitPair(pairId, aop, offset);
        _G.pairs[pairId].offset = offset;
@@ -967,6 +988,10 @@ static char *aopGet(asmop *aop, int offset, bool bit16)
        }
        return "!zero";
 
+    case AOP_HLREG:
+       wassert(offset < 2);
+       return aop->aopu.aop_str[offset];
+
     case AOP_LIT:
        return aopLiteral (aop->aopu.aop_lit,offset);
        
@@ -1038,8 +1063,11 @@ static void aopPut (asmop *aop, char *s, int offset)
        break;
        
     case AOP_REG:
-       emitcode("ld","%s,%s",
-                aop->aopu.aop_reg[offset]->name,s);
+       if (!strcmp(s, "!*hl"))
+           emit2("ld %s,!*hl", aop->aopu.aop_reg[offset]->name);
+       else
+           emit2("ld %s,%s",
+                 aop->aopu.aop_reg[offset]->name, s);
        break;
        
     case AOP_IY:
@@ -1122,6 +1150,11 @@ static void aopPut (asmop *aop, char *s, int offset)
        }
        break;
 
+    case AOP_HLREG:
+       wassert(offset < 2);
+       emit2("ld %s,%s", aop->aopu.aop_str[offset], s);
+       break;
+
     default :
        werror(E_INTERNAL_ERROR,__FILE__,__LINE__,
               "aopPut got unsupported aop->type");
@@ -1404,11 +1437,18 @@ static void genIpush (iCode *ic)
        else {
            offset = size;
            while (size--) {
-               l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
                /* Simple for now - load into A and PUSH AF */
-               emitcode("ld", "a,%s", l);
-               emitcode("push", "af");
-               emitcode("inc", "sp");
+               if (AOP(IC_LEFT(ic))->type == AOP_IY) {
+                   char *l = aopGetLitWordLong(AOP(IC_LEFT(ic)), --offset, FALSE);
+                   wassert(l);
+                   emit2("ld a,(%s)", l);
+               }
+               else {
+                   l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
+                   emit2("ld a,%s", l);
+               }
+               emit2("push af");
+               emit2("inc sp");
                _G.stack.pushed++;
            }
        }
@@ -1448,8 +1488,15 @@ static void genIpush (iCode *ic)
        }
        offset = size;
        while (size--) {
-           l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
-           emitcode("ld", "a,%s", l);
+           if (AOP(IC_LEFT(ic))->type == AOP_IY) {
+               char *l = aopGetLitWordLong(AOP(IC_LEFT(ic)), --offset, FALSE);
+               wassert(l);
+               emit2("ld a,(%s)", l);
+           }
+           else {
+               l = aopGet(AOP(IC_LEFT(ic)), --offset, FALSE);
+               emit2("ld a,%s", l);
+           }
            emitcode("push", "af");
            emitcode("inc", "sp");
            _G.stack.pushed++;
@@ -2776,6 +2823,9 @@ static void genAnd (iCode *ic, iCode *ifx)
                         if(bytelit != 0x0FFL)
                             emitcode("and","a,%s",
                                      aopGet(AOP(right),offset,FALSE));
+                       else
+                           /* For the flags */
+                           emit2("or a,a");
                         emit2("!shortjp nz,!tlabel", tlbl->key+100);
                     }
                 }
@@ -3155,13 +3205,8 @@ static void shiftR2Left2Result (operand *left, int offl,
                                 operand *result, int offr,
                                 int shCount, int sign)
 {
-    if(sameRegs(AOP(result), AOP(left)) &&
-       ((offl + MSB16) == offr)){
-       wassert(0);
-    } else {
-       movLeft2Result(left, offl, result, offr, 0);
-       movLeft2Result(left, offl+1, result, offr+1, 0);
-    }
+    movLeft2Result(left, offl, result, offr, 0);
+    movLeft2Result(left, offl+1, result, offr+1, 0);
 
     if (sign) {
        wassert(0);
@@ -3564,7 +3609,6 @@ static void genrshTwo (operand *result,operand *left,
     if (shCount >= 8) {
         shCount -= 8 ;
         if (shCount) {
-           wassert(0);
             shiftR1Left2Result(left, MSB16, result, LSB,
                                shCount, sign);
        }
@@ -4007,8 +4051,8 @@ static void genAssign (iCode *ic)
 
     if(AOP_TYPE(right) == AOP_LIT)
        lit = (unsigned long)floatFromVal(AOP(right)->aopu.aop_lit);
-    if (isPair(AOP(result)) && isLitWord(AOP(right))) {
-       emitcode("ld", "%s,%s", getPairName(AOP(result)), aopGetWord(AOP(right), 0));
+    if (isPair(AOP(result))) {
+       fetchPair(getPairId(AOP(result)), AOP(right));
     }
     else if((size > 1) &&
        (AOP_TYPE(result) != AOP_REG) &&
@@ -4040,7 +4084,7 @@ static void genAssign (iCode *ic)
            offset++;
        }
     }
-    else if (size == 2 && requiresHL(AOP(right)) && requiresHL(AOP(result))) {
+    else if (size == 2 && requiresHL(AOP(right)) && requiresHL(AOP(result)) && IS_GB) {
        /* Special case.  Load into a and d, then load out. */
        MOVA(aopGet(AOP(right), 0, FALSE));
        emitcode("ld", "e,%s", aopGet(AOP(right), 1, FALSE));
index b312bb4c31bc40b5978810586f750e398951976f..389c32ee45c2cd5224d10ea0563266d87b8bf6c3 100644 (file)
@@ -48,7 +48,9 @@ typedef enum {
     /* Is pointed to by HL */
     AOP_HL,
     /* Is in A */
-    AOP_ACC 
+    AOP_ACC,
+    /* Is in H and L */
+    AOP_HLREG
 } AOP_TYPE;
 
 /* type asmop : a homogenised type for 
index c46ce7c8781b80b304b41a933cad25b04753b431..d41992deab53187a14551a3040215ef7d8684cb5 100644 (file)
@@ -246,6 +246,7 @@ PORT z80_port = {
     0, /* no local IVT generation code */
     _reset_regparm,
     _reg_parm,
+    _process_pragma,
     TRUE
 };
 
index 53c593385fbc7f578fb74f3d5f5766da2036b23b..92eacf591d9ee9c4e0dd9f7e343667f0c55d0fd1 100644 (file)
@@ -35,33 +35,59 @@ static const ASM_MAPPING _asxxxx_gb_mapping[] = {
 };
 
 static const ASM_MAPPING _asxxxx_z80_mapping[] = {
+    /* We want to prepend the _ */
+    { "area", ".area _%s" },
+    { "areacode", ".area _%s" },
+    { "areadata", ".area _%s" },
     { "*ixx", "%d(ix)" },
     { "*iyx", "%d(iy)" },
     { "*hl", "(hl)" },
     { "di", "di" },
-    { "ldahli", "ld a,(hl+)" },
-    { "ldahlsp", "lda hl,%d(sp)" },
-    { "ldaspsp", "lda sp,%d(sp)" },
+    { "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", "jr" },
-    { "enter", "push bc" },
+    { "shortjp", "jp" },
+    { "enter", 
+               "push bc\n"
+               "\tpush\tde\n"
+               "\tpush\tix\n"
+               "\tld\tix,#0\n"
+               "\tadd\tix,sp" },
     { "enterx", 
-      "push bc\n"
-      "lda sp,-%d(sp)" },
+               "push bc\n"
+               "\tpush\tde\n"
+               "\tpush\tix\n"
+               "\tld\tix,#0\n"
+               "\tadd\tix,sp\n"
+               "\tld\thl,#-%d\n"
+               "\tadd\thl,sp\n"
+               "\tld\tsp,hl" },
     { "leave", 
-      "pop bc\n"
-      "\tret"
+               "pop\tix\n"
+               "\tpop\tde\n"
+               "\tpop\tbc\n"
+               "\tret"
     },
     { "leavex", 
-      "lda sp,%d(sp)\n"
-      "\tpop bc\n"
-      "\tret"
+               "ld sp,ix\n"
+               "\tpop\tix\n"
+               "\tpop\tde\n"
+               "\tpop\tbc\n"
+               "\tret"
     },
     { "pusha", 
-      "push af\n"
-      "\tpush bc\n"
-      "\tpush de\n"
-      "\tpush hl"
+               "push af\n"
+               "\tpush\tbc\n"
+               "\tpush\tde\n"
+               "\tpush\thl"
     },
     { "adjustsp", "lda sp,-%d(sp)" },
     { NULL, NULL }
index 02a2fc90cc64b471ee0c0f5aa97a211ceb802e08..16148a817b743d8dc6189a69b43b0eb6ff267f02 100644 (file)
@@ -1397,7 +1397,6 @@ pack:
         
     remiCodeFromeBBlock(ebp,ic);
     return 1;
-    
 }
 
 /** Scanning backwards looks for first assig found.
@@ -1799,7 +1798,40 @@ static void packRegsForAccUse (iCode *ic)
        goto accuse ;
     return ;
  accuse:
-    OP_SYMBOL(IC_RESULT(ic))->accuse = 1;
+    OP_SYMBOL(IC_RESULT(ic))->accuse = ACCUSE_A;
+}
+
+static void packRegsForHLUse (iCode *ic)
+{
+    iCode *uic;
+
+    if (IS_GB)
+       return;
+
+    /* has only one definition */
+    if (bitVectnBitsOn(OP_DEFS(IC_RESULT(ic))) > 1)
+       return ;
+
+    /* has only one use */
+    if (bitVectnBitsOn(OP_USES(IC_RESULT(ic))) > 1)
+       return ;
+
+    /* and the usage immediately follows this iCode */
+    if (!(uic = hTabItemWithKey(iCodehTab,
+                               bitVectFirstBit(OP_USES(IC_RESULT(ic))))))
+       return ;
+
+    if (ic->next != uic)
+       return ;
+
+    if (ic->op == ADDRESS_OF && uic->op == IPUSH)
+       goto hluse;
+    if (ic->op == CALL && IC_LEFT(ic)->parmBytes == 0 && (uic->op == '-' || uic->op == '+'))
+       goto hluse;
+    return;
+ hluse:
+    printf("Hey, it worked!\n");
+    OP_SYMBOL(IC_RESULT(ic))->accuse = ACCUSE_HL;
 }
 
 bool opPreservesA(iCode *ic, iCode *uic)
@@ -1860,7 +1892,7 @@ bool opPreservesA(iCode *ic, iCode *uic)
 
 /** Pack registers for acc use.
     When the result of this operation is small and short lived it may
-    be able to be stored in the accumelator.
+    be able to be stored in the accumulator.
 
     Note that the 'A preserving' list is currently emperical :)e
  */
@@ -2160,6 +2192,10 @@ static void packRegisters (eBBlock *ebp)
           only one operand or has two operands but one is literal & the
           result of that operation is not on stack then we can leave the
           result of this operation in acc:b combination */
+
+       if (IS_ITEMP(IC_RESULT(ic))) {
+           packRegsForHLUse(ic);
+       }
 #if 0
        if ((IS_ARITHMETIC_OP(ic) 
             || IS_BITWISE_OP(ic)
index 288d91a42ea404a53995cf028a02138890dcc0c0..d51ec9161ada7d081bc4206db05601aa0affc40d 100644 (file)
@@ -19,3 +19,7 @@ extern Z80_OPTS z80_opts;
 #define IS_GB  (z80_opts.sub == SUB_GBZ80)
 #define IS_Z80 (z80_opts.sub == SUB_Z80)
 
+enum {
+    ACCUSE_A,
+    ACCUSE_HL
+};