X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fgen.c;h=cb42cdeb452318abcb8b476399b5a11f9d480c34;hb=17475724ba3b307a3dd40764f224d4031666f6f2;hp=f99fa6a02ea9df804a4b1f832b1a0f15869fc0b2;hpb=ac423fe4107206080b692f3a6e6a4fdd9b48f0b6;p=fw%2Fsdcc diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index f99fa6a0..cb42cdeb 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -181,19 +181,20 @@ emitcode (const char *inst, const char *fmt,...) lbp++; } - if (lbp && *lbp) + if (lbp) { rtrackUpdate (lbp); lineCurr = (lineCurr ? connectLine (lineCurr, newLineNode (lb)) : (lineHead = newLineNode (lb))); + + lineCurr->isInline = _G.inLine; + lineCurr->isDebug = _G.debugLine; + lineCurr->ic = _G.current_iCode; + lineCurr->isComment = (*lbp==';'); } - lineCurr->isInline = _G.inLine; - lineCurr->isDebug = _G.debugLine; - lineCurr->ic = _G.current_iCode; - lineCurr->isComment = (*lbp==';'); va_end (ap); dbuf_destroy(&dbuf); @@ -968,7 +969,7 @@ aopOp (operand * op, iCode * ic, bool result) if (sym->remat) { sym->aop = op->aop = aop = aopForRemat (sym); - aop->size = getSize (sym->type); + aop->size = operandSize (op); return; } @@ -1491,6 +1492,7 @@ aopPut (operand * result, const char *s, int offset) bool bvolatile = isOperandVolatile (result, FALSE); bool accuse = FALSE; asmop * aop = AOP (result); + const char *d = NULL; if (aop->size && offset > (aop->size - 1)) { @@ -1666,28 +1668,40 @@ aopPut (operand * result, const char *s, int offset) break; case AOP_CRY: - /* if result no bit variable */ - if (!aop->aopu.aop_dir) - { - assert (!strcmp (s, "c")); - /* inefficient: move carry into A and use jz/jnz */ - emitcode ("clr", "a"); - emitcode ("rlc", "a"); - accuse = TRUE; - } - else if (s == zero) - emitcode ("clr", "%s", aop->aopu.aop_dir); - else if (s == one) - emitcode ("setb", "%s", aop->aopu.aop_dir); - else if (!strcmp (s, "c")) - emitcode ("mov", "%s,c", aop->aopu.aop_dir); - else if (strcmp (s, aop->aopu.aop_dir)) + // destination is carry for return-use-only + d = (IS_OP_RUONLY (result)) ? "c" : aop->aopu.aop_dir; + // source is no literal and not in carry + if ((s != zero) && (s != one) && strcmp (s, "c")) { MOVA (s); /* set C, if a >= 1 */ emitcode ("add", "a,#0xff"); - emitcode ("mov", "%s,c", aop->aopu.aop_dir); + s = "c"; + } + // now source is zero, one or carry + + /* if result no bit variable */ + if (!d) + { + if (!strcmp (s, "c")) + { + /* inefficient: move carry into A and use jz/jnz */ + emitcode ("clr", "a"); + emitcode ("rlc", "a"); + accuse = TRUE; + } + else + { + MOVA (s); + accuse = TRUE; + } } + else if (s == zero) + emitcode ("clr", "%s", d); + else if (s == one) + emitcode ("setb", "%s", d); + else if (strcmp (s, d)) + emitcode ("mov", "%s,c", d); break; case AOP_STR: @@ -1838,7 +1852,7 @@ outBitC (operand * result) /* if the result is bit */ if (AOP_TYPE (result) == AOP_CRY) { - if (!OP_SYMBOL (result)->ruonly) + if (!IS_OP_RUONLY (result)) aopPut (result, "c", 0); } else @@ -1992,7 +2006,7 @@ genNot (iCode * ic) } else { - emitcode ("mov", "c,%s", IC_LEFT (ic)->aop->aopu.aop_dir); + toCarry (IC_LEFT (ic)); emitcode ("cpl", "c"); outBitC (IC_RESULT (ic)); } @@ -2669,9 +2683,9 @@ saveRBank (int bank, iCode * ic, bool pushPsw) } if (ic) - { - ic->bankSaved = 1; - } + { + ic->bankSaved = 1; + } } /*-----------------------------------------------------------------*/ @@ -3405,7 +3419,7 @@ genFunction (iCode * ic) } } } - else + else { /* This ISR uses a non-zero bank. * @@ -3590,7 +3604,7 @@ genFunction (iCode * ic) int ofs; _G.current_iCode = ric; - D(emitcode ("; genReceive","")); + D(emitcode (";", "genReceive")); for (ofs=0; ofs < sym->recvSize; ofs++) { if (!strcmp (fReturn[ofs], "a")) @@ -3615,7 +3629,7 @@ genFunction (iCode * ic) int ofs; _G.current_iCode = ric; - D(emitcode ("; genReceive","")); + D(emitcode (";", "genReceive")); for (ofs=0; ofs < sym->recvSize; ofs++) { emitcode ("mov", "%s,%s", rsym->regs[ofs]->name, fReturn[ofs]); @@ -4039,7 +4053,7 @@ genRet (iCode * ic) if (IS_BIT(_G.currentFunc->etype)) { - if (!OP_SYMBOL (IC_LEFT (ic))->ruonly) + if (!IS_OP_RUONLY (IC_LEFT (ic))) toCarry (IC_LEFT (ic)); } else @@ -4514,7 +4528,7 @@ genPlus (iCode * ic) && (SPEC_ADDR (OP_SYM_ETYPE (op)) & 0xff) == 0 ) { - D(emitcode ("; genPlus aligned array","")); + D(emitcode (";", "genPlus aligned array")); aopPut (IC_RESULT (ic), aopGet (rightOp, 0, FALSE, FALSE), 0); @@ -4543,7 +4557,7 @@ genPlus (iCode * ic) skip_bytes++; } if (skip_bytes) - D(emitcode ("; genPlus shortcut","")); + D(emitcode (";", "genPlus shortcut")); } while (size--) @@ -5214,7 +5228,7 @@ genDivbits (operand * left, char *l; bool pushedB; - D(emitcode ("; genDivbits","")); + D(emitcode (";", "genDivbits")); pushedB = pushB (); @@ -5247,7 +5261,7 @@ genDivOneByte (operand * left, symbol *lbl; int size, offset; - D(emitcode ("; genDivOneByte","")); + D(emitcode (";", "genDivOneByte")); /* Why is it necessary that genDivOneByte() can return an int result? Have a look at: @@ -5459,7 +5473,7 @@ genDiv (iCode * ic) D (emitcode (";", "genDiv")); - /* assign the amsops */ + /* assign the asmops */ aopOp (left, ic, FALSE); aopOp (right, ic, FALSE); aopOp (result, ic, TRUE); @@ -5978,7 +5992,7 @@ genCmpGt (iCode * ic, iCode * ifx) retype = getSpec (operandType (right)); sign = !((SPEC_USIGN (letype) && !(IS_CHAR (letype) && IS_LITERAL (letype))) || (SPEC_USIGN (retype) && !(IS_CHAR (retype) && IS_LITERAL (retype)))); - /* assign the amsops */ + /* assign the asmops */ aopOp (result, ic, TRUE); aopOp (left, ic, FALSE); aopOp (right, ic, FALSE); @@ -6008,7 +6022,7 @@ genCmpLt (iCode * ic, iCode * ifx) retype = getSpec (operandType (right)); sign = !((SPEC_USIGN (letype) && !(IS_CHAR (letype) && IS_LITERAL (letype))) || (SPEC_USIGN (retype) && !(IS_CHAR (retype) && IS_LITERAL (retype)))); - /* assign the amsops */ + /* assign the asmops */ aopOp (result, ic, TRUE); aopOp (left, ic, FALSE); aopOp (right, ic, FALSE); @@ -6033,8 +6047,9 @@ gencjneshort (operand * left, operand * right, symbol * lbl) /* if the left side is a literal or if the right is in a pointer register and left is not */ - if ((AOP_TYPE (left) == AOP_LIT) || + if ((AOP_TYPE (left) == AOP_LIT) || (AOP_TYPE (left) == AOP_IMMD) || + (AOP_TYPE (left) == AOP_DIR) || (IS_AOP_PREG (right) && !IS_AOP_PREG (left))) { operand *t = right; @@ -6101,7 +6116,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl) /* gencjne - compare and jump if not equal */ /*-----------------------------------------------------------------*/ static void -gencjne (operand * left, operand * right, symbol * lbl) +gencjne (operand * left, operand * right, symbol * lbl, bool useCarry) { symbol *tlbl = newiTempLabel (NULL); @@ -6109,10 +6124,16 @@ gencjne (operand * left, operand * right, symbol * lbl) gencjneshort (left, right, lbl); - emitcode ("mov", "a,%s", one); + if (useCarry) + SETC; + else + MOVA (one); emitcode ("sjmp", "%05d$", tlbl->key + 100); emitLabel (lbl); - emitcode ("clr", "a"); + if (useCarry) + CLRC; + else + MOVA (zero); emitLabel (tlbl); } @@ -6273,12 +6294,13 @@ genCmpEq (iCode * ic, iCode * ifx) } else { - gencjne (left, right, newiTempLabel (NULL)); if (AOP_TYPE (result) == AOP_CRY && AOP_SIZE (result)) { - aopPut (result, "a", 0); + gencjne (left, right, newiTempLabel (NULL), TRUE); + aopPut (result, "c", 0); goto release; } + gencjne (left, right, newiTempLabel (NULL), FALSE); if (ifx) { genIfxJump (ifx, "a", left, right, result); @@ -6539,10 +6561,10 @@ genAnd (iCode * ic, iCode * ifx) aopOp ((result = IC_RESULT (ic)), ic, TRUE); #ifdef DEBUG_TYPE - emitcode ("", "; Type res[%d] = l[%d]&r[%d]", + emitcode (";", "Type res[%d] = l[%d]&r[%d]", AOP_TYPE (result), AOP_TYPE (left), AOP_TYPE (right)); - emitcode ("", "; Size res[%d] = l[%d]&r[%d]", + emitcode (";", "Size res[%d] = l[%d]&r[%d]", AOP_SIZE (result), AOP_SIZE (left), AOP_SIZE (right)); #endif @@ -6963,10 +6985,10 @@ genOr (iCode * ic, iCode * ifx) aopOp ((result = IC_RESULT (ic)), ic, TRUE); #ifdef DEBUG_TYPE - emitcode ("", "; Type res[%d] = l[%d]&r[%d]", + emitcode (";", "Type res[%d] = l[%d]&r[%d]", AOP_TYPE (result), AOP_TYPE (left), AOP_TYPE (right)); - emitcode ("", "; Size res[%d] = l[%d]&r[%d]", + emitcode (";", "Size res[%d] = l[%d]&r[%d]", AOP_SIZE (result), AOP_SIZE (left), AOP_SIZE (right)); #endif @@ -7340,10 +7362,10 @@ genXor (iCode * ic, iCode * ifx) aopOp ((result = IC_RESULT (ic)), ic, TRUE); #ifdef DEBUG_TYPE - emitcode ("", "; Type res[%d] = l[%d]&r[%d]", + emitcode (";", "Type res[%d] = l[%d]&r[%d]", AOP_TYPE (result), AOP_TYPE (left), AOP_TYPE (right)); - emitcode ("", "; Size res[%d] = l[%d]&r[%d]", + emitcode (";", "Size res[%d] = l[%d]&r[%d]", AOP_SIZE (result), AOP_SIZE (left), AOP_SIZE (right)); #endif @@ -7374,6 +7396,7 @@ genXor (iCode * ic, iCode * ifx) right = left; left = tmp; } + if (AOP_TYPE (right) == AOP_LIT) lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit); @@ -7432,25 +7455,21 @@ genXor (iCode * ic, iCode * ifx) if (AOP_TYPE (right) == AOP_CRY) { // c = bit ^ bit; - emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir); + if (IS_OP_ACCUSE (left)) + {// left already is in the carry + operand *tmp = right; + right = left; + left = tmp; + } + else + { + toCarry (right); + } } else { - int sizer = AOP_SIZE (right); // c = bit ^ val - // if val>>1 != 0, result = 1 - emitcode ("setb", "c"); - while (sizer) - { - MOVA (aopGet (right, sizer - 1, FALSE, FALSE)); - if (sizer == 1) - // test the msb of the lsb - emitcode ("anl", "a,#0xfe"); - emitcode ("jnz", "%05d$", tlbl->key + 100); - sizer--; - } - // val = (0,1) - emitcode ("rrc", "a"); + toCarry (right); } emitcode ("jnb", "%s,%05d$", AOP (left)->aopu.aop_dir, (tlbl->key + 100)); emitcode ("cpl", "c"); @@ -7678,40 +7697,51 @@ static void genInline (iCode * ic) { char *buffer, *bp, *bp1; + bool inComment = FALSE; D (emitcode (";", "genInline")); _G.inLine += (!options.asmpeep); - buffer = bp = bp1 = Safe_strdup(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'; emitcode (bp1, ""); bp1 = bp; - } - else - { + break; + + default: /* Add \n for labels, not dirs such as c:\mydir */ - if ( (*bp == ':') && (isspace((unsigned char)bp[1])) ) + if (!inComment && (*bp == ':') && (isspace((unsigned char)bp[1]))) { - bp++; + ++bp; *bp = '\0'; - bp++; + ++bp; emitcode (bp1, ""); bp1 = bp; } else - bp++; + ++bp; + break; } } if (bp1 != bp) emitcode (bp1, ""); - /* emitcode("",buffer); */ + + Safe_free (buffer); + _G.inLine -= (!options.asmpeep); } @@ -7995,7 +8025,7 @@ genSwap (iCode * ic) { operand *left, *result; - D(emitcode ("; genSwap","")); + D(emitcode (";", "genSwap")); left = IC_LEFT (ic); result = IC_RESULT (ic); @@ -9696,7 +9726,7 @@ genUnpackBits (operand * result, char *rname, int ptype, iCode *ifx) int bstr; /* bitfield starting bit within byte */ char buffer[10]; - D(emitcode ("; genUnpackBits","")); + D(emitcode (";", "genUnpackBits")); etype = getSpec (operandType (result)); rsize = getSize (operandType (result)); @@ -10086,7 +10116,7 @@ loadDptrFromOperand (operand *op, bool loadBToo) else { wassertl(FALSE, "need pointerCode"); - emitcode ("", "; mov b,???"); + emitcode (";", "mov b,???"); /* genPointerGet and genPointerSet originally did different ** things for this case. Both seem wrong. ** from genPointerGet: @@ -10369,7 +10399,7 @@ genPackBits (sym_link * etype, int litval; /* source literal value (if AOP_LIT) */ unsigned char mask; /* bitmask within current byte */ - D(emitcode ("; genPackBits","")); + D(emitcode (";", "genPackBits")); blen = SPEC_BLEN (etype); bstr = SPEC_BSTR (etype); @@ -10505,7 +10535,7 @@ genDataPointerSet (operand * right, l = aopGet (result, 0, FALSE, TRUE); l++; //remove # - size = AOP_SIZE (right); + size = max (AOP_SIZE (right), AOP_SIZE (result)); while (size--) { if (offset) @@ -10516,12 +10546,12 @@ genDataPointerSet (operand * right, aopGet (right, offset++, FALSE, FALSE)); } - freeAsmop (result, NULL, ic, TRUE); freeAsmop (right, NULL, ic, TRUE); + freeAsmop (result, NULL, ic, TRUE); } /*-----------------------------------------------------------------*/ -/* genNearPointerSet - emitcode for near pointer put */ +/* genNearPointerSet - emitcode for near pointer put */ /*-----------------------------------------------------------------*/ static void genNearPointerSet (operand * right, @@ -10646,9 +10676,10 @@ genNearPointerSet (operand * right, } /* done */ - if (pi) pi->generated = 1; - freeAsmop (result, NULL, ic, TRUE); + if (pi) + pi->generated = 1; freeAsmop (right, NULL, ic, TRUE); + freeAsmop (result, NULL, ic, TRUE); } /*-----------------------------------------------------------------*/ @@ -10753,7 +10784,7 @@ genFarPointerSet (operand * right, sym_link *retype = getSpec (operandType (right)); sym_link *letype = getSpec (operandType (result)); - D(emitcode ("; genFarPointerSet","")); + D(emitcode (";", "genFarPointerSet")); aopOp (result, ic, FALSE); loadDptrFromOperand (result, FALSE); @@ -11702,7 +11733,7 @@ genCritical (iCode *ic) static void genEndCritical (iCode *ic) { - D(emitcode("; genEndCritical","")); + D(emitcode(";", "genEndCritical")); if (IC_RIGHT (ic)) { @@ -11767,7 +11798,7 @@ gen51Code (iCode * lic) debugFile->writeCLine (ic); } if (!options.noCcodeInAsm) { - emitcode ("", ";\t%s:%d: %s", ic->filename, ic->lineno, + emitcode (";", "%s:%d: %s", ic->filename, ic->lineno, printCLine(ic->filename, ic->lineno)); } cln = ic->lineno; @@ -11775,7 +11806,7 @@ gen51Code (iCode * lic) #if 0 if (ic->seqPoint && ic->seqPoint != cseq) { - emitcode ("", "; sequence point %d", ic->seqPoint); + emitcode (";", "sequence point %d", ic->seqPoint); cseq = ic->seqPoint; } #endif @@ -11800,7 +11831,7 @@ gen51Code (iCode * lic) #endif } iLine = printILine(ic); - emitcode("", "; [%s] ic:%d: %s", regsInUse, ic->seq, printILine(ic)); + emitcode(";", "[%s] ic:%d: %s", regsInUse, ic->seq, iLine); dbuf_free(iLine); } /* if the result is marked as