X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fmcs51%2Fgen.c;h=649c643e5ea6f50e6b464777b546b4369137ce52;hb=67da89445478477cbda97171c16f8cc2666ce240;hp=34c178c00454d23ecfe80712a442eb4c09829d61;hpb=9998aea306b1018e7c6880e990b3d723f716a021;p=fw%2Fsdcc diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index 34c178c0..649c643e 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -3192,8 +3192,10 @@ static void genPlus (iCode * ic) { int size, offset = 0; - char *add; + int skip_bytes = 0; + char *add = "add"; asmop *leftOp, *rightOp; + operand * op; /* special cases :- */ @@ -3255,33 +3257,92 @@ genPlus (iCode * ic) goto release; size = getDataSize (IC_RESULT (ic)); - leftOp = AOP(IC_LEFT(ic)); rightOp = AOP(IC_RIGHT(ic)); - add = "add"; + op=IC_LEFT(ic); + + /* if this is an add for an array access + at a 256 byte boundary */ + if ( 2 == size + && AOP_TYPE (op) == AOP_IMMD + && IS_SYMOP (op) + && IS_SPEC (OP_SYM_ETYPE (op)) + && SPEC_ABSA (OP_SYM_ETYPE (op)) + && (SPEC_ADDR (OP_SYM_ETYPE (op)) & 0xff) == 0 + ) + { + D(emitcode ("; genPlus aligned array","")); + aopPut (AOP (IC_RESULT (ic)), + aopGet (rightOp, 0, FALSE, FALSE), + 0, + isOperandVolatile (IC_RESULT (ic), FALSE)); - while (size--) - { - if (aopGetUsesAcc (leftOp, offset) && aopGetUsesAcc (rightOp, offset)) + if( 1 == getDataSize (IC_RIGHT (ic)) ) { - emitcode("mov", "b,a"); - MOVA (aopGet (leftOp, offset, FALSE, TRUE)); - emitcode("xch", "a,b"); - MOVA (aopGet (rightOp, offset, FALSE, TRUE)); - emitcode (add, "a,b"); + aopPut (AOP (IC_RESULT (ic)), + aopGet (leftOp, 1, FALSE, FALSE), + 1, + isOperandVolatile (IC_RESULT (ic), FALSE)); } - else if (aopGetUsesAcc (leftOp, offset)) - { - MOVA (aopGet (leftOp, offset, FALSE, TRUE)); - emitcode (add, "a,%s", aopGet (rightOp, offset, FALSE, TRUE)); + else + { + MOVA (aopGet (AOP (IC_LEFT (ic)), 1, FALSE, FALSE)); + emitcode ("add", "a,%s", aopGet (rightOp, 1, FALSE, FALSE)); + aopPut (AOP (IC_RESULT (ic)), "a", 1, isOperandVolatile (IC_RESULT (ic), FALSE)); } + goto release; + } + + /* if the lower bytes of a literal are zero skip the addition */ + if (AOP_TYPE (IC_RIGHT (ic)) == AOP_LIT ) + { + while ((0 == ((unsigned int) floatFromVal (AOP (IC_RIGHT (ic))->aopu.aop_lit) & (0xff << skip_bytes*8))) && + (skip_bytes+1 < size)) + { + skip_bytes++; + } + if (skip_bytes) + D(emitcode ("; genPlus shortcut","")); + } + + while (size--) + { + if( offset >= skip_bytes ) + { + if (aopGetUsesAcc (leftOp, offset) && aopGetUsesAcc (rightOp, offset)) + { + emitcode("mov", "b,a"); + MOVA (aopGet (leftOp, offset, FALSE, TRUE)); + emitcode("xch", "a,b"); + MOVA (aopGet (rightOp, offset, FALSE, TRUE)); + emitcode (add, "a,b"); + } + else if (aopGetUsesAcc (leftOp, offset)) + { + MOVA (aopGet (leftOp, offset, FALSE, TRUE)); + emitcode (add, "a,%s", aopGet (rightOp, offset, FALSE, TRUE)); + } + else + { + MOVA (aopGet (rightOp, offset, FALSE, TRUE)); + emitcode (add, "a,%s", aopGet (leftOp, offset, FALSE, TRUE)); + } + aopPut (AOP (IC_RESULT (ic)), "a", offset, isOperandVolatile (IC_RESULT (ic), FALSE)); + add = "addc"; /* further adds must propagate carry */ + } else - { - MOVA (aopGet (rightOp, offset, FALSE, TRUE)); - emitcode (add, "a,%s", aopGet (leftOp, offset, FALSE, TRUE)); + { + if( !sameRegs (AOP (IC_LEFT (ic)), AOP (IC_RESULT (ic))) || + isOperandVolatile (IC_RESULT (ic), FALSE)) + { + /* just move */ + aopPut (AOP (IC_RESULT (ic)), + aopGet (leftOp, offset, FALSE, FALSE), + offset, + isOperandVolatile (IC_RESULT (ic), FALSE)); + } } - aopPut (AOP (IC_RESULT (ic)), "a", offset++, isOperandVolatile (IC_RESULT (ic), FALSE)); - add = "addc"; /* further adds must propagate carry */ + offset++; } adjustArithmeticResult (ic); @@ -3614,8 +3675,16 @@ genMultOneByte (operand * left, // just an unsigned 8*8=8/16 multiply //emitcode (";","unsigned"); // TODO: check for accumulator clash between left & right aops? - emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); - MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); + + if( AOP_TYPE(right)==AOP_LIT ){ + // moving to accumulator first helps peepholes + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); + emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); + } else { + emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); + } + emitcode ("mul", "ab"); aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE)); if (size==2) { @@ -4263,12 +4332,14 @@ gencjneshort (operand * left, operand * right, symbol * lbl) if the right is in a pointer register and left is not */ if ((AOP_TYPE (left) == AOP_LIT) || + (AOP_TYPE (left) == AOP_IMMD) || (IS_AOP_PREG (right) && !IS_AOP_PREG (left))) { operand *t = right; right = left; left = t; } + if (AOP_TYPE (right) == AOP_LIT) lit = (unsigned long) floatFromVal (AOP (right)->aopu.aop_lit); @@ -4292,6 +4363,7 @@ gencjneshort (operand * left, operand * right, symbol * lbl) else if (AOP_TYPE (right) == AOP_REG || AOP_TYPE (right) == AOP_DIR || AOP_TYPE (right) == AOP_LIT || + AOP_TYPE (right) == AOP_IMMD || (AOP_TYPE (left) == AOP_DIR && AOP_TYPE (right) == AOP_LIT) || (IS_AOP_PREG (left) && !IS_AOP_PREG (right))) { @@ -4891,6 +4963,8 @@ genAnd (iCode * ic, iCode * ifx) { if (ifx) jmpTrueOrFalse (ifx, tlbl); + else + emitcode ("", "%05d$:", tlbl->key + 100); goto release; } } @@ -4981,6 +5055,8 @@ genAnd (iCode * ic, iCode * ifx) } else if (ifx) jmpTrueOrFalse (ifx, tlbl); + else + emitcode ("", "%05d$:", tlbl->key + 100); } else { @@ -5267,6 +5343,8 @@ genOr (iCode * ic, iCode * ifx) } else if (ifx) jmpTrueOrFalse (ifx, tlbl); + else + emitcode ("", "%05d$:", tlbl->key + 100); } else for (; (size--); offset++) @@ -5748,6 +5826,66 @@ genGetHbit (iCode * ic) freeAsmop (result, NULL, ic, TRUE); } +/*-----------------------------------------------------------------*/ +/* genSwap - generates code to swap nibbles or bytes */ +/*-----------------------------------------------------------------*/ +static void +genSwap (iCode * ic) +{ + operand *left, *result; + + D(emitcode ("; genSwap","")); + + left = IC_LEFT (ic); + result = IC_RESULT (ic); + aopOp (left, ic, FALSE); + aopOp (result, ic, FALSE); + + switch (AOP_SIZE (left)) + { + case 1: /* swap nibbles in byte */ + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); + emitcode ("swap", "a"); + aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE)); + break; + case 2: /* swap bytes in word */ + if (AOP_TYPE(left) == AOP_REG && sameRegs(AOP(left), AOP(result))) + { + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); + aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE), + 0, isOperandVolatile (result, FALSE)); + aopPut (AOP (result), "a", 1, isOperandVolatile (result, FALSE)); + } + else if (operandsEqu (left, result)) + { + char * reg = "a"; + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); + if (aopGetUsesAcc(AOP (left), 1) || aopGetUsesAcc(AOP (result), 0)) + { + emitcode ("mov", "b,a"); + reg = "b"; + } + aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE), + 0, isOperandVolatile (result, FALSE)); + aopPut (AOP (result), reg, 1, isOperandVolatile (result, FALSE)); + } + else + { + aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE), + 0, isOperandVolatile (result, FALSE)); + aopPut (AOP (result), aopGet (AOP (left), 0, FALSE, FALSE), + 1, isOperandVolatile (result, FALSE)); + } + break; + default: + wassertl(FALSE, "unsupported SWAP operand size"); + } + + freeAsmop (left, NULL, ic, TRUE); + freeAsmop (result, NULL, ic, TRUE); +} + + /*-----------------------------------------------------------------*/ /* AccRol - rotate left accumulator by known count */ /*-----------------------------------------------------------------*/ @@ -7060,7 +7198,7 @@ static void genRightShift (iCode * ic) { operand *right, *left, *result; - sym_link *retype; + sym_link *letype; int size, offset; char *l; symbol *tlbl, *tlbl1; @@ -7069,9 +7207,9 @@ genRightShift (iCode * ic) /* if signed then we do it the hard way preserve the sign bit moving it inwards */ - retype = getSpec (operandType (IC_RESULT (ic))); + letype = getSpec (operandType (IC_LEFT (ic))); - if (!SPEC_USIGN (retype)) + if (!SPEC_USIGN (letype)) { genSignedRightShift (ic); return; @@ -8977,34 +9115,58 @@ genReceive (iCode * ic) static void genDummyRead (iCode * ic) { - operand *right; + operand *op; int size, offset; D(emitcode("; genDummyRead","")); - right = IC_RIGHT (ic); + op = IC_RIGHT (ic); + if (op && IS_SYMOP (op)) + { + aopOp (op, ic, FALSE); - aopOp (right, ic, FALSE); + /* if the result is a bit */ + if (AOP_TYPE (op) == AOP_CRY) + emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir); + else + { + /* bit variables done */ + /* general case */ + size = AOP_SIZE (op); + offset = 0; + while (size--) + { + MOVA (aopGet (AOP (op), offset, FALSE, FALSE)); + offset++; + } + } - /* if the result is a bit */ - if (AOP_TYPE (right) == AOP_CRY) - { - emitcode ("mov", "c,%s", AOP (right)->aopu.aop_dir); - goto release; + freeAsmop (op, NULL, ic, TRUE); } - /* bit variables done */ - /* general case */ - size = AOP_SIZE (right); - offset = 0; - while (size--) + op = IC_LEFT (ic); + if (op && IS_SYMOP (op)) { - MOVA (aopGet (AOP (right), offset, FALSE, FALSE)); - offset++; - } + aopOp (op, ic, FALSE); -release: - freeAsmop (right, NULL, ic, TRUE); + /* if the result is a bit */ + if (AOP_TYPE (op) == AOP_CRY) + emitcode ("mov", "c,%s", AOP (op)->aopu.aop_dir); + else + { + /* bit variables done */ + /* general case */ + size = AOP_SIZE (op); + offset = 0; + while (size--) + { + MOVA (aopGet (AOP (op), offset, FALSE, FALSE)); + offset++; + } + } + + freeAsmop (op, NULL, ic, TRUE); + } } /*-----------------------------------------------------------------*/ @@ -9332,6 +9494,10 @@ gen51Code (iCode * lic) genEndCritical (ic); break; + case SWAP: + genSwap (ic); + break; + default: ic = ic; }