X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fz80%2Fgen.c;h=f957a6ac9ab98aa2655727e6c1e92542efa56a10;hb=31dc61b2804673867ffd66fad66c5d2638ec4ea2;hp=527f3c1e91b359e4ff06ad1613b651646895ff5a;hpb=e29becd95456cf7510a45c41af35bee5fa362ba8;p=fw%2Fsdcc diff --git a/src/z80/gen.c b/src/z80/gen.c index 527f3c1e..f957a6ac 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -87,12 +87,6 @@ #include #include -#if defined(__BORLANDC__) || defined(_MSC_VER) -#define STRCASECMP stricmp -#else -#define STRCASECMP strcasecmp -#endif - #include "z80.h" #include "SDCCglobl.h" #include "SDCCpeeph.h" @@ -128,16 +122,16 @@ enum }; static char *_z80_return[] = -{"l", "h", "e", "d"}; + {"l", "h", "e", "d"}; static char *_gbz80_return[] = -{"e", "d", "l", "h"}; + {"e", "d", "l", "h"}; static char *_fReceive[] = { "c", "b", "e", "d" }; static char **_fReturn; static char **_fTmp; -extern FILE *codeOutFile; +extern struct dbuf_s *codeOutBuf; enum { @@ -388,7 +382,7 @@ _tidyUp (char *buf) } static lineNode * -_newLineNode (char *line) +_newLineNode (const char *line) { lineNode *pl; @@ -401,11 +395,16 @@ _newLineNode (char *line) static void _vemit2 (const char *szFormat, va_list ap) { - char buffer[INITIAL_INLINEASM]; + struct dbuf_s dbuf; + const char *buffer; + + dbuf_init(&dbuf, INITIAL_INLINEASM); - tvsprintf (buffer, sizeof(buffer), szFormat, ap); + dbuf_tvprintf (&dbuf, szFormat, ap); - _tidyUp (buffer); + buffer = dbuf_c_str(&dbuf); + + _tidyUp ((char *)buffer); _G.lines.current = (_G.lines.current ? connectLine (_G.lines.current, _newLineNode (buffer)) : (_G.lines.head = _newLineNode (buffer))); @@ -413,6 +412,9 @@ _vemit2 (const char *szFormat, va_list ap) _G.lines.current->isInline = _G.lines.isInline; _G.lines.current->isDebug = _G.lines.isDebug; _G.lines.current->ic = _G.current_iCode; + _G.lines.current->isComment = (*buffer == ';'); + + dbuf_destroy(&dbuf); } static void @@ -699,9 +701,12 @@ _push (PAIR_ID pairId) static void _pop (PAIR_ID pairId) { - emit2 ("pop %s", _pairs[pairId].name); - _G.stack.pushed -= 2; - spillPair (pairId); + if (pairId != PAIR_INVALID) + { + emit2 ("pop %s", _pairs[pairId].name); + _G.stack.pushed -= 2; + spillPair (pairId); + } } void @@ -1255,7 +1260,7 @@ aopGetLitWordLong (asmop * aop, int offset, bool with_hash) /* otherwise it is fairly simple */ if (!IS_FLOAT (val->type)) { - unsigned long v = (unsigned long) floatFromVal (val); + unsigned long v = ulFromVal (val); if (offset == 2) { @@ -1503,8 +1508,18 @@ fetchPairLong (PAIR_ID pairId, asmop * aop, iCode *ic, int offset) } else { - emit2 ("ld %s,%s", _pairs[pairId].l, aopGet (aop, offset, FALSE)); - emit2 ("ld %s,%s", _pairs[pairId].h, aopGet (aop, offset + 1, FALSE)); + /* Swapping register contents within register pair */ + if(!strcmp(aopGet (aop, offset, FALSE), _pairs[pairId].h)) + { + 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); + } + else + { + emit2 ("ld %s,%s", _pairs[pairId].l, aopGet (aop, offset, FALSE)); + emit2 ("ld %s,%s", _pairs[pairId].h, aopGet (aop, offset + 1, FALSE)); + } } /* PENDING: check? */ if (pairId == PAIR_HL) @@ -1636,6 +1651,7 @@ static void emitLabel (int key) { emit2 ("!tlabeldef", key); + _G.lines.current->isLabel = 1; spillCached (); } @@ -2083,6 +2099,7 @@ aopPut (asmop * aop, const char *s, int offset) #define AOP_TYPE(op) AOP(op)->type #define AOP_SIZE(op) AOP(op)->size #define AOP_NEEDSACC(x) (AOP(x) && ((AOP_TYPE(x) == AOP_CRY) || (AOP_TYPE(x) == AOP_SFR))) +#define AOP_IS_PAIRPTR(x, p) (AOP_TYPE (x) == AOP_PAIRPTR && AOP (x)->aopu.aop_pairId == p) static void commitPair (asmop * aop, PAIR_ID id) @@ -2223,29 +2240,22 @@ outAcc (operand * result) /** Take the value in carry and put it into a register */ void -outBitCLong (operand * result, bool swap_sense) +outBitC (operand * result) { /* if the result is bit */ if (AOP_TYPE (result) == AOP_CRY) { - wassertl (0, "Tried to write carry to a bit"); + if (!IS_OP_RUONLY (result)) + aopPut (AOP (result), "c", 0); } else { emit2 ("ld a,!zero"); emit2 ("rla"); - if (swap_sense) - emit2 ("xor a,!immedbyte", 1); outAcc (result); } } -void -outBitC (operand * result) -{ - outBitCLong (result, FALSE); -} - /*-----------------------------------------------------------------*/ /* toBoolean - emit code for orl a,operator(sizeop) */ /*-----------------------------------------------------------------*/ @@ -2513,6 +2523,16 @@ assignResultValue (operand * oper) } else { + if ((AOP_TYPE (oper) == AOP_REG) && (AOP_SIZE (oper) == 4) && + !strcmp (AOP (oper)->aopu.aop_reg[size-1]->name, _fReturn[size-2])) + { + size--; + _emitMove ("a", _fReturn[size-1]); + _emitMove (_fReturn[size-1], _fReturn[size]); + _emitMove (_fReturn[size], "a"); + aopPut (AOP (oper), _fReturn[size], size-1); + size--; + } while (size--) { aopPut (AOP (oper), _fReturn[size], size); @@ -2680,13 +2700,23 @@ genIpush (iCode * ic) char *l = aopGetLitWordLong (AOP (IC_LEFT (ic)), --offset, FALSE); wassert (l); emit2 ("ld a,(%s)", l); + emit2 ("push af"); } else { l = aopGet (AOP (IC_LEFT (ic)), --offset, FALSE); - emit2 ("ld a,%s", l); + if (!strcmp(l, "b")) + emit2 ("push bc"); + else if (!strcmp(l, "d")) + emit2 ("push de"); + else if (!strcmp(l, "h")) + emit2 ("push hl"); + else + { + emit2 ("ld a,%s", l); + emit2 ("push af"); + } } - emit2 ("push af"); emit2 ("inc sp"); _G.stack.pushed++; } @@ -2899,6 +2929,7 @@ emitCall (iCode * ic, bool ispcall) fetchHL (AOP (IC_LEFT (ic))); emit2 ("jp !*hl"); emit2 ("!tlabeldef", (rlbl->key + 100)); + _G.lines.current->isLabel = 1; _G.stack.pushed -= 2; } freeAsmop (IC_LEFT (ic), NULL, ic); @@ -2931,7 +2962,6 @@ emitCall (iCode * ic, bool ispcall) OP_SYMBOL (IC_RESULT (ic))->spildir)) || IS_TRUE_SYMOP (IC_RESULT (ic))) { - aopOp (IC_RESULT (ic), ic, FALSE, FALSE); assignResultValue (IC_RESULT (ic)); @@ -3112,8 +3142,10 @@ genFunction (iCode * ic) { sprintf (buffer, "%s_start", sym->rname); emit2 ("!labeldef", buffer); + _G.lines.current->isLabel = 1; } emit2 ("!functionlabeldef", sym->rname); + _G.lines.current->isLabel = 1; ftype = operandType (IC_LEFT (ic)); @@ -3332,6 +3364,7 @@ genEndFunction (iCode * ic) emit2 ("jp PO,!tlabel", tlbl->key + 100); emit2 ("!ei"); emit2 ("!tlabeldef", (tlbl->key + 100)); + _G.lines.current->isLabel = 1; } } } @@ -3359,6 +3392,7 @@ genEndFunction (iCode * ic) { sprintf (buffer, "%s_end", sym->rname); emit2 ("!labeldef", buffer); + _G.lines.current->isLabel = 1; } _G.flushStatics = 1; @@ -3476,7 +3510,7 @@ genPlusIncr (iCode * ic) emitDebug ("; genPlusIncr"); - icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit); + icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit); /* If result is a pair */ if (resultId != PAIR_INVALID) @@ -3749,8 +3783,6 @@ genPlus (iCode * ic) if (genPlusIncr (ic) == TRUE) goto release; - emitDebug ("; Can't optimise plus by inc, falling back to the normal way"); - size = getDataSize (IC_RESULT (ic)); /* Special case when left and right are constant */ @@ -3890,28 +3922,57 @@ genPlus (iCode * ic) setupToPreserveCarry (ic); - while (size--) + /* This is ugly, but it fixes the worst code generation bug on Z80. */ + /* Probably something similar has to be done for addition of larger numbers, too. */ + if(size == 2) { - if (AOP_TYPE (IC_LEFT (ic)) == AOP_ACC) + _moveA (aopGet (AOP (IC_LEFT (ic)), 0, FALSE)); + emit2 ("add a,%s", aopGet (AOP (IC_RIGHT (ic)), 0, FALSE)); + if(strcmp (aopGet (AOP (IC_RESULT (ic)), 0, FALSE), aopGet (AOP (IC_LEFT (ic)), 1, FALSE))) { - _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE)); - if (offset == 0) - 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", 0); + _moveA (aopGet (AOP (IC_LEFT (ic)), 1, FALSE)); } else { - _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE)); - if (offset == 0) - emit2 ("add a,%s", - aopGet (AOP (IC_RIGHT (ic)), offset, FALSE)); + emitDebug ("; Addition result is in same register as operand of next addition."); + if(strchr (aopGet (AOP (IC_RESULT (ic)), 0, FALSE), 'c') || + strchr (aopGet (AOP (IC_RESULT (ic)), 0, FALSE), 'b') ) + { + emit2 ("push de"); + emit2 ("ld e, a"); + emit2 ("ld a, %s", aopGet (AOP (IC_LEFT (ic)), 1, FALSE)); + emit2 ("ld d, a"); + emit2 ("ld a, e"); + emit2 ("ld %s, a", aopGet (AOP (IC_RESULT (ic)), 0, FALSE)); + emit2 ("ld a, d"); + emit2 ("pop de"); + } else - emit2 ("adc a,%s", - aopGet (AOP (IC_RIGHT (ic)), offset, FALSE)); + { + emit2 ("push bc"); + emit2 ("ld c, a"); + emit2 ("ld a, %s", aopGet (AOP (IC_LEFT (ic)), 1, FALSE)); + emit2 ("ld b, a"); + emit2 ("ld a, c"); + emit2 ("ld %s, a", aopGet (AOP (IC_RESULT (ic)), 0, FALSE)); + 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); + goto release; + } + + while (size--) + { + _moveA (aopGet (AOP (IC_LEFT (ic)), offset, FALSE)); + if (offset == 0) + 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++); } @@ -3938,7 +3999,7 @@ genMinusDec (iCode * ic) /* if the literal value of the right hand side is greater than 4 then it is not worth it */ - if ((icount = (unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 2) + if ((icount = (unsigned int) ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit)) > 2) return FALSE; size = getDataSize (IC_RESULT (ic)); @@ -4028,7 +4089,7 @@ genMinus (iCode * ic) } else { - lit = (unsigned long) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit); + lit = ulFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit); lit = -(long) lit; } @@ -4161,7 +4222,7 @@ genMult (iCode * ic) wassertl (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT, "Right must be a literal"); - val = (int)floatFromVal ( AOP (IC_RIGHT (ic))->aopu.aop_lit); + val = (int) ulFromVal ( AOP (IC_RIGHT (ic))->aopu.aop_lit); // wassertl (val > 0, "Multiply must be positive"); wassertl (val != 1, "Can't multiply by 1"); @@ -4170,7 +4231,9 @@ genMult (iCode * ic) _G.stack.pushedDE = TRUE; } - if ( AOP_SIZE (IC_LEFT (ic)) == 1 && !SPEC_USIGN (getSpec (operandType ( IC_LEFT (ic))))) + if (byteResult) + emit2 ("ld a,%s", aopGet (AOP (IC_LEFT (ic)), LSB, FALSE)); + else if ( AOP_SIZE (IC_LEFT (ic)) == 1 && !SPEC_USIGN (getSpec (operandType ( IC_LEFT (ic))))) { emit2 ("ld e,%s", aopGet (AOP (IC_LEFT (ic)), LSB, FALSE)); if (!byteResult) @@ -4188,25 +4251,33 @@ genMult (iCode * ic) i = val; - /* Fully unroled version of mul.s. Not the most efficient. - */ for (count = 0; count < 16; count++) { if (count != 0 && active) { - emit2 ("add hl,hl"); + if (byteResult) + emit2 ("add a,a"); + else + emit2 ("add hl,hl"); } if (i & 0x8000U) { if (active == FALSE) { - emit2 ("ld l,e"); - if (!byteResult) - emit2 ("ld h,d"); + if (byteResult) + emit2("ld e,a"); + else + { + emit2 ("ld l,e"); + emit2 ("ld h,d"); + } } else { - emit2 ("add hl,de"); + if (byteResult) + emit2 ("add a,e"); + else + emit2 ("add hl,de"); } active = TRUE; } @@ -4222,7 +4293,7 @@ genMult (iCode * ic) } if (byteResult) - aopPut (AOP (IC_RESULT (ic)), _pairs[PAIR_HL].l, 0); + aopPut (AOP (IC_RESULT (ic)), "a", 0); else commitPair ( AOP (IC_RESULT (ic)), PAIR_HL); @@ -4452,7 +4523,7 @@ _getPairIdName (PAIR_ID id) { if (AOP_TYPE (right) == AOP_LIT) { - lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit); + lit = ulFromVal (AOP (right)->aopu.aop_lit); /* optimize if(x < 0) or if(x >= 0) */ if (lit == 0L) { @@ -4483,8 +4554,7 @@ _getPairIdName (PAIR_ID id) bool fDidXor = FALSE; if (AOP_TYPE (left) == AOP_LIT) { - unsigned long lit = (unsigned long) - floatFromVal (AOP (left)->aopu.aop_lit); + unsigned long lit = ulFromVal (AOP (left)->aopu.aop_lit); emit2 ("ld %s,!immedbyte", _fTmp[0], 0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL)); } @@ -4497,8 +4567,7 @@ _getPairIdName (PAIR_ID id) } if (AOP_TYPE (right) == AOP_LIT) { - unsigned long lit = (unsigned long) - floatFromVal (AOP (right)->aopu.aop_lit); + unsigned long lit = ulFromVal (AOP (right)->aopu.aop_lit); emit2 ("ld %s,!immedbyte", _fTmp[1], 0x80 ^ (unsigned int) ((lit >> ((size - 1) * 8)) & 0x0FFL)); } @@ -4541,7 +4610,6 @@ genCmp (operand * left, operand * right, { int size, offset = 0; unsigned long lit = 0L; - bool swap_sense = FALSE; /* if left & right are bit variables */ if (AOP_TYPE (left) == AOP_CRY && @@ -4582,7 +4650,7 @@ genCmp (operand * left, operand * right, if (AOP_TYPE (right) == AOP_LIT) { - lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit); + lit = ulFromVal (AOP (right)->aopu.aop_lit); /* optimize if(x < 0) or if(x >= 0) */ if (lit == 0) { @@ -4608,7 +4676,7 @@ genCmp (operand * left, operand * right, } if (ifx) { - genIfxJump (ifx, swap_sense ? "c" : "nc"); + genIfxJump (ifx, "nc"); return; } } @@ -4634,7 +4702,7 @@ release: /* Shift the sign bit up into carry */ emit2 ("rlca"); } - outBitCLong (result, swap_sense); + outBitC (result); } else { @@ -4648,16 +4716,16 @@ release: if (IS_GB) { emit2 ("rlca"); - genIfxJump (ifx, swap_sense ? "nc" : "c"); + genIfxJump (ifx, "c"); } else { - genIfxJump (ifx, swap_sense ? "p" : "m"); + genIfxJump (ifx, "m"); } } else { - genIfxJump (ifx, swap_sense ? "nc" : "c"); + genIfxJump (ifx, "c"); } } else @@ -4667,7 +4735,7 @@ release: /* Shift the sign bit up into carry */ emit2 ("rlca"); } - outBitCLong (result, swap_sense); + outBitC (result); } /* leave the result in acc */ } @@ -4734,8 +4802,9 @@ genCmpLt (iCode * ic, iCode * ifx) /*-----------------------------------------------------------------*/ /* gencjneshort - compare and jump if not equal */ +/* returns pair that still needs to be popped */ /*-----------------------------------------------------------------*/ -static void +static PAIR_ID gencjneshort (operand * left, operand * right, symbol * lbl) { int size = max (AOP_SIZE (left), AOP_SIZE (right)); @@ -4750,18 +4819,13 @@ gencjneshort (operand * left, operand * right, symbol * lbl) left = t; } - if (AOP_TYPE (right) == AOP_LIT) - { - lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit); - } - /* if the right side is a literal then anything goes */ - if (AOP_TYPE (right) == AOP_LIT && - AOP_TYPE (left) != AOP_DIR) + if (AOP_TYPE (right) == AOP_LIT) { + lit = ulFromVal (AOP (right)->aopu.aop_lit); if (lit == 0) { - emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE)); + _moveA (aopGet (AOP (left), offset, FALSE)); if (size > 1) { while (--size) @@ -4779,49 +4843,68 @@ gencjneshort (operand * left, operand * right, symbol * lbl) { while (size--) { - emit2 ("ld a,%s", aopGet (AOP (left), offset, FALSE)); - if ((AOP_TYPE (right) == AOP_LIT) && lit == 0) + _moveA (aopGet (AOP (left), offset, FALSE)); + if ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0) emit2 ("or a,a"); else - emit2 ("cp a,%s", aopGet (AOP (right), offset, FALSE)); + emit2 ("sub a,%s", aopGet (AOP (right), offset, FALSE)); emit2 ("jp NZ,!tlabel", lbl->key + 100); offset++; } } } - /* if the right side is in a register or in direct space or - if the left is a pointer register & right is not */ + /* if the right side is in a register or + pointed to by HL, IX or IY */ else if (AOP_TYPE (right) == AOP_REG || - AOP_TYPE (right) == AOP_DIR || - (AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT)) + AOP_TYPE (right) == AOP_HL || + AOP_TYPE (right) == AOP_IY || + AOP_TYPE (right) == AOP_STK || + AOP_IS_PAIRPTR (right, PAIR_HL) || + AOP_IS_PAIRPTR (right, PAIR_IX) || + AOP_IS_PAIRPTR (right, PAIR_IY)) { while (size--) { _moveA (aopGet (AOP (left), offset, FALSE)); - if ((AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) && + if (AOP_TYPE (right) == AOP_LIT && ((unsigned int) ((lit >> (offset * 8)) & 0x0FFL) == 0)) - /* PENDING */ - emit2 ("jp NZ,!tlabel", lbl->key + 100); + { + emit2 ("or a,a"); + emit2 ("jp NZ,!tlabel", lbl->key + 100); + } else { - emit2 ("cp %s", aopGet (AOP (right), offset, FALSE)); + emit2 ("sub %s", aopGet (AOP (right), offset, FALSE)); emit2 ("jp NZ,!tlabel", lbl->key + 100); } offset++; } } + /* right is in direct space or a pointer reg, need both a & b */ else { - /* right is a pointer reg need both a & b */ - /* PENDING: is this required? */ + PAIR_ID pair; + for (pair = PAIR_BC; pair <= PAIR_HL; pair++) + { + if (((AOP_TYPE (left) != AOP_PAIRPTR) || (AOP (left)->aopu.aop_pairId != pair)) && + ((AOP_TYPE (right) != AOP_PAIRPTR) || (AOP (right)->aopu.aop_pairId != pair))) + { + break; + } + } + _push (pair); while (size--) { + emit2 ("; direct compare"); + _emitMove (_pairs[pair].l, aopGet (AOP (left), offset, FALSE)); _moveA (aopGet (AOP (right), offset, FALSE)); - emit2 ("cp %s", aopGet (AOP (left), offset, FALSE)); + emit2 ("sub %s", _pairs[pair].l); emit2 ("!shortjp NZ,!tlabel", lbl->key + 100); offset++; } + return pair; } + return PAIR_INVALID; } /*-----------------------------------------------------------------*/ @@ -4832,7 +4915,7 @@ gencjne (operand * left, operand * right, symbol * lbl) { symbol *tlbl = newiTempLabel (NULL); - gencjneshort (left, right, lbl); + PAIR_ID pop = gencjneshort (left, right, lbl); /* PENDING: ?? */ emit2 ("ld a,!one"); @@ -4840,6 +4923,7 @@ gencjne (operand * left, operand * right, symbol * lbl) emitLabel (lbl->key + 100); emit2 ("xor a,a"); emitLabel (tlbl->key + 100); + _pop (pop); } /*-----------------------------------------------------------------*/ @@ -4877,19 +4961,24 @@ genCmpEq (iCode * ic, iCode * ifx) } else { + PAIR_ID pop; tlbl = newiTempLabel (NULL); - gencjneshort (left, right, tlbl); + pop = gencjneshort (left, right, tlbl); if (IC_TRUE (ifx)) { + _pop (pop); emit2 ("jp !tlabel", IC_TRUE (ifx)->key + 100); emitLabel (tlbl->key + 100); + _pop (pop); } else { /* PENDING: do this better */ symbol *lbl = newiTempLabel (NULL); + _pop (pop); emit2 ("!shortjp !tlabel", lbl->key + 100); emitLabel (tlbl->key + 100); + _pop (pop); emit2 ("jp !tlabel", IC_FALSE (ifx)->key + 100); emitLabel (lbl->key + 100); } @@ -5118,7 +5207,7 @@ genAnd (iCode * ic, iCode * ifx) left = tmp; } if (AOP_TYPE (right) == AOP_LIT) - lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit); + lit = ulFromVal (AOP (right)->aopu.aop_lit); size = AOP_SIZE (result); @@ -5164,6 +5253,7 @@ genAnd (iCode * ic, iCode * ifx) { emit2 ("clr c"); emit2 ("!tlabeldef", tlbl->key + 100); + _G.lines.current->isLabel = 1; } // if(left & literal) else @@ -5308,7 +5398,7 @@ genOr (iCode * ic, iCode * ifx) left = tmp; } if (AOP_TYPE (right) == AOP_LIT) - lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit); + lit = ulFromVal (AOP (right)->aopu.aop_lit); size = AOP_SIZE (result); @@ -5466,7 +5556,7 @@ genXor (iCode * ic, iCode * ifx) left = tmp; } if (AOP_TYPE (right) == AOP_LIT) - lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit); + lit = ulFromVal (AOP (right)->aopu.aop_lit); size = AOP_SIZE (result); @@ -5592,37 +5682,49 @@ static void genInline (iCode * ic) { char *buffer, *bp, *bp1; + bool inComment = FALSE; _G.lines.isInline += (!options.asmpeep); - buffer = bp = bp1 = Safe_calloc(1, strlen(IC_INLINE(ic))+1); - strcpy (buffer, IC_INLINE (ic)); + buffer = bp = bp1 = Safe_strdup (IC_INLINE (ic)); /* emit each line as a code */ while (*bp) { - if (*bp == '\n') + switch (*bp) { + case ';': + inComment = TRUE; + ++bp; + break; + + case '\n': + inComment = FALSE; *bp++ = '\0'; emit2 (bp1); bp1 = bp; - } - else - { - if (*bp == ':') + break; + + default: + /* Add \n for labels, not dirs such as c:\mydir */ + if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1]))) { - bp++; + ++bp; *bp = '\0'; - bp++; + ++bp; emit2 (bp1); bp1 = bp; } else - bp++; + ++bp; + break; } } if (bp1 != bp) emit2 (bp1); + + Safe_free (buffer); + _G.lines.isInline -= (!options.asmpeep); } @@ -5707,7 +5809,7 @@ shiftR2Left2Result (operand * left, int offl, int shCount, int is_signed) { int size = 2; - symbol *tlbl, *tlbl1; + symbol *tlbl; movLeft2Result (left, offl, result, offr, 0); movLeft2Result (left, offl + 1, result, offr + 1, 0); @@ -5718,10 +5820,10 @@ shiftR2Left2Result (operand * left, int offl, /* if (AOP(result)->type == AOP_REG) { */ tlbl = newiTempLabel (NULL); - tlbl1 = newiTempLabel (NULL); /* Left is already in result - so now do the shift */ - if (shCount <= 4) + /* Optimizing for speed by default. */ + if (!optimize.codeSize || shCount <= 2) { while (shCount--) { @@ -5730,13 +5832,12 @@ shiftR2Left2Result (operand * left, int offl, } else { - emit2 ("ld a,!immedbyte+1", shCount); - emit2 ("!shortjp !tlabel", tlbl1->key + 100); + emit2 ("ld a,!immedbyte", shCount); + emitLabel (tlbl->key + 100); emitRsh2 (AOP (result), size, is_signed); - emitLabel (tlbl1->key + 100); emit2 ("dec a"); emit2 ("!shortjp NZ,!tlabel", tlbl->key + 100); } @@ -5958,13 +6059,25 @@ shiftL1Left2Result (operand * left, int offl, operand * result, int offr, int shCount) { const char *l; - l = aopGet (AOP (left), offl, FALSE); - _moveA (l); - /* shift left accumulator */ - AccLsh (shCount); - aopPut (AOP (result), "a", offr); -} + /* If operand and result are the same we can shift in place. + However shifting in acc using add is cheaper than shifting + in place using sla; when shifting by more than 2 shifting in + acc is worth the additional effort for loading from/to acc. */ + if (sameRegs (AOP (left), AOP (result)) && shCount <= 2 && offr == offl) + { + while (shCount--) + emit2 ("sla %s", aopGet (AOP (result), 0, FALSE)); + } + else + { + l = aopGet (AOP (left), offl, FALSE); + _moveA (l); + /* shift left accumulator */ + AccLsh (shCount); + aopPut (AOP (result), "a", offr); + } +} /*-----------------------------------------------------------------*/ /* genlshTwo - left shift two bytes by known amount */ @@ -6031,7 +6144,7 @@ genLeftShiftLiteral (operand * left, operand * result, iCode * ic) { - int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit); + int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit); int size; freeAsmop (right, NULL, ic); @@ -6288,7 +6401,7 @@ genRightShiftLiteral (operand * left, iCode * ic, int sign) { - int shCount = (int) floatFromVal (AOP (right)->aopu.aop_lit); + int shCount = (int) ulFromVal (AOP (right)->aopu.aop_lit); int size; freeAsmop (right, NULL, ic); @@ -6746,7 +6859,7 @@ genPackBits (sym_link * etype, { /* Case with a bitfield length <8 and literal source */ - litval = (int) floatFromVal (AOP (right)->aopu.aop_lit); + litval = (int) ulFromVal (AOP (right)->aopu.aop_lit); litval <<= bstr; litval &= (~mask) & 0xff; emit2 ("ld a,!*pair", _pairs[pair].name); @@ -6811,7 +6924,7 @@ genPackBits (sym_link * etype, { /* Case with partial byte and literal source */ - litval = (int) floatFromVal (AOP (right)->aopu.aop_lit); + litval = (int) ulFromVal (AOP (right)->aopu.aop_lit); litval >>= (blen-rlen); litval &= (~mask) & 0xff; emit2 ("ld a,!*pair", _pairs[pair].name); @@ -7147,7 +7260,7 @@ genAssign (iCode * ic) if (AOP_TYPE (right) == AOP_LIT) { - lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit); + lit = ulFromVal (AOP (right)->aopu.aop_lit); } if (isPair (AOP (result))) @@ -7464,6 +7577,7 @@ genCritical (iCode *ic) emit2 ("jp PO,!tlabel", tlbl->key + 100); aopPut (AOP (IC_RESULT (ic)), "!one", 0); emit2 ("!tlabeldef", (tlbl->key + 100)); + _G.lines.current->isLabel = 1; freeAsmop (IC_RESULT (ic), NULL, ic); } else @@ -7508,6 +7622,7 @@ genEndCritical (iCode *ic) emit2 ("jp PO,!tlabel", tlbl->key + 100); emit2 ("!ei"); emit2 ("!tlabeldef", (tlbl->key + 100)); + _G.lines.current->isLabel = 1; } } @@ -8084,7 +8199,9 @@ genZ80Code (iCode * lic) } if (options.iCodeInAsm) { - emit2 (";ic:%d: %s", ic->key, printILine(ic)); + const char *iLine = printILine(ic); + emit2 (";ic:%d: %s", ic->key, iLine); + dbuf_free(iLine); } /* if the result is marked as spilt and rematerializable or code for @@ -8121,7 +8238,7 @@ genZ80Code (iCode * lic) spilt live range, if there is an ifx statement following this pop then the if statement might be using some of the registers being popped which - would destory the contents of the register so + would destroy the contents of the register so we need to check for this condition and handle it */ if (ic->next && ic->next->op == IFX && @@ -8368,16 +8485,16 @@ genZ80Code (iCode * lic) /* This is unfortunate */ /* now do the actual printing */ { - FILE *fp = codeOutFile; - if (isInHome () && codeOutFile == code->oFile) - codeOutFile = home->oFile; - printLine (_G.lines.head, codeOutFile); + struct dbuf_s *buf = codeOutBuf; + if (isInHome () && codeOutBuf == &code->oBuf) + codeOutBuf = &home->oBuf; + printLine (_G.lines.head, codeOutBuf); if (_G.flushStatics) { flushStatics (); _G.flushStatics = 0; } - codeOutFile = fp; + codeOutBuf = buf; } freeTrace(&_G.lines.trace); @@ -8413,7 +8530,7 @@ fetchLitSpecial (asmop * aop, bool negate, bool xor) wassert (aop->type == AOP_LIT); wassert (!IS_FLOAT (val->type)); - v = (unsigned long) floatFromVal (val); + v = ulFromVal (val); if (xor) v ^= 0x8000;