#include "common.h"
#include "newalloc.h"
+#include "math.h"
/*-----------------------------------------------------------------*/
/* global variables */
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 *);
pedantic>1: "char c=200" is not allowed (evaluates to -56)
*/
-void checkConstantRange(sym_link *ltype, double v, char *msg, int pedantic) {
- LONG_LONG max = (LONG_LONG) 1 << bitsForType(ltype);
+void checkConstantRange(sym_link *ltype, value *val, char *msg, int pedantic) {
+ double max;
char message[132]="";
int warnings=0;
int negative=0;
+ 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
return;
}
- if (v<0) {
+ if (!SPEC_USIGN(val->type) && v<0) {
negative=1;
- // if not pedantic: -1 equals to 0xf..f
- if (SPEC_USIGN(ltype) && (!pedantic ? v!=-1 : 1)) {
+ if (SPEC_USIGN(ltype) && (pedantic>1)) {
warnings++;
}
v=-v;
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}", /*{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
);
{
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)) {
+ if (IS_VOID(operandType(condition))) {
werror(E_VOID_VALUE_USED);
}
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:
return 0;
}
+
/*-----------------------------------------------------------------*/
/* isOperandInFarSpace - will return true if operand is in farSpace */
/*-----------------------------------------------------------------*/
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);
+}
+
/*-----------------------------------------------------------------*/
/* isOperandOnStack - will return true if operand is on stack */
/*-----------------------------------------------------------------*/
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 */
/*-----------------------------------------------------------------*/
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) ==
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) &&
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;
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;
!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 */
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;
}
else
IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
- IC_RESULT (ic)->operand.symOperand->args = sym->args;
-
ADDTOCHAIN (ic);
return IC_RESULT (ic);
/* 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);
/* 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.
if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
- if (IS_GENPTR(type)) {
+ if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
// no way to set the storage
if (IS_LITERAL(optype)) {
werror(E_LITERAL_GENERIC);
} 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 (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 (!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++;
+ }
+ }
}
}
}
}
}
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 */
if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
{
checkConstantRange(ltype,
- operandLitValue(right), "compare operation", 1);
+ OP_VALUE(right), "compare operation", 1);
}
ctype = usualBinaryConversions (&left, &right);
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 */
if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
{
checkConstantRange(ltype,
- operandLitValue(right), "= operation", 0);
+ 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) &&
- compareType (ltype, rtype) < 0)
+ compareType (ltype, rtype) <= 0)
{
if (compareType (ltype->next, rtype) < 0)
right = geniCodeCast (ltype->next, right, TRUE);
/*-----------------------------------------------------------------*/
/* 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 */
}
/* 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->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
}
}
+ argVals=argVals->next;
+ return argVals;
}
/*-----------------------------------------------------------------*/
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))
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;
/* 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;
ADDTOCHAIN (ic);
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;
}
/*-----------------------------------------------------------------*/
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 */