From: michaelh Date: Sun, 21 May 2000 02:34:30 +0000 (+0000) Subject: Merged gbdk-294 branch X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=c36942cfa3dd71c993330f0ef36e99e0612e13c7;p=fw%2Fsdcc Merged gbdk-294 branch git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@254 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 31ebf5b9..1a3c5158 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -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) diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index f97f554b..517c49e7 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -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 */ diff --git a/src/z80/gen.c b/src/z80/gen.c index 8d97b83b..a257244c 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -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)); diff --git a/src/z80/gen.h b/src/z80/gen.h index b312bb4c..389c32ee 100644 --- a/src/z80/gen.h +++ b/src/z80/gen.h @@ -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 diff --git a/src/z80/main.c b/src/z80/main.c index c46ce7c8..d41992de 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -246,6 +246,7 @@ PORT z80_port = { 0, /* no local IVT generation code */ _reset_regparm, _reg_parm, + _process_pragma, TRUE }; diff --git a/src/z80/mappings.i b/src/z80/mappings.i index 53c59338..92eacf59 100644 --- a/src/z80/mappings.i +++ b/src/z80/mappings.i @@ -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 } diff --git a/src/z80/ralloc.c b/src/z80/ralloc.c index 02a2fc90..16148a81 100644 --- a/src/z80/ralloc.c +++ b/src/z80/ralloc.c @@ -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) diff --git a/src/z80/z80.h b/src/z80/z80.h index 288d91a4..d51ec916 100644 --- a/src/z80/z80.h +++ b/src/z80/z80.h @@ -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 +};