X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=0f3e0725ad90725de33233b577fb63f7942c93fb;hb=fd67da9d82f190df558abfb076460cf4f9bf1bc0;hp=6d1b6b8941b1ef3df76ca1a2fdbef432692d5a94;hpb=5176a0afa6144f13e53ef0731e8a631d966d1a3c;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index 6d1b6b89..0f3e0725 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -24,6 +24,7 @@ #include "common.h" #include "newalloc.h" +#include "math.h" /*-----------------------------------------------------------------*/ /* global variables */ @@ -41,12 +42,6 @@ int scopeLevel; symbol *returnLabel; /* function return label */ symbol *entryLabel; /* function entry label */ -#if defined(__BORLANDC__) || defined(_MSC_VER) -#define LONG_LONG __int64 -#else -#define LONG_LONG long long -#endif - /*-----------------------------------------------------------------*/ /* forward definition of some functions */ operand *geniCodeDivision (operand *, operand *); @@ -131,12 +126,29 @@ iCodeTable codeTable[] = pedantic>1: "char c=200" is not allowed (evaluates to -56) */ -void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) { - LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype); - char message[132]=""; +void checkConstantRange(sym_link *ltype, value *val, char *msg, + int pedantic) { + double max; int warnings=0; int negative=0; - long v=SPEC_CVAL(val->type).v_long; + long v; + + max = pow ((double)2.0, (double)bitsForType(ltype)); + + if (SPEC_LONG(val->type)) { + if (SPEC_USIGN(val->type)) { + v=SPEC_CVAL(val->type).v_ulong; + } else { + v=SPEC_CVAL(val->type).v_long; + } + } else { + if (SPEC_USIGN(val->type)) { + v=SPEC_CVAL(val->type).v_uint; + } else { + v=SPEC_CVAL(val->type).v_int; + } + } + #if 0 // this could be a good idea @@ -166,6 +178,7 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) { warnings++; } +#if 0 // temporary disabled, leaving the warning as a reminder if (warnings) { sprintf (message, "for %s %s in %s", SPEC_USIGN(ltype) ? "unsigned" : "signed", @@ -175,6 +188,7 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) { if (pedantic>1) fatalError++; } +#endif } /*-----------------------------------------------------------------*/ @@ -210,12 +224,14 @@ printOperand (operand * op, FILE * file) case SYMBOL: #define REGA 1 #ifdef REGA - fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */ + fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */ (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name), op->key, OP_LIVEFROM (op), OP_LIVETO (op), OP_SYMBOL (op)->stack, - op->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc + op->isaddr, OP_SYMBOL (op)->isreqv, + OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc, + OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr ); { fprintf (file, "{"); @@ -370,6 +386,9 @@ PRINTFUNC (picGenericOne) if (!IC_RESULT (ic) && !IC_LEFT (ic)) fprintf (of, s); + if (ic->op == SEND || ic->op == RECEIVE) { + fprintf(of,"{argreg = %d}",ic->argreg); + } fprintf (of, "\n"); } @@ -499,7 +518,7 @@ newOperand () { operand *op; - op = Safe_calloc (1, sizeof (operand)); + op = Safe_alloc ( sizeof (operand)); op->key = 0; return op; @@ -513,7 +532,7 @@ newiCode (int op, operand * left, operand * right) { iCode *ic; - ic = Safe_calloc (1, sizeof (iCode)); + ic = Safe_alloc ( sizeof (iCode)); ic->lineno = lineno; ic->filename = filename; @@ -537,7 +556,7 @@ newiCodeCondition (operand * condition, { iCode *ic; - if (IS_VOID(OP_SYMBOL(condition)->type)) { + if (IS_VOID(operandType(condition))) { werror(E_VOID_VALUE_USED); } @@ -671,7 +690,6 @@ copyiCode (iCode * ic) case PCALL: IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic)); IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic)); - IC_ARGS (nic) = IC_ARGS (ic); break; case INLINEASM: @@ -846,6 +864,7 @@ isOperandLiteral (operand * op) return 0; } + /*-----------------------------------------------------------------*/ /* isOperandInFarSpace - will return true if operand is in farSpace */ /*-----------------------------------------------------------------*/ @@ -874,6 +893,64 @@ isOperandInFarSpace (operand * op) return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE); } +/*------------------------------------------------------------------*/ +/* isOperandInDirSpace - will return true if operand is in dirSpace */ +/*------------------------------------------------------------------*/ +bool +isOperandInDirSpace (operand * op) +{ + sym_link *etype; + + if (!op) + return FALSE; + + if (!IS_SYMOP (op)) + return FALSE; + + if (!IS_TRUE_SYMOP (op)) + { + if (SPIL_LOC (op)) + etype = SPIL_LOC (op)->etype; + else + return FALSE; + } + else + { + etype = getSpec (operandType (op)); + } + return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE); +} + +/*--------------------------------------------------------------------*/ +/* isOperandInCodeSpace - will return true if operand is in codeSpace */ +/*--------------------------------------------------------------------*/ +bool +isOperandInCodeSpace (operand * op) +{ + sym_link *etype; + + if (!op) + return FALSE; + + if (!IS_SYMOP (op)) + return FALSE; + + etype = getSpec (operandType (op)); + + if (!IS_TRUE_SYMOP (op)) + { + if (SPIL_LOC (op)) + etype = SPIL_LOC (op)->etype; + else + return FALSE; + } + else + { + etype = getSpec (operandType (op)); + } + return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE); +} + /*-----------------------------------------------------------------*/ /* isOperandOnStack - will return true if operand is on stack */ /*-----------------------------------------------------------------*/ @@ -889,8 +966,12 @@ isOperandOnStack (operand * op) return FALSE; etype = getSpec (operandType (op)); + if (IN_STACK (etype) || + OP_SYMBOL(op)->onStack || + (SPIL_LOC(op) && SPIL_LOC(op)->onStack)) + return TRUE; - return ((IN_STACK (etype)) ? TRUE : FALSE); + return FALSE; } /*-----------------------------------------------------------------*/ @@ -904,6 +985,31 @@ operandLitValue (operand * op) return floatFromVal (op->operand.valOperand); } +/*-----------------------------------------------------------------*/ +/* getBuiltInParms - returns parameters to a builtin functions */ +/*-----------------------------------------------------------------*/ +iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms) +{ + sym_link *ftype; + + *pcount = 0; + /* builtin functions uses only SEND for parameters */ + while (ic->op != CALL) { + assert(ic->op == SEND && ic->builtinSEND); + ic->generated = 1; /* mark the icode as generated */ + parms[*pcount] = IC_LEFT(ic); + ic = ic->next; + (*pcount)++; + } + + ic->generated = 1; + /* make sure this is a builtin function call */ + assert(IS_SYMOP(IC_LEFT(ic))); + ftype = operandType(IC_LEFT(ic)); + assert(IFFUNC_ISBUILTIN(ftype)); + return ic; +} + /*-----------------------------------------------------------------*/ /* operandOperation - perforoms operations on operands */ /*-----------------------------------------------------------------*/ @@ -965,20 +1071,20 @@ operandOperation (operand * left, operand * right, break; case LEFT_OP: - retval = operandFromLit (((SPEC_USIGN(let) ? + retval = operandFromLit ((SPEC_USIGN(let) ? (unsigned long) operandLitValue (left) : (long) operandLitValue (left)) << (SPEC_USIGN(ret) ? (unsigned long) operandLitValue (right) : - (long) operandLitValue (right)))); + (long) operandLitValue (right))); break; case RIGHT_OP: - retval = operandFromLit (((SPEC_USIGN(let) ? + retval = operandFromLit ((SPEC_USIGN(let) ? (unsigned long) operandLitValue (left) : (long) operandLitValue (left)) >> (SPEC_USIGN(ret) ? (unsigned long) operandLitValue (right) : - (long) operandLitValue (right)))); + (long) operandLitValue (right))); break; case EQ_OP: retval = operandFromLit (operandLitValue (left) == @@ -1005,16 +1111,16 @@ operandOperation (operand * left, operand * right, operandLitValue (right)); break; case BITWISEAND: - retval = operandFromLit ((unsigned long) operandLitValue (left) & - (unsigned long) operandLitValue (right)); + retval = operandFromLit ((long)operandLitValue(left) & + (long)operandLitValue(right)); break; case '|': - retval = operandFromLit ((unsigned long) operandLitValue (left) | - (unsigned long) operandLitValue (right)); + retval = operandFromLit ((long)operandLitValue (left) | + (long)operandLitValue (right)); break; case '^': - retval = operandFromLit ((unsigned long) operandLitValue (left) ^ - (unsigned long) operandLitValue (right)); + retval = operandFromLit ((long)operandLitValue (left) ^ + (long)operandLitValue (right)); break; case AND_OP: retval = operandFromLit (operandLitValue (left) && @@ -1101,9 +1207,9 @@ isOperandEqual (operand * left, operand * right) return 0; } -/*-----------------------------------------------------------------*/ -/* isiCodeEqual - comapres two iCodes are returns true if yes */ -/*-----------------------------------------------------------------*/ +/*-------------------------------------------------------------------*/ +/* isiCodeEqual - compares two iCodes are equal, returns true if yes */ +/*-------------------------------------------------------------------*/ int isiCodeEqual (iCode * left, iCode * right) { @@ -1137,6 +1243,7 @@ isiCodeEqual (iCode * left, iCode * right) if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right))) return 0; } + return 1; } return 0; @@ -1253,7 +1360,6 @@ operandFromSymbol (symbol * sym) register equivalent for a local symbol */ if (sym->level && sym->etype && SPEC_OCLS (sym->etype) && (IN_FARSPACE (SPEC_OCLS (sym->etype)) && - /* (!TARGET_IS_DS390)) && */ (!(options.model == MODEL_FLAT24)) ) && options.stackAuto == 0) ok = 0; @@ -1263,7 +1369,7 @@ operandFromSymbol (symbol * sym) !sym->_isparm && /* not a parameter */ sym->level && /* is a local variable */ !sym->addrtaken && /* whose address has not been taken */ - !sym->reqv && /* does not already have a register euivalence */ + !sym->reqv && /* does not already have a reg equivalence */ !IS_VOLATILE (sym->etype) && /* not declared as volatile */ !IS_STATIC (sym->etype) && /* and not declared static */ !sym->islbl && /* not a label */ @@ -1279,6 +1385,7 @@ operandFromSymbol (symbol * sym) OP_SYMBOL (sym->reqv)->key = sym->key; OP_SYMBOL (sym->reqv)->isreqv = 1; OP_SYMBOL (sym->reqv)->islocal = 1; + OP_SYMBOL (sym->reqv)->onStack = sym->onStack; SPIL_LOC (sym->reqv) = sym; } @@ -1317,8 +1424,6 @@ operandFromSymbol (symbol * sym) else IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type)); - IC_RESULT (ic)->operand.symOperand->args = sym->args; - ADDTOCHAIN (ic); return IC_RESULT (ic); @@ -1559,10 +1664,6 @@ geniCodeRValue (operand * op, bool force) /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */ - /* if the right is a symbol */ - if (op->type == SYMBOL) - IC_RESULT (ic)->operand.symOperand->args = - op->operand.symOperand->args; ADDTOCHAIN (ic); return IC_RESULT (ic); @@ -1598,9 +1699,9 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) /* if casting to/from pointers, do some checking */ if (IS_PTR(type)) { // to a pointer - if (!IS_PTR(optype) && !IS_FUNC(optype)) { // from a non pointer + if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer if (IS_INTEGRAL(optype)) { - // maybe this is NULL, than it's ok. + // maybe this is NULL, than it's ok. if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) { if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) { // no way to set the storage @@ -1619,17 +1720,20 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) } else { // shouldn't do that with float, array or structure unless to void if (!IS_VOID(getSpec(type)) && - !(IS_CODEPTR(type) && IS_FUNC(optype))) { + !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { werror(E_INCOMPAT_TYPES); errors++; } } } else { // from a pointer to a pointer if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) { - if (implicit) { // if not to generic, they have to match - if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) { - werror(E_INCOMPAT_PTYPES); - errors++; + // if not a pointer to a function + if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { + if (implicit) { // if not to generic, they have to match + if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) { + werror(E_INCOMPAT_PTYPES); + errors++; + } } } } @@ -1648,13 +1752,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) } } if (errors) { - /* fprintf (stderr, "%s%s %d: ", op->operand.symOperand->name, - implicit?"(implicit)":"", errors); */ - fprintf (stderr, "from type '"); - printTypeChain (optype, stderr); - fprintf (stderr, "' to type '"); - printTypeChain (type, stderr); - fprintf (stderr, "'\n"); + printFromToType (optype, type); } /* if they are the same size create an assignment */ @@ -1683,7 +1781,8 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) /* preserve the storage class & output class */ /* of the original variable */ restype = getSpec (operandType (IC_RESULT (ic))); - SPEC_SCLS (restype) = SPEC_SCLS (opetype); + if (!IS_LITERAL(opetype)) + SPEC_SCLS (restype) = SPEC_SCLS (opetype); SPEC_OCLS (restype) = SPEC_OCLS (opetype); ADDTOCHAIN (ic); @@ -1922,7 +2021,7 @@ geniCodeSubtract (operand * left, operand * right) /* geniCodeAdd - generates iCode for addition */ /*-----------------------------------------------------------------*/ operand * -geniCodeAdd (operand * left, operand * right,int lvl) +geniCodeAdd (operand * left, operand * right, int lvl) { iCode *ic; sym_link *resType; @@ -1943,7 +2042,7 @@ geniCodeAdd (operand * left, operand * right,int lvl) if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype))) return right; - /* if left is an array or pointer then size */ + /* if left is a pointer then size */ if (IS_PTR (ltype)) { isarray = left->isaddr; @@ -1955,7 +2054,7 @@ geniCodeAdd (operand * left, operand * right,int lvl) resType = copyLinkChain (ltype); } else - { /* make them the same size */ + { // make them the same size resType = usualBinaryConversions (&left, &right); } @@ -2055,7 +2154,7 @@ geniCodeArray (operand * left, operand * right,int lvl) { left = geniCodeRValue (left, FALSE); } - return geniCodeDerefPtr (geniCodeAdd (left, right,lvl),lvl); + return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl); } right = geniCodeMultiply (right, @@ -2561,7 +2660,7 @@ geniCodeConditional (ast * tree,int lvl) true = ast2iCode (tree->right->left,lvl+1); /* move the value to a new Operand */ - result = newiTempOperand (operandType (true), 0); + result = newiTempOperand (tree->right->ftype, 0); geniCodeAssign (result, geniCodeRValue (true, FALSE), 0); /* generate an unconditional goto */ @@ -2610,7 +2709,7 @@ geniCodeAssign (operand * left, operand * right, int nosupdate) /* first check the type for pointer assignement */ if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) && - compareType (ltype, rtype) < 0) + compareType (ltype, rtype) <= 0) { if (compareType (ltype->next, rtype) < 0) right = geniCodeCast (ltype->next, right, TRUE); @@ -2676,30 +2775,37 @@ geniCodeSEParms (ast * parms,int lvl) IS_ADDRESS_OF_OP (parms->right)) parms->right->left->lvalue = 1; - parms->opval.oprnd = + parms->opval.oprnd = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE); - + parms->type = EX_OPERAND; + AST_ARGREG(parms) = SPEC_ARGREG(parms->etype); } /*-----------------------------------------------------------------*/ /* geniCodeParms - generates parameters */ /*-----------------------------------------------------------------*/ -static void -geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl) +value * +geniCodeParms (ast * parms, value *argVals, int *stack, + sym_link * fetype, symbol * func,int lvl) { iCode *ic; operand *pval; if (!parms) - return; + return argVals; + + if (argVals==NULL) { + // first argument + argVals=FUNC_ARGS(func->type); + } /* if this is a param node then do the left & right */ if (parms->type == EX_OP && parms->opval.op == PARAM) { - geniCodeParms (parms->left, stack, fetype, func,lvl); - geniCodeParms (parms->right, stack, fetype, func,lvl); - return; + argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl); + argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl); + return argVals; } /* get the parameter value */ @@ -2722,20 +2828,24 @@ geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl } /* if register parm then make it a send */ - if (((parms->argSym && IS_REGPARM (parms->argSym->etype)) || - IS_REGPARM (parms->etype)) && !func->hasVargs) + if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) || + IFFUNC_ISBUILTIN(func->type)) { ic = newiCode (SEND, pval, NULL); + ic->argreg = SPEC_ARGREG(parms->etype); + ic->builtinSEND = FUNC_ISBUILTIN(func->type); ADDTOCHAIN (ic); } else { /* now decide whether to push or assign */ - if (!(options.stackAuto || IS_RENT (fetype))) + if (!(options.stackAuto || IFFUNC_ISREENT (func->type))) { /* assign */ - operand *top = operandFromSymbol (parms->argSym); + operand *top = operandFromSymbol (argVals->sym); + /* clear useDef and other bitVectors */ + OP_USES (top) = OP_DEFS (top) = OP_SYMBOL(top)->clashes = NULL; geniCodeAssign (top, pval, 1); } else @@ -2750,6 +2860,8 @@ geniCodeParms (ast * parms, int *stack, sym_link * fetype, symbol * func,int lvl } } + argVals=argVals->next; + return argVals; } /*-----------------------------------------------------------------*/ @@ -2775,15 +2887,15 @@ geniCodeCall (operand * left, ast * parms,int lvl) geniCodeSEParms (parms,lvl); /* first the parameters */ - geniCodeParms (parms, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl); + geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl); /* now call : if symbol then pcall */ - if (IS_OP_POINTER (left) || IS_ITEMP(left)) + if (IS_OP_POINTER (left) || IS_ITEMP(left)) { ic = newiCode (PCALL, left, NULL); - else + } else { ic = newiCode (CALL, left, NULL); + } - IC_ARGS (ic) = left->operand.symOperand->args; type = copyLinkChain (operandType (left)->next); etype = getSpec (type); SPEC_EXTR (etype) = 0; @@ -2806,7 +2918,7 @@ geniCodeReceive (value * args) /* for all arguments that are passed in registers */ while (args) { - + int first = 1; if (IS_REGPARM (args->etype)) { operand *opr = operandFromValue (args); @@ -2837,8 +2949,12 @@ geniCodeReceive (value * args) } } - ic = newiCode (RECEIVE, NULL, NULL); - currFunc->recvSize = getSize (sym->etype); + ic = newiCode (RECEIVE, NULL, NULL); + ic->argreg = SPEC_ARGREG(args->etype); + if (first) { + currFunc->recvSize = getSize (sym->type); + first = 0; + } IC_RESULT (ic) = opr; ADDTOCHAIN (ic); } @@ -2875,10 +2991,7 @@ geniCodeFunctionBody (ast * tree,int lvl) /* create a proc icode */ ic = newiCode (FUNCTION, func, NULL); - /* if the function has parmas then */ - /* save the parameters information */ - ic->argLabel.args = tree->values.args; - ic->lineno = OP_SYMBOL (func)->lineDef; + lineno=ic->lineno = OP_SYMBOL (func)->lineDef; ADDTOCHAIN (ic); @@ -2939,14 +3052,14 @@ geniCodeIfx (ast * tree,int lvl) if (tree->trueLabel) geniCodeGoto (tree->trueLabel); else - assert (1); + assert (0); } else { if (tree->falseLabel) geniCodeGoto (tree->falseLabel); else - assert (1); + assert (0); } goto exit; } @@ -3163,7 +3276,7 @@ lvalItem; /*-----------------------------------------------------------------*/ void addLvaluereq(int lvl) { - lvalItem * lpItem = (lvalItem *)Safe_calloc (1, sizeof (lvalItem)); + lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem)); lpItem->req=1; lpItem->lvl=lvl; addSetHead(&lvaluereqSet,lpItem); @@ -3176,7 +3289,7 @@ void delLvaluereq() { lvalItem * lpItem; lpItem = getSet(&lvaluereqSet); - if(lpItem) free(lpItem); + if(lpItem) Safe_free(lpItem); } /*-----------------------------------------------------------------*/ /* clearLvaluereq - clear lvalreq flag */ @@ -3218,6 +3331,7 @@ ast2iCode (ast * tree,int lvl) operand *right = NULL; if (!tree) return NULL; + /* set the global variables for filename & line number */ if (tree->filename) filename = tree->filename;