#include "common.h"
#include "newalloc.h"
#include "math.h"
+#include "dbuf_string.h"
/*-----------------------------------------------------------------*/
/* global variables */
int iTempLblNum = 0;
int operandKey = 0;
int iCodeKey = 0;
-char *filename;
-int lineno;
+char *filename; /* current file name */
+int lineno = 1; /* current line number */
int block;
int scopeLevel;
int seqPoint;
void setOClass (sym_link * ptr, sym_link * spec);
static operand *geniCodeCast (sym_link *, operand *, bool);
-#define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
+#define PRINTFUNC(x) void x (struct dbuf_s *dbuf, iCode *ic, char *s)
/* forward definition of ic print functions */
PRINTFUNC (picGetValueAtAddr);
PRINTFUNC (picSetValueAtAddr);
{RRC, "rrc", picGenericOne, NULL},
{RLC, "rlc", picGenericOne, NULL},
{GETHBIT, "ghbit", picGenericOne, NULL},
+ {GETABIT, "gabit", picGenericOne, NULL},
+ {GETBYTE, "gbyte", picGenericOne, NULL},
+ {GETWORD, "gword", picGenericOne, NULL},
{UNARYMINUS, "-", picGenericOne, NULL},
{IPUSH, "push", picGenericOne, NULL},
{IPOP, "pop", picGenericOne, NULL},
};
/*-----------------------------------------------------------------*/
-/* checkConstantRange: check a constant against the type */
+/* operandName - returns the name of the operand */
/*-----------------------------------------------------------------*/
+int
+printOperand (operand * op, FILE * file)
+{
+ struct dbuf_s dbuf;
+ int ret;
+ int pnl = 0;
-
-/* 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) {
- double max;
- int warnings=0;
- int negative=0;
- long v;
-
- max = pow ((double)2.0, (double)bitsForType(ltype));
-
- if (IS_LONG(val->type)) {
- if (IS_UNSIGNED(val->type)) {
- v=SPEC_CVAL(val->type).v_ulong;
- } else {
- v=SPEC_CVAL(val->type).v_long;
- }
- } else {
- if (IS_UNSIGNED(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
- if (options.pedantic)
- pedantic=2;
-#endif
-
- if (IS_FLOAT(ltype)) {
- // anything will do
- return;
- }
-
- if (IS_FIXED(ltype)) {
- // anything will do
- return;
- }
-
- if (!IS_UNSIGNED(val->type) && v<0) {
- negative=1;
- if (IS_UNSIGNED(ltype) && (pedantic>1)) {
- warnings++;
+ if (!file)
+ {
+ file = stdout;
+ pnl = 1;
}
- v=-v;
- }
-
- // if very pedantic: "char c=200" is not allowed
- if (pedantic>1 && !IS_UNSIGNED(ltype)) {
- max = max/2 + negative;
- }
-
- if (v >= max) {
- warnings++;
- }
+ dbuf_init (&dbuf, 1024);
+ ret = dbuf_printOperand(op, &dbuf);
+ dbuf_write_and_destroy (&dbuf, file);
-#if 0 // temporary disabled, leaving the warning as a reminder
- if (warnings) {
- SNPRINTF (message, sizeof(message), "for %s %s in %s",
- IS_UNSIGNED(ltype) ? "unsigned" : "signed",
- nounName(ltype), msg);
- werror (W_CONST_RANGE, message);
+ if (pnl)
+ putc ('\n', file);
- if (pedantic>1)
- fatalError++;
- }
-#endif
+ return ret;
}
-/*-----------------------------------------------------------------*/
-/* operandName - returns the name of the operand */
-/*-----------------------------------------------------------------*/
int
-printOperand (operand * op, FILE * file)
+dbuf_printOperand (operand * op, struct dbuf_s *dbuf)
{
sym_link *opetype;
- int pnl = 0;
if (!op)
return 1;
- if (!file)
- {
- file = stdout;
- pnl = 1;
- }
switch (op->type)
{
case VALUE:
opetype = getSpec (operandType (op));
if (IS_FLOAT (opetype))
- fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
- if (IS_FIXED16X16 (opetype))
- fprintf (file, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
+ dbuf_printf (dbuf, "%g {", SPEC_CVAL (opetype).v_float);
+ else if (IS_FIXED16X16 (opetype))
+ dbuf_printf (dbuf, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
else
- fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
- printTypeChain (operandType (op), file);
- fprintf (file, "}");
+ dbuf_printf (dbuf, "0x%x {", (unsigned int) ulFromVal (op->operand.valOperand));
+ dbuf_printTypeChain (operandType (op), dbuf);
+ dbuf_append_char (dbuf, '}');
break;
case SYMBOL:
#define REGA 1
//#if REGA /* { */
if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
- fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%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}" , */
+ dbuf_printf (dbuf, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%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)->ruonly,OP_SYMBOL(op)->dptr
);
{
- fprintf (file, "{");
- printTypeChain (operandType (op), file);
+ dbuf_append_char (dbuf, '{');
+ dbuf_printTypeChain (operandType (op), dbuf);
if (SPIL_LOC (op) && IS_ITEMP (op))
- fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
- fprintf (file, "}");
+ dbuf_printf (dbuf, "}{ sir@ %s", SPIL_LOC (op)->rname);
+ dbuf_append_char (dbuf, '}');
}
{
if (!OP_SYMBOL (op)->remat)
if (OP_SYMBOL (op)->usl.spillLoc)
- fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
+ dbuf_printf (dbuf, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
OP_SYMBOL (op)->usl.spillLoc->rname :
OP_SYMBOL (op)->usl.spillLoc->name));
else
- fprintf (file, "[err]");
+ dbuf_append_str (dbuf, "[err]");
else
- fprintf (file, "[remat]");
+ dbuf_append_str (dbuf, "[remat]");
}
else
{
int i;
- fprintf (file, "[");
+ dbuf_append_char (dbuf, '[');
for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
- fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
- fprintf (file, "]");
+ dbuf_printf (dbuf, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
+ dbuf_append_char (dbuf, ']');
}
}
//#else /* } else { */
} else {
/* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
- fprintf (file, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
+ dbuf_printf (dbuf, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
{
- fprintf (file, "[lr%d:%d so:%d]",
+ dbuf_printf (dbuf, "[lr%d:%d so:%d]",
OP_LIVEFROM (op), OP_LIVETO (op),
OP_SYMBOL (op)->stack);
}
if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
{
- fprintf (file, "{");
- printTypeChain (operandType (op), file);
+ dbuf_append_char (dbuf, '{');
+ dbuf_printTypeChain (operandType (op), dbuf);
if (SPIL_LOC (op) && IS_ITEMP (op))
- fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
- fprintf (file, "}");
+ dbuf_printf (dbuf, "}{ sir@ %s", SPIL_LOC (op)->rname);
+ dbuf_append_char (dbuf, '}');
}
/* if assigned to registers */
{
if (!OP_SYMBOL (op)->remat)
if (OP_SYMBOL (op)->usl.spillLoc)
- fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
+ dbuf_printf (dbuf, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
OP_SYMBOL (op)->usl.spillLoc->rname :
OP_SYMBOL (op)->usl.spillLoc->name));
else
- fprintf (file, "[err]");
+ dbuf_append_str (dbuf, "[err]");
else
- fprintf (file, "[remat]");
+ dbuf_append_str (dbuf, "[remat]");
}
else
{
int i;
- fprintf (file, "[");
+ dbuf_append_char (dbuf, '[');
for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
- fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
- fprintf (file, "]");
+ dbuf_printf (dbuf, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
+ dbuf_append_char (dbuf, ']');
}
}
//#endif /* } */
break;
case TYPE:
- fprintf (file, "(");
- printTypeChain (op->operand.typeOperand, file);
- fprintf (file, ")");
+ dbuf_append_char (dbuf, '(');
+ dbuf_printTypeChain (op->operand.typeOperand, dbuf);
+ dbuf_append_char (dbuf, ')');
break;
}
- if (pnl)
- fprintf (file, "\n");
return 0;
}
/*-----------------------------------------------------------------*/
PRINTFUNC (picGetValueAtAddr)
{
- fprintf (of, "\t");
- printOperand (IC_RESULT (ic), of);
- fprintf (of, " = ");
- fprintf (of, "@[");
- printOperand (IC_LEFT (ic), of);
- fprintf (of, "]");
-
- fprintf (of, "\n");
+ dbuf_append_char (dbuf, '\t');
+ dbuf_printOperand (IC_RESULT (ic), dbuf);
+ dbuf_append_str (dbuf, " = ");
+ dbuf_append_str (dbuf, "@[");
+ dbuf_printOperand (IC_LEFT (ic), dbuf);
+ dbuf_append_str (dbuf, "]\n");
}
PRINTFUNC (picSetValueAtAddr)
{
- fprintf (of, "\t");
- fprintf (of, "*[");
- printOperand (IC_LEFT (ic), of);
- fprintf (of, "] = ");
- printOperand (IC_RIGHT (ic), of);
- fprintf (of, "\n");
+ dbuf_append_char (dbuf, '\t');
+ dbuf_append_str (dbuf, "*[");
+ dbuf_printOperand (IC_LEFT (ic), dbuf);
+ dbuf_append_str (dbuf, "] = ");
+ dbuf_printOperand (IC_RIGHT (ic), dbuf);
+ dbuf_append_char (dbuf, '\n');
}
PRINTFUNC (picAddrOf)
{
- fprintf (of, "\t");
- printOperand (IC_RESULT (ic), of);
+ dbuf_append_char (dbuf, '\t');
+ dbuf_printOperand (IC_RESULT (ic), dbuf);
if (IS_ITEMP (IC_LEFT (ic)))
- fprintf (of, " = ");
+ dbuf_append_str (dbuf, " = ");
else
- fprintf (of, " = &[");
- printOperand (IC_LEFT (ic), of);
+ dbuf_append_str (dbuf, " = &[");
+ dbuf_printOperand (IC_LEFT (ic), dbuf);
if (IC_RIGHT (ic))
{
if (IS_ITEMP (IC_LEFT (ic)))
- fprintf (of, " offsetAdd ");
+ dbuf_append_str (dbuf, " offsetAdd ");
else
- fprintf (of, " , ");
- printOperand (IC_RIGHT (ic), of);
+ dbuf_append_str (dbuf, " , ");
+ dbuf_printOperand (IC_RIGHT (ic), dbuf);
}
if (IS_ITEMP (IC_LEFT (ic)))
- fprintf (of, "\n");
+ dbuf_append_char (dbuf, '\n');
else
- fprintf (of, "]\n");
+ dbuf_append_str (dbuf, "]\n");
}
PRINTFUNC (picJumpTable)
{
symbol *sym;
- fprintf (of, "\t");
- fprintf (of, "%s\t", s);
- printOperand (IC_JTCOND (ic), of);
- fprintf (of, "\n");
+ dbuf_append_char (dbuf, '\t');
+ dbuf_printf (dbuf, "%s\t", s);
+ dbuf_printOperand (IC_JTCOND (ic), dbuf);
for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
sym = setNextItem (IC_JTLABELS (ic)))
- fprintf (of, "\t\t\t%s\n", sym->name);
+ dbuf_printf (dbuf, "; %s", sym->name);
+ dbuf_append_char (dbuf, '\n');
}
PRINTFUNC (picGeneric)
{
- fprintf (of, "\t");
- printOperand (IC_RESULT (ic), of);
- fprintf (of, " = ");
- printOperand (IC_LEFT (ic), of);
- fprintf (of, " %s ", s);
- printOperand (IC_RIGHT (ic), of);
- fprintf (of, "\n");
+ dbuf_append_char (dbuf, '\t');
+ dbuf_printOperand (IC_RESULT (ic), dbuf);
+ dbuf_append_str (dbuf, " = ");
+ dbuf_printOperand (IC_LEFT (ic), dbuf);
+ dbuf_printf (dbuf, " %s ", s);
+ dbuf_printOperand (IC_RIGHT (ic), dbuf);
+ dbuf_append_char (dbuf, '\n');
}
PRINTFUNC (picGenericOne)
{
- fprintf (of, "\t");
+ dbuf_append_char (dbuf, '\t');
if (IC_RESULT (ic))
{
- printOperand (IC_RESULT (ic), of);
- fprintf (of, " = ");
+ dbuf_printOperand (IC_RESULT (ic), dbuf);
+ dbuf_append_str (dbuf, " = ");
}
if (IC_LEFT (ic))
{
- fprintf (of, "%s ", s);
- printOperand (IC_LEFT (ic), of);
+ dbuf_printf (dbuf, "%s ", s);
+ dbuf_printOperand (IC_LEFT (ic), dbuf);
}
if (!IC_RESULT (ic) && !IC_LEFT (ic))
- fprintf (of, s);
+ dbuf_append_str (dbuf, s);
if (ic->op == SEND || ic->op == RECEIVE) {
- fprintf(of,"{argreg = %d}",ic->argreg);
+ dbuf_printf (dbuf,"{argreg = %d}",ic->argreg);
}
if (ic->op == IPUSH) {
- fprintf(of,"{parmPush = %d}",ic->parmPush);
+ dbuf_printf (dbuf,"{parmPush = %d}",ic->parmPush);
}
- fprintf (of, "\n");
+ dbuf_append_char (dbuf, '\n');
}
PRINTFUNC (picCast)
{
- fprintf (of, "\t");
- printOperand (IC_RESULT (ic), of);
- fprintf (of, " = ");
- printOperand (IC_LEFT (ic), of);
- printOperand (IC_RIGHT (ic), of);
- fprintf (of, "\n");
+ dbuf_append_char (dbuf, '\t');
+ dbuf_printOperand (IC_RESULT (ic), dbuf);
+ dbuf_append_str (dbuf, " = ");
+ dbuf_printOperand (IC_LEFT (ic), dbuf);
+ dbuf_printOperand (IC_RIGHT (ic), dbuf);
+ dbuf_append_char (dbuf, '\n');
}
PRINTFUNC (picAssign)
{
- fprintf (of, "\t");
+ dbuf_append_char (dbuf, '\t');
if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
- fprintf (of, "*(");
+ dbuf_append_str (dbuf, "*(");
- printOperand (IC_RESULT (ic), of);
+ dbuf_printOperand (IC_RESULT (ic), dbuf);
if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
- fprintf (of, ")");
+ dbuf_append_char (dbuf, ')');
- fprintf (of, " %s ", s);
- printOperand (IC_RIGHT (ic), of);
+ dbuf_printf (dbuf, " %s ", s);
+ dbuf_printOperand (IC_RIGHT (ic), dbuf);
- fprintf (of, "\n");
+ dbuf_append_char (dbuf, '\n');
}
PRINTFUNC (picLabel)
{
- fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
+ dbuf_printf (dbuf, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
}
PRINTFUNC (picGoto)
{
- fprintf (of, "\t");
- fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
+ dbuf_append_char (dbuf, '\t');
+ dbuf_printf (dbuf, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
}
PRINTFUNC (picIfx)
{
- fprintf (of, "\t");
- fprintf (of, "if ");
- printOperand (IC_COND (ic), of);
+ dbuf_append_char (dbuf, '\t');
+ dbuf_append_str (dbuf, "if ");
+ dbuf_printOperand (IC_COND (ic), dbuf);
if (!IC_TRUE (ic))
- fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
+ dbuf_printf (dbuf, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
else
{
- fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
+ dbuf_printf (dbuf, " != 0 goto %s($%d)", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
if (IC_FALSE (ic))
- fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
+ dbuf_printf (dbuf, "; zzgoto %s\n", IC_FALSE (ic)->name);
+ dbuf_append_char (dbuf, '\n');
}
}
PRINTFUNC (picInline)
{
- fprintf (of, "%s", IC_INLINE (ic));
+ dbuf_append_str (dbuf, IC_INLINE (ic));
}
PRINTFUNC (picReceive)
{
- printOperand (IC_RESULT (ic), of);
- fprintf (of, " = %s ", s);
- printOperand (IC_LEFT (ic), of);
- fprintf (of, "\n");
+ dbuf_printOperand (IC_RESULT (ic), dbuf);
+ dbuf_printf (dbuf, " = %s ", s);
+ dbuf_printOperand (IC_LEFT (ic), dbuf);
+ dbuf_append_char (dbuf, '\n');
}
PRINTFUNC (picDummyRead)
{
- fprintf (of, "\t");
- fprintf (of, "%s ", s);
- printOperand (IC_RIGHT (ic), of);
- fprintf (of, "\n");
+ dbuf_append_char (dbuf, '\t');
+ dbuf_printf (dbuf, "%s ", s);
+ dbuf_printOperand (IC_RIGHT (ic), dbuf);
+ dbuf_append_char (dbuf, '\n');
}
PRINTFUNC (picCritical)
{
- fprintf (of, "\t");
+ dbuf_append_char (dbuf, '\t');
if (IC_RESULT (ic))
- printOperand (IC_RESULT (ic), of);
+ dbuf_printOperand (IC_RESULT (ic), dbuf);
else
- fprintf (of, "(stack)");
- fprintf (of, " = %s ", s);
- fprintf (of, "\n");
+ dbuf_append_str (dbuf, "(stack)");
+ dbuf_printf (dbuf, " = %s ", s);
+ dbuf_append_char (dbuf, '\n');
}
PRINTFUNC (picEndCritical)
{
- fprintf (of, "\t");
- fprintf (of, "%s = ", s);
+ dbuf_append_char (dbuf, '\t');
+ dbuf_printf (dbuf, "%s = ", s);
if (IC_RIGHT (ic))
- printOperand (IC_RIGHT (ic), of);
+ dbuf_printOperand (IC_RIGHT (ic), dbuf);
else
- fprintf (of, "(stack)");
- fprintf (of, "\n");
+ dbuf_append_str (dbuf, "(stack)");
+ dbuf_append_char (dbuf, '\n');
}
/*-----------------------------------------------------------------*/
{
iCode *ic = item;
iCodeTable *icTab;
+ struct dbuf_s dbuf;
if (!of)
of = stdout;
fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
ic->filename, ic->lineno,
ic->seq, ic->key, ic->depth, ic->supportRtn);
- icTab->iCodePrint (of, ic, icTab->printName);
+ dbuf_init (&dbuf, 1024);
+ icTab->iCodePrint (&dbuf, ic, icTab->printName);
+ dbuf_write_and_destroy (&dbuf, of);
return 1;
}
{
iCode *loop;
iCodeTable *icTab;
+ struct dbuf_s dbuf;
if (!of)
of = stdout;
loop->filename, loop->lineno,
loop->seq, loop->key, loop->depth, loop->supportRtn);
- icTab->iCodePrint (of, loop, icTab->printName);
+ dbuf_init(&dbuf, 1024);
+ icTab->iCodePrint (&dbuf, loop, icTab->printName);
+ dbuf_write_and_destroy (&dbuf, of);
+ ////
+ fflush(of);
}
}
}
ic = Safe_alloc ( sizeof (iCode));
ic->seqPoint = seqPoint;
- ic->lineno = lineno;
ic->filename = filename;
+ ic->lineno = lineno;
ic->block = block;
ic->level = scopeLevel;
ic->op = op;
}
/*-----------------------------------------------------------------*/
-/* newiTempPreheaderLabel - creates a new preheader label */
+/* newiTempLoopHeaderLabel - creates a new loop header label */
/*-----------------------------------------------------------------*/
symbol *
-newiTempPreheaderLabel ()
+newiTempLoopHeaderLabel (bool pre)
{
symbol *itmplbl;
- SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
+ SNPRINTF (buffer, sizeof(buffer), pre ? "preHeaderLbl%d" : LOOPEXITLBL "%d",
+ iTempLblNum++);
itmplbl = newSymbol (buffer, 1);
itmplbl->isitmp = 1;
{
iCode *nic = newiCode (ic->op, NULL, NULL);
- nic->lineno = ic->lineno;
nic->filename = ic->filename;
+ nic->lineno = ic->lineno;
nic->block = ic->block;
nic->level = ic->level;
nic->parmBytes = ic->parmBytes;
/* depending on type of operand */
switch (op->type)
{
-
case VALUE:
return op->operand.valOperand->type;
case TYPE:
return op->operand.typeOperand;
+
default:
werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
" operand type not known ");
}
}
+/*-----------------------------------------------------------------*/
+/* operandSize - returns size of an operand in bytes */
+/*-----------------------------------------------------------------*/
+unsigned int
+operandSize (operand * op)
+{
+ sym_link *type;
+
+ /* if nothing return 0 */
+ if (!op)
+ return 0;
+
+ type = operandType (op);
+ if (op->aggr2ptr == 2)
+ type = type->next;
+ return getSize (type);
+}
+
/*-----------------------------------------------------------------*/
/* isParamterToCall - will return 1 if op is a parameter to args */
/*-----------------------------------------------------------------*/
return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
}
+/*-----------------------------------------------------------------*/
+/* isOperandInPagedSpace - return true if operand is in pagedSpace */
+/*-----------------------------------------------------------------*/
+bool
+isOperandInPagedSpace (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_PAGEDSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
+}
+
/*------------------------------------------------------------------*/
/* isOperandInDirSpace - will return true if operand is in dirSpace */
/*------------------------------------------------------------------*/
/* signed and unsigned mul are the same, as long as the precision
of the result isn't bigger than the precision of the operands. */
retval = operandFromValue (valCastLiteral (type,
- (TYPE_UDWORD) operandLitValue (left) *
- (TYPE_UDWORD) operandLitValue (right)));
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) *
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right))));
else if (IS_UNSIGNED (type)) /* unsigned int */
{
/* unsigned int is handled here in order to detect overflow */
- TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
- (TYPE_UWORD) operandLitValue (right);
+ TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) double2ul (operandLitValue (left)) *
+ (TYPE_TARGET_UINT) double2ul (operandLitValue (right));
- retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
- if (ul != (TYPE_UWORD) ul)
+ retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_UINT) ul));
+ if (ul != (TYPE_TARGET_UINT) ul)
werror (W_INT_OVL);
}
else /* signed int */
{
/* signed int is handled here in order to detect overflow */
- TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
- (TYPE_WORD) operandLitValue (right);
+ TYPE_TARGET_LONG l = (TYPE_TARGET_INT) operandLitValue (left) *
+ (TYPE_TARGET_INT) operandLitValue (right);
- retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
- if (l != (TYPE_WORD) l)
+ retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_INT) l));
+ if (l != (TYPE_TARGET_INT) l)
werror (W_INT_OVL);
}
}
operandLitValue (right)));
break;
case '/':
- if ((TYPE_UDWORD) operandLitValue (right) == 0)
+ if (IS_UNSIGNED (type))
{
- werror (E_DIVIDE_BY_ZERO);
- retval = right;
-
+ if ((TYPE_TARGET_ULONG) double2ul (operandLitValue (right)) == 0)
+ {
+ werror (E_DIVIDE_BY_ZERO);
+ retval = right;
+ }
+ SPEC_USIGN (let) = 1;
+ SPEC_USIGN (ret) = 1;
+ retval = operandFromValue (valCastLiteral (type,
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) /
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right))));
}
else
{
- if (IS_UNSIGNED (type))
- {
- SPEC_USIGN (let) = 1;
- SPEC_USIGN (ret) = 1;
- retval = operandFromValue (valCastLiteral (type,
- (TYPE_UDWORD) operandLitValue (left) /
- (TYPE_UDWORD) operandLitValue (right)));
- }
- else
+ if (operandLitValue (right) == 0)
{
- retval = operandFromValue (valCastLiteral (type,
- operandLitValue (left) /
- operandLitValue (right)));
+ werror (E_DIVIDE_BY_ZERO);
+ retval = right;
}
+ retval = operandFromValue (valCastLiteral (type,
+ operandLitValue (left) /
+ operandLitValue (right)));
}
break;
case '%':
- if ((TYPE_UDWORD) operandLitValue (right) == 0)
+ if ((TYPE_TARGET_ULONG) double2ul (operandLitValue (right)) == 0)
{
werror (E_DIVIDE_BY_ZERO);
retval = right;
else
{
if (IS_UNSIGNED (type))
- retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
- (TYPE_UDWORD) operandLitValue (right));
+ retval = operandFromLit ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) %
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
else
- retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
- (TYPE_DWORD) operandLitValue (right));
+ retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) %
+ (TYPE_TARGET_LONG) operandLitValue (right));
}
break;
case LEFT_OP:
/* The number of left shifts is always unsigned. Signed doesn't make
sense here. Shifting by a negative number is impossible. */
retval = operandFromValue (valCastLiteral (type,
- ((TYPE_UDWORD) operandLitValue (left) <<
- (TYPE_UDWORD) operandLitValue (right))));
+ ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) <<
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)))));
break;
case RIGHT_OP:
/* The number of right shifts is always unsigned. Signed doesn't make
sense here. Shifting by a negative number is impossible. */
if (IS_UNSIGNED(let))
/* unsigned: logic shift right */
- retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
- (TYPE_UDWORD) operandLitValue (right));
+ retval = operandFromLit ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) >>
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
else
/* signed: arithmetic shift right */
- retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
- (TYPE_UDWORD) operandLitValue (right));
+ retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) >>
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
break;
case EQ_OP:
- if (IS_FLOAT (let) ||
- IS_FLOAT (ret))
+ if (IS_FLOAT (let) || IS_FLOAT (ret))
{
retval = operandFromLit (operandLitValue (left) ==
operandLitValue (right));
}
- else
- if (IS_FIXED16X16 (let) ||
- IS_FIXED16X16 (ret))
+ else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
{
retval = operandFromLit (operandLitValue (left) ==
operandLitValue (right));
else
{
/* this op doesn't care about signedness */
- TYPE_UDWORD l, r;
+ TYPE_TARGET_ULONG l, r;
- l = (TYPE_UDWORD) operandLitValue (left);
- r = (TYPE_UDWORD) operandLitValue (right);
+ l = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
+ r = (TYPE_TARGET_ULONG) double2ul (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
if (!IS_LONG (let) &&
!IS_LONG (ret))
{
- r = (TYPE_UWORD) r;
- l = (TYPE_UWORD) l;
+ r = (TYPE_TARGET_UINT) r;
+ l = (TYPE_TARGET_UINT) l;
}
retval = operandFromLit (l == r);
}
break;
case BITWISEAND:
retval = operandFromValue (valCastLiteral (type,
- (TYPE_UDWORD)operandLitValue(left) &
- (TYPE_UDWORD)operandLitValue(right)));
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) &
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
break;
case '|':
retval = operandFromValue (valCastLiteral (type,
- (TYPE_UDWORD)operandLitValue(left) |
- (TYPE_UDWORD)operandLitValue(right)));
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) |
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
break;
case '^':
retval = operandFromValue (valCastLiteral (type,
- (TYPE_UDWORD)operandLitValue(left) ^
- (TYPE_UDWORD)operandLitValue(right)));
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) ^
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
break;
case AND_OP:
retval = operandFromLit (operandLitValue (left) &&
break;
case RRC:
{
- TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
+ TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
(i << 1));
break;
case RLC:
{
- TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
+ TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
(i >> 1));
}
break;
+ case GETABIT:
+ retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))) & 1);
+ break;
+ case GETBYTE:
+ retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)) & 0xFF));
+ break;
+ case GETWORD:
+ retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
+ (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)) & 0xFFFF));
+ break;
+
+ case GETHBIT:
+ retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
+ ((getSize (let) * 8) - 1)) & 1);
+ break;
case UNARYMINUS:
retval = operandFromValue (valCastLiteral (type,
case '~':
retval = operandFromValue (valCastLiteral (type,
- ~((TYPE_UDWORD)
- operandLitValue (left))));
+ ~((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)))));
break;
case '!':
/*-----------------------------------------------------------------*/
/* Get size in byte of ptr need to access an array */
/*-----------------------------------------------------------------*/
-static int
+static unsigned int
getArraySizePtr (operand * op)
{
sym_link *ltype = operandType(op);
return IC_RESULT (ic);
}
+static DECLARATOR_TYPE
+getPtrType(sym_link *type)
+{
+ //for Z80 anything goes
+ if (TARGET_Z80_LIKE)
+ return POINTER;
+
+ //preserve original behaviour for PIC16
+ if (TARGET_IS_PIC16)
+ return POINTER;
+
+ //for HC08 only zeropage ptr is different
+ if (TARGET_IS_HC08)
+ {
+ if (IS_DATA_PTR (type))
+ return POINTER;
+ else
+ return FPOINTER;
+ }
+
+ if (IS_DATA_PTR (type) && TARGET_MCS51_LIKE)
+ return IPOINTER;
+ if (IS_PTR (type))
+ return DCL_TYPE (type);
+ else if (IS_FUNC (type))
+ return CPOINTER;
+ else if (IS_ARRAY (type))
+ return PTR_TYPE (SPEC_OCLS (getSpec (type)));
+ return UPOINTER;
+}
+
/*-----------------------------------------------------------------*/
/* geniCodeCast - changes the value from one type to another */
/*-----------------------------------------------------------------*/
/* if this is a literal then just change the type & return */
if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
{
- return operandFromValue (valCastLiteral (type,
- operandLitValue (op)));
+ return operandFromValue (valCastLiteral (type, operandLitValue (op)));
}
/* if casting to/from pointers, do some checking */
/* This seems very dangerous to me, since there are several */
/* optimizations (for example, gcse) that don't notice the */
- /* cast hidden in this assignement and may simplify an */
+ /* cast hidden in this assignment and may simplify an */
/* iCode to use the original (uncasted) operand. */
/* Unfortunately, other things break when this cast is */
/* made explicit. Need to fix this someday. */
!IS_FIXED (type) &&
!IS_FIXED (optype) &&
((IS_SPEC (type) && IS_SPEC (optype)) ||
- (!IS_SPEC (type) && !IS_SPEC (optype))))
+ (IS_DECL (type) && IS_DECL (optype) && getPtrType (type) == getPtrType (optype))))
{
ic = newiCode ('=', NULL, op);
IC_RESULT (ic) = newiTempOperand (type, 0);
right->operand.valOperand));
if (IS_LITERAL(retype)) {
- p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
+ p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand));
}
resType = usualBinaryConversions (&left, &right, resultType, '*');
/* 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) && !IS_FIXED (letype)
+ if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
&& !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
&& (port->support.muldiv == 1))
&& strcmp (port->target, "pic16") != 0 /* don't shift for pic */
}
else
{
- ic = newiCode ('*', left, right); /* normal multiplication */
/* if the size left or right > 1 then support routine */
if (getSize (ltype) > 1 || getSize (rtype) > 1)
- ic->supportRtn = 1;
-
+ {
+ if (IS_LITERAL (retype))
+ ic = newiCode ('*', right, left); /* multiplication by support routine with one literal */
+ else
+ ic = newiCode ('*', left, right); /* multiplication by support routine */
+ ic->supportRtn = 1;
+ }
+ else
+ {
+ ic = newiCode ('*', left, right); /* normal multiplication */
+ }
}
IC_RESULT (ic) = newiTempOperand (resType, 1);
!IS_FLOAT (letype) &&
!IS_FIXED (letype) &&
IS_UNSIGNED(letype) &&
- (p2 = powof2 ((TYPE_UDWORD)
- floatFromVal (right->operand.valOperand)))) {
+ ((p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand))) > 0)) {
ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
}
else
size = operandFromLit (getSize (ltype->next));
SPEC_USIGN (getSpec (operandType (size))) = 1;
indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
- right = geniCodeMultiply (right,
- size,
- (getArraySizePtr(left) >= INTSIZE) ?
- RESULT_TYPE_INT :
- RESULT_TYPE_CHAR);
+ right = geniCodeMultiply (right, size, resultType);
/* 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: */
operand *size;
sym_link *ltype = operandType (left);
bool indexUnsigned;
+ RESULT_TYPE resultType;
+
+ resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
+ if (DCL_ELEM (ltype))
+ {
+ if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
+ resultType = RESULT_TYPE_CHAR;
+ }
if (IS_PTR (ltype))
{
left = geniCodeRValue (left, FALSE);
}
- return geniCodeDerefPtr (geniCodeAdd (left,
- right,
- (getArraySizePtr(left) >= INTSIZE) ?
- RESULT_TYPE_INT :
- RESULT_TYPE_CHAR,
- lvl),
+ return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, 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) ?
- RESULT_TYPE_INT :
- RESULT_TYPE_CHAR);
+ right = geniCodeMultiply (right, size, resultType);
/* 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)
werror(W_SIZEOF_VOID);
if (IS_FLOAT (rvtype))
ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
- else
- if (IS_FIXED16X16 (rvtype))
+ else if (IS_FIXED16X16 (rvtype))
ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
else
ic = newiCode ('+', rv, operandFromLit (size));
werror(W_SIZEOF_VOID);
if (IS_FLOAT (roptype))
ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
- else
- if (IS_FIXED16X16 (roptype))
+ else if (IS_FIXED16X16 (roptype))
ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
else
ic = newiCode ('+', rop, operandFromLit (size));
werror(W_SIZEOF_VOID);
if (IS_FLOAT (rvtype))
ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
- else
- if (IS_FIXED16X16 (rvtype))
+ else if (IS_FIXED16X16 (rvtype))
ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
else
ic = newiCode ('-', rv, operandFromLit (size));
werror(W_SIZEOF_VOID);
if (IS_FLOAT (roptype))
ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
- else
- if (IS_FIXED16X16 (roptype))
+ else if (IS_FIXED16X16 (roptype))
ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
else
ic = newiCode ('-', rop, operandFromLit (size));
/*-----------------------------------------------------------------*/
-/* geniCodeBitwise - gen int code for bitWise operators */
+/* geniCodeBitwise - gen int code for bitWise operators */
/*-----------------------------------------------------------------*/
operand *
geniCodeBitwise (operand * left, operand * right,
return op;
}
- /* other wise make this of the type coming in */
+ /* otherwise make this of the type coming in */
ic = newiCode (ADDRESS_OF, op, NULL);
IC_RESULT (ic) = newiTempOperand (p, 1);
IC_RESULT (ic)->isaddr = 0;
ADDTOCHAIN (ic);
return IC_RESULT (ic);
}
+
/*-----------------------------------------------------------------*/
/* setOClass - sets the output class depending on the pointer type */
/*-----------------------------------------------------------------*/
/* geniCodeLogic- logic code */
/*-----------------------------------------------------------------*/
static operand *
-geniCodeLogic (operand * left, operand * right, int op)
+geniCodeLogic (operand * left, operand * right, int op, ast *tree)
{
iCode *ic;
- sym_link *ctype;
+ sym_link *ctype, *ttype;
sym_link *rtype = operandType (right);
sym_link *ltype = operandType (left);
check if the literal value is within bounds */
if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
{
- checkConstantRange(ltype,
- OP_VALUE(right), "compare operation", 1);
+ CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE);
+ switch (ccr_result)
+ {
+ case CCR_ALWAYS_TRUE:
+ case CCR_ALWAYS_FALSE:
+ if (!options.lessPedantic)
+ werror (W_COMP_RANGE, "true resp. false");
+ return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0);
+ default:
+ break;
+ }
}
/* if one operand is a pointer and the other is a literal generic void pointer,
}
}
- ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
+ ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
ic = newiCode (op, left, right);
- IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
+ /* store 0 or 1 in result */
+ ttype = (tree && IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
+ IC_RESULT (ic) = newiTempOperand (ttype, 1);
/* if comparing float
and not a '==' || '!=' || '&&' || '||' (these
ADDTOCHAIN (ic);
/* store 0 or 1 in result */
- type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
+ type = (IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
result = newiTempOperand (type, 1);
geniCodeLabel (falseLabel);
}
/*-----------------------------------------------------------------*/
-/* geniCodeUnary - for a a generic unary operation */
+/* geniCodeUnary - for a generic unary operation */
/*-----------------------------------------------------------------*/
operand *
geniCodeUnary (operand * op, int oper)
return IC_RESULT (ic);
}
+/*-----------------------------------------------------------------*/
+/* geniCodeBinary - for a generic binary operation */
+/*-----------------------------------------------------------------*/
+operand *
+geniCodeBinary (operand * left, operand * right, int oper)
+{
+ iCode *ic = newiCode (oper, left, right);
+
+ IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
+ ADDTOCHAIN (ic);
+ return IC_RESULT (ic);
+}
+
/*-----------------------------------------------------------------*/
/* geniCodeConditional - geniCode for '?' ':' operation */
/*-----------------------------------------------------------------*/
iCode *ic;
symbol *falseLabel = newiTempLabel (NULL);
symbol *exitLabel = newiTempLabel (NULL);
- operand *cond = ast2iCode (tree->left,lvl+1);
- operand *true, *false, *result;
+ ast *astTrue = tree->right->left;
+ ast *astFalse = tree->right->right;
+ operand *cond = ast2iCode (tree->left, lvl+1);
+ operand *result = newiTempOperand (tree->ftype, 0);
+ operand *opTrue, *opFalse;
- ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
- NULL, falseLabel);
+ ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel);
ADDTOCHAIN (ic);
- true = ast2iCode (tree->right->left,lvl+1);
+ opTrue = ast2iCode (astTrue, lvl+1);
- /* move the value to a new Operand */
- result = newiTempOperand (tree->right->ftype, 0);
- geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
+ /* move the value to the new operand */
+ geniCodeAssign (result, geniCodeRValue (opTrue, FALSE), 0, 0);
/* generate an unconditional goto */
geniCodeGoto (exitLabel);
/* now for the right side */
geniCodeLabel (falseLabel);
- false = ast2iCode (tree->right->right,lvl+1);
- geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
+ opFalse = ast2iCode (astFalse, lvl+1);
+ geniCodeAssign (result, geniCodeRValue (opFalse, FALSE), 0, 0);
/* create the exit label */
geniCodeLabel (exitLabel);
/* left is integral type and right is literal then
check if the literal value is within bounds */
- if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
+ if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
+ checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
+ !options.lessPedantic)
{
- checkConstantRange(ltype,
- OP_VALUE(right), "= operation", 0);
+ werror (W_LIT_OVERFLOW);
}
/* if the left & right type don't exactly match */
if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
compareType (ltype, rtype) <= 0)
{
- if (compareType (ltype->next, rtype) < 0)
+ if (left->aggr2ptr)
+ right = geniCodeCast (ltype, right, TRUE);
+ else if (compareType (ltype->next, rtype) < 0)
right = geniCodeCast (ltype->next, right, TRUE);
}
else if (compareType (ltype, rtype) < 0)
isOperandGlobal (left))
{
symbol *sym = NULL;
+ operand *newRight;
if (IS_TRUE_SYMOP (right))
sym = OP_SYMBOL (right);
ic = newiCode ('=', NULL, right);
- IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
- SPIL_LOC (right) = sym;
+ IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
+ /* avoid double fetch from volatile right, see bug 1369874 */
+ if (!isOperandVolatile (right, FALSE))
+ SPIL_LOC (newRight) = sym;
+ right = newRight;
ADDTOCHAIN (ic);
}
ic->supportRtn = 1;
ic->nosupdate = nosupdate;
- return left;
+ /* left could be a pointer assignment,
+ return the properly casted right instead */
+ return right;
}
/*-----------------------------------------------------------------*/
/* for all arguments that are passed in registers */
while (args)
{
- int first = 1;
if (IS_REGPARM (args->etype))
{
operand *opr = operandFromValue (args);
ic = newiCode (RECEIVE, func, NULL);
ic->argreg = SPEC_ARGREG(args->etype);
- if (first) {
+ if (ic->argreg == 1) {
currFunc->recvSize = getSize (sym->type);
- first = 0;
}
IC_RESULT (ic) = opr;
iCode *ic;
operand *func;
sym_link *fetype;
+ char *savefilename;
int savelineno;
/* reset the auto generation */
func = ast2iCode (tree->left,lvl+1);
fetype = getSpec (operandType (func));
+ savefilename = filename;
savelineno = lineno;
+ filename = OP_SYMBOL (func)->fileDef;
lineno = OP_SYMBOL (func)->lineDef;
/* create an entry label */
geniCodeLabel (entryLabel);
+ filename = savefilename;
lineno = savelineno;
/* create a proc icode */
ic = newiCode (FUNCTION, func, NULL);
- lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
+ filename = ic->filename = OP_SYMBOL (func)->fileDef;
+ lineno = ic->lineno = OP_SYMBOL (func)->lineDef;
ic->tree = tree;
ADDTOCHAIN (ic);
{
if (tree->falseLabel)
geniCodeGoto (tree->falseLabel);
- else
- assert (0);
}
goto exit;
}
/* If not all integer numbers are present the algorithm */
/* inserts jumps to the default label for the missing numbers */
/* and decides later whether it is worth it */
- min = (int) floatFromVal (vch = caseVals);
+ min = (int) ulFromVal (vch = caseVals);
while (vch->next)
{
cnt++;
vch = vch->next;
}
- max = (int) floatFromVal (vch);
+ max = (int) ulFromVal (vch);
/* Exit if the range is too large to handle with a jump table. */
if (1 + max - min > port->jumptableCost.maxCount)
/* Build the list of labels for the jump table. */
vch = caseVals;
- t = (int) floatFromVal (vch);
+ t = (int) ulFromVal (vch);
for (i=min; i<=max; i++)
{
if (vch && t==i)
addSet (&labels, newiTempLabel (buffer));
vch = vch->next;
if (vch)
- t = (int) floatFromVal (vch);
+ t = (int) ulFromVal (vch);
}
else
{
the condition is unsigned & minimum value is zero */
if (!(min == 0 && IS_UNSIGNED (cetype)))
{
- boundary = geniCodeLogic (cond, operandFromLit (min), '<');
+ boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL);
ic = newiCodeCondition (boundary, falseLabel, NULL);
ADDTOCHAIN (ic);
}
/* now for upper bounds */
- boundary = geniCodeLogic (cond, operandFromLit (max), '>');
+ boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL);
ic = newiCodeCondition (boundary, falseLabel, NULL);
ADDTOCHAIN (ic);
}
{
int switchVal, caseVal;
- switchVal = (int) floatFromVal (cond->operand.valOperand);
+ switchVal = (int) ulFromVal (cond->operand.valOperand);
while (caseVals)
{
- caseVal = (int) floatFromVal (caseVals);
+ caseVal = (int) ulFromVal (caseVals);
if (caseVal == switchVal)
{
SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
operand *compare = geniCodeLogic (cond,
operandFromValue (caseVals),
- EQ_OP);
+ EQ_OP, NULL);
SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
tree->values.switchVals.swNum,
- (int) floatFromVal (caseVals));
+ (int) ulFromVal (caseVals));
trueLabel = newiTempLabel (buffer);
ic = newiCodeCondition (compare, trueLabel, NULL);
case GETHBIT:
{
operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
+ if (!IS_BIT (operandType (op)))
+ setOperandType (op, UCHARTYPE);
+ return op;
+ }
+ case GETABIT:
+ {
+ operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
+ geniCodeRValue (right, FALSE),
+ tree->opval.op);
+ if (!IS_BIT (operandType (op)))
+ setOperandType (op, UCHARTYPE);
+ return op;
+ }
+ case GETBYTE:
+ {
+ operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
+ geniCodeRValue (right, FALSE),
+ tree->opval.op);
setOperandType (op, UCHARTYPE);
return op;
}
+ case GETWORD:
+ {
+ operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
+ geniCodeRValue (right, FALSE),
+ tree->opval.op);
+ setOperandType (op, UINTTYPE);
+ return op;
+ }
case AND_OP:
case OR_OP:
return geniCodeLogicAndOr (tree, lvl);
case NE_OP:
/* different compilers (even different gccs) evaluate
the two calls in a different order. to get the same
- result on all machines we've to specify a clear sequence.
+ result on all machines we have to specify a clear sequence.
return geniCodeLogic (geniCodeRValue (left, FALSE),
geniCodeRValue (right, FALSE),
tree->opval.op);
*/
{
- operand *leftOp, *rightOp;
+ operand *leftOp, *rightOp;
leftOp = geniCodeRValue (left , FALSE);
rightOp = geniCodeRValue (right, FALSE);
- return geniCodeLogic (leftOp, rightOp, tree->opval.op);
+ return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree);
}
case '?':
return geniCodeConditional (tree,lvl);
else
right = geniCodeRValue (right, FALSE);
- geniCodeAssign (left, right, 0, 1);
- return right;
+ return geniCodeAssign (left, right, 0, 1);
}
case MUL_ASSIGN:
return
" expected %s, got %s\n",
macro, args, file, line,
opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
- exit(-1);
+ exit(EXIT_FAILURE);
return op; // never reached, makes compiler happy.
}