#if 0 // temporary disabled, leaving the warning as a reminder
if (warnings) {
- sprintf (message, "for %s %s in %s",
+ SNPRINTF (message, sizeof(message), "for %s %s in %s",
SPEC_USIGN(ltype) ? "unsigned" : "signed",
nounName(ltype), msg);
werror (W_CONST_RANGE, message);
{
if ((icTab = getTableEntry (loop->op)))
{
- fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
+ fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
loop->filename, loop->lineno,
loop->seq, loop->key, loop->depth, loop->supportRtn);
ic = newiCode (op, NULL, NULL);
ic->op = op;
- ic->argLabel.label = label;
+ ic->label = label;
IC_LEFT (ic) = NULL;
IC_RIGHT (ic) = NULL;
IC_RESULT (ic) = NULL;
symbol *itmp;
if (s)
- sprintf (buffer, "%s", s);
+ {
+ SNPRINTF (buffer, sizeof(buffer), "%s", s);
+ }
else
- sprintf (buffer, "iTemp%d", iTempNum++);
+ {
+ SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
+ }
+
itmp = newSymbol (buffer, 1);
- strcpy (itmp->rname, itmp->name);
+ strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
itmp->isitmp = 1;
return itmp;
return itmplbl;
if (s)
- itmplbl = newSymbol (s, 1);
+ {
+ itmplbl = newSymbol (s, 1);
+ }
else
{
- sprintf (buffer, "iTempLbl%d", iTempLblNum++);
+ SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
itmplbl = newSymbol (buffer, 1);
}
{
symbol *itmplbl;
- sprintf (buffer, "preHeaderLbl%d", iTempLblNum++);
+ SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
itmplbl = newSymbol (buffer, 1);
itmplbl->isitmp = 1;
{
value *tval = args;
+ wassert (IS_SYMOP(op));
+
while (tval)
{
if (tval->sym &&
if (IS_ITEMP (op))
return 0;
- if (op->type == SYMBOL &&
+ if (IS_SYMOP(op) &&
(op->operand.symOperand->level == 0 ||
IS_STATIC (op->operand.symOperand->etype) ||
IS_EXTERN (op->operand.symOperand->etype))
return 0;
opetype = getSpec (optype = operandType (op));
-
- if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
- return 1;
-
- if (IS_VOLATILE (opetype))
- return 1;
- return 0;
+
+ if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
+ return 1;
+
+ if (IS_VOLATILE (opetype))
+ return 1;
+ return 0;
}
/*-----------------------------------------------------------------*/
(unsigned long) operandLitValue (right) :
(long) operandLitValue (right)));
break;
- case RIGHT_OP:
- retval = operandFromLit ((SPEC_USIGN(let) ?
- (unsigned long) operandLitValue (left) :
- (long) operandLitValue (left)) >>
- (SPEC_USIGN(ret) ?
- (unsigned long) operandLitValue (right) :
- (long) operandLitValue (right)));
+ case RIGHT_OP: {
+ double lval = operandLitValue(left), rval = operandLitValue(right);
+ double res=0;
+ switch ((SPEC_USIGN(let) ? 2 : 0) + (SPEC_USIGN(ret) ? 1 : 0))
+ {
+ case 0: // left=unsigned right=unsigned
+ res=(unsigned long)lval >> (unsigned long)rval;
+ break;
+ case 1: // left=unsigned right=signed
+ res=(unsigned long)lval >> (signed long)rval;
+ break;
+ case 2: // left=signed right=unsigned
+ res=(signed long)lval >> (unsigned long)rval;
+ break;
+ case 3: // left=signed right=signed
+ res=(signed long)lval >> (signed long)rval;
+ break;
+ }
+ retval = operandFromLit (res);
break;
+ }
case EQ_OP:
retval = operandFromLit (operandLitValue (left) ==
operandLitValue (right));
case EX_LINK:
return operandFromLink (tree->opval.lnk);
- }
+ break;
- assert (0);
- /* Just to keep the comiler happy */
+ default:
+ assert (0);
+ }
+
+ /* Just to keep the compiler happy */
return (operand *) 0;
}
sym_link *ltype = operandType (*op1);
ctype = computeType (ltype, rtype);
+
*op1 = geniCodeCast (ctype, *op1, TRUE);
*op2 = geniCodeCast (ctype, *op2, TRUE);
if (IS_SPEC (type) &&
IS_TRUE_SYMOP (op) &&
(!IN_FARSPACE (SPEC_OCLS (etype)) ||
- /* TARGET_IS_DS390)) */
(options.model == MODEL_FLAT24) ))
{
op = operandFromOperand (op);
resType = usualBinaryConversions (&left, &right);
- /* if the right is a literal & power of 2 */
- /* then make it a right shift */
+ /* if the right is a literal & power of 2
+ and left is unsigned then make it a
+ right shift */
if (IS_LITERAL (retype) &&
!IS_FLOAT (letype) &&
+ SPEC_USIGN(letype) &&
(p2 = powof2 ((unsigned long)
floatFromVal (right->operand.valOperand)))) {
ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
ADDTOCHAIN (ic);
subtractExit:
+ if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
+ return result;
+ }
+
+ // should we really do this? is this ANSI?
return geniCodeDivision (result,
operandFromLit (getSize (ltype->next)));
}
int isarray = 0;
LRTYPE;
- /* if left is an array then array access */
- if (IS_ARRAY (ltype))
- return geniCodeArray (left, right,lvl);
-
/* if the right side is LITERAL zero */
/* return the left side */
if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
return right;
/* if left is a pointer then size */
- if (IS_PTR (ltype))
+ if (IS_PTR (ltype) || IS_ARRAY(ltype))
{
isarray = left->isaddr;
// there is no need to multiply with 1
return type;
etype = getSpec (type);
- ptype = newLink ();
+ ptype = newLink (DECLARATOR);
ptype->next = type;
- /* if the output class is generic */
+
+ /* if the output class is code */
if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
DCL_PTR_CONST (ptype) = port->mem.code_ro;
/* the variable was volatile then pointer to volatile */
if (IS_VOLATILE (etype))
DCL_PTR_VOLATILE (ptype) = 1;
+
return ptype;
}
if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
DCL_PTR_CONST (optype) = port->mem.code_ro;
-
/* if the variable was declared a constant */
/* then the pointer points to a constant */
if (IS_CONSTANT (opetype))
/* the variable was volatile then pointer to volatile */
if (IS_VOLATILE (opetype))
DCL_PTR_VOLATILE (optype) = 1;
+
op->isaddr = 0;
return op;
}
symbol *element = getStructElement (SPEC_STRUCT (etype),
right->operand.symOperand);
+ wassert(IS_SYMOP(right));
+
/* add the offset */
ic = newiCode ('+', left, operandFromLit (element->offset));
/* return op; */
/* } */
- p = newLink ();
- p->class = DECLARATOR;
+ p = newLink (DECLARATOR);
/* set the pointer depending on the storage class */
if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
sym_link *rtype, *retype;
sym_link *optype = operandType (op);
- /* if this is a pointer then generate the rvalue */
- if (IS_PTR (optype))
+ // if this is an array then array access
+ if (IS_ARRAY (optype)) {
+ // don't worry, this will be optimized out later
+ return geniCodeArray (op, operandFromLit (0), lvl);
+ }
+
+ // just in case someone screws up
+ wassert (IS_PTR (optype));
+
+ if (IS_TRUE_SYMOP (op))
{
- if (IS_TRUE_SYMOP (op))
- {
- op->isaddr = 1;
- op = geniCodeRValue (op, TRUE);
- }
- else
- op = geniCodeRValue (op, TRUE);
+ op->isaddr = 1;
+ op = geniCodeRValue (op, TRUE);
}
/* now get rid of the pointer part */
retype = getSpec (rtype = copyLinkChain (optype->next));
}
- /* if this is a pointer then outputclass needs 2b updated */
- if (IS_PTR (optype))
- setOClass (optype, retype);
+ /* outputclass needs 2b updated */
+ setOClass (optype, retype);
op->isGptr = IS_GENPTR (optype);
geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
parms->type = EX_OPERAND;
- AST_ARGREG(parms) = SPEC_ARGREG(parms->etype);
+ AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
+ SPEC_ARGREG(parms->ftype);
}
/*-----------------------------------------------------------------*/
/* assign */
operand *top = operandFromSymbol (argVals->sym);
/* clear useDef and other bitVectors */
- OP_USES (top) = OP_DEFS (top) = OP_SYMBOL(top)->clashes = NULL;
+ OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
geniCodeAssign (top, pval, 1);
}
else
if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
options.stackAuto == 0 &&
- /* !TARGET_IS_DS390) */
(!(options.model == MODEL_FLAT24)) )
{
}
/* create a proc icode */
ic = newiCode (FUNCTION, func, NULL);
- ic->lineno = OP_SYMBOL (func)->lineDef;
+ lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
ADDTOCHAIN (ic);
/* all integer numbers between the maximum & minimum must */
/* be present , the maximum value should not exceed 255 */
min = max = (int) floatFromVal (vch = caseVals);
- sprintf (buffer, "_case_%d_%d",
+ SNPRINTF (buffer, sizeof(buffer),
+ "_case_%d_%d",
tree->values.switchVals.swNum,
min);
addSet (&labels, newiTempLabel (buffer));
{
if (((t = (int) floatFromVal (vch)) - max) != 1)
return 0;
- sprintf (buffer, "_case_%d_%d",
+ SNPRINTF (buffer, sizeof(buffer),
+ "_case_%d_%d",
tree->values.switchVals.swNum,
t);
addSet (&labels, newiTempLabel (buffer));
return 0;
if (tree->values.switchVals.swDefault)
- sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
+ {
+ SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
+ }
else
- sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
+ {
+ SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
+ }
+
falseLabel = newiTempLabel (buffer);
operandFromValue (caseVals),
EQ_OP);
- sprintf (buffer, "_case_%d_%d",
+ SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
tree->values.switchVals.swNum,
(int) floatFromVal (caseVals));
trueLabel = newiTempLabel (buffer);
/* if default is present then goto break else break */
if (tree->values.switchVals.swDefault)
- sprintf (buffer, "_default_%d", tree->values.switchVals.swNum);
+ {
+ SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
+ }
else
- sprintf (buffer, "_swBrk_%d", tree->values.switchVals.swNum);
+ {
+ SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
+ }
falseLabel = newiTempLabel (buffer);
geniCodeGoto (falseLabel);
operand *right = NULL;
if (!tree)
return NULL;
+
/* set the global variables for filename & line number */
if (tree->filename)
filename = tree->filename;
case RIGHT_OP:
return geniCodeRightShift (geniCodeRValue (left, FALSE),
geniCodeRValue (right, FALSE));
- case CAST:
+ case CAST:
+#if 0 // this indeed needs a second thought
+ {
+ operand *op;
+
+ // let's keep this simple: get the rvalue we need
+ op=geniCodeRValue (right, FALSE);
+ // now cast it to whatever we want
+ op=geniCodeCast (operandType(left), op, FALSE);
+ // if this is going to be used as an lvalue, make it so
+ if (tree->lvalue) {
+ op->isaddr=1;
+ }
+ return op;
+ }
+#else // bug #604575, is it a bug ????
return geniCodeCast (operandType (left),
geniCodeRValue (right, FALSE), FALSE);
+#endif
case '~':
case '!':
ast2iCode (tree,0);
return reverseiCChain ();
}
+
+static const char *opTypeToStr(OPTYPE op)
+{
+ switch(op)
+ {
+ case SYMBOL: return "symbol";
+ case VALUE: return "value";
+ case TYPE: return "type";
+ }
+ return "undefined type";
+}
+
+
+operand *validateOpType(operand *op,
+ const char *macro,
+ const char *args,
+ OPTYPE type,
+ const char *file,
+ unsigned line)
+{
+ if (op && op->type == type)
+ {
+ return op;
+ }
+ fprintf(stderr,
+ "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
+ " expected %s, got %s\n",
+ macro, args, file, line,
+ opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
+ exit(-1);
+ return op; // never reached, makes compiler happy.
+}