#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);
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 ru%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_SYMBOL(op)->ruonly
+ OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
);
{
fprintf (file, "{");
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");
}
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 (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
}
-/*------------------------------------------------------------------*/
-/* isOperandInDirSpace - will return true if operand is in dirSpace */
-/*------------------------------------------------------------------*/
+/*--------------------------------------------------------------------*/
+/* isOperandInCodeSpace - will return true if operand is in codeSpace */
+/*--------------------------------------------------------------------*/
bool
isOperandInCodeSpace (operand * op)
{
if (!IS_SYMOP (op))
return FALSE;
+ etype = getSpec (operandType (op));
+
if (!IS_TRUE_SYMOP (op))
{
if (SPIL_LOC (op))
(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));
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);
/* 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);
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 0
/* if left is an array then array access */
if (IS_ARRAY (ltype))
return geniCodeArray (left, right,lvl);
+#endif
/* if the right side is LITERAL zero */
/* return the left side */
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
symbol *element = getStructElement (SPEC_STRUCT (etype),
right->operand.symOperand);
+ wassert(IS_SYMOP(right));
+
/* add the offset */
ic = newiCode ('+', left, operandFromLit (element->offset));
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) = parms->etype ? SPEC_ARGREG(parms->etype) :
+ SPEC_ARGREG(parms->ftype);
}
/*-----------------------------------------------------------------*/
IFFUNC_ISBUILTIN(func->type))
{
ic = newiCode (SEND, pval, NULL);
+ ic->argreg = SPEC_ARGREG(parms->etype);
ic->builtinSEND = FUNC_ISBUILTIN(func->type);
ADDTOCHAIN (ic);
}
/* 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
/* for all arguments that are passed in registers */
while (args)
{
-
+ int first = 1;
if (IS_REGPARM (args->etype))
{
operand *opr = operandFromValue (args);
if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
options.stackAuto == 0 &&
- /* !TARGET_IS_DS390) */
(!(options.model == MODEL_FLAT24)) )
{
}
}
}
- 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);
}
/* 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;
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.
+}