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 *);
operand *geniCodeArray2Ptr (operand *);
operand *geniCodeRValue (operand *, bool);
operand *geniCodeDerefPtr (operand *,int);
+int isLvaluereq(int lvl);
#define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
/* forward definition of ic print functions */
{IFX, "if", picIfx, NULL},
{INLINEASM, "", picInline, NULL},
{RECEIVE, "recv", picReceive, NULL},
- {SEND, "send", picGenericOne, NULL}
+ {SEND, "send", picGenericOne, NULL},
+ {ARRAYINIT, "arrayInit", picGenericOne, NULL},
};
+/*-----------------------------------------------------------------*/
+/* checkConstantRange: check a constant against the type */
+/*-----------------------------------------------------------------*/
+
+/* pedantic=0: allmost anything is allowed as long as the absolute
+ value is within the bit range of the type, and -1 is treated as
+ 0xf..f for unsigned types (e.g. in assign)
+ pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
+ 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]="";
+ int warnings=0;
+ int negative=0;
+ long v;
+
+ if (SPEC_LONG(val->type)) {
+ v=SPEC_CVAL(val->type).v_long;
+ } else {
+ v=SPEC_CVAL(val->type).v_int;
+ }
+
+
+#if 0
+ // this could be a good idea
+ if (options.pedantic)
+ pedantic=2;
+#endif
+
+ if (SPEC_NOUN(ltype)==FLOAT) {
+ // anything will do
+ return;
+ }
+
+ if (!SPEC_USIGN(val->type) && v<0) {
+ negative=1;
+ if (SPEC_USIGN(ltype) && (pedantic>1)) {
+ warnings++;
+ }
+ v=-v;
+ }
+
+ // if very pedantic: "char c=200" is not allowed
+ if (pedantic>1 && !SPEC_USIGN(ltype)) {
+ max = max/2 + negative;
+ }
+
+ if (v >= max) {
+ warnings++;
+ }
+
+ if (warnings) {
+ sprintf (message, "for %s %s in %s",
+ SPEC_USIGN(ltype) ? "unsigned" : "signed",
+ nounName(ltype), msg);
+ werror (W_CONST_RANGE, message);
+
+ if (pedantic>1)
+ fatalError++;
+ }
+}
/*-----------------------------------------------------------------*/
/* operandName - returns the name of the operand */
case SYMBOL:
#define REGA 1
#ifdef REGA
- fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%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}", /*{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->isaddr, OP_SYMBOL (op)->isreqv, OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc
);
{
fprintf (file, "{");
{
operand *op;
- op = Safe_calloc (1, sizeof (operand));
+ op = Safe_alloc ( sizeof (operand));
op->key = 0;
return op;
{
iCode *ic;
- ic = Safe_calloc (1, sizeof (iCode));
+ ic = Safe_alloc ( sizeof (iCode));
ic->lineno = lineno;
ic->filename = filename;
{
iCode *ic;
+ if (IS_VOID(OP_SYMBOL(condition)->type)) {
+ werror(E_VOID_VALUE_USED);
+ }
+
ic = newiCode (IFX, NULL, NULL);
IC_COND (ic) = condition;
IC_TRUE (ic) = trueLabel;
itmplbl->isitmp = 1;
itmplbl->islbl = 1;
itmplbl->key = labelKey++;
- addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
+ addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
return itmplbl;
}
itmplbl->isitmp = 1;
itmplbl->islbl = 1;
itmplbl->key = labelKey++;
- addSym (LabelTab, itmplbl, itmplbl->name, 0, 0);
+ addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
return itmplbl;
}
IC_INLINE (nic) = IC_INLINE (ic);
break;
+ case ARRAYINIT:
+ IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
+ break;
+
default:
IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
operandOperation (operand * left, operand * right,
int op, sym_link * type)
{
+ sym_link *let , *ret=NULL;
operand *retval = (operand *) 0;
-
+
assert (isOperandLiteral (left));
- if (right)
+ let = getSpec(operandType(left));
+ if (right) {
assert (isOperandLiteral (right));
+ ret = getSpec(operandType(left));
+ }
switch (op)
{
operandLitValue (right)));
break;
case '%':
- if ((unsigned long) operandLitValue (right) == 0)
- {
+ if ((unsigned long) operandLitValue (right) == 0) {
werror (E_DIVIDE_BY_ZERO);
retval = right;
- }
- else
- retval = operandFromLit ((unsigned long) operandLitValue (left) %
- (unsigned long) operandLitValue (right));
+ }
+ else
+ retval = operandFromLit ((SPEC_USIGN(let) ?
+ (unsigned long) operandLitValue (left) :
+ (long) operandLitValue (left)) %
+ (SPEC_USIGN(ret) ?
+ (unsigned long) operandLitValue (right) :
+ (long) operandLitValue (right)));
+
break;
case LEFT_OP:
- retval = operandFromLit ((unsigned long) operandLitValue (left) <<
- (unsigned long) operandLitValue (right));
+ retval = operandFromLit ((SPEC_USIGN(let) ?
+ (unsigned long) operandLitValue (left) :
+ (long) operandLitValue (left)) <<
+ (SPEC_USIGN(ret) ?
+ (unsigned long) operandLitValue (right) :
+ (long) operandLitValue (right)));
break;
case RIGHT_OP:
- retval = operandFromLit ((unsigned long) operandLitValue (left) >>
- (unsigned long) operandLitValue (right));
+ retval = operandFromLit ((SPEC_USIGN(let) ?
+ (unsigned long) operandLitValue (left) :
+ (long) operandLitValue (left)) >>
+ (SPEC_USIGN(ret) ?
+ (unsigned long) operandLitValue (right) :
+ (long) operandLitValue (right)));
break;
case EQ_OP:
retval = operandFromLit (operandLitValue (left) ==
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) &&
break;
case RRC:
{
- long i = operandLitValue (left);
+ long i = (long) operandLitValue (left);
retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
(i << 1));
break;
case RLC:
{
- long i = operandLitValue (left);
+ long i = (long) operandLitValue (left);
retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
(i >> 1));
return (floatFromVal (left->operand.valOperand) ==
floatFromVal (right->operand.valOperand));
case TYPE:
- if (checkType (left->operand.typeOperand,
+ if (compareType (left->operand.typeOperand,
right->operand.typeOperand) == 1)
return 1;
}
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)
{
if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
return 0;
}
+
return 1;
}
return 0;
nop->isvolatile = op->isvolatile;
nop->isGlobal = op->isGlobal;
nop->isLiteral = op->isLiteral;
- nop->noSpilLoc = op->noSpilLoc;
nop->usesDefs = op->usesDefs;
nop->isParm = op->isParm;
return nop;
nop->isvolatile = op->isvolatile;
nop->isGlobal = op->isGlobal;
nop->isLiteral = op->isLiteral;
- nop->noSpilLoc = op->noSpilLoc;
nop->usesDefs = op->usesDefs;
nop->isParm = op->isParm;
/* under the following conditions create a
register equivalent for a local symbol */
if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
- (IN_FARSPACE (SPEC_OCLS (sym->etype)) && (!TARGET_IS_DS390)) &&
+ (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
+ /* (!TARGET_IS_DS390)) && */
+ (!(options.model == MODEL_FLAT24)) ) &&
options.stackAuto == 0)
ok = 0;
/* operandFromLit - makes an operand from a literal value */
/*-----------------------------------------------------------------*/
operand *
-operandFromLit (float i)
+operandFromLit (double i)
{
return operandFromValue (valueFromLit (i));
}
{
if (IS_INTEGRAL (operandType (op)))
{
- if (getSize (operandType (op)) < INTSIZE)
+ if (getSize (operandType (op)) < (unsigned int) INTSIZE)
{
/* Widen to int. */
return geniCodeCast (INTTYPE, op, TRUE);
if (IS_SPEC (type) &&
IS_TRUE_SYMOP (op) &&
- (!IN_FARSPACE (SPEC_OCLS (etype)) || TARGET_IS_DS390))
+ (!IN_FARSPACE (SPEC_OCLS (etype)) ||
+ /* TARGET_IS_DS390)) */
+ (options.model == MODEL_FLAT24) ))
{
op = operandFromOperand (op);
op->isaddr = 0;
sym_link *optype;
sym_link *opetype = getSpec (optype = operandType (op));
sym_link *restype;
+ int errors=0;
/* one of them has size zero then error */
if (IS_VOID (optype))
}
/* if the operand is already the desired type then do nothing */
- if (checkType (type, optype) == 1)
+ if (compareType (type, optype) == 1)
return op;
/* if this is a literal then just change the type & return */
return operandFromValue (valCastLiteral (type,
operandLitValue (op)));
- /* if casting to some pointer type &&
- the destination is not a generic pointer
- then give a warning : (only for implicit casts) */
- if (IS_PTR (optype) && implicit &&
- (DCL_TYPE (optype) != DCL_TYPE (type)) &&
- !IS_GENPTR (type))
- {
- werror (E_INCOMPAT_CAST);
- werror (E_CONTINUE, "from type '");
- printTypeChain (optype, stderr);
- fprintf (stderr, "' to type '");
- printTypeChain (type, stderr);
- fprintf (stderr, "'\n");
+ /* if casting to/from pointers, do some checking */
+ if (IS_PTR(type)) { // to a 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.
+ 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
+ if (IS_LITERAL(optype)) {
+ werror(E_LITERAL_GENERIC);
+ errors++;
+ } else {
+ werror(E_NONPTR2_GENPTR);
+ errors++;
+ }
+ } else if (implicit) {
+ werror(W_INTEGRAL2PTR_NOCAST);
+ errors++;
+ }
+ }
+ } else {
+ // shouldn't do that with float, array or structure unless to void
+ if (!IS_VOID(getSpec(type)) &&
+ !(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 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++;
+ }
+ }
+ }
+ }
+ }
+ } else { // to a non pointer
+ if (IS_PTR(optype)) { // from a pointer
+ if (implicit) { // sneaky
+ if (IS_INTEGRAL(type)) {
+ werror(W_PTR2INTEGRAL_NOCAST);
+ errors++;
+ } else { // shouldn't do that with float, array or structure
+ werror(E_INCOMPAT_TYPES);
+ errors++;
+ }
+ }
}
+ }
+ 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");
+ }
/* if they are the same size create an assignment */
if (getSize (type) == getSize (optype) &&
if (resultIsInt)
{
SPEC_NOUN(getSpec(resType))=V_INT;
- SPEC_SHORT(getSpec(resType))=0;
}
/* if the right is a literal & power of 2 */
if port has 1 byte muldiv */
if (p2 && !IS_FLOAT (letype) &&
!((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
- (port->muldiv.native_below == 1)))
+ (port->support.muldiv == 1)))
{
if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
{
if (IS_LITERAL (retype) &&
!IS_FLOAT (letype) &&
(p2 = powof2 ((unsigned long)
- floatFromVal (right->operand.valOperand))))
- ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
+ floatFromVal (right->operand.valOperand)))) {
+ ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
+ }
else
{
ic = newiCode ('/', left, right); /* normal division */
}
rOp = newiTempOperand (rvtype, 0);
- rOp->noSpilLoc = 1;
+ OP_SYMBOL(rOp)->noSpilLoc = 1;
if (IS_ITEMP (rv))
- rv->noSpilLoc = 1;
+ OP_SYMBOL(rv)->noSpilLoc = 1;
geniCodeAssign (rOp, rv, 0);
/* if this is not an address we have trouble */
if (!op->isaddr)
{
- werror (E_LVALUE_REQUIRED, "++");
+ werror (E_LVALUE_REQUIRED, "--");
return op;
}
rOp = newiTempOperand (rvtype, 0);
- rOp->noSpilLoc = 1;
+ OP_SYMBOL(rOp)->noSpilLoc = 1;
if (IS_ITEMP (rv))
- rv->noSpilLoc = 1;
+ OP_SYMBOL(rv)->noSpilLoc = 1;
geniCodeAssign (rOp, rv, 0);
if (!op->isaddr)
{
- werror (E_LVALUE_REQUIRED, "++");
+ werror (E_LVALUE_REQUIRED, "--");
return op;
}
return IC_RESULT (ic);
}
-#if defined(__BORLANDC__) || defined(_MSC_VER)
-#define LONG_LONG __int64
-#else
-#define LONG_LONG long long
-#endif
-
/*-----------------------------------------------------------------*/
/* geniCodeLogic- logic code */
/*-----------------------------------------------------------------*/
/* left is integral type and right is literal then
check if the literal value is within bounds */
- if (IS_INTEGRAL (ltype) && IS_LITERAL (rtype))
+ if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
{
- int nbits = bitsForType (ltype);
- long v = operandLitValue (right);
-
- if (v > ((LONG_LONG) 1 << nbits) && v > 0)
- werror (W_CONST_RANGE, " compare operation ");
+ checkConstantRange(ltype,
+ OP_VALUE(right), "compare operation", 1);
}
ctype = usualBinaryConversions (&left, &right);
check if the literal value is within bounds */
if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
{
- int nbits = bitsForType (ltype);
- long v = operandLitValue (right);
-
- if (v > ((LONG_LONG) 1 << nbits) && v > 0)
- werror (W_CONST_RANGE, " = operation");
+ checkConstantRange(ltype,
+ OP_VALUE(right), "= operation", 0);
}
/* if the left & right type don't exactly match */
/* first check the type for pointer assignement */
if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
- checkType (ltype, rtype) < 0)
+ compareType (ltype, rtype) < 0)
{
- if (checkType (ltype->next, rtype) < 0)
+ if (compareType (ltype->next, rtype) < 0)
right = geniCodeCast (ltype->next, right, TRUE);
}
- else if (checkType (ltype, rtype) < 0)
+ else if (compareType (ltype, rtype) < 0)
right = geniCodeCast (ltype, right, TRUE);
/* if left is a true symbol & ! volatile
sym_link *type, *etype;
int stack = 0;
+ if (!IS_FUNC(OP_SYMBOL(left)->type) &&
+ !IS_CODEPTR(OP_SYMBOL(left)->type)) {
+ werror (E_FUNCTION_EXPECTED);
+ return NULL;
+ }
+
/* take care of parameters with side-effecting
function calls in them, this is required to take care
of overlaying function parameters */
if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
options.stackAuto == 0 &&
- !TARGET_IS_DS390)
+ /* !TARGET_IS_DS390) */
+ (!(options.model == MODEL_FLAT24)) )
{
}
else
ADDTOCHAIN (ic);
}
+/*-----------------------------------------------------------------*/
+/* geniCodeArrayInit - intermediate code for array initializer */
+/*-----------------------------------------------------------------*/
+static void
+geniCodeArrayInit (ast * tree, operand *array)
+{
+ iCode *ic;
+
+ if (!getenv("TRY_THE_NEW_INITIALIZER")) {
+ ic = newiCode (ARRAYINIT, array, NULL);
+ IC_ARRAYILIST (ic) = tree->values.constlist;
+ } else {
+ operand *left=newOperand(), *right=newOperand();
+ left->type=right->type=SYMBOL;
+ OP_SYMBOL(left)=AST_SYMBOL(tree->left);
+ OP_SYMBOL(right)=AST_SYMBOL(tree->right);
+ ic = newiCode (ARRAYINIT, left, right);
+ }
+ ADDTOCHAIN (ic);
+}
+
/*-----------------------------------------------------------------*/
/* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
/* particular case. Ie : assigning or dereferencing array or ptr */
/*-----------------------------------------------------------------*/
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);
{
lvalItem * lpItem;
lpItem = getSet(&lvaluereqSet);
- if(lpItem) free(lpItem);
+ if(lpItem) Safe_free(lpItem);
}
/*-----------------------------------------------------------------*/
/* clearLvaluereq - clear lvalreq flag */
case '[': /* array operation */
{
- sym_link *ltype = operandType (left);
- left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
+ //sym_link *ltype = operandType (left);
+ //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
+ left = geniCodeRValue (left, FALSE);
right = geniCodeRValue (right, TRUE);
}
sym_link *rtype = operandType (right);
sym_link *ltype = operandType (left);
if (IS_PTR (rtype) && IS_ITEMP (right)
- && right->isaddr && checkType (rtype->next, ltype) == 1)
+ && right->isaddr && compareType (rtype->next, ltype) == 1)
right = geniCodeRValue (right, TRUE);
else
right = geniCodeRValue (right, FALSE);
sym_link *rtype = operandType (right);
sym_link *ltype = operandType (left);
if (IS_PTR (rtype) && IS_ITEMP (right)
- && right->isaddr && checkType (rtype->next, ltype) == 1)
+ && right->isaddr && compareType (rtype->next, ltype) == 1)
right = geniCodeRValue (right, TRUE);
else
right = geniCodeRValue (right, FALSE);
sym_link *rtype = operandType (right);
sym_link *ltype = operandType (left);
if (IS_PTR (rtype) && IS_ITEMP (right)
- && right->isaddr && checkType (rtype->next, ltype) == 1)
+ && right->isaddr && compareType (rtype->next, ltype) == 1)
{
right = geniCodeRValue (right, TRUE);
}
case INLINEASM:
geniCodeInline (tree);
return NULL;
+
+ case ARRAYINIT:
+ geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
+ return NULL;
}
return NULL;