X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fz80%2Fgen.c;h=b45d7a8516c2fe621b1cb7e75ce53458700e8f8e;hb=5a1d5e778e85664f4e6657019348b4756b16eacb;hp=817acecc230fa68f6aa29b5f22d73c2c628e9863;hpb=4d4cea3d78badb61025545d2736d0318e969ce16;p=fw%2Fsdcc diff --git a/src/z80/gen.c b/src/z80/gen.c index 817acecc..b45d7a85 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -1385,28 +1385,62 @@ 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) || + (_G.pairs[pairId].last_type == AOP_IY && left->type == AOP_IY)) { 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 @@ -1510,10 +1544,10 @@ fetchPairLong (PAIR_ID pairId, asmop * aop, iCode *ic, int offset) } else { - /* Swapping register contents within register pair */ - if(!strcmp(aopGet (aop, offset, FALSE), _pairs[pairId].h)) + /* Operand resides (partially) in the pair */ + if(!strcmp(aopGet (aop, offset + 1, FALSE), _pairs[pairId].l)) { - emit2 ("ld a,%s",aopGet (aop, offset + 1, FALSE)); + emit2 ("ld a,%s", aopGet (aop, offset + 1, FALSE)); emit2 ("ld %s,%s", _pairs[pairId].l, aopGet (aop, offset, FALSE)); emit2 ("ld %s,a", _pairs[pairId].h); } @@ -1649,6 +1683,14 @@ setupPair (PAIR_ID pairId, asmop * aop, int offset) _G.pairs[pairId].last_type = aop->type; } +/* Can be used for local labels where Code generation takes care of spilling */ +static void +emitLabelNoSpill (int key) +{ + emit2 ("!tlabeldef", key); + _G.lines.current->isLabel = 1; +} + static void emitLabel (int key) { @@ -2676,7 +2718,6 @@ genIpush (iCode * ic) { fetchHL (AOP (IC_LEFT (ic))); emit2 ("push hl"); - spillPair (PAIR_HL); _G.stack.pushed += 2; goto release; } @@ -2684,11 +2725,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; } @@ -3599,7 +3638,7 @@ genPlusIncr (iCode * ic) emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); } } - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); return TRUE; } @@ -3651,7 +3690,7 @@ outBitAcc (operand * result) { emit2 ("!shortjp Z,!tlabel", tlbl->key + 100); emit2 ("ld a,!one"); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); outAcc (result); } } @@ -3983,7 +4022,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 +4033,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++); @@ -4252,11 +4296,11 @@ genMultOneChar (iCode * ic) emit2 ("ld l,#0x00"); emit2 ("ld d,l"); emit2 ("ld b,#0x08"); - emitLabel (tlbl1->key + 100); + emitLabelNoSpill (tlbl1->key + 100); emit2 ("add hl,hl"); emit2 ("jp NC,!tlabel", tlbl2->key + 100); emit2 ("add hl,de"); - emitLabel (tlbl2->key + 100); + emitLabelNoSpill (tlbl2->key + 100); emit2 ("djnz !tlabel", tlbl1->key + 100); spillPair(PAIR_HL); @@ -4981,7 +5025,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl) } else { - emit2 ("sub %s", aopGet (AOP (right), offset, FALSE)); + emit2 ("sub a,%s", aopGet (AOP (right), offset, FALSE)); emit2 ("jp NZ,!tlabel", lbl->key + 100); } offset++; @@ -5005,7 +5049,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl) emit2 ("; direct compare"); _emitMove (_pairs[pair].l, aopGet (AOP (left), offset, FALSE)); _moveA (aopGet (AOP (right), offset, FALSE)); - emit2 ("sub %s", _pairs[pair].l); + emit2 ("sub a,%s", _pairs[pair].l); emit2 ("!shortjp NZ,!tlabel", lbl->key + 100); offset++; } @@ -5029,7 +5073,7 @@ gencjne (operand * left, operand * right, symbol * lbl) emit2 ("!shortjp !tlabel", tlbl->key + 100); emitLabel (lbl->key + 100); emit2 ("xor a,a"); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); _pop (pop); } @@ -5075,7 +5119,7 @@ genCmpEq (iCode * ic, iCode * ifx) { _pop (pop); emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); _pop (pop); } else @@ -5084,10 +5128,10 @@ genCmpEq (iCode * ic, iCode * ifx) symbol *lbl = newiTempLabel (NULL); _pop (pop); emit2 ("!shortjp !tlabel", lbl->key + 100); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); _pop (pop); emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100); - emitLabel (lbl->key + 100); + emitLabelNoSpill (lbl->key + 100); } } /* mark the icode as generated */ @@ -5182,7 +5226,7 @@ genAndOp (iCode * ic) _toBoolean (left); emit2 ("!shortjp Z,!tlabel", tlbl->key + 100); _toBoolean (right); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); outBitAcc (result); } @@ -5219,7 +5263,7 @@ genOrOp (iCode * ic) _toBoolean (left); emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); _toBoolean (right); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); outBitAcc (result); } @@ -5261,14 +5305,14 @@ jmpTrueOrFalse (iCode * ic, symbol * tlbl) { symbol *nlbl = newiTempLabel (NULL); emit2 ("jp !tlabel", nlbl->key + 100); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); emit2 ("jp !tlabel", IC_TRUE (ic)->key + 100); - emitLabel (nlbl->key + 100); + emitLabelNoSpill (nlbl->key + 100); } else { emit2 ("jp !tlabel", IC_FALSE (ic)->key + 100); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); } ic->generated = 1; } @@ -5351,6 +5395,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 +5579,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++; } @@ -5941,7 +5996,7 @@ shiftR2Left2Result (operand * left, int offl, { emit2 ("ld a,!immedbyte", shCount); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); emitRsh2 (AOP (result), size, is_signed); @@ -6015,7 +6070,7 @@ shiftL2Left2Result (operand * left, int offl, { emit2 ("ld a,!immedbyte+1", shCount); emit2 ("!shortjp !tlabel", tlbl1->key + 100); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); } while (size--) @@ -6035,7 +6090,7 @@ shiftL2Left2Result (operand * left, int offl, } if (shCount > 1) { - emitLabel (tlbl1->key + 100); + emitLabelNoSpill (tlbl1->key + 100); emit2 ("dec a"); emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); } @@ -6354,7 +6409,7 @@ genLeftShift (iCode * ic) _pop (PAIR_AF); emit2 ("!shortjp !tlabel", tlbl1->key + 100); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); l = aopGet (AOP (result), offset, FALSE); while (size--) @@ -6371,7 +6426,7 @@ genLeftShift (iCode * ic) } offset++; } - emitLabel (tlbl1->key + 100); + emitLabelNoSpill (tlbl1->key + 100); emit2 ("dec a"); emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); @@ -6629,7 +6684,7 @@ genRightShift (iCode * ic) _pop (PAIR_AF); emit2 ("!shortjp !tlabel", tlbl1->key + 100); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); while (size--) { l = aopGet (AOP (result), offset--, FALSE); @@ -6643,7 +6698,7 @@ genRightShift (iCode * ic) emit2 ("rr %s", l); } } - emitLabel (tlbl1->key + 100); + emitLabelNoSpill (tlbl1->key + 100); emit2 ("dec a"); emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); @@ -6686,7 +6741,7 @@ genUnpackBits (operand * result, int pair) emit2 ("bit %d,a", blen - 1); emit2 ("jp Z,!tlabel", tlbl->key + 100); emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen)); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); } aopPut (AOP (result), "a", offset++); goto finish; @@ -6706,11 +6761,10 @@ genUnpackBits (operand * result, int pair) { /* signed bitfield */ symbol *tlbl = newiTempLabel (NULL); - - emit2 ("bit %d,a", blen - 1); + emit2 ("bit %d,a", blen - 1 - 8); emit2 ("jp Z,!tlabel", tlbl->key + 100); - emit2 ("or a,!immedbyte", (unsigned char) (0xff << blen)); - emitLabel (tlbl->key + 100); + emit2 ("or a,!immedbyte", (unsigned char) (0xff << (blen - 8))); + emitLabelNoSpill (tlbl->key + 100); } emit2 ("ld h,a"); spillPair (PAIR_HL); @@ -6743,7 +6797,7 @@ genUnpackBits (operand * result, int pair) emit2 ("bit %d,a", rlen - 1); emit2 ("jp Z,!tlabel", tlbl->key + 100); emit2 ("or a,!immedbyte", (unsigned char) (0xff << rlen)); - emitLabel (tlbl->key + 100); + emitLabelNoSpill (tlbl->key + 100); } aopPut (AOP (result), "a", offset++); } @@ -8000,7 +8054,7 @@ _swap (PAIR_ID one, PAIR_ID two) } 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] = { @@ -8080,7 +8134,7 @@ setupForBuiltin3 (iCode *ic, int nparams, operand **pparams) { fetchPair (dest[i], AOP (pparams[i])); continue; - } + } } } } @@ -8114,54 +8168,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); - - _saveRegsForCall (ic, 0); - - 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; - 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]; _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 */ @@ -8195,11 +8222,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); }