int scopeLevel;
int lvaluereq;
-extern int labelKey ;
-
symbol *returnLabel ; /* function return label */
symbol *entryLabel ; /* function entry label */
/*-----------------------------------------------------------------*/
operand *geniCodeDerefPtr (operand *);
#define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
-
/* forward definition of print functions */
PRINTFUNC(picGetValueAtAddr);
PRINTFUNC(picSetValueAtAddr);
PRINTFUNC(picGeneric);
PRINTFUNC(picGenericOne);
PRINTFUNC(picCast);
-PRINTFUNC(picIncrement);
-PRINTFUNC(picDecrement);
PRINTFUNC(picAssign);
PRINTFUNC(picLabel);
PRINTFUNC(picGoto);
/*-----------------------------------------------------------------*/
int printOperand (operand *op, FILE *file)
{
- link *opetype;
+ sym_link *opetype;
int pnl = 0;
if (!op)
OP_LIVEFROM(op),OP_LIVETO(op),
OP_SYMBOL(op)->stack,
op->isaddr, OP_SYMBOL(op)->isreqv,OP_SYMBOL(op)->remat
-/* , */
-/* OP_SYMBOL(op)->allocreq,OP_SYMBOL(op)->remat, */
-/* OP_SYMBOL(op)->ruonly, */
-/* OP_SYMBOL(op)->isptr,op->isaddr,OP_SYMBOL(op)->used, */
-/* OP_SYMBOL(op)->isind, */
-/* OP_SYMBOL(op)->accuse, op->key, OP_SYMBOL(op)->key */
);
{
fprintf(file,"{"); printTypeChain(operandType(op),file);
}
+/*-----------------------------------------------------------------*/
+/* copyiCode - make a copy of the iCode given */
+/*-----------------------------------------------------------------*/
+iCode *copyiCode (iCode *ic)
+{
+ iCode *nic = newiCode(ic->op,NULL,NULL);
+
+ nic->lineno = ic->lineno ;
+ nic->filename= ic->filename ;
+ nic->block = ic->block;
+ nic->level = ic->level;
+
+ /* deal with the special cases first */
+ switch (ic->op) {
+ case IFX:
+ IC_COND(nic) = operandFromOperand(IC_COND(ic));
+ IC_TRUE(nic) = IC_TRUE(ic);
+ IC_FALSE(nic)= IC_FALSE(ic);
+ break;
+
+ case JUMPTABLE:
+ IC_JTCOND(nic) = operandFromOperand(IC_JTCOND(ic));
+ IC_JTLABELS(nic) = IC_JTLABELS(ic);
+ break;
+
+ case CALL:
+ 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:
+ IC_INLINE(nic) = IC_INLINE(ic);
+ break;
+
+ default:
+ IC_RESULT(nic) = operandFromOperand(IC_RESULT(ic));
+ IC_LEFT(nic) = operandFromOperand(IC_LEFT(ic));
+ IC_RIGHT(nic)= operandFromOperand(IC_RIGHT(ic));
+ }
+
+ return nic;
+}
+
/*-----------------------------------------------------------------*/
/* getTableEntry - gets the table entry for the given operator */
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
/* newiTempOperand - new intermediate temp operand */
/*-----------------------------------------------------------------*/
-operand *newiTempOperand (link *type, char throwType)
+operand *newiTempOperand (sym_link *type, char throwType)
{
symbol *itmp;
operand *op = newOperand();
- link *etype;
+ sym_link *etype;
op->type = SYMBOL ;
itmp = newiTemp(NULL);
/*-----------------------------------------------------------------*/
/* operandType - returns the type chain for an operand */
/*-----------------------------------------------------------------*/
-link *operandType (operand *op)
+sym_link *operandType (operand *op)
{
/* depending on type of operand */
switch (op->type) {
case TYPE :
return op->operand.typeOperand ;
+ default:
+ werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
+ " operand type not known ");
+ assert (0) ; /* should never come here */
+ /* Just to keep the compiler happy */
+ return (sym_link *)0;
}
-
- werror (E_INTERNAL_ERROR,__FILE__,__LINE__,
- " operand type not known ");
- assert (0) ; /* should never come here */
- /* Just to keep the compiler happy */
- return (link *)0;
}
/*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*/
int isOperandVolatile ( operand *op , bool chkTemp)
{
- link *optype ;
- link *opetype ;
+ sym_link *optype ;
+ sym_link *opetype ;
if (IS_ITEMP(op) && !chkTemp)
return 0;
/*-----------------------------------------------------------------*/
int isOperandLiteral ( operand *op )
{
- link *opetype ;
+ sym_link *opetype ;
if (!op)
return 0;
/*-----------------------------------------------------------------*/
bool isOperandInFarSpace (operand *op)
{
- link *etype;
+ sym_link *etype;
if (!op)
return FALSE;
else
return FALSE;
}
+ else
+ {
+ etype = getSpec(operandType(op));
+ }
+ return (IN_FARSPACE(SPEC_OCLS(etype)) ? TRUE : FALSE);
+}
+
+/*-----------------------------------------------------------------*/
+/* isOperandOnStack - will return true if operand is on stack */
+/*-----------------------------------------------------------------*/
+bool isOperandOnStack(operand *op)
+{
+ sym_link *etype;
+
+ if (!op)
+ return FALSE;
+
+ if (!IS_SYMOP(op))
+ return FALSE ;
etype = getSpec(operandType(op));
- return (IN_FARSPACE(SPEC_OCLS(etype)) ? TRUE : FALSE);
+
+ return ((IN_STACK(etype)) ? TRUE : FALSE);
}
/*-----------------------------------------------------------------*/
/* operandOperation - perforoms operations on operands */
/*-----------------------------------------------------------------*/
operand *operandOperation (operand *left,operand *right,
- int op, link *type)
+ int op, sym_link *type)
{
operand *retval = (operand *)0;
return 0;
}
+/*-----------------------------------------------------------------*/
+/* newiTempFromOp - create a temp Operand with same attributes */
+/*-----------------------------------------------------------------*/
+operand *newiTempFromOp (operand *op)
+{
+ operand *nop;
+
+ if (!op)
+ return NULL;
+
+ if (!IS_ITEMP(op))
+ return op;
+
+ nop = newiTempOperand(operandType(op),TRUE);
+ nop->isaddr = op->isaddr ;
+ nop->isvolatile = op->isvolatile ;
+ nop->isGlobal = op->isGlobal ;
+ nop->isLiteral= op->isLiteral ;
+ nop->noSpilLoc= op->noSpilLoc;
+ nop->usesDefs = op->usesDefs;
+ nop->isParm = op->isParm;
+ nop->parmBytes = op->parmBytes;
+ return nop;
+}
+
/*-----------------------------------------------------------------*/
/* operand from operand - creates an operand holder for the type */
/*-----------------------------------------------------------------*/
operand *operandFromOperand (operand *op)
{
- operand *nop = newOperand();
+ operand *nop ;
+ if (!op)
+ return NULL;
+ nop = newOperand();
nop->type = op->type;
nop->isaddr = op->isaddr ;
nop->key = op->key ;
{
operand *op ;
iCode *ic ;
-
+ int ok =1 ;
/* if the symbol's type is a literal */
/* then it is an enumerator type */
if (IS_LITERAL(sym->etype) && SPEC_ENUM(sym->etype))
op->key = sym->key ;
op->isvolatile = isOperandVolatile(op,TRUE);
op->isGlobal = isOperandGlobal(op);
+ op->parmBytes = sym->argStack;
return op;
}
/* 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)) && (!IS_DS390_PORT)) &&
+ options.stackAuto == 0)
+ ok =0;
+
if (!IS_AGGREGATE(sym->type) && /* not an aggregate */
!IS_FUNC(sym->type) && /* not a function */
!sym->_isparm && /* not a parameter */
!IS_VOLATILE(sym->etype) && /* not declared as volatile */
!IS_STATIC(sym->etype) && /* and not declared static */
!sym->islbl && /* not a label */
- !IN_FARSPACE(SPEC_OCLS(sym->etype)) && /* not in far space */
+ ok && /* farspace check */
!IS_BITVAR(sym->etype) /* not a bit variable */
) {
OP_SYMBOL(sym->reqv)->islocal = 1;
SPIL_LOC(sym->reqv) = sym;
}
-
+
if (!IS_AGGREGATE(sym->type)) {
op = newOperand();
op->type = SYMBOL;
/*-----------------------------------------------------------------*/
/* operandFromLink - operand from typeChain */
/*-----------------------------------------------------------------*/
-operand *operandFromLink (link *type)
+operand *operandFromLink (sym_link *type)
{
operand *op ;
- /* operand from link */
+ /* operand from sym_link */
if ( ! type )
return NULL ;
/*-----------------------------------------------------------------*/
/* setOperandType - sets the operand's type to the given type */
/*-----------------------------------------------------------------*/
-void setOperandType (operand *op, link *type)
+void setOperandType (operand *op, sym_link *type)
{
/* depending on the type of operand */
switch (op->type) {
operand *geniCodeRValue (operand *op, bool force)
{
iCode *ic ;
- link *type = operandType(op);
- link *etype= getSpec(type);
+ sym_link *type = operandType(op);
+ sym_link *etype= getSpec(type);
/* if this is an array & already */
/* an address then return this */
/*-----------------------------------------------------------------*/
/* geniCodeCast - changes the value from one type to another */
/*-----------------------------------------------------------------*/
-operand *geniCodeCast (link *type, operand *op, bool implicit)
+operand *geniCodeCast (sym_link *type, operand *op, bool implicit)
{
iCode *ic ;
- link *optype ;
- link *opetype = getSpec(optype = operandType(op));
- link *restype ;
+ sym_link *optype ;
+ sym_link *opetype = getSpec(optype = operandType(op));
+ sym_link *restype ;
/* one of them has size zero then error */
if (IS_VOID(optype)) {
return op;
/* if this is a literal then just change the type & return */
- if (IS_LITERAL(opetype) && !IS_PTR(type) && !IS_PTR(optype))
+ if (IS_LITERAL(opetype) && op->type == VALUE && !IS_PTR(type) && !IS_PTR(optype))
return operandFromValue(valCastLiteral(type,
operandLitValue(op)));
{
iCode *ic ;
int p2 = 0;
- link *resType ;
+ sym_link *resType ;
LRTYPE ;
/* if they are both literal then we know the result */
{
iCode *ic ;
int p2 = 0;
- link *resType;
- link *rtype = operandType(right);
- link *retype= getSpec(rtype);
- link *ltype = operandType(left);
- link *letype= getSpec(ltype);
+ sym_link *resType;
+ sym_link *rtype = operandType(right);
+ sym_link *retype= getSpec(rtype);
+ sym_link *ltype = operandType(left);
+ sym_link *letype= getSpec(ltype);
resType = computeType (ltype,rtype) ;
left = geniCodeCast(resType,left,TRUE);
operand *geniCodeModulus (operand *left, operand *right)
{
iCode *ic ;
- link *resType;
+ sym_link *resType;
LRTYPE ;
/* if they are both literal then we know the result */
{
iCode *ic ;
int isarray= 0;
- link *resType;
+ sym_link *resType;
LRTYPE ;
/* if they both pointers then */
return geniCodePtrPtrSubtract (left,right);
/* if they are both literal then we know the result */
- if (IS_LITERAL(letype) && IS_LITERAL(retype))
+ if (IS_LITERAL(letype) && IS_LITERAL(retype)
+ && left->isLiteral && right->isLiteral)
return operandFromValue (valMinus(left->operand.valOperand,
right->operand.valOperand));
operand *geniCodeAdd (operand *left, operand *right )
{
iCode *ic ;
- link *resType ;
+ sym_link *resType ;
operand *size ;
int isarray = 0;
LRTYPE ;
-
+
/* if left is an array then array access */
if (IS_ARRAY(ltype))
return geniCodeArray (left,right);
/* if the right side is LITERAL zero */
/* return the left side */
- if (IS_LITERAL(retype) && !floatFromVal(valFromType(retype)))
+ if (IS_LITERAL(retype) && right->isLiteral && !floatFromVal(valFromType(retype)))
return left;
/* if left is literal zero return right */
- if (IS_LITERAL(letype) && !floatFromVal(valFromType(letype)))
+ if (IS_LITERAL(letype) && left->isLiteral && !floatFromVal(valFromType(letype)))
return right ;
/* if left is an array or pointer then size */
isarray = left->isaddr;
size =
operandFromLit(getSize(ltype->next));
+ if (getSize(ltype) > 1 && (getSize(rtype) < INTSIZE))
+ {
+ right = geniCodeCast(INTTYPE,right,TRUE);
+ }
right = geniCodeMultiply (right ,size);
+
resType = copyLinkChain(ltype);
}
else { /* make them the same size */
}
/* if they are both literals then we know */
- if (IS_LITERAL(letype) && IS_LITERAL(retype))
+ if (IS_LITERAL(letype) && IS_LITERAL(retype)
+ && left->isLiteral && right->isLiteral)
return operandFromValue (valPlus(valFromType(letype),
valFromType(retype)));
/*-----------------------------------------------------------------*/
/* aggrToPtr - changes an aggregate to pointer to an aggregate */
/*-----------------------------------------------------------------*/
-link *aggrToPtr ( link *type, bool force)
+sym_link *aggrToPtr ( sym_link *type, bool force)
{
- link *etype ;
- link *ptype ;
+ sym_link *etype ;
+ sym_link *ptype ;
if (IS_PTR(type) && !force)
ptype->next = type;
/* if the output class is generic */
- if (SPEC_OCLS(etype) == generic)
- DCL_TYPE(ptype) = GPOINTER;
- else
- if (SPEC_OCLS(etype)->codesp ) {
- DCL_TYPE(ptype) = CPOINTER ;
- DCL_PTR_CONST(ptype) = 1;
- }
- else
- if (SPEC_OCLS(etype)->fmap && !SPEC_OCLS(etype)->paged)
- DCL_TYPE(ptype) = FPOINTER ;
- else
- if (SPEC_OCLS(etype)->fmap && SPEC_OCLS(etype)->paged)
- DCL_TYPE(ptype) = PPOINTER ;
- else
- if (SPEC_OCLS(etype) == idata)
- DCL_TYPE(ptype) = IPOINTER;
- else
- DCL_TYPE(ptype) = POINTER ;
-
+ if ((DCL_TYPE(ptype) = PTR_TYPE(SPEC_OCLS(etype))) == CPOINTER)
+ DCL_PTR_CONST(ptype) = port->mem.code_ro;
+
/* if the variable was declared a constant */
/* then the pointer points to a constant */
if (IS_CONSTANT(etype) )
/*-----------------------------------------------------------------*/
operand *geniCodeArray2Ptr (operand *op)
{
- link *optype = operandType(op);
- link *opetype = getSpec(optype);
-
- /* set the pointer depending on the storage class */
- if (SPEC_OCLS(opetype)->codesp ) {
- DCL_TYPE(optype) = CPOINTER ;
- DCL_PTR_CONST(optype) = 1;
- }
- else
- if (SPEC_OCLS(opetype)->fmap && !SPEC_OCLS(opetype)->paged)
- DCL_TYPE(optype) = FPOINTER ;
- else
- if (SPEC_OCLS(opetype)->fmap && SPEC_OCLS(opetype)->paged)
- DCL_TYPE(optype) = PPOINTER ;
- else
- if (SPEC_OCLS(opetype) == idata)
- DCL_TYPE(optype) = IPOINTER;
- else
- DCL_TYPE(optype) = POINTER ;
+ sym_link *optype = operandType(op);
+ sym_link *opetype = getSpec(optype);
+
+ /* set the pointer depending on the storage class */
+ 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 */
operand *geniCodeArray (operand *left,operand *right)
{
iCode *ic;
- link *ltype = operandType(left);
+ sym_link *ltype = operandType(left);
if (IS_PTR(ltype)) {
- operand *r ;
- int olval = lvaluereq ;
- lvaluereq = IS_PTR(ltype->next);
- r= geniCodeDerefPtr(geniCodeAdd(left,right));
- lvaluereq = olval;
- return r;
+ if (IS_PTR(ltype->next) && left->isaddr)
+ {
+ left = geniCodeRValue(left,FALSE);
+ }
+ return geniCodeDerefPtr(geniCodeAdd(left,right));
}
- /* array access */
+ /* array access */
+ if (getSize(operandType(right)) < INTSIZE)
+ {
+ /* Widen the index type to int first. */
+ right = geniCodeCast(INTTYPE,right,TRUE);
+ }
right = geniCodeMultiply(right,
operandFromLit(getSize(ltype->next)));
!IS_AGGREGATE(ltype->next) &&
!IS_PTR(ltype->next))
? ltype : ltype->next),0);
-/* IC_RESULT(ic) = newiTempOperand(ltype->next,0); */
+
IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(ltype->next));
ADDTOCHAIN(ic);
return IC_RESULT(ic) ;
operand *geniCodeStruct (operand *left, operand *right, bool islval)
{
iCode *ic ;
- link *type = operandType(left);
- link *etype = getSpec(type);
- link *retype ;
+ sym_link *type = operandType(left);
+ sym_link *etype = getSpec(type);
+ sym_link *retype ;
symbol *element = getStructElement(SPEC_STRUCT(etype),
right->operand.symOperand);
{
iCode *ic ;
operand *rOp ;
- link *optype = operandType(op);
+ sym_link *optype = operandType(op);
operand *result ;
operand *rv = (IS_ITEMP(op) ?
geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) :
op);
- link *rvtype = operandType(rv);
- int diff = (IS_PTR(rvtype) && DCL_TYPE(optype) != DCL_TYPE(rvtype));
+ sym_link *rvtype = operandType(rv);
int size = 0;
/* if this is not an address we have trouble */
return op ;
}
- rOp = newiTempOperand((diff ? rvtype : optype),0);
+ rOp = newiTempOperand(rvtype,0);
rOp->noSpilLoc = 1;
if (IS_ITEMP(rv))
size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
ic = newiCode('+',rv,operandFromLit(size));
- IC_RESULT(ic) = result =newiTempOperand((diff ? rvtype : optype),0);
+ IC_RESULT(ic) = result =newiTempOperand(rvtype,0);
ADDTOCHAIN(ic);
geniCodeAssign(op,result,0);
operand *geniCodePreInc (operand *op)
{
iCode *ic ;
- link *optype = operandType(op);
+ sym_link *optype = operandType(op);
operand *rop = (IS_ITEMP(op) ?
geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) :
op);
- link *roptype = operandType(rop);
- int diff = (IS_PTR(roptype) && (DCL_TYPE(roptype) != DCL_TYPE(optype)));
+ sym_link *roptype = operandType(rop);
operand *result;
int size = 0;
size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
ic = newiCode('+',rop,operandFromLit(size));
- IC_RESULT(ic) = result = newiTempOperand((diff ? roptype : optype),0) ;
+ IC_RESULT(ic) = result = newiTempOperand(roptype,0) ;
ADDTOCHAIN(ic);
{
iCode *ic ;
operand *rOp ;
- link *optype = operandType(op);
+ sym_link *optype = operandType(op);
operand *result ;
operand *rv = (IS_ITEMP(op) ?
geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) :
op);
- link *rvtype = operandType(rv);
- int diff = (IS_PTR(rvtype) && DCL_TYPE(optype) != DCL_TYPE(rvtype));
+ sym_link *rvtype = operandType(rv);
int size = 0;
/* if this is not an address we have trouble */
return op ;
}
- rOp = newiTempOperand((diff ? rvtype : optype),0);
+ rOp = newiTempOperand(rvtype,0);
rOp->noSpilLoc = 1;
if (IS_ITEMP(rv))
size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1);
ic = newiCode('-',rv,operandFromLit(size));
- IC_RESULT(ic) = result =newiTempOperand((diff ? rvtype : optype),0);
+ IC_RESULT(ic) = result =newiTempOperand(rvtype,0);
ADDTOCHAIN(ic);
geniCodeAssign(op,result,0);
operand *geniCodePreDec (operand *op)
{
iCode *ic ;
- link *optype = operandType(op);
+ sym_link *optype = operandType(op);
operand *rop = (IS_ITEMP(op) ?
geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) :
op);
- link *roptype = operandType(rop);
- int diff = (IS_PTR(roptype) && (DCL_TYPE(roptype) != DCL_TYPE(optype)));
+ sym_link *roptype = operandType(rop);
operand *result;
int size = 0;
size = (IS_PTR(roptype) ? getSize(roptype->next) : 1);
ic = newiCode('-',rop,operandFromLit(size));
- IC_RESULT(ic) = result = newiTempOperand((diff ? roptype : optype),0) ;
+ IC_RESULT(ic) = result = newiTempOperand(roptype,0) ;
ADDTOCHAIN(ic);
/* geniCodeBitwise - gen int code for bitWise operators */
/*-----------------------------------------------------------------*/
operand *geniCodeBitwise (operand *left, operand *right,
- int oper, link *resType)
+ int oper, sym_link *resType)
{
iCode *ic;
operand *geniCodeAddressOf (operand *op)
{
iCode *ic;
- link *p ;
- link *optype = operandType(op);
- link *opetype= getSpec(optype);
+ sym_link *p ;
+ sym_link *optype = operandType(op);
+ sym_link *opetype= getSpec(optype);
+ /* lvalue check already done in decorateType */
/* this must be a lvalue */
- if (!op->isaddr && !IS_AGGREGATE(optype)) {
- werror (E_LVALUE_REQUIRED,"&");
- return op;
- }
+/* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
+/* werror (E_LVALUE_REQUIRED,"&"); */
+/* return op; */
+/* } */
p = newLink();
p->class = DECLARATOR ;
- /* set the pointer depending on the storage class */
- if (SPEC_OCLS(opetype)->codesp ) {
- DCL_TYPE(p) = CPOINTER ;
- DCL_PTR_CONST(p) = 1;
- }
- else
- if (SPEC_OCLS(opetype)->fmap && !SPEC_OCLS(opetype)->paged)
- DCL_TYPE(p) = FPOINTER ;
- else
- if (SPEC_OCLS(opetype)->fmap && SPEC_OCLS(opetype)->paged)
- DCL_TYPE(p) = PPOINTER ;
- else
- if (SPEC_OCLS(opetype) == idata)
- DCL_TYPE(p) = IPOINTER;
- else
- if (SPEC_OCLS(opetype) == data ||
- SPEC_OCLS(opetype) == overlay)
- DCL_TYPE(p) = POINTER ;
- else
- DCL_TYPE(p) = GPOINTER;
+ /* set the pointer depending on the storage class */
+ if ((DCL_TYPE(p) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER)
+ DCL_PTR_CONST(p) = port->mem.code_ro;
+
/* make sure we preserve the const & volatile */
if (IS_CONSTANT(opetype))
DCL_PTR_CONST(p) = 1;
/*-----------------------------------------------------------------*/
/* setOClass - sets the output class depending on the pointer type */
/*-----------------------------------------------------------------*/
-void setOClass (link *ptr, link *spec)
+void setOClass (sym_link *ptr, sym_link *spec)
{
switch (DCL_TYPE(ptr)) {
case POINTER:
case PPOINTER:
SPEC_OCLS(spec) = xstack;
break;
-
+
+ case EEPPOINTER:
+ SPEC_OCLS(spec) = eeprom;
+ break;
+
+ default:
+ break;
+
}
}
/*-----------------------------------------------------------------*/
operand *geniCodeDerefPtr (operand *op)
{
- link *rtype , *retype ;
- link *optype = operandType(op);
+ sym_link *rtype , *retype ;
+ sym_link *optype = operandType(op);
/* if this is a pointer then generate the rvalue */
if (IS_PTR(optype)) {
}
/* now get rid of the pointer part */
- if (lvaluereq && IS_ITEMP(op))
+ if (lvaluereq && IS_ITEMP(op) )
+ {
retype = getSpec(rtype = copyLinkChain(optype)) ;
+ }
else
+ {
retype = getSpec(rtype = copyLinkChain(optype->next)) ;
+ }
/* if this is a pointer then outputclass needs 2b updated */
if (IS_PTR(optype))
setOClass(optype,retype);
- op = geniCodeRValue(op,TRUE);
op->isGptr = IS_GENPTR(optype);
/* if the pointer was declared as a constant */
if (IS_PTR_CONST(optype))
SPEC_CONST(retype) = 1;
-
- setOperandType(op,rtype);
op->isaddr = (IS_PTR(rtype) ||
IS_STRUCT(rtype) ||
IS_INT(rtype) ||
IS_CHAR(rtype) ||
IS_FLOAT(rtype) );
+
+ if (!lvaluereq)
+ op = geniCodeRValue(op,TRUE);
+
+ setOperandType(op,rtype);
return op;
}
operand *geniCodeUnaryMinus (operand *op)
{
iCode *ic ;
- link *optype = operandType(op);
+ sym_link *optype = operandType(op);
if (IS_LITERAL(optype))
return operandFromLit(- floatFromVal(op->operand.valOperand));
operand *geniCodeLeftShift (operand *left, operand *right)
{
iCode *ic;
- link *ltype = operandType(left);
+
+ /* Operands must be promoted to int, according to ISO. */
+ if (getSize(operandType(right)) < INTSIZE)
+ {
+ right = geniCodeCast(INTTYPE,right,TRUE);
+ }
+
+ if (getSize(operandType(left)) < INTSIZE)
+ {
+ left = geniCodeCast(INTTYPE,left,TRUE);
+ }
ic = newiCode(LEFT_OP,left,right);
- IC_RESULT(ic) = newiTempOperand(ltype,0);
+ IC_RESULT(ic) = newiTempOperand(operandType(left),0);
ADDTOCHAIN(ic);
return IC_RESULT(ic) ;
}
operand *geniCodeRightShift (operand *left, operand *right)
{
iCode *ic;
- link *ltype = operandType(left);
+
+ /* Operands must be promoted to int, according to ISO. */
+ if (getSize(operandType(right)) < INTSIZE)
+ {
+ right = geniCodeCast(INTTYPE,right,TRUE);
+ }
+
+ if (getSize(operandType(left)) < INTSIZE)
+ {
+ left = geniCodeCast(INTTYPE,left,TRUE);
+ }
ic = newiCode(RIGHT_OP,left,right);
- IC_RESULT(ic) = newiTempOperand(ltype,0);
+ IC_RESULT(ic) = newiTempOperand(operandType(left),0);
ADDTOCHAIN(ic);
return IC_RESULT(ic) ;
}
+#if defined(__BORLANDC__) || defined(_MSC_VER)
+#define LONG_LONG __int64
+#else
+#define LONG_LONG long long
+#endif
+
/*-----------------------------------------------------------------*/
/* geniCodeLogic- logic code */
/*-----------------------------------------------------------------*/
operand *geniCodeLogic (operand *left, operand *right, int op )
{
iCode *ic ;
- link *ctype;
- link *rtype = operandType(right);
- link *ltype = operandType(left);
+ sym_link *ctype;
+ sym_link *rtype = operandType(right);
+ sym_link *ltype = operandType(left);
/* left is integral type and right is literal then
check if the literal value is within bounds */
int nbits = bitsForType(ltype);
long v = operandLitValue(right);
- if (v > ((long long) 1 << nbits) && v > 0)
+ if (v > ((LONG_LONG) 1 << nbits) && v > 0)
werror(W_CONST_RANGE," compare operation ");
}
operand *geniCodeAssign (operand *left, operand *right, int nosupdate)
{
iCode *ic ;
- link *ltype = operandType(left);
- link *rtype = operandType(right);
+ sym_link *ltype = operandType(left);
+ sym_link *rtype = operandType(right);
if (!left->isaddr && !IS_ITEMP(left)) {
werror(E_LVALUE_REQUIRED,"assignment");
/* 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) && right->type == VALUE && IS_LITERAL(rtype)) {
int nbits = bitsForType(ltype);
long v = operandLitValue(right);
- if (v > ((long long)1 << nbits) && v > 0)
+ if (v > ((LONG_LONG)1 << nbits) && v > 0)
werror(W_CONST_RANGE," = operation");
}
+
/* if the left & right type don't exactly match */
/* if pointer set then make sure the check is
done with the type & not the pointer */
parms->right->left->lvalue = 1;
parms->opval.oprnd =
- geniCodeRValue(ast2iCode (parms),TRUE);
+ geniCodeRValue(ast2iCode (parms),FALSE);
parms->type = EX_OPERAND ;
}
/*-----------------------------------------------------------------*/
/* geniCodeParms - generates parameters */
/*-----------------------------------------------------------------*/
-static void geniCodeParms ( ast *parms , int *stack, link *fetype)
+static void geniCodeParms ( ast *parms , int *stack, sym_link *fetype, symbol *func)
{
iCode *ic ;
operand *pval ;
/* 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) ;
- geniCodeParms (parms->right, stack,fetype);
+ geniCodeParms (parms->left, stack,fetype,func) ;
+ geniCodeParms (parms->right, stack,fetype,func);
return ;
}
}
/* if register parm then make it a send */
- if ((parms->argSym && IS_REGPARM(parms->argSym->etype)) ||
- IS_REGPARM(parms->etype)) {
+ if (((parms->argSym && IS_REGPARM(parms->argSym->etype)) ||
+ IS_REGPARM(parms->etype)) && !func->hasVargs ) {
ic = newiCode(SEND,pval,NULL);
ADDTOCHAIN(ic);
} else {
geniCodeAssign(top,pval,1);
}
else {
-
+ sym_link *p = operandType(pval);
/* push */
ic = newiCode(IPUSH,pval,NULL);
ic->parmPush = 1;
/* update the stack adjustment */
- *stack += getSize(operandType(pval));
+ *stack += getSize(IS_AGGREGATE(p)? aggrToPtr(p,FALSE):p);
ADDTOCHAIN(ic);
}
}
{
iCode *ic ;
operand *result ;
- link *type, *etype;
+ sym_link *type, *etype;
int stack = 0 ;
/* take care of parameters with side-effecting
geniCodeSEParms ( parms );
/* first the parameters */
- geniCodeParms ( parms , &stack , getSpec(operandType(left)));
+ geniCodeParms ( parms , &stack , getSpec(operandType(left)), OP_SYMBOL(left));
/* now call : if symbol then pcall */
if (IS_ITEMP(left))
/* we will use it after all optimizations
and before liveRange calculation */
- if (!sym->addrtaken &&
- !IS_VOLATILE(sym->etype) &&
- !IN_FARSPACE(SPEC_OCLS(sym->etype))) {
- opl = newiTempOperand(args->type,0);
- sym->reqv = opl ;
- sym->reqv->key = sym->key ;
- OP_SYMBOL(sym->reqv)->key = sym->key;
- OP_SYMBOL(sym->reqv)->isreqv = 1;
- OP_SYMBOL(sym->reqv)->islocal= 0;
- SPIL_LOC(sym->reqv) = sym;
+ if (!sym->addrtaken && !IS_VOLATILE(sym->etype)) {
+
+ if (IN_FARSPACE(SPEC_OCLS(sym->etype)) &&
+ options.stackAuto == 0 &&
+ !IS_DS390_PORT) {
+ } else {
+ opl = newiTempOperand(args->type,0);
+ sym->reqv = opl ;
+ sym->reqv->key = sym->key ;
+ OP_SYMBOL(sym->reqv)->key = sym->key;
+ OP_SYMBOL(sym->reqv)->isreqv = 1;
+ OP_SYMBOL(sym->reqv)->islocal= 0;
+ SPIL_LOC(sym->reqv) = sym;
+ }
}
ic = newiCode(RECEIVE,NULL,NULL);
{
iCode *ic ;
operand *func ;
- link *fetype ;
+ sym_link *fetype ;
int savelineno ;
/* reset the auto generation */
{
iCode *ic;
operand *condition = ast2iCode(tree->left);
-/* link *ctype = operandType(condition); */
- link *cetype;
+ sym_link *cetype;
/* if condition is null then exit */
if (!condition)
/* first we rule out the boundary conditions */
/* if only optimization says so */
if ( ! optimize.noJTabBoundary ) {
- link *cetype = getSpec(operandType(cond));
+ sym_link *cetype = getSpec(operandType(cond));
/* no need to check the lower bound if
the condition is unsigned & minimum value is zero */
if (!( min == 0 && SPEC_USIGN(cetype))) {
/* if the min is not zero then we no make it zero */
if (min) {
cond = geniCodeSubtract(cond,operandFromLit(min));
- setOperandType(cond,ucharType);
+ setOperandType(cond, UCHARTYPE);
}
/* now create the jumptable */
tree->opval.op != SWITCH &&
tree->opval.op != FUNCTION &&
tree->opval.op != INLINEASM ) {
- if (IS_ASSIGN_OP(tree->opval.op) || IS_DEREF_OP(tree)) {
+
+ if (IS_ASSIGN_OP(tree->opval.op) ||
+ IS_DEREF_OP(tree) ||
+ (tree->opval.op == '&' && !tree->right) ||
+ tree->opval.op == PTR_OP) {
+ lvaluereq++;
+ if ((IS_ARRAY_OP(tree->left) && IS_ARRAY_OP(tree->left->left)) ||
+ (IS_DEREF_OP(tree) && IS_ARRAY_OP(tree->left)))
+ {
+ int olvr = lvaluereq ;
+ lvaluereq = 0;
+ left = operandFromAst(tree->left);
+ lvaluereq = olvr - 1;
+ } else {
+ left = operandFromAst(tree->left);
+ lvaluereq--;
+ }
+ if (IS_DEREF_OP(tree) && IS_DEREF_OP(tree->left))
+ left = geniCodeRValue(left,TRUE);
+ } else {
+ left = operandFromAst(tree->left);
+ }
+ if (tree->opval.op == INC_OP ||
+ tree->opval.op == DEC_OP) {
lvaluereq++;
- left = operandFromAst(tree->left);
+ right= operandFromAst(tree->right);
lvaluereq--;
} else {
- left = operandFromAst(tree->left);
+ right= operandFromAst(tree->right);
}
- right= operandFromAst(tree->right);
}
/* now depending on the type of operand */
switch (tree->opval.op) {
case '[' : /* array operation */
- left= geniCodeRValue (left,FALSE);
- right=geniCodeRValue (right,TRUE);
+ {
+ sym_link *ltype = operandType(left);
+ left= geniCodeRValue (left,IS_PTR(ltype->next) ? TRUE : FALSE);
+ right=geniCodeRValue (right,TRUE);
+ }
return geniCodeArray (left,right);
case PTR_OP: /* structure pointer dereference */
{
- link *pType;
+ sym_link *pType;
pType = operandType(left);
left = geniCodeRValue(left,TRUE);
case GETHBIT:
{
operand *op = geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op);
- setOperandType(op,ucharType);
+ setOperandType(op, UCHARTYPE);
return op;
}
case '>' :
case '=' :
{
- link *rtype = operandType(right);
- link *ltype = operandType(left);
+ 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 = geniCodeRValue(right,TRUE);
geniCodeRValue(right,FALSE)),0);
case ADD_ASSIGN:
{
- link *rtype = operandType(right);
- link *ltype = operandType(left);
+ 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 = geniCodeRValue(right,TRUE);
}
case SUB_ASSIGN:
{
- link *rtype = operandType(right);
- link *ltype = operandType(left);
+ 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 = geniCodeRValue(right,TRUE);