X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=f4e50eba162c9333a736ee99c9196b129101bc24;hb=67613b6eceb41c8a242c2556a0f59311adb0b388;hp=34d5437540c6125cef986479e30be5e8d9f84e78;hpb=589a7d9c77e21f8425d4c96bdc8446c84df27dca;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 34d54375..f4e50eba 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -45,7 +45,6 @@ symbol *entryLabel; /* function entry label */ /*-----------------------------------------------------------------*/ /* forward definition of some functions */ -operand *geniCodeDivision (operand *, operand *); operand *geniCodeAssign (operand *, operand *, int); static operand *geniCodeArray (operand *, operand *,int); static operand *geniCodeArray2Ptr (operand *); @@ -1219,22 +1218,32 @@ operandOperation (operand * left, operand * right, (TYPE_UDWORD) operandLitValue (right)); break; case EQ_OP: - /* this op doesn't care about signedness */ - { - TYPE_UDWORD l, r; - - l = (TYPE_UDWORD) operandLitValue (left); - if (IS_CHAR(OP_VALUE(left)->type)) - l &= 0xff; - else if (!IS_LONG (OP_VALUE(left)->type)) - l &= 0xffff; - r = (TYPE_UDWORD) operandLitValue (right); - if (IS_CHAR(OP_VALUE(right)->type)) - r &= 0xff; - else if (!IS_LONG (OP_VALUE(right)->type)) - r &= 0xffff; - retval = operandFromLit (l == r); - } + if (IS_FLOAT (let) || + IS_FLOAT (ret)) + { + retval = operandFromLit (operandLitValue (left) == + operandLitValue (right)); + } + else + { + /* this op doesn't care about signedness */ + TYPE_UDWORD l, r; + + l = (TYPE_UDWORD) operandLitValue (left); + r = (TYPE_UDWORD) operandLitValue (right); + /* In order to correctly compare 'signed int' and 'unsigned int' it's + neccessary to strip them to 16 bit. + Literals are reduced to their cheapest type, therefore left and + right might have different types. It's neccessary to find a + common type: int (used for char too) or long */ + if (!IS_LONG (let) && + !IS_LONG (ret)) + { + r = (TYPE_UWORD) r; + l = (TYPE_UWORD) l; + } + retval = operandFromLit (l == r); + } break; case '<': retval = operandFromLit (operandLitValue (left) < @@ -1533,6 +1542,7 @@ operandFromSymbol (symbol * sym) and before liveRange calculation */ sym->reqv = newiTempOperand (sym->type, 0); sym->reqv->key = sym->key; + OP_SYMBOL (sym->reqv)->prereqv = sym; OP_SYMBOL (sym->reqv)->key = sym->key; OP_SYMBOL (sym->reqv)->isreqv = 1; OP_SYMBOL (sym->reqv)->islocal = 1; @@ -1692,10 +1702,11 @@ setOperandType (operand * op, sym_link * type) } } + /*-----------------------------------------------------------------*/ /* Get size in byte of ptr need to access an array */ /*-----------------------------------------------------------------*/ -int +static int getArraySizePtr (operand * op) { sym_link *ltype = operandType(op); @@ -1752,36 +1763,89 @@ usualUnaryConversions (operand * op) /*-----------------------------------------------------------------*/ /* perform "usual binary conversions" */ /*-----------------------------------------------------------------*/ + static sym_link * usualBinaryConversions (operand ** op1, operand ** op2, - bool promoteCharToInt, bool isMul) + RESULT_TYPE resultType, char op) { sym_link *ctype; sym_link *rtype = operandType (*op2); sym_link *ltype = operandType (*op1); - ctype = computeType (ltype, rtype, promoteCharToInt); +#define OLDONEBYTEOPS 1 - /* special for multiplication: - This if for 'mul a,b', which takes two chars and returns an int */ - if ( isMul - /* && promoteCharToInt superfluous, already handled by computeType() */ - && IS_INT (getSpec (ctype))) +#ifdef OLDONEBYTEOPS + bool oldOneByteOps = FALSE; + static bool saidHello = FALSE; + + if (strcmp (port->target, "pic14") == 0) + oldOneByteOps = TRUE; + if (getenv ("SDCC_NEWONEBYTEOPS")) { - sym_link *retype = getSpec (rtype); - sym_link *letype = getSpec (ltype); - - if ( IS_CHAR (letype) - && IS_CHAR (retype) - && IS_UNSIGNED (letype) - && IS_UNSIGNED (retype)) - { - return ctype; + if (!saidHello) + { + fprintf (stderr, "Override: oldOneByteOps = FALSE\n"); + saidHello = TRUE; } + oldOneByteOps = FALSE; + } + else if (getenv ("SDCC_OLDONEBYTEOPS")) + { + if (!saidHello) + { + fprintf (stderr, "Override: oldOneByteOps = TRUE\n"); + saidHello = TRUE; + } + oldOneByteOps = TRUE; + } + + + if ( oldOneByteOps + && ( (IS_CHAR (getSpec (ltype)) && !IS_UNSIGNED (getSpec (ltype))) + || (IS_CHAR (getSpec (rtype)) && !IS_UNSIGNED (getSpec (rtype))))) + /* one or two signed char operands: promote to int */ + resultType = RESULT_TYPE_INT; +#endif + + ctype = computeType (ltype, rtype, resultType, op); + +#ifdef OLDONEBYTEOPS + + if (oldOneByteOps) + { + if ( op == '*' + && IS_CHAR (getSpec (ltype)) && IS_UNSIGNED (getSpec (ltype)) + && IS_CHAR (getSpec (rtype)) && IS_UNSIGNED (getSpec (rtype))) + { + /* two unsigned char operands and Mult: no promotion */ + return ctype; + } + *op1 = geniCodeCast (ctype, *op1, TRUE); + *op2 = geniCodeCast (ctype, *op2, TRUE); + + return ctype; + } + +#endif + + switch (op) + { + case '*': + case '/': + case '%': + if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype))) + { + /* one byte operations: keep signedness for code generator */ + return ctype; + } + break; + default: + break; } + *op1 = geniCodeCast (ctype, *op1, TRUE); *op2 = geniCodeCast (ctype, *op2, TRUE); - + return ctype; } @@ -2005,8 +2069,8 @@ geniCodeGoto (symbol * label) /*-----------------------------------------------------------------*/ /* geniCodeMultiply - gen intermediate code for multiplication */ /*-----------------------------------------------------------------*/ -operand * -geniCodeMultiply (operand * left, operand * right, int resultIsInt) +static operand * +geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; int p2 = 0; @@ -2022,7 +2086,7 @@ geniCodeMultiply (operand * left, operand * right, int resultIsInt) p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand)); } - resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE); + resType = usualBinaryConversions (&left, &right, resultType, '*'); #if 1 rtype = operandType (right); retype = getSpec (rtype); @@ -2035,11 +2099,13 @@ geniCodeMultiply (operand * left, operand * right, int resultIsInt) /* code generated for 1 byte * 1 byte literal = 2 bytes result is more efficient in most cases than 2 bytes result = 2 bytes << literal if port has 1 byte muldiv */ - if (p2 && !IS_FLOAT (letype) && - !((resultIsInt) && (getSize (resType) != getSize (ltype)) && - (port->support.muldiv == 1))) + if (p2 && !IS_FLOAT (letype) + && !((resultType != RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)) + && (port->support.muldiv == 1)) + && strcmp (port->target, "pic14") != 0 /* don't shift for pic */ + && strcmp (port->target, "pic16") != 0) { - if ((resultIsInt) && (getSize (resType) != getSize (ltype))) + if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))) { /* LEFT_OP need same size for left and result, */ left = geniCodeCast (resType, left, TRUE); @@ -2064,8 +2130,8 @@ geniCodeMultiply (operand * left, operand * right, int resultIsInt) /*-----------------------------------------------------------------*/ /* geniCodeDivision - gen intermediate code for division */ /*-----------------------------------------------------------------*/ -operand * -geniCodeDivision (operand * left, operand * right) +static operand * +geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; int p2 = 0; @@ -2075,9 +2141,7 @@ geniCodeDivision (operand * left, operand * right) sym_link *ltype = operandType (left); sym_link *letype = getSpec (ltype); - resType = usualBinaryConversions (&left, &right, - (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE, - FALSE); + resType = usualBinaryConversions (&left, &right, resultType, '/'); /* if the right is a literal & power of 2 and left is unsigned then make it a @@ -2104,8 +2168,8 @@ geniCodeDivision (operand * left, operand * right) /*-----------------------------------------------------------------*/ /* geniCodeModulus - gen intermediate code for modulus */ /*-----------------------------------------------------------------*/ -operand * -geniCodeModulus (operand * left, operand * right) +static operand * +geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; sym_link *resType; @@ -2116,9 +2180,7 @@ geniCodeModulus (operand * left, operand * right) return operandFromValue (valMod (left->operand.valOperand, right->operand.valOperand)); - resType = usualBinaryConversions (&left, &right, - (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE, - FALSE); + resType = usualBinaryConversions (&left, &right, resultType, '%'); /* now they are the same size */ ic = newiCode ('%', left, right); @@ -2162,14 +2224,15 @@ subtractExit: // should we really do this? is this ANSI? return geniCodeDivision (result, - operandFromLit (getSize (ltype->next))); + operandFromLit (getSize (ltype->next)), + FALSE); } /*-----------------------------------------------------------------*/ /* geniCodeSubtract - generates code for subtraction */ /*-----------------------------------------------------------------*/ -operand * -geniCodeSubtract (operand * left, operand * right) +static operand * +geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType) { iCode *ic; int isarray = 0; @@ -2192,12 +2255,15 @@ geniCodeSubtract (operand * left, operand * right) { isarray = left->isaddr; right = geniCodeMultiply (right, - operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE)); + operandFromLit (getSize (ltype->next)), + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR); resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype); } else { /* make them the same size */ - resType = usualBinaryConversions (&left, &right, FALSE, FALSE); + resType = usualBinaryConversions (&left, &right, resultType, '-'); } ic = newiCode ('-', left, right); @@ -2216,8 +2282,8 @@ geniCodeSubtract (operand * left, operand * right) /*-----------------------------------------------------------------*/ /* geniCodeAdd - generates iCode for addition */ /*-----------------------------------------------------------------*/ -operand * -geniCodeAdd (operand * left, operand * right, int lvl) +static operand * +geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl) { iCode *ic; sym_link *resType; @@ -2245,7 +2311,11 @@ geniCodeAdd (operand * left, operand * right, int lvl) size = operandFromLit (getSize (ltype->next)); SPEC_USIGN (getSpec (operandType (size))) = 1; indexUnsigned = IS_UNSIGNED (getSpec (operandType (right))); - right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE)); + right = geniCodeMultiply (right, + size, + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR); /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules. It doesn't make sense when accessing arrays, so let's fix it here: */ @@ -2256,7 +2326,7 @@ geniCodeAdd (operand * left, operand * right, int lvl) } else { // make them the same size - resType = usualBinaryConversions (&left, &right, FALSE, FALSE); + resType = usualBinaryConversions (&left, &right, resultType, '+'); } /* if they are both literals then we know */ @@ -2338,12 +2408,22 @@ geniCodeArray (operand * left, operand * right, int lvl) left = geniCodeRValue (left, FALSE); } - return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl); + return geniCodeDerefPtr (geniCodeAdd (left, + right, + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR, + lvl), + lvl); } size = operandFromLit (getSize (ltype->next)); SPEC_USIGN (getSpec (operandType (size))) = 1; indexUnsigned = IS_UNSIGNED (getSpec (operandType (right))); - right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE)); + right = geniCodeMultiply (right, + size, + (getArraySizePtr(left) >= INTSIZE) ? + RESULT_TYPE_INT : + RESULT_TYPE_CHAR); /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules. It doesn't make sense when accessing arrays, so let's fix it here: */ if (indexUnsigned) @@ -2846,7 +2926,7 @@ geniCodeLogic (operand * left, operand * right, int op) } } - ctype = usualBinaryConversions (&left, &right, FALSE, FALSE); + ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, ' '); ic = newiCode (op, left, right); IC_RESULT (ic) = newiTempOperand (newCharLink (), 1); @@ -3435,7 +3515,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) /* if the min is not zero then we no make it zero */ if (min) { - cond = geniCodeSubtract (cond, operandFromLit (min)); + cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR); if (!IS_LITERAL(getSpec(operandType(cond)))) setOperandType (cond, UCHARTYPE); } @@ -3802,29 +3882,35 @@ ast2iCode (ast * tree,int lvl) case '/': return geniCodeDivision (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); case '%': return geniCodeModulus (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); case '*': if (right) return geniCodeMultiply (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE),IS_INT(tree->ftype)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); else return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl); case '-': if (right) return geniCodeSubtract (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE)); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)); else return geniCodeUnaryMinus (geniCodeRValue (left, FALSE)); case '+': if (right) return geniCodeAdd (geniCodeRValue (left, FALSE), - geniCodeRValue (right, FALSE),lvl); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype), + lvl); else return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */ @@ -3915,20 +4001,25 @@ ast2iCode (ast * tree,int lvl) geniCodeAssign (left, geniCodeMultiply (geniCodeRValue (operandFromOperand (left), FALSE), - geniCodeRValue (right, FALSE),FALSE), 0); + geniCodeRValue (right, FALSE), FALSE), + getResultTypeFromType (tree->ftype)); case DIV_ASSIGN: return geniCodeAssign (left, geniCodeDivision (geniCodeRValue (operandFromOperand (left), FALSE), - geniCodeRValue (right, FALSE)), 0); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)), + 0); case MOD_ASSIGN: return geniCodeAssign (left, geniCodeModulus (geniCodeRValue (operandFromOperand (left), FALSE), - geniCodeRValue (right, FALSE)), 0); + geniCodeRValue (right, FALSE), + getResultTypeFromType (tree->ftype)), + 0); case ADD_ASSIGN: { sym_link *rtype = operandType (right); @@ -3943,7 +4034,10 @@ ast2iCode (ast * tree,int lvl) return geniCodeAssign (left, geniCodeAdd (geniCodeRValue (operandFromOperand (left), FALSE), - right,lvl), 0); + right, + getResultTypeFromType (tree->ftype), + lvl), + 0); } case SUB_ASSIGN: { @@ -3962,7 +4056,9 @@ ast2iCode (ast * tree,int lvl) geniCodeAssign (left, geniCodeSubtract (geniCodeRValue (operandFromOperand (left), FALSE), - right), 0); + right, + getResultTypeFromType (tree->ftype)), + 0); } case LEFT_ASSIGN: return