X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fz80%2Fgen.c;h=a6e3a247b9d9d2f52bcb61cc75f8f132133781dc;hb=b1a10c8ec5142594ec5698fa241d7433873ce710;hp=eac67d7b0b18e60694bbfce18dea1b95a692116e;hpb=3dc8038c8b8b8affcac918268cef56b923829525;p=fw%2Fsdcc diff --git a/src/z80/gen.c b/src/z80/gen.c index eac67d7b..a6e3a247 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -1385,28 +1385,61 @@ fetchLitPair (PAIR_ID pairId, asmop * left, int offset) { if (pairId == PAIR_HL || pairId == PAIR_IY) { - if (_G.pairs[pairId].last_type == left->type) + if (_G.pairs[pairId].last_type == AOP_IMMD && left->type == AOP_IMMD) { if (_G.pairs[pairId].base && !strcmp (_G.pairs[pairId].base, base)) { if (pairId == PAIR_HL && abs (_G.pairs[pairId].offset - offset) < 3) { adjustPair (pair, &_G.pairs[pairId].offset, offset); - return; + goto adjusted; } if (pairId == PAIR_IY && (offset >= INT8MIN && offset <= INT8MAX)) { - return; + goto adjusted; } } } } + + if (pairId == PAIR_HL && left->type == AOP_LIT && _G.pairs[pairId].last_type == AOP_LIT && + !IS_FLOAT (left->aopu.aop_lit->type) && offset == 0 && _G.pairs[pairId].offset == 0) + { + unsigned new_low, new_high, old_low, old_high; + unsigned long v_new = ulFromVal (left->aopu.aop_lit); + unsigned long v_old = strtoul (_G.pairs[pairId].base, NULL, 0); + new_low = (v_new >> 0) & 0xff; + new_high = (v_new >> 8) & 0xff; + old_low = (v_old >> 0) & 0xff; + old_high = (v_old >> 8) & 0xff; + + /* Change lower byte only. */ + if(new_high == old_high) + { + emit2("ld l, %s", aopGet (left, 0, FALSE)); + goto adjusted; + } + /* Change upper byte only. */ + else if(new_low == old_low) + { + emit2("ld h, %s", aopGet (left, 1, FALSE)); + goto adjusted; + } + } + + _G.pairs[pairId].last_type = left->type; _G.pairs[pairId].base = traceAlloc(&_G.trace.aops, Safe_strdup (base)); _G.pairs[pairId].offset = offset; } /* Both a lit on the right and a true symbol on the left */ emit2 ("ld %s,!hashedstr", pair, l); + return; + +adjusted: + _G.pairs[pairId].last_type = left->type; + _G.pairs[pairId].base = traceAlloc(&_G.trace.aops, Safe_strdup (base)); + _G.pairs[pairId].offset = offset; } static PAIR_ID @@ -2676,7 +2709,6 @@ genIpush (iCode * ic) { fetchHL (AOP (IC_LEFT (ic))); emit2 ("push hl"); - spillPair (PAIR_HL); _G.stack.pushed += 2; goto release; } @@ -2684,11 +2716,9 @@ genIpush (iCode * ic) { fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), ic, 2); emit2 ("push hl"); - spillPair (PAIR_HL); _G.stack.pushed += 2; fetchPairLong (PAIR_HL, AOP (IC_LEFT (ic)), ic, 0); emit2 ("push hl"); - spillPair (PAIR_HL); _G.stack.pushed += 2; goto release; } @@ -3983,7 +4013,7 @@ genPlus (iCode * ic) emit2 ("ld a, b"); emit2 ("pop bc"); } - + } emit2 ("adc a,%s", aopGet (AOP (IC_RIGHT (ic)), 1, FALSE)); aopPut (AOP (IC_RESULT (ic)), "a", 1); @@ -3994,7 +4024,12 @@ genPlus (iCode * ic) { _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE)); if (offset == 0) - emit2 ("add a,%s", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE)); + { + if(size == 0 && AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT && ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) == 1) + emit2 ("inc a"); + else + emit2 ("add a,%s", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE)); + } else emit2 ("adc a,%s", aopGet (AOP (IC_RIGHT (ic)), offset, FALSE)); aopPut (AOP (IC_RESULT (ic)), "a", offset++); @@ -5351,6 +5386,7 @@ genAnd (iCode * ic, iCode * ifx) /* For the flags */ emit2 ("or a,a"); } + if (size || ifx) /* emit jmp only, if it is actually used */ emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); } offset++; @@ -5534,9 +5570,19 @@ genOr (iCode * ic, iCode * ifx) bytelit = (lit >> (offset * 8)) & 0x0FFL; _moveA (aopGet (AOP (left), offset, FALSE)); - /* OR with any literal is the same as OR with itself. */ - emit2 ("or a,a"); - emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); + + if (bytelit != 0) + { /* FIXME, allways true, shortcut possible */ + emit2 ("or a,%s", aopGet (AOP (right), offset, FALSE)); + } + else + { + /* For the flags */ + emit2 ("or a,a"); + } + + if (ifx) /* emit jmp only, if it is actually used */ + emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); offset++; } @@ -7999,67 +8045,12 @@ _swap (PAIR_ID one, PAIR_ID two) } } -/* The problem is that we may have all three pairs used and they may - be needed in a different order. - - Note: Have ex de,hl - - Combinations: - hl = hl => unity, fine - bc = bc - de = de - - hl = hl hl = hl, swap de <=> bc - bc = de - de = bc - - hl = bc Worst case - bc = de - de = hl - - hl = bc de = de, swap bc <=> hl - bc = hl - de = de - - hl = de Worst case - bc = hl - de = bc - - hl = de bc = bc, swap hl <=> de - bc = bc - de = hl - - Break it down into: - * Any pair = pair are done last - * Any pair = iTemp are done last - * Any swaps can be done any time - - A worst case: - push p1 - p1 = p2 - p2 = p3 - pop p3 - - So how do we detect the cases? - How about a 3x3 matrix? - source - dest x x x x - x x x x - x x x x (Fourth for iTemp/other) - - First determin which mode to use by counting the number of unity and - iTemp assigns. - Three - any order - Two - Assign the pair first, then the rest - One - Swap the two, then the rest - Zero - Worst case. -*/ static void -setupForBuiltin3 (iCode *ic, int nparams, operand **pparams) +setupForMemcpy (iCode *ic, int nparams, operand **pparams) { PAIR_ID ids[NUM_PAIRS][NUM_PAIRS]; PAIR_ID dest[3] = { - PAIR_BC, PAIR_HL, PAIR_DE + PAIR_DE, PAIR_HL, PAIR_BC }; int i, j, nunity = 0; memset (ids, PAIR_INVALID, sizeof (ids)); @@ -8067,10 +8058,6 @@ setupForBuiltin3 (iCode *ic, int nparams, operand **pparams) /* Sanity checks */ wassert (nparams == 3); - /* First save everything that needs to be saved. */ - _saveRegsForCall (ic, 0); - - /* Loading HL first means that DE is always fine. */ for (i = 0; i < nparams; i++) { aopOp (pparams[i], ic, FALSE, FALSE); @@ -8092,7 +8079,7 @@ setupForBuiltin3 (iCode *ic, int nparams, operand **pparams) } else if (nunity == 2) { - /* One is assigned. Pull it out and assign. */ + /* Two are OK. Assign the other one. */ for (i = 0; i < 3; i++) { for (j = 0; j < NUM_PAIRS; j++) @@ -8115,7 +8102,7 @@ setupForBuiltin3 (iCode *ic, int nparams, operand **pparams) } else if (nunity == 1) { - /* Find the pairs to swap. */ + /* One is OK. Find the other two. */ for (i = 0; i < 3; i++) { for (j = 0; j < NUM_PAIRS; j++) @@ -8124,12 +8111,22 @@ setupForBuiltin3 (iCode *ic, int nparams, operand **pparams) { if (j == PAIR_INVALID || j == dest[i]) { - /* Keep looking. */ + /* This one is OK. */ } else { - _swap (j, dest[i]); - goto done; + /* Found one. */ + if(ids[j][dest[i]] == TRUE) + { + /* Just swap. */ + _swap (j, dest[i]); + goto done; + } + else + { + fetchPair (dest[i], AOP (pparams[i])); + continue; + } } } } @@ -8163,53 +8160,27 @@ setupForBuiltin3 (iCode *ic, int nparams, operand **pparams) } } -static void -genBuiltInStrcpy (iCode *ic, int nParams, operand **pparams) -{ - operand *from, *to; - symbol *label; - bool deInUse; - - wassertl (nParams == 2, "Built-in strcpy must have two parameters"); - to = pparams[0]; - from = pparams[1]; - - deInUse = bitVectBitValue (ic->rMask, D_IDX) || bitVectBitValue(ic->rMask, E_IDX); - - setupForBuiltin3 (ic, nParams, pparams); - - label = newiTempLabel(NULL); - - emitLabel (label->key); - emit2 ("ld a,(hl)"); - emit2 ("ldi"); - emit2 ("or a"); - emit2 ("!shortjp NZ,!tlabel ; 1", label->key); - - freeAsmop (from, NULL, ic->next); - freeAsmop (to, NULL, ic); -} - static void genBuiltInMemcpy (iCode *ic, int nParams, operand **pparams) { operand *from, *to, *count; - bool deInUse; - wassertl (nParams == 3, "Built-in memcpy must have three parameters"); + wassertl (nParams == 3, "Built-in memcpy() must have three parameters"); to = pparams[2]; from = pparams[1]; count = pparams[0]; - deInUse = bitVectBitValue (ic->rMask, D_IDX) || bitVectBitValue(ic->rMask, E_IDX); + _saveRegsForCall (ic, 0); - setupForBuiltin3 (ic, nParams, pparams); + setupForMemcpy (ic, nParams, pparams); emit2 ("ldir"); freeAsmop (count, NULL, ic->next->next); freeAsmop (from, NULL, ic); + spillPair (PAIR_HL); + _restoreRegsAfterCall(); /* if we need assign a result value */ @@ -8243,11 +8214,7 @@ static void genBuiltIn (iCode *ic) /* which function is it */ bif = OP_SYMBOL(IC_LEFT(bi_iCode)); - if (strcmp(bif->name,"__builtin_strcpy")==0) - { - genBuiltInStrcpy(bi_iCode, nbi_parms, bi_parms); - } - else if (strcmp(bif->name,"__builtin_memcpy")==0) + if (strcmp(bif->name,"__builtin_memcpy")==0) { genBuiltInMemcpy(bi_iCode, nbi_parms, bi_parms); }