X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fz80%2Fgen.c;h=ff07195b9d6a0a9eebe9d89c28075ad4f00b7618;hb=871e6c6aefc06309a03c295ce0d3c9d4bbb4a742;hp=2ef191da5a0f8b66ab8c8db4dd50a3756480d224;hpb=5948fe48b6494da15546dfe936e6507055d6e16d;p=fw%2Fsdcc diff --git a/src/z80/gen.c b/src/z80/gen.c index 2ef191da..ff07195b 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -3994,7 +3994,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++); @@ -4215,6 +4220,72 @@ release: freeAsmop (IC_RESULT (ic), NULL, ic); } +/*-----------------------------------------------------------------*/ +/* genMultChar - generates code for unsigned 8x8 multiplication */ +/*-----------------------------------------------------------------*/ +static void +genMultOneChar (iCode * ic) +{ + symbol *tlbl1, *tlbl2; + bool savedB = FALSE; + + if(IS_GB) + { + wassertl (0, "Multiplication is handled through support function calls on gbz80"); + return; + } + + /* Save b into a if b is in use. */ + if (bitVectBitValue (ic->rMask, B_IDX) && + !(getPairId (AOP (IC_RESULT (ic))) == PAIR_BC)) + { + emit2 ("ld a, b"); + savedB = TRUE; + } + if (isPairInUse (PAIR_DE, ic) && + !(getPairId (AOP (IC_RESULT (ic))) == PAIR_DE)) + { + _push (PAIR_DE); + _G.stack.pushedDE = TRUE; + } + + tlbl1 = newiTempLabel (NULL); + tlbl2 = newiTempLabel (NULL); + + emit2 ("ld e,%s", aopGet (AOP (IC_RIGHT (ic)), LSB, FALSE)); + emit2 ("ld h,%s", aopGet (AOP (IC_LEFT (ic)), LSB, FALSE)); + emit2 ("ld l,#0x00"); + emit2 ("ld d,l"); + emit2 ("ld b,#0x08"); + emitLabel (tlbl1->key + 100); + emit2 ("add hl,hl"); + emit2 ("jp NC,!tlabel", tlbl2->key + 100); + emit2 ("add hl,de"); + emitLabel (tlbl2->key + 100); + emit2 ("djnz !tlabel", tlbl1->key + 100); + + spillPair(PAIR_HL); + + if (IS_Z80 && _G.stack.pushedDE) + { + _pop (PAIR_DE); + _G.stack.pushedDE = FALSE; + } + if (savedB) + { + emit2 ("ld b, a"); + } + + if (AOP_SIZE (IC_RESULT (ic)) == 1) + aopPut (AOP (IC_RESULT (ic)), "l", 0); + else + commitPair ( AOP (IC_RESULT (ic)), PAIR_HL); + + freeAsmop (IC_LEFT (ic), NULL, ic); + freeAsmop (IC_RIGHT (ic), NULL, ic); + freeAsmop (IC_RESULT (ic), NULL, ic); +} + /*-----------------------------------------------------------------*/ /* genMult - generates code for multiplication */ /*-----------------------------------------------------------------*/ @@ -4249,6 +4320,12 @@ genMult (iCode * ic) IC_LEFT (ic) = t; } + if (AOP_TYPE (IC_RIGHT (ic)) != AOP_LIT) + { + genMultOneChar (ic); + return; + } + wassertl (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT, "Right must be a literal"); val = (int) ulFromVal ( AOP (IC_RIGHT (ic))->aopu.aop_lit); @@ -4787,13 +4864,16 @@ genCmpGt (iCode * ic, iCode * ifx) letype = getSpec (operandType (left)); retype = getSpec (operandType (right)); sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype)); - /* assign the amsops */ + /* assign the asmops */ aopOp (left, ic, FALSE, FALSE); aopOp (right, ic, FALSE, FALSE); aopOp (result, ic, TRUE, FALSE); + setupToPreserveCarry (ic); + genCmp (right, left, result, ifx, sign); + _G.preserveCarry = FALSE; freeAsmop (left, NULL, ic); freeAsmop (right, NULL, ic); freeAsmop (result, NULL, ic); @@ -4817,13 +4897,16 @@ genCmpLt (iCode * ic, iCode * ifx) retype = getSpec (operandType (right)); sign = !(SPEC_USIGN (letype) | SPEC_USIGN (retype)); - /* assign the amsops */ + /* assign the asmops */ aopOp (left, ic, FALSE, FALSE); aopOp (right, ic, FALSE, FALSE); aopOp (result, ic, TRUE, FALSE); + setupToPreserveCarry (ic); + genCmp (left, right, result, ifx, sign); + _G.preserveCarry = FALSE; freeAsmop (left, NULL, ic); freeAsmop (right, NULL, ic); freeAsmop (result, NULL, ic); @@ -7493,8 +7576,7 @@ genCast (iCode * ic) else { /* we need to extend the sign :{ */ - const char *l = aopGet (AOP (right), AOP_SIZE (right) - 1, - FALSE); + const char *l = aopGet (AOP (right), AOP_SIZE (right) - 1, FALSE); _moveA (l); emit2 ("rla "); emit2 ("sbc a,a"); @@ -7922,67 +8004,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)); @@ -7990,10 +8017,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); @@ -8015,7 +8038,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++) @@ -8038,7 +8061,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++) @@ -8047,12 +8070,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; + } } } } @@ -8086,53 +8119,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 two 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 */ @@ -8166,11 +8173,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); }