X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCicode.c;h=49d1aaa414046272d4052e3751999912683df3c8;hb=20d011f428a26a3ae0546e7dbc0c1f89ded856ce;hp=bcfe1a2c754c15cbbc7672e90282a2a1533109c2;hpb=f6224daca530284743e68a8234854416234a6155;p=fw%2Fsdcc diff --git a/src/SDCCicode.c b/src/SDCCicode.c index bcfe1a2c..49d1aaa4 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -24,384 +24,488 @@ #include "common.h" #include "newalloc.h" +#include "math.h" /*-----------------------------------------------------------------*/ /* global variables */ -set *iCodeChain = NULL ; +set *iCodeChain = NULL; int iTempNum = 0; int iTempLblNum = 0; -int operandKey = 0 ; +int operandKey = 0; int iCodeKey = 0; -char *filename ; -int lineno ; +char *filename; +int lineno; int block; int scopeLevel; -int lvaluereq; -symbol *returnLabel ; /* function return label */ -symbol *entryLabel ; /* function entry label */ +symbol *returnLabel; /* function return label */ +symbol *entryLabel; /* function entry label */ + /*-----------------------------------------------------------------*/ /* forward definition of some functions */ -operand *geniCodeDivision (operand *,operand *); -operand *geniCodeAssign (operand *,operand *,int); -operand *geniCodeArray (operand *,operand *); +operand *geniCodeDivision (operand *, operand *); +operand *geniCodeAssign (operand *, operand *, int); +operand *geniCodeArray (operand *, operand *,int); operand *geniCodeArray2Ptr (operand *); -operand *geniCodeRValue (operand *, bool ); -operand *geniCodeDerefPtr (operand *); +operand *geniCodeRValue (operand *, bool); +operand *geniCodeDerefPtr (operand *,int); +int isLvaluereq(int lvl); #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s) -/* forward definition of print functions */ -PRINTFUNC(picGetValueAtAddr); -PRINTFUNC(picSetValueAtAddr); -PRINTFUNC(picAddrOf); -PRINTFUNC(picGeneric); -PRINTFUNC(picGenericOne); -PRINTFUNC(picCast); -PRINTFUNC(picAssign); -PRINTFUNC(picLabel); -PRINTFUNC(picGoto); -PRINTFUNC(picIfx); -PRINTFUNC(picJumpTable); -PRINTFUNC(picInline); -PRINTFUNC(picReceive); - -iCodeTable codeTable[] = { - { '!' , "not", picGenericOne , NULL }, - { '~' , "~" , picGenericOne , NULL }, - { RRC , "rrc", picGenericOne , NULL }, - { RLC , "rlc", picGenericOne , NULL }, - { GETHBIT ,"ghbit", picGenericOne , NULL }, - { UNARYMINUS , "-" , picGenericOne , NULL }, - { IPUSH , "push",picGenericOne , NULL }, - { IPOP , "pop", picGenericOne , NULL }, - { CALL , "call",picGenericOne , NULL }, - { PCALL , "pcall",picGenericOne , NULL }, - { FUNCTION , "proc", picGenericOne , NULL }, - { ENDFUNCTION ,"eproc", picGenericOne , NULL }, - { RETURN , "ret", picGenericOne , NULL }, - { '+' , "+" , picGeneric , NULL }, - { '-' , "-" , picGeneric , NULL }, - { '*' , "*" , picGeneric , NULL }, - { '/' , "/" , picGeneric , NULL }, - { '%' , "%" , picGeneric , NULL }, - { '>' , ">" , picGeneric , NULL }, - { '<' , "<" , picGeneric , NULL }, - { LE_OP , "<=" , picGeneric , NULL }, - { GE_OP , ">=" , picGeneric , NULL }, - { EQ_OP , "==" , picGeneric , NULL }, - { NE_OP , "!=" , picGeneric , NULL }, - { AND_OP , "&&" , picGeneric , NULL }, - { OR_OP , "||" , picGeneric , NULL }, - { '^' , "^" , picGeneric , NULL }, - { '|' , "|" , picGeneric , NULL }, - { BITWISEAND , "&" , picGeneric , NULL }, - { LEFT_OP , "<<" , picGeneric , NULL }, - { RIGHT_OP , ">>" , picGeneric , NULL }, - { GET_VALUE_AT_ADDRESS, "@" , picGetValueAtAddr, NULL }, - { ADDRESS_OF , "&" , picAddrOf , NULL }, - { CAST , "<>" , picCast , NULL }, - { '=' , ":=" , picAssign , NULL }, - { LABEL , "" , picLabel , NULL }, - { GOTO , "" , picGoto , NULL }, - { JUMPTABLE ,"jtab" , picJumpTable , NULL }, - { IFX , "if" , picIfx , NULL }, - { INLINEASM , "" , picInline , NULL }, - { RECEIVE , "recv", picReceive , NULL }, - { SEND , "send", picGenericOne , NULL } +/* forward definition of ic print functions */ +PRINTFUNC (picGetValueAtAddr); +PRINTFUNC (picSetValueAtAddr); +PRINTFUNC (picAddrOf); +PRINTFUNC (picGeneric); +PRINTFUNC (picGenericOne); +PRINTFUNC (picCast); +PRINTFUNC (picAssign); +PRINTFUNC (picLabel); +PRINTFUNC (picGoto); +PRINTFUNC (picIfx); +PRINTFUNC (picJumpTable); +PRINTFUNC (picInline); +PRINTFUNC (picReceive); + +iCodeTable codeTable[] = +{ + {'!', "not", picGenericOne, NULL}, + {'~', "~", picGenericOne, NULL}, + {RRC, "rrc", picGenericOne, NULL}, + {RLC, "rlc", picGenericOne, NULL}, + {GETHBIT, "ghbit", picGenericOne, NULL}, + {UNARYMINUS, "-", picGenericOne, NULL}, + {IPUSH, "push", picGenericOne, NULL}, + {IPOP, "pop", picGenericOne, NULL}, + {CALL, "call", picGenericOne, NULL}, + {PCALL, "pcall", picGenericOne, NULL}, + {FUNCTION, "proc", picGenericOne, NULL}, + {ENDFUNCTION, "eproc", picGenericOne, NULL}, + {RETURN, "ret", picGenericOne, NULL}, + {'+', "+", picGeneric, NULL}, + {'-', "-", picGeneric, NULL}, + {'*', "*", picGeneric, NULL}, + {'/', "/", picGeneric, NULL}, + {'%', "%", picGeneric, NULL}, + {'>', ">", picGeneric, NULL}, + {'<', "<", picGeneric, NULL}, + {LE_OP, "<=", picGeneric, NULL}, + {GE_OP, ">=", picGeneric, NULL}, + {EQ_OP, "==", picGeneric, NULL}, + {NE_OP, "!=", picGeneric, NULL}, + {AND_OP, "&&", picGeneric, NULL}, + {OR_OP, "||", picGeneric, NULL}, + {'^', "^", picGeneric, NULL}, + {'|', "|", picGeneric, NULL}, + {BITWISEAND, "&", picGeneric, NULL}, + {LEFT_OP, "<<", picGeneric, NULL}, + {RIGHT_OP, ">>", picGeneric, NULL}, + {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL}, + {ADDRESS_OF, "&", picAddrOf, NULL}, + {CAST, "<>", picCast, NULL}, + {'=', ":=", picAssign, NULL}, + {LABEL, "", picLabel, NULL}, + {GOTO, "", picGoto, NULL}, + {JUMPTABLE, "jtab", picJumpTable, NULL}, + {IFX, "if", picIfx, NULL}, + {INLINEASM, "", picInline, NULL}, + {RECEIVE, "recv", picReceive, NULL}, + {SEND, "send", picGenericOne, NULL}, + {ARRAYINIT, "arrayInit", picGenericOne, NULL}, }; +/*-----------------------------------------------------------------*/ +/* checkConstantRange: check a constant against the type */ +/*-----------------------------------------------------------------*/ + +/* 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 (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 + if (options.pedantic) + pedantic=2; +#endif + + if (SPEC_NOUN(ltype)==FLOAT) { + // anything will do + return; + } + + if (!SPEC_USIGN(val->type) && v<0) { + negative=1; + if (SPEC_USIGN(ltype) && (pedantic>1)) { + warnings++; + } + v=-v; + } + + // if very pedantic: "char c=200" is not allowed + if (pedantic>1 && !SPEC_USIGN(ltype)) { + max = max/2 + negative; + } + + if (v >= max) { + warnings++; + } + +#if 0 // temporary disabled, leaving the warning as a reminder + if (warnings) { + SNPRINTF (message, sizeof(message), "for %s %s in %s", + SPEC_USIGN(ltype) ? "unsigned" : "signed", + nounName(ltype), msg); + werror (W_CONST_RANGE, message); + + if (pedantic>1) + fatalError++; + } +#endif +} /*-----------------------------------------------------------------*/ /* operandName - returns the name of the operand */ /*-----------------------------------------------------------------*/ -int printOperand (operand *op, FILE *file) +int +printOperand (operand * op, FILE * file) { - sym_link *opetype; - int pnl = 0; + sym_link *opetype; + int pnl = 0; - if (!op) - return 1; + if (!op) + return 1; - if (!file) { - file = stdout; - pnl = 1; + if (!file) + { + file = stdout; + pnl = 1; } - switch (op->type) { + switch (op->type) + { case VALUE: - opetype = getSpec (operandType(op)); - if (SPEC_NOUN(opetype) == V_FLOAT) - fprintf (file,"%g {", SPEC_CVAL(opetype).v_float); - else - fprintf (file,"0x%x {",(int) floatFromVal(op->operand.valOperand)); - printTypeChain(operandType(op),file); - fprintf(file,"}"); - break; + opetype = getSpec (operandType (op)); + if (SPEC_NOUN (opetype) == V_FLOAT) + fprintf (file, "%g {", SPEC_CVAL (opetype).v_float); + else + fprintf (file, "0x%x {", (int) floatFromVal (op->operand.valOperand)); + printTypeChain (operandType (op), file); + fprintf (file, "}"); + break; - case SYMBOL : + case SYMBOL: #define REGA 1 #ifdef REGA - fprintf (file,"%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%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 - ); - { - fprintf(file,"{"); printTypeChain(operandType(op),file); - if (SPIL_LOC(op) && IS_ITEMP(op)) - fprintf(file,"}{ sir@ %s",SPIL_LOC(op)->rname); - fprintf(file,"}"); - - } + 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)->dptr + ); + { + fprintf (file, "{"); + printTypeChain (operandType (op), file); + if (SPIL_LOC (op) && IS_ITEMP (op)) + fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname); + fprintf (file, "}"); - /* if assigned to registers */ - if (OP_SYMBOL(op)->nRegs) { - if (OP_SYMBOL(op)->isspilt) { - if (!OP_SYMBOL(op)->remat) - if (OP_SYMBOL(op)->usl.spillLoc) - fprintf(file,"[%s]",(OP_SYMBOL(op)->usl.spillLoc->rname[0] ? - OP_SYMBOL(op)->usl.spillLoc->rname : - OP_SYMBOL(op)->usl.spillLoc->name)); - else - fprintf(file,"[err]"); - else - fprintf(file,"[remat]"); - } - else { - int i; - fprintf(file,"["); - for(i=0;inRegs;i++) - fprintf(file,"%s ", port->getRegName(OP_SYMBOL(op)->regs[i])); - fprintf(file,"]"); } - } + + /* if assigned to registers */ + if (OP_SYMBOL (op)->nRegs) + { + if (OP_SYMBOL (op)->isspilt) + { + if (!OP_SYMBOL (op)->remat) + if (OP_SYMBOL (op)->usl.spillLoc) + fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ? + OP_SYMBOL (op)->usl.spillLoc->rname : + OP_SYMBOL (op)->usl.spillLoc->name)); + else + fprintf (file, "[err]"); + else + fprintf (file, "[remat]"); + } + else + { + int i; + fprintf (file, "["); + for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) + fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i])); + fprintf (file, "]"); + } + } #else - fprintf(file,"%s",(OP_SYMBOL(op)->rname[0] ? - OP_SYMBOL(op)->rname : OP_SYMBOL(op)->name)); - /* if assigned to registers */ - if (OP_SYMBOL(op)->nRegs && !OP_SYMBOL(op)->isspilt) { - int i; - fprintf(file,"["); - for(i=0;inRegs;i++) - fprintf(file,"%s ",(OP_SYMBOL(op)->regs[i] ? - OP_SYMBOL(op)->regs[i]->name : - "err")); - fprintf(file,"]"); - } + fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ? + OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name)); + /* if assigned to registers */ + if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt) + { + int i; + fprintf (file, "["); + for (i = 0; i < OP_SYMBOL (op)->nRegs; i++) + fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ? + OP_SYMBOL (op)->regs[i]->name : + "err")); + fprintf (file, "]"); + } #endif - break ; + break; case TYPE: - fprintf(file,"("); - printTypeChain(op->operand.typeOperand,file); - fprintf(file,")"); - break; + fprintf (file, "("); + printTypeChain (op->operand.typeOperand, file); + fprintf (file, ")"); + break; } - if (pnl) - fprintf(file,"\n"); - return 0; + if (pnl) + fprintf (file, "\n"); + return 0; } /*-----------------------------------------------------------------*/ /* print functions */ /*-----------------------------------------------------------------*/ -PRINTFUNC(picGetValueAtAddr) +PRINTFUNC (picGetValueAtAddr) { - fprintf(of,"\t"); - printOperand (IC_RESULT(ic),of); - fprintf (of," = "); - fprintf (of,"@["); - printOperand (IC_LEFT(ic), of); - fprintf (of,"]"); + fprintf (of, "\t"); + printOperand (IC_RESULT (ic), of); + fprintf (of, " = "); + fprintf (of, "@["); + printOperand (IC_LEFT (ic), of); + fprintf (of, "]"); - fprintf(of,"\n"); + fprintf (of, "\n"); } -PRINTFUNC(picSetValueAtAddr) +PRINTFUNC (picSetValueAtAddr) { - fprintf(of,"\t"); - fprintf(of,"*["); - printOperand(IC_LEFT(ic),of); - fprintf(of,"] = "); - printOperand(IC_RIGHT(ic),of); - fprintf (of,"\n"); + fprintf (of, "\t"); + fprintf (of, "*["); + printOperand (IC_LEFT (ic), of); + fprintf (of, "] = "); + printOperand (IC_RIGHT (ic), of); + fprintf (of, "\n"); } -PRINTFUNC(picAddrOf) +PRINTFUNC (picAddrOf) { - fprintf(of,"\t"); - printOperand(IC_RESULT(ic),of); - if (IS_ITEMP(IC_LEFT(ic))) - fprintf(of," = "); - else - fprintf(of," = &["); - printOperand(IC_LEFT(ic),of); - if (IC_RIGHT(ic)) { - if (IS_ITEMP(IC_LEFT(ic))) - fprintf(of," offsetAdd "); + fprintf (of, "\t"); + printOperand (IC_RESULT (ic), of); + if (IS_ITEMP (IC_LEFT (ic))) + fprintf (of, " = "); else - fprintf(of," , "); - printOperand(IC_RIGHT(ic),of); + fprintf (of, " = &["); + printOperand (IC_LEFT (ic), of); + if (IC_RIGHT (ic)) + { + if (IS_ITEMP (IC_LEFT (ic))) + fprintf (of, " offsetAdd "); + else + fprintf (of, " , "); + printOperand (IC_RIGHT (ic), of); } - if (IS_ITEMP(IC_LEFT(ic))) - fprintf (of,"\n"); - else - fprintf (of,"]\n"); + if (IS_ITEMP (IC_LEFT (ic))) + fprintf (of, "\n"); + else + fprintf (of, "]\n"); } -PRINTFUNC(picJumpTable) +PRINTFUNC (picJumpTable) { - symbol *sym; + symbol *sym; - fprintf(of,"\t"); - fprintf(of,"%s\t",s); - printOperand(IC_JTCOND(ic),of); - fprintf(of,"\n"); - for ( sym = setFirstItem(IC_JTLABELS(ic)); sym; - sym = setNextItem(IC_JTLABELS(ic))) - fprintf(of,"\t\t\t%s\n",sym->name); + fprintf (of, "\t"); + fprintf (of, "%s\t", s); + printOperand (IC_JTCOND (ic), of); + fprintf (of, "\n"); + for (sym = setFirstItem (IC_JTLABELS (ic)); sym; + sym = setNextItem (IC_JTLABELS (ic))) + fprintf (of, "\t\t\t%s\n", sym->name); } -PRINTFUNC(picGeneric) +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"); + 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"); } -PRINTFUNC(picGenericOne) +PRINTFUNC (picGenericOne) { - fprintf(of,"\t"); - if ( IC_RESULT(ic) ) { - printOperand(IC_RESULT(ic),of); - fprintf (of," = "); + fprintf (of, "\t"); + if (IC_RESULT (ic)) + { + printOperand (IC_RESULT (ic), of); + fprintf (of, " = "); } - if (IC_LEFT(ic)) { - fprintf (of,"%s ",s); - printOperand(IC_LEFT(ic),of); + if (IC_LEFT (ic)) + { + fprintf (of, "%s ", s); + printOperand (IC_LEFT (ic), of); } - if (! IC_RESULT(ic) && !IC_LEFT(ic)) - fprintf (of,s); + if (!IC_RESULT (ic) && !IC_LEFT (ic)) + fprintf (of, s); - fprintf(of,"\n"); + if (ic->op == SEND || ic->op == RECEIVE) { + fprintf(of,"{argreg = %d}",ic->argreg); + } + fprintf (of, "\n"); } -PRINTFUNC(picCast) +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"); + fprintf (of, "\t"); + printOperand (IC_RESULT (ic), of); + fprintf (of, " = "); + printOperand (IC_LEFT (ic), of); + printOperand (IC_RIGHT (ic), of); + fprintf (of, "\n"); } -PRINTFUNC(picAssign) +PRINTFUNC (picAssign) { - fprintf(of,"\t"); + fprintf (of, "\t"); - if (IC_RESULT(ic)->isaddr && IS_ITEMP(IC_RESULT(ic))) - fprintf(of,"*("); + if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic))) + fprintf (of, "*("); - printOperand(IC_RESULT(ic),of); + printOperand (IC_RESULT (ic), of); - if (IC_RESULT(ic)->isaddr && IS_ITEMP(IC_RESULT(ic))) - fprintf(of,")"); + if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic))) + fprintf (of, ")"); - fprintf(of," %s ", s); - printOperand (IC_RIGHT(ic),of); + fprintf (of, " %s ", s); + printOperand (IC_RIGHT (ic), of); - fprintf(of,"\n"); + fprintf (of, "\n"); } -PRINTFUNC(picLabel) +PRINTFUNC (picLabel) { - fprintf(of," %s($%d) :\n",IC_LABEL(ic)->name,IC_LABEL(ic)->key); + fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key); } -PRINTFUNC(picGoto) +PRINTFUNC (picGoto) { - fprintf(of,"\t"); - fprintf (of," goto %s($%d)\n", IC_LABEL(ic)->name,IC_LABEL(ic)->key); + fprintf (of, "\t"); + fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key); } -PRINTFUNC(picIfx) +PRINTFUNC (picIfx) { - fprintf(of,"\t"); - fprintf (of,"if "); - printOperand(IC_COND(ic),of); + fprintf (of, "\t"); + fprintf (of, "if "); + printOperand (IC_COND (ic), of); - if ( ! IC_TRUE(ic) ) - fprintf (of," == 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); - if (IC_FALSE(ic)) - fprintf (of,"\tzzgoto %s\n",IC_FALSE(ic)->name); + if (!IC_TRUE (ic)) + fprintf (of, " == 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); + if (IC_FALSE (ic)) + fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name); } } -PRINTFUNC(picInline) +PRINTFUNC (picInline) { - fprintf(of,"%s",IC_INLINE(ic)); + fprintf (of, "%s", IC_INLINE (ic)); } -PRINTFUNC(picReceive) +PRINTFUNC (picReceive) { - printOperand(IC_RESULT(ic),of); - fprintf(of," = %s ",s); - printOperand(IC_LEFT(ic),of); - fprintf(of,"\n"); + printOperand (IC_RESULT (ic), of); + fprintf (of, " = %s ", s); + printOperand (IC_LEFT (ic), of); + fprintf (of, "\n"); } /*-----------------------------------------------------------------*/ /* piCode - prints one iCode */ /*-----------------------------------------------------------------*/ -int piCode (void *item, FILE *of) +int +piCode (void *item, FILE * of) { - iCode *ic = item; - iCodeTable *icTab ; + iCode *ic = item; + iCodeTable *icTab; - if (!of) - of = stdout; + if (!of) + of = stdout; - icTab = getTableEntry(ic->op) ; - fprintf(stdout,"%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); - return 1; + icTab = getTableEntry (ic->op); + fprintf (stdout, "%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); + return 1; } +void PICC(iCode *ic) +{ + printiCChain(ic,stdout); +} /*-----------------------------------------------------------------*/ /* printiCChain - prints intermediate code for humans */ /*-----------------------------------------------------------------*/ -void printiCChain (iCode *icChain, FILE *of) +void +printiCChain (iCode * icChain, FILE * of) { - iCode *loop ; - iCodeTable *icTab ; + iCode *loop; + iCodeTable *icTab; - if (!of) - of = stdout; - for ( loop = icChain ; loop ; loop = loop->next ) { - if ((icTab = getTableEntry (loop->op ))) { - fprintf(of,"%s(%d:%d:%d:%d:%d)\t", - loop->filename,loop->lineno, - loop->seq,loop->key,loop->depth,loop->supportRtn); + if (!of) + of = stdout; + for (loop = icChain; loop; loop = loop->next) + { + if ((icTab = getTableEntry (loop->op))) + { + fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t", + loop->filename, loop->lineno, + loop->seq, loop->key, loop->depth, loop->supportRtn); - icTab->iCodePrint (of,loop,icTab->printName); - } + icTab->iCodePrint (of, loop, icTab->printName); + } } } @@ -409,134 +513,154 @@ void printiCChain (iCode *icChain, FILE *of) /*-----------------------------------------------------------------*/ /* newOperand - allocate, init & return a new iCode */ /*-----------------------------------------------------------------*/ -operand *newOperand () +operand * +newOperand () { - operand *op ; + operand *op; - op = Safe_calloc(1,sizeof(operand)); + op = Safe_alloc ( sizeof (operand)); - op->key = 0 ; - return op; + op->key = 0; + return op; } /*-----------------------------------------------------------------*/ /* newiCode - create and return a new iCode entry initialised */ /*-----------------------------------------------------------------*/ -iCode *newiCode (int op, operand *left, operand *right) +iCode * +newiCode (int op, operand * left, operand * right) { - iCode *ic ; + iCode *ic; - ic = Safe_calloc(1,sizeof(iCode)); + ic = Safe_alloc ( sizeof (iCode)); - ic->lineno = lineno ; - ic->filename= filename ; - ic->block = block; - ic->level = scopeLevel; - ic->op = op; - ic->key= iCodeKey++ ; - IC_LEFT(ic) = left; - IC_RIGHT(ic)= right; + ic->lineno = lineno; + ic->filename = filename; + ic->block = block; + ic->level = scopeLevel; + ic->op = op; + ic->key = iCodeKey++; + IC_LEFT (ic) = left; + IC_RIGHT (ic) = right; - return ic; + return ic; } /*-----------------------------------------------------------------*/ /* newiCode for conditional statements */ /*-----------------------------------------------------------------*/ -iCode *newiCodeCondition (operand *condition, - symbol *trueLabel, - symbol *falseLabel ) +iCode * +newiCodeCondition (operand * condition, + symbol * trueLabel, + symbol * falseLabel) { - iCode *ic ; + iCode *ic; - ic = newiCode(IFX,NULL,NULL); - IC_COND(ic) = condition ; - IC_TRUE(ic) = trueLabel ; - IC_FALSE(ic) = falseLabel; - return ic; + if (IS_VOID(operandType(condition))) { + werror(E_VOID_VALUE_USED); + } + + ic = newiCode (IFX, NULL, NULL); + IC_COND (ic) = condition; + IC_TRUE (ic) = trueLabel; + IC_FALSE (ic) = falseLabel; + return ic; } /*-----------------------------------------------------------------*/ /* newiCodeLabelGoto - unconditional goto statement| label stmnt */ /*-----------------------------------------------------------------*/ -iCode *newiCodeLabelGoto (int op, symbol *label) +iCode * +newiCodeLabelGoto (int op, symbol * label) { - iCode *ic ; + iCode *ic; - ic = newiCode(op,NULL,NULL); - ic->op = op ; - ic->argLabel.label = label ; - IC_LEFT(ic) = NULL ; - IC_RIGHT(ic) = NULL ; - IC_RESULT(ic) = NULL ; - return ic; + ic = newiCode (op, NULL, NULL); + ic->op = op; + ic->label = label; + IC_LEFT (ic) = NULL; + IC_RIGHT (ic) = NULL; + IC_RESULT (ic) = NULL; + return ic; } /*-----------------------------------------------------------------*/ /* newiTemp - allocate & return a newItemp Variable */ /*-----------------------------------------------------------------*/ -symbol *newiTemp (char *s) +symbol * +newiTemp (char *s) { - symbol *itmp; + symbol *itmp; - if (s) - sprintf(buffer,"%s",s); - else - sprintf (buffer,"iTemp%d",iTempNum++); - itmp = newSymbol (buffer,1); - strcpy(itmp->rname,itmp->name); - itmp->isitmp = 1; + if (s) + { + SNPRINTF (buffer, sizeof(buffer), "%s", s); + } + else + { + SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++); + } + + itmp = newSymbol (buffer, 1); + strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX); + itmp->isitmp = 1; - return itmp; + return itmp; } /*-----------------------------------------------------------------*/ /* newiTempLabel - creates a temp variable label */ /*-----------------------------------------------------------------*/ -symbol *newiTempLabel (char *s) +symbol * +newiTempLabel (char *s) { - symbol *itmplbl; + symbol *itmplbl; - /* check if this alredy exists */ - if (s && (itmplbl = findSym(LabelTab, NULL, s))) - return itmplbl ; + /* check if this alredy exists */ + if (s && (itmplbl = findSym (LabelTab, NULL, s))) + return itmplbl; - if (s) - itmplbl = newSymbol(s,1); - else { - sprintf(buffer,"iTempLbl%d",iTempLblNum++); - itmplbl = newSymbol(buffer,1); + if (s) + { + itmplbl = newSymbol (s, 1); + } + else + { + SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++); + itmplbl = newSymbol (buffer, 1); } - itmplbl->isitmp = 1; - itmplbl->islbl = 1; - itmplbl->key = labelKey++ ; - addSym (LabelTab, itmplbl, itmplbl->name,0,0); - return itmplbl ; + itmplbl->isitmp = 1; + itmplbl->islbl = 1; + itmplbl->key = labelKey++; + addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0); + return itmplbl; } /*-----------------------------------------------------------------*/ /* newiTempPreheaderLabel - creates a new preheader label */ /*-----------------------------------------------------------------*/ -symbol *newiTempPreheaderLabel() +symbol * +newiTempPreheaderLabel () { - symbol *itmplbl ; + symbol *itmplbl; - sprintf(buffer,"preHeaderLbl%d",iTempLblNum++); - itmplbl = newSymbol(buffer,1); + SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++); + itmplbl = newSymbol (buffer, 1); - itmplbl->isitmp = 1; - itmplbl->islbl = 1; - itmplbl->key = labelKey++ ; - addSym (LabelTab, itmplbl, itmplbl->name,0,0); - return itmplbl ; + itmplbl->isitmp = 1; + itmplbl->islbl = 1; + itmplbl->key = labelKey++; + addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0); + return itmplbl; } /*-----------------------------------------------------------------*/ /* initiCode - initialises some iCode related stuff */ /*-----------------------------------------------------------------*/ -void initiCode () +void +initiCode () { } @@ -544,1623 +668,1862 @@ void initiCode () /*-----------------------------------------------------------------*/ /* copyiCode - make a copy of the iCode given */ /*-----------------------------------------------------------------*/ -iCode *copyiCode (iCode *ic) +iCode * +copyiCode (iCode * ic) { - iCode *nic = newiCode(ic->op,NULL,NULL); + iCode *nic = newiCode (ic->op, NULL, NULL); - nic->lineno = ic->lineno ; - nic->filename= ic->filename ; - nic->block = ic->block; - nic->level = ic->level; + nic->lineno = ic->lineno; + nic->filename = ic->filename; + nic->block = ic->block; + nic->level = ic->level; + nic->parmBytes = ic->parmBytes; - /* deal with the special cases first */ - switch (ic->op) { + /* 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; + 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; + 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; + IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic)); + IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic)); + break; case INLINEASM: - IC_INLINE(nic) = IC_INLINE(ic); - break; + IC_INLINE (nic) = IC_INLINE (ic); + break; + + case ARRAYINIT: + IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic); + break; default: - IC_RESULT(nic) = operandFromOperand(IC_RESULT(ic)); - IC_LEFT(nic) = operandFromOperand(IC_LEFT(ic)); - IC_RIGHT(nic)= operandFromOperand(IC_RIGHT(ic)); + IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic)); + IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic)); + IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic)); } - return nic; + return nic; } /*-----------------------------------------------------------------*/ /* getTableEntry - gets the table entry for the given operator */ /*-----------------------------------------------------------------*/ -iCodeTable *getTableEntry (int oper ) +iCodeTable * +getTableEntry (int oper) { - int i ; + int i; - for ( i = 0 ; i < (sizeof(codeTable)/sizeof(iCodeTable)); i++ ) - if (oper == codeTable[i].icode) - return &codeTable[i] ; + for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++) + if (oper == codeTable[i].icode) + return &codeTable[i]; - return NULL ; + return NULL; } /*-----------------------------------------------------------------*/ /* newiTempOperand - new intermediate temp operand */ /*-----------------------------------------------------------------*/ -operand *newiTempOperand (sym_link *type, char throwType) +operand * +newiTempOperand (sym_link * type, char throwType) { - symbol *itmp; - operand *op = newOperand(); - sym_link *etype; + symbol *itmp; + operand *op = newOperand (); + sym_link *etype; - op->type = SYMBOL ; - itmp = newiTemp(NULL); + op->type = SYMBOL; + itmp = newiTemp (NULL); - etype = getSpec(type); + etype = getSpec (type); - if (IS_LITERAL(etype) ) - throwType = 0 ; + if (IS_LITERAL (etype)) + throwType = 0; - /* copy the type information */ - if (type) - itmp->etype = getSpec (itmp->type = (throwType ? type : - copyLinkChain(type))); - if (IS_LITERAL(itmp->etype)) { - SPEC_SCLS(itmp->etype) = S_REGISTER ; - SPEC_OCLS(itmp->etype) = reg; + /* copy the type information */ + if (type) + itmp->etype = getSpec (itmp->type = (throwType ? type : + copyLinkChain (type))); + if (IS_LITERAL (itmp->etype)) + { + SPEC_SCLS (itmp->etype) = S_REGISTER; + SPEC_OCLS (itmp->etype) = reg; } - op->operand.symOperand = itmp; - op->key = itmp->key = ++operandKey ; - return op; + op->operand.symOperand = itmp; + op->key = itmp->key = ++operandKey; + return op; } /*-----------------------------------------------------------------*/ /* operandType - returns the type chain for an operand */ /*-----------------------------------------------------------------*/ -sym_link *operandType (operand *op) +sym_link * +operandType (operand * op) { - /* depending on type of operand */ - switch (op->type) { + /* depending on type of operand */ + switch (op->type) + { - case VALUE : - return op->operand.valOperand->type ; + case VALUE: + return op->operand.valOperand->type; case SYMBOL: - return op->operand.symOperand->type ; + return op->operand.symOperand->type; - case TYPE : - return op->operand.typeOperand ; + 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 (sym_link *) 0; } } /*-----------------------------------------------------------------*/ /* isParamterToCall - will return 1 if op is a parameter to args */ /*-----------------------------------------------------------------*/ -int isParameterToCall (value *args, operand *op) +int +isParameterToCall (value * args, operand * op) { - value *tval = args ; + value *tval = args; - while (tval) { - if (tval->sym && - isSymbolEqual(op->operand.symOperand,tval->sym)) - return 1; - tval = tval->next ; + wassert (IS_SYMOP(op)); + + while (tval) + { + if (tval->sym && + isSymbolEqual (op->operand.symOperand, tval->sym)) + return 1; + tval = tval->next; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* isOperandGlobal - return 1 if operand is a global variable */ /*-----------------------------------------------------------------*/ -int isOperandGlobal ( operand *op ) +int +isOperandGlobal (operand * op) { - if (!op) - return 0; + if (!op) + return 0; - if (IS_ITEMP(op)) - return 0; + if (IS_ITEMP (op)) + return 0; - if (op->type == SYMBOL && - (op->operand.symOperand->level == 0 || - IS_STATIC(op->operand.symOperand->etype) || - IS_EXTERN(op->operand.symOperand->etype)) + if (IS_SYMOP(op) && + (op->operand.symOperand->level == 0 || + IS_STATIC (op->operand.symOperand->etype) || + IS_EXTERN (op->operand.symOperand->etype)) ) - return 1; + return 1; - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* isOperandVolatile - return 1 if the operand is volatile */ /*-----------------------------------------------------------------*/ -int isOperandVolatile ( operand *op , bool chkTemp) +int +isOperandVolatile (operand * op, bool chkTemp) { - sym_link *optype ; - sym_link *opetype ; - - if (IS_ITEMP(op) && !chkTemp) - return 0; - - opetype = getSpec(optype = operandType(op)); + sym_link *optype; + sym_link *opetype; - if (IS_PTR(optype) && DCL_PTR_VOLATILE(optype)) - return 1; - - if (IS_VOLATILE(opetype)) - return 1; + if (IS_ITEMP (op) && !chkTemp) return 0; + + return IS_VOLATILE(operandType(op)); } /*-----------------------------------------------------------------*/ /* isOperandLiteral - returns 1 if an operand contains a literal */ /*-----------------------------------------------------------------*/ -int isOperandLiteral ( operand *op ) +int +isOperandLiteral (operand * op) { - sym_link *opetype ; + sym_link *opetype; - if (!op) - return 0; + if (!op) + return 0; - opetype = getSpec (operandType(op)); + opetype = getSpec (operandType (op)); - if (IS_LITERAL(opetype)) - return 1; + if (IS_LITERAL (opetype)) + return 1; - return 0; + return 0; } + /*-----------------------------------------------------------------*/ -/* isOperandInFarSpace - will return true if operand is in farSpace*/ +/* isOperandInFarSpace - will return true if operand is in farSpace */ /*-----------------------------------------------------------------*/ -bool isOperandInFarSpace (operand *op) +bool +isOperandInFarSpace (operand * op) { - sym_link *etype; + sym_link *etype; - if (!op) - return FALSE; + if (!op) + return FALSE; - if (!IS_SYMOP(op)) - return FALSE ; + if (!IS_SYMOP (op)) + return FALSE; - if (!IS_TRUE_SYMOP(op)) { - if (SPIL_LOC(op)) - etype = SPIL_LOC(op)->etype; + if (!IS_TRUE_SYMOP (op)) + { + if (SPIL_LOC (op)) + etype = SPIL_LOC (op)->etype; + else + return FALSE; + } else - return FALSE; + { + etype = getSpec (operandType (op)); } - else + 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)) { - etype = getSpec(operandType(op)); + if (SPIL_LOC (op)) + etype = SPIL_LOC (op)->etype; + else + return FALSE; } - return (IN_FARSPACE(SPEC_OCLS(etype)) ? TRUE : FALSE); + else + { + etype = getSpec (operandType (op)); + } + return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE); +} + +/*--------------------------------------------------------------------*/ +/* isOperandInCodeSpace - will return true if operand is in codeSpace */ +/*--------------------------------------------------------------------*/ +bool +isOperandInCodeSpace (operand * op) +{ + sym_link *etype; + + if (!op) + return FALSE; + + if (!IS_SYMOP (op)) + return FALSE; + + etype = getSpec (operandType (op)); + + if (!IS_TRUE_SYMOP (op)) + { + if (SPIL_LOC (op)) + etype = SPIL_LOC (op)->etype; + else + return FALSE; + } + else + { + etype = getSpec (operandType (op)); + } + return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE); } /*-----------------------------------------------------------------*/ /* isOperandOnStack - will return true if operand is on stack */ /*-----------------------------------------------------------------*/ -bool isOperandOnStack(operand *op) +bool +isOperandOnStack (operand * op) { - sym_link *etype; + sym_link *etype; - if (!op) - return FALSE; + if (!op) + return FALSE; - if (!IS_SYMOP(op)) - return FALSE ; + if (!IS_SYMOP (op)) + return FALSE; - etype = getSpec(operandType(op)); + etype = getSpec (operandType (op)); + if (IN_STACK (etype) || + OP_SYMBOL(op)->onStack || + (SPIL_LOC(op) && SPIL_LOC(op)->onStack)) + return TRUE; - return ((IN_STACK(etype)) ? TRUE : FALSE); + return FALSE; } /*-----------------------------------------------------------------*/ /* operandLitValue - literal value of an operand */ /*-----------------------------------------------------------------*/ -double operandLitValue ( operand *op ) +double +operandLitValue (operand * op) { - assert(isOperandLiteral(op)); + assert (isOperandLiteral (op)); - return floatFromVal(op->operand.valOperand); + 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 */ /*-----------------------------------------------------------------*/ -operand *operandOperation (operand *left,operand *right, - int op, sym_link *type) -{ - operand *retval = (operand *)0; - - assert(isOperandLiteral(left)); - if (right) - assert(isOperandLiteral(right)); - - switch (op) { - case '+' : - retval = operandFromValue (valCastLiteral(type, - operandLitValue(left) + - operandLitValue(right))); - break ; - case '-' : - retval = operandFromValue(valCastLiteral(type, - operandLitValue(left) - - operandLitValue(right))); - break; +operand * +operandOperation (operand * left, operand * right, + int op, sym_link * type) +{ + sym_link *let , *ret=NULL; + operand *retval = (operand *) 0; + + assert (isOperandLiteral (left)); + let = getSpec(operandType(left)); + if (right) { + assert (isOperandLiteral (right)); + ret = getSpec(operandType(left)); + } + + switch (op) + { + case '+': + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) + + operandLitValue (right))); + break; + case '-': + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) - + operandLitValue (right))); + break; case '*': - retval = operandFromValue(valCastLiteral(type, - operandLitValue(left) * - operandLitValue(right))); - break; + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) * + operandLitValue (right))); + break; case '/': - if ((unsigned long) operandLitValue(right) == 0){ - werror(E_DIVIDE_BY_ZERO); - retval = right; + if ((unsigned long) operandLitValue (right) == 0) + { + werror (E_DIVIDE_BY_ZERO); + retval = right; - } - else - retval = operandFromValue (valCastLiteral(type, - operandLitValue(left) / - operandLitValue(right))); - break; + } + else + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) / + operandLitValue (right))); + break; case '%': - if ((unsigned long) operandLitValue(right) == 0){ - werror(E_DIVIDE_BY_ZERO); - retval = right; - } - else - retval = operandFromLit ((unsigned long) operandLitValue(left) % - (unsigned long) operandLitValue(right)); - break; - case LEFT_OP : - retval = operandFromLit ((unsigned long) operandLitValue(left) << - (unsigned long) operandLitValue(right)); - break; - case RIGHT_OP : - retval = operandFromLit ((unsigned long) operandLitValue(left) >> - (unsigned long) operandLitValue(right)); - break; - case EQ_OP : - retval = operandFromLit (operandLitValue(left) == - operandLitValue(right)); - break; - case '<' : - retval = operandFromLit (operandLitValue(left) < - operandLitValue(right)); - break; - case LE_OP : - retval = operandFromLit (operandLitValue(left) <= - operandLitValue(right)); - break; - case NE_OP : - retval = operandFromLit (operandLitValue(left) != - operandLitValue(right)); - break; - case '>' : - retval = operandFromLit (operandLitValue(left) > - operandLitValue(right)); - break; - case GE_OP : - retval = operandFromLit (operandLitValue(left) >= - operandLitValue(right)); - break; - case BITWISEAND : - retval = operandFromLit ((unsigned long) operandLitValue(left) & - (unsigned long) operandLitValue(right)); - break; - case '|' : - retval = operandFromLit ((unsigned long) operandLitValue(left) | - (unsigned long) operandLitValue(right)); - break; - case '^' : - retval = operandFromLit ((unsigned long) operandLitValue(left) ^ - (unsigned long) operandLitValue(right)); - break; + if ((unsigned long) operandLitValue (right) == 0) { + werror (E_DIVIDE_BY_ZERO); + retval = right; + } + else + retval = operandFromLit ((SPEC_USIGN(let) ? + (unsigned long) operandLitValue (left) : + (long) operandLitValue (left)) % + (SPEC_USIGN(ret) ? + (unsigned long) operandLitValue (right) : + (long) operandLitValue (right))); + + break; + case LEFT_OP: + retval = operandFromLit ((SPEC_USIGN(let) ? + (unsigned long) operandLitValue (left) : + (long) operandLitValue (left)) << + (SPEC_USIGN(ret) ? + (unsigned long) operandLitValue (right) : + (long) operandLitValue (right))); + break; + 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)); + break; + case '<': + retval = operandFromLit (operandLitValue (left) < + operandLitValue (right)); + break; + case LE_OP: + retval = operandFromLit (operandLitValue (left) <= + operandLitValue (right)); + break; + case NE_OP: + retval = operandFromLit (operandLitValue (left) != + operandLitValue (right)); + break; + case '>': + retval = operandFromLit (operandLitValue (left) > + operandLitValue (right)); + break; + case GE_OP: + retval = operandFromLit (operandLitValue (left) >= + operandLitValue (right)); + break; + case BITWISEAND: + retval = operandFromLit ((long)operandLitValue(left) & + (long)operandLitValue(right)); + break; + case '|': + retval = operandFromLit ((long)operandLitValue (left) | + (long)operandLitValue (right)); + break; + case '^': + retval = operandFromLit ((long)operandLitValue (left) ^ + (long)operandLitValue (right)); + break; case AND_OP: - retval = operandFromLit (operandLitValue(left) && - operandLitValue(right)); - break; + retval = operandFromLit (operandLitValue (left) && + operandLitValue (right)); + break; case OR_OP: - retval = operandFromLit (operandLitValue(left) || - operandLitValue(right)); - break; + retval = operandFromLit (operandLitValue (left) || + operandLitValue (right)); + break; case RRC: - { - long i = operandLitValue(left); + { + long i = (long) operandLitValue (left); - retval = operandFromLit ((i >> (getSize(operandType(left))*8 - 1)) | - (i << 1)); - } - break; + retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) | + (i << 1)); + } + break; case RLC: - { - long i = operandLitValue(left); + { + long i = (long) operandLitValue (left); - retval = operandFromLit ((i << (getSize(operandType(left))*8 - 1)) | - (i >> 1)); - } - break; + retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) | + (i >> 1)); + } + break; case UNARYMINUS: - retval = operandFromLit(-1 * operandLitValue(left)); - break; + retval = operandFromLit (-1 * operandLitValue (left)); + break; case '~': - retval = operandFromLit(~ ((long) operandLitValue(left))); - break; + retval = operandFromLit (~((long) operandLitValue (left))); + break; case '!': - retval = operandFromLit(! operandLitValue(left)); - break; + retval = operandFromLit (!operandLitValue (left)); + break; - default : - werror(E_INTERNAL_ERROR,__FILE__,__LINE__, - " operandOperation invalid operator "); - assert (0); + default: + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + " operandOperation invalid operator "); + assert (0); } - return retval; + return retval; } /*-----------------------------------------------------------------*/ /* isOperandEqual - compares two operand & return 1 if they r = */ /*-----------------------------------------------------------------*/ -int isOperandEqual (operand *left, operand *right) +int +isOperandEqual (operand * left, operand * right) { - /* if the pointers are equal then they are equal */ - if ( left == right ) - return 1; + /* if the pointers are equal then they are equal */ + if (left == right) + return 1; - /* if either of them null then false */ - if ( !left || !right) - return 0; + /* if either of them null then false */ + if (!left || !right) + return 0; - if (left->type != right->type) - return 0; + if (left->type != right->type) + return 0; - if (IS_SYMOP(left) && IS_SYMOP(right)) - return left->key == right->key ; - - /* if types are the same */ - switch (left->type) { - case SYMBOL : - return isSymbolEqual(left->operand.symOperand, - right->operand.symOperand); - case VALUE : - return (floatFromVal(left->operand.valOperand) == - floatFromVal(right->operand.valOperand)); - case TYPE : - if (checkType(left->operand.typeOperand, - right->operand.typeOperand) == 1) - return 1; + if (IS_SYMOP (left) && IS_SYMOP (right)) + return left->key == right->key; + + /* if types are the same */ + switch (left->type) + { + case SYMBOL: + return isSymbolEqual (left->operand.symOperand, + right->operand.symOperand); + case VALUE: + return (floatFromVal (left->operand.valOperand) == + floatFromVal (right->operand.valOperand)); + case TYPE: + if (compareType (left->operand.typeOperand, + right->operand.typeOperand) == 1) + return 1; } - return 0; + return 0; } -/*-----------------------------------------------------------------*/ -/* isiCodeEqual - comapres two iCodes are returns true if yes */ -/*-----------------------------------------------------------------*/ -int isiCodeEqual (iCode *left, iCode *right) +/*-------------------------------------------------------------------*/ +/* isiCodeEqual - compares two iCodes are equal, returns true if yes */ +/*-------------------------------------------------------------------*/ +int +isiCodeEqual (iCode * left, iCode * right) { - /* if the same pointer */ - if (left == right) - return 1; + /* if the same pointer */ + if (left == right) + return 1; - /* if either of them null */ - if (!left || !right) - return 0; + /* if either of them null */ + if (!left || !right) + return 0; - /* if operand are the same */ - if ( left->op == right->op ) { + /* if operand are the same */ + if (left->op == right->op) + { - /* compare all the elements depending on type */ - if (left->op != IFX ) { - if (!isOperandEqual(IC_LEFT(left),IC_LEFT(right))) - return 0; - if (!isOperandEqual(IC_RIGHT(left),IC_RIGHT(right))) - return 0; + /* compare all the elements depending on type */ + if (left->op != IFX) + { + if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right))) + return 0; + if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right))) + return 0; - } else { - if (!isOperandEqual(IC_COND(left),IC_COND(right))) - return 0; - if (!isSymbolEqual (IC_TRUE(left),IC_TRUE(right))) - return 0; - if (!isSymbolEqual(IC_FALSE(left),IC_FALSE(right))) - return 0; - } - return 1; + } + else + { + if (!isOperandEqual (IC_COND (left), IC_COND (right))) + return 0; + if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right))) + return 0; + if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right))) + return 0; + } + + return 1; } - return 0; + return 0; } /*-----------------------------------------------------------------*/ /* newiTempFromOp - create a temp Operand with same attributes */ /*-----------------------------------------------------------------*/ -operand *newiTempFromOp (operand *op) +operand * +newiTempFromOp (operand * op) { - operand *nop; + operand *nop; - if (!op) - return NULL; + if (!op) + return NULL; - if (!IS_ITEMP(op)) - return op; + 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; + nop = newiTempOperand (operandType (op), TRUE); + nop->isaddr = op->isaddr; + nop->isvolatile = op->isvolatile; + nop->isGlobal = op->isGlobal; + nop->isLiteral = op->isLiteral; + nop->usesDefs = op->usesDefs; + nop->isParm = op->isParm; + return nop; } /*-----------------------------------------------------------------*/ /* operand from operand - creates an operand holder for the type */ /*-----------------------------------------------------------------*/ -operand *operandFromOperand (operand *op) +operand * +operandFromOperand (operand * op) { - operand *nop ; + operand *nop; - if (!op) - return NULL; - nop = newOperand(); - nop->type = op->type; - nop->isaddr = op->isaddr ; - nop->key = op->key ; - 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; - - switch (nop->type) { - case SYMBOL : - nop->operand.symOperand = op->operand.symOperand ; - break; - case VALUE : - nop->operand.valOperand = op->operand.valOperand; - break; - case TYPE : - nop->operand.typeOperand = op->operand.typeOperand ; - break ; - } - - return nop; + if (!op) + return NULL; + nop = newOperand (); + nop->type = op->type; + nop->isaddr = op->isaddr; + nop->key = op->key; + nop->isvolatile = op->isvolatile; + nop->isGlobal = op->isGlobal; + nop->isLiteral = op->isLiteral; + nop->usesDefs = op->usesDefs; + nop->isParm = op->isParm; + + switch (nop->type) + { + case SYMBOL: + nop->operand.symOperand = op->operand.symOperand; + break; + case VALUE: + nop->operand.valOperand = op->operand.valOperand; + break; + case TYPE: + nop->operand.typeOperand = op->operand.typeOperand; + break; + } + + return nop; } /*-----------------------------------------------------------------*/ /* opFromOpWithDU - makes a copy of the operand and DU chains */ /*-----------------------------------------------------------------*/ -operand *opFromOpWithDU (operand *op, bitVect *defs, bitVect *uses) +operand * +opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses) { - operand *nop = operandFromOperand(op); + operand *nop = operandFromOperand (op); - if (nop->type == SYMBOL) { - OP_SYMBOL(nop)->defs = bitVectCopy(defs); - OP_SYMBOL(nop)->uses = bitVectCopy(uses); + if (nop->type == SYMBOL) + { + OP_SYMBOL (nop)->defs = bitVectCopy (defs); + OP_SYMBOL (nop)->uses = bitVectCopy (uses); } - return nop; + return nop; } /*-----------------------------------------------------------------*/ /* operandFromSymbol - creates an operand from a symbol */ /*-----------------------------------------------------------------*/ -operand *operandFromSymbol (symbol *sym) -{ - 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)) - return operandFromValue (valFromType(sym->etype)); - - if (!sym->key) - sym->key = ++operandKey ; - - /* if this an implicit variable, means struct/union */ - /* member so just return it */ - if (sym->implicit || IS_FUNC(sym->type)) { - op = newOperand(); - op->type = SYMBOL ; - op->operand.symOperand = sym; - op->key = sym->key ; - op->isvolatile = isOperandVolatile(op,TRUE); - op->isGlobal = isOperandGlobal(op); - op->parmBytes = sym->argStack; - return op; +operand * +operandFromSymbol (symbol * sym) +{ + 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)) + return operandFromValue (valFromType (sym->etype)); + + if (!sym->key) + sym->key = ++operandKey; + + /* if this an implicit variable, means struct/union */ + /* member so just return it */ + if (sym->implicit || IS_FUNC (sym->type)) + { + op = newOperand (); + op->type = SYMBOL; + op->operand.symOperand = sym; + op->key = sym->key; + op->isvolatile = isOperandVolatile (op, TRUE); + op->isGlobal = isOperandGlobal (op); + 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 */ - sym->level && /* is a local variable */ - !sym->addrtaken && /* whose address has not been taken */ - !sym->reqv && /* does not already have a register euivalence */ - !IS_VOLATILE(sym->etype) && /* not declared as volatile */ - !IS_STATIC(sym->etype) && /* and not declared static */ - !sym->islbl && /* not a label */ - ok && /* farspace check */ - !IS_BITVAR(sym->etype) /* not a bit variable */ - ) { - - /* we will use it after all optimizations - and before liveRange calculation */ - sym->reqv = newiTempOperand(sym->type,0); - sym->reqv->key = sym->key ; - OP_SYMBOL(sym->reqv)->key = sym->key; - OP_SYMBOL(sym->reqv)->isreqv = 1; - OP_SYMBOL(sym->reqv)->islocal = 1; - SPIL_LOC(sym->reqv) = sym; - } - - if (!IS_AGGREGATE(sym->type)) { - op = newOperand(); - op->type = SYMBOL; - op->operand.symOperand = sym; - op->isaddr = 1; - op->key = sym->key; - op->isvolatile = isOperandVolatile(op,TRUE); - op->isGlobal = isOperandGlobal(op); - op->isPtr = IS_PTR(operandType(op)); - op->isParm = sym->_isparm ; - 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)) && + (!(options.model == MODEL_FLAT24)) ) && + 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 */ + sym->level && /* is a local variable */ + !sym->addrtaken && /* whose address has not been taken */ + !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 */ + ok && /* farspace check */ + !IS_BITVAR (sym->etype) /* not a bit variable */ + ) + { + + /* we will use it after all optimizations + and before liveRange calculation */ + sym->reqv = newiTempOperand (sym->type, 0); + sym->reqv->key = sym->key; + 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; } - /* create :- */ - /* itemp = &[_symbol] */ + if (!IS_AGGREGATE (sym->type)) + { + op = newOperand (); + op->type = SYMBOL; + op->operand.symOperand = sym; + op->isaddr = 1; + op->key = sym->key; + op->isvolatile = isOperandVolatile (op, TRUE); + op->isGlobal = isOperandGlobal (op); + op->isPtr = IS_PTR (operandType (op)); + op->isParm = sym->_isparm; + return op; + } - ic = newiCode(ADDRESS_OF,newOperand(),NULL); - IC_LEFT(ic)->type = SYMBOL ; - IC_LEFT(ic)->operand.symOperand = sym ; - IC_LEFT(ic)->key = sym->key; - (IC_LEFT(ic))->isvolatile = isOperandVolatile(IC_LEFT(ic),TRUE); - (IC_LEFT(ic))->isGlobal = isOperandGlobal(IC_LEFT(ic)); - IC_LEFT(ic)->isPtr = IS_PTR(operandType(IC_LEFT(ic))); + /* create :- */ + /* itemp = &[_symbol] */ - /* create result */ - IC_RESULT(ic) = newiTempOperand(sym->type,0); - if (IS_ARRAY(sym->type)) { - IC_RESULT(ic) = geniCodeArray2Ptr (IC_RESULT(ic)); - IC_RESULT(ic)->isaddr = 0; - } else - IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(sym->type)); + ic = newiCode (ADDRESS_OF, newOperand (), NULL); + IC_LEFT (ic)->type = SYMBOL; + IC_LEFT (ic)->operand.symOperand = sym; + IC_LEFT (ic)->key = sym->key; + (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE); + (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic)); + IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic))); - IC_RESULT(ic)->operand.symOperand->args = sym->args; + /* create result */ + IC_RESULT (ic) = newiTempOperand (sym->type, 0); + if (IS_ARRAY (sym->type)) + { + IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic)); + IC_RESULT (ic)->isaddr = 0; + } + else + IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type)); - ADDTOCHAIN(ic); + ADDTOCHAIN (ic); - return IC_RESULT(ic) ; + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* operandFromValue - creates an operand from value */ /*-----------------------------------------------------------------*/ -operand *operandFromValue (value *val) +operand * +operandFromValue (value * val) { - operand *op ; + operand *op; - /* if this is a symbol then do the symbol thing */ - if (val->sym) - return operandFromSymbol (val->sym); + /* if this is a symbol then do the symbol thing */ + if (val->sym) + return operandFromSymbol (val->sym); - /* this is not a symbol */ - op = newOperand(); - op->type = VALUE ; - op->operand.valOperand = val ; - op->isLiteral = isOperandLiteral(op); - return op; + /* this is not a symbol */ + op = newOperand (); + op->type = VALUE; + op->operand.valOperand = val; + op->isLiteral = isOperandLiteral (op); + return op; } /*-----------------------------------------------------------------*/ /* operandFromLink - operand from typeChain */ /*-----------------------------------------------------------------*/ -operand *operandFromLink (sym_link *type) +operand * +operandFromLink (sym_link * type) { - operand *op ; + operand *op; - /* operand from sym_link */ - if ( ! type ) - return NULL ; + /* operand from sym_link */ + if (!type) + return NULL; - op = newOperand(); - op->type = TYPE ; - op->operand.typeOperand = copyLinkChain(type); - return op; + op = newOperand (); + op->type = TYPE; + op->operand.typeOperand = copyLinkChain (type); + return op; } /*-----------------------------------------------------------------*/ /* operandFromLit - makes an operand from a literal value */ /*-----------------------------------------------------------------*/ -operand *operandFromLit ( float i) +operand * +operandFromLit (double i) { - return operandFromValue (valueFromLit (i)); + return operandFromValue (valueFromLit (i)); } /*-----------------------------------------------------------------*/ /* operandFromAst - creates an operand from an ast */ /*-----------------------------------------------------------------*/ -operand *operandFromAst ( ast *tree ) +operand * +operandFromAst (ast * tree,int lvl) { - if (! tree ) - return NULL ; + if (!tree) + return NULL; - /* depending on type do */ - switch (tree->type ) { - case EX_OP : - return ast2iCode (tree) ; - break ; + /* depending on type do */ + switch (tree->type) + { + case EX_OP: + return ast2iCode (tree,lvl+1); + break; - case EX_VALUE : - return operandFromValue(tree->opval.val) ; - break ; + case EX_VALUE: + return operandFromValue (tree->opval.val); + break; - case EX_LINK : - return operandFromLink (tree->opval.lnk) ; + case EX_LINK: + return operandFromLink (tree->opval.lnk); } - assert(0); - /* Just to keep the comiler happy */ - return (operand *)0; + assert (0); + /* Just to keep the comiler happy */ + return (operand *) 0; } /*-----------------------------------------------------------------*/ /* setOperandType - sets the operand's type to the given type */ /*-----------------------------------------------------------------*/ -void setOperandType (operand *op, sym_link *type) +void +setOperandType (operand * op, sym_link * type) { - /* depending on the type of operand */ - switch (op->type) { + /* depending on the type of operand */ + switch (op->type) + { - case VALUE : - op->operand.valOperand->etype = - getSpec( op->operand.valOperand->type = - copyLinkChain (type )) ; - return ; + case VALUE: + op->operand.valOperand->etype = + getSpec (op->operand.valOperand->type = + copyLinkChain (type)); + return; - case SYMBOL : - if (op->operand.symOperand->isitmp ) - op->operand.symOperand->etype = - getSpec( op->operand.symOperand->type = - copyLinkChain (type )) ; - else - werror (E_INTERNAL_ERROR,__FILE__,__LINE__, - "attempt to modify type of source"); - return; + case SYMBOL: + if (op->operand.symOperand->isitmp) + op->operand.symOperand->etype = + getSpec (op->operand.symOperand->type = + copyLinkChain (type)); + else + werror (E_INTERNAL_ERROR, __FILE__, __LINE__, + "attempt to modify type of source"); + return; case TYPE: - op->operand.typeOperand = copyLinkChain (type); - return ; + op->operand.typeOperand = copyLinkChain (type); + return; } } - /*-----------------------------------------------------------------*/ -/* perform "usual unary conversions" */ +/* Get size in byte of ptr need to access an array */ /*-----------------------------------------------------------------*/ -operand *usualUnaryConversions(operand *op) +int +getArraySizePtr (operand * op) { - if (IS_INTEGRAL(operandType(op))) - { - if (getSize(operandType(op)) < INTSIZE) - { - /* Widen to int. */ - return geniCodeCast(INTTYPE,op,TRUE); - } - } - return op; -} + sym_link *ltype = operandType(op); -/*-----------------------------------------------------------------*/ -/* perform "usual binary conversions" */ -/*-----------------------------------------------------------------*/ -sym_link * usualBinaryConversions(operand **op1, operand **op2) -{ - if (!options.ANSIint) + if(IS_PTR(ltype)) { - /* "Classic" SDCC behavior. */ - sym_link *ctype; - sym_link *rtype = operandType(*op2); - sym_link *ltype = operandType(*op1); - - ctype = computeType(ltype,rtype); - *op1 = geniCodeCast(ctype,*op1,TRUE); - *op2= geniCodeCast(ctype,*op2,TRUE); - - return ctype; + int size = getSize(ltype); + return(IS_GENPTR(ltype)?(size-1):size); } - *op1 = usualUnaryConversions(*op1); - *op2 = usualUnaryConversions(*op2); - - /* Try to make the two operands of the same type, following - * the "usual binary conversions" promotion rules. - * - * NB: floating point types are not yet properly handled; we - * follow the "classic" behavior. - */ - - if (IS_FLOAT(operandType(*op1)) || IS_FLOAT(operandType(*op2))) + if(IS_ARRAY(ltype)) { - return newFloatLink(); - } + sym_link *letype = getSpec(ltype); + switch (PTR_TYPE (SPEC_OCLS (letype))) + { + case IPOINTER: + case PPOINTER: + case POINTER: + return (PTRSIZE); + case EEPPOINTER: + case FPOINTER: + case CPOINTER: + case FUNCTION: + return (FPTRSIZE); + case GPOINTER: + return (GPTRSIZE-1); - if (!IS_INTEGRAL(operandType(*op1)) || !IS_INTEGRAL(operandType(*op2))) - { - /* if either is not an integer type, we're done. */ - return copyLinkChain(operandType(*op1)); /* Punt! we should never get here. */ - } - - /* If either is an unsigned long, make sure both are. */ - if (SPEC_USIGN(operandType(*op1)) && IS_LONG(operandType(*op1))) - { - if (!SPEC_USIGN(operandType(*op2)) || !IS_LONG(operandType(*op2))) - { - *op2 = geniCodeCast(ULONGTYPE,*op2,TRUE); - } - return copyLinkChain(operandType(*op1)); - } - - if (SPEC_USIGN(operandType(*op2)) && IS_LONG(operandType(*op2))) - { - if (!SPEC_USIGN(operandType(*op1)) || !IS_LONG(operandType(*op1))) - { - *op1 = geniCodeCast(ULONGTYPE,*op1,TRUE); - } - return copyLinkChain(operandType(*op2)); - } - - /* Next, if one is long and the other is int (signed or un), - * cast both to long. - * - * Note that because in our environment a long can hold all - * the values of an unsigned int, the "long/unsigned int" pair - * in the ANSI conversion table is unnecessary; this test - * handles that case implicitly. - */ - if (IS_LONG(operandType(*op1))) - { - /* NB: because of the unary conversions, op2 cannot - * be smaller than int. Therefore, if it is not - * long, it is a regular int. - */ - if (!IS_LONG(operandType(*op2))) - { - *op2 = geniCodeCast(LONGTYPE,*op2,TRUE); - } - return copyLinkChain(operandType(*op1)); - } - - if (IS_LONG(operandType(*op2))) - { - /* NB: because of the unary conversions, op2 cannot - * be smaller than int. Therefore, if it is not - * long, it is a regular int. - */ - if (!IS_LONG(operandType(*op1))) - { - *op1 = geniCodeCast(LONGTYPE,*op1,TRUE); - } - return copyLinkChain(operandType(*op2)); + default: + return (FPTRSIZE); + } } + return (FPTRSIZE); +} - /* All right, neither is long; they must both be integers. - * - * Only remaining issue is signed vs. unsigned; if one is unsigned - * and the other isn't, convert both to unsigned. - */ - if (SPEC_USIGN(operandType(*op1))) +/*-----------------------------------------------------------------*/ +/* perform "usual unary conversions" */ +/*-----------------------------------------------------------------*/ +operand * +usualUnaryConversions (operand * op) +{ + if (IS_INTEGRAL (operandType (op))) { - if (!SPEC_USIGN(operandType(*op2))) - { - *op2 = geniCodeCast(UINTTYPE,*op2,TRUE); - } - return copyLinkChain(operandType(*op1)); + if (getSize (operandType (op)) < (unsigned int) INTSIZE) + { + /* Widen to int. */ + return geniCodeCast (INTTYPE, op, TRUE); + } } + return op; +} - if (SPEC_USIGN(operandType(*op2))) - { - if (!SPEC_USIGN(operandType(*op1))) - { - *op1 = geniCodeCast(UINTTYPE,*op1,TRUE); - } - return copyLinkChain(operandType(*op2)); - } +/*-----------------------------------------------------------------*/ +/* perform "usual binary conversions" */ +/*-----------------------------------------------------------------*/ +sym_link * +usualBinaryConversions (operand ** op1, operand ** op2) +{ + sym_link *ctype; + sym_link *rtype = operandType (*op2); + sym_link *ltype = operandType (*op1); + + ctype = computeType (ltype, rtype); - /* Done! */ - return copyLinkChain(operandType(*op1)); + *op1 = geniCodeCast (ctype, *op1, TRUE); + *op2 = geniCodeCast (ctype, *op2, TRUE); + + return ctype; } - /*-----------------------------------------------------------------*/ /* geniCodeValueAtAddress - generate intermeditate code for value */ /* at address */ /*-----------------------------------------------------------------*/ -operand *geniCodeRValue (operand *op, bool force) +operand * +geniCodeRValue (operand * op, bool force) { - iCode *ic ; - sym_link *type = operandType(op); - sym_link *etype= getSpec(type); + iCode *ic; + sym_link *type = operandType (op); + sym_link *etype = getSpec (type); - /* if this is an array & already */ - /* an address then return this */ - if (IS_AGGREGATE(type) || - (IS_PTR(type) && !force && !op->isaddr)) - return operandFromOperand(op); + /* if this is an array & already */ + /* an address then return this */ + if (IS_AGGREGATE (type) || + (IS_PTR (type) && !force && !op->isaddr)) + return operandFromOperand (op); - /* if this is not an address then must be */ - /* rvalue already so return this one */ - if (!op->isaddr) - return op ; + /* if this is not an address then must be */ + /* rvalue already so return this one */ + if (!op->isaddr) + return op; - /* if this is not a temp symbol then */ - if (!IS_ITEMP(op) && - !force && - !IN_FARSPACE(SPEC_OCLS(etype))) { - op = operandFromOperand(op); - op->isaddr = 0; - return op; + /* if this is not a temp symbol then */ + if (!IS_ITEMP (op) && + !force && + !IN_FARSPACE (SPEC_OCLS (etype))) + { + op = operandFromOperand (op); + op->isaddr = 0; + return op; } - if (IS_SPEC(type) && - IS_TRUE_SYMOP(op) && - (!IN_FARSPACE(SPEC_OCLS(etype)) || IS_DS390_PORT)) { - op = operandFromOperand(op); - op->isaddr = 0; - return op; + if (IS_SPEC (type) && + IS_TRUE_SYMOP (op) && + (!IN_FARSPACE (SPEC_OCLS (etype)) || + (options.model == MODEL_FLAT24) )) + { + op = operandFromOperand (op); + op->isaddr = 0; + return op; } - ic = newiCode(GET_VALUE_AT_ADDRESS,op,NULL); - if (IS_PTR(type) && op->isaddr && force) - type = type->next; + ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL); + if (IS_PTR (type) && op->isaddr && force) + type = type->next; - type = copyLinkChain(type); + type = copyLinkChain (type); - IC_RESULT(ic) = newiTempOperand (type,1); - IC_RESULT(ic)->isaddr = 0; + IC_RESULT (ic) = newiTempOperand (type, 1); + IC_RESULT (ic)->isaddr = 0; /* 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); + ADDTOCHAIN (ic); - return IC_RESULT(ic) ; + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeCast - changes the value from one type to another */ /*-----------------------------------------------------------------*/ -operand *geniCodeCast (sym_link *type, operand *op, bool implicit) +operand * +geniCodeCast (sym_link * type, operand * op, bool implicit) { - iCode *ic ; - sym_link *optype ; - sym_link *opetype = getSpec(optype = operandType(op)); - sym_link *restype ; + iCode *ic; + sym_link *optype; + sym_link *opetype = getSpec (optype = operandType (op)); + sym_link *restype; + int errors=0; - /* one of them has size zero then error */ - if (IS_VOID(optype)) { - werror(E_CAST_ZERO); - return op; + /* one of them has size zero then error */ + if (IS_VOID (optype)) + { + werror (E_CAST_ZERO); + return op; } - /* if the operand is already the desired type then do nothing */ - if ( checkType (type,optype) == 1) - return op; + /* if the operand is already the desired type then do nothing */ + if (compareType (type, optype) == 1) + return op; - /* 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))); - - /* if casting to some pointer type && - the destination is not a generic pointer - then give a warning : (only for implicit casts)*/ - if (IS_PTR(optype) && implicit && - (DCL_TYPE(optype) != DCL_TYPE(type)) && - !IS_GENPTR(type)) { - werror(E_INCOMPAT_CAST); - werror(E_CONTINUE,"from type '"); - printTypeChain(optype,stderr);fprintf(stderr,"' to type '"); - printTypeChain(type,stderr);fprintf(stderr,"'\n"); - } - - /* if they are the same size create an assignment */ - if (getSize(type) == getSize(optype) && - !IS_BITFIELD(type) && - !IS_FLOAT(type) && - !IS_FLOAT(optype) && - ((IS_SPEC(type) && IS_SPEC(optype)) || - (!IS_SPEC(type) && !IS_SPEC(optype)))) { - - ic = newiCode('=',NULL,op); - IC_RESULT(ic) = newiTempOperand(type,0); - SPIL_LOC(IC_RESULT(ic)) = - (IS_TRUE_SYMOP(op) ? OP_SYMBOL(op) : NULL); - IC_RESULT(ic)->isaddr = 0; - } else { - ic = newiCode(CAST,operandFromLink(type), - geniCodeRValue(op,FALSE)); + /* 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))); + + /* if casting to/from pointers, do some checking */ + if (IS_PTR(type)) { // to a 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 (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) { + // no way to set the storage + if (IS_LITERAL(optype)) { + werror(E_LITERAL_GENERIC); + errors++; + } else { + werror(E_NONPTR2_GENPTR); + errors++; + } + } else if (implicit) { + werror(W_INTEGRAL2PTR_NOCAST); + errors++; + } + } + } else { + // shouldn't do that with float, array or structure unless to void + if (!IS_VOID(getSpec(type)) && + !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { + werror(E_INCOMPAT_TYPES); + errors++; + } + } + } else { // from a pointer to a pointer + 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++; + } + } + } + } + } + } else { // to a non pointer + if (IS_PTR(optype)) { // from a pointer + if (implicit) { // sneaky + if (IS_INTEGRAL(type)) { + werror(W_PTR2INTEGRAL_NOCAST); + errors++; + } else { // shouldn't do that with float, array or structure + werror(E_INCOMPAT_TYPES); + errors++; + } + } + } + } + if (errors) { + printFromToType (optype, type); + } + + /* if they are the same size create an assignment */ + if (getSize (type) == getSize (optype) && + !IS_BITFIELD (type) && + !IS_FLOAT (type) && + !IS_FLOAT (optype) && + ((IS_SPEC (type) && IS_SPEC (optype)) || + (!IS_SPEC (type) && !IS_SPEC (optype)))) + { + + ic = newiCode ('=', NULL, op); + IC_RESULT (ic) = newiTempOperand (type, 0); + SPIL_LOC (IC_RESULT (ic)) = + (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL); + IC_RESULT (ic)->isaddr = 0; + } + else + { + ic = newiCode (CAST, operandFromLink (type), + geniCodeRValue (op, FALSE)); - IC_RESULT(ic)= newiTempOperand(type,0); + IC_RESULT (ic) = newiTempOperand (type, 0); } - /* preserve the storage class & output class */ - /* of the original variable */ - restype = getSpec(operandType(IC_RESULT(ic))); - SPEC_SCLS(restype) = SPEC_SCLS(opetype); - SPEC_OCLS(restype) = SPEC_OCLS(opetype); + /* preserve the storage class & output class */ + /* of the original variable */ + restype = getSpec (operandType (IC_RESULT (ic))); + if (!IS_LITERAL(opetype)) + SPEC_SCLS (restype) = SPEC_SCLS (opetype); + SPEC_OCLS (restype) = SPEC_OCLS (opetype); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeLabel - will create a Label */ /*-----------------------------------------------------------------*/ -void geniCodeLabel (symbol *label) +void +geniCodeLabel (symbol * label) { - iCode *ic; + iCode *ic; - ic = newiCodeLabelGoto(LABEL,label); - ADDTOCHAIN(ic); + ic = newiCodeLabelGoto (LABEL, label); + ADDTOCHAIN (ic); } /*-----------------------------------------------------------------*/ /* geniCodeGoto - will create a Goto */ /*-----------------------------------------------------------------*/ -void geniCodeGoto (symbol *label) +void +geniCodeGoto (symbol * label) { - iCode *ic; + iCode *ic; - ic = newiCodeLabelGoto(GOTO,label); - ADDTOCHAIN(ic); + ic = newiCodeLabelGoto (GOTO, label); + ADDTOCHAIN (ic); } /*-----------------------------------------------------------------*/ /* geniCodeMultiply - gen intermediate code for multiplication */ /*-----------------------------------------------------------------*/ -operand *geniCodeMultiply (operand *left, operand *right) +operand * +geniCodeMultiply (operand * left, operand * right,int resultIsInt) { - iCode *ic ; - int p2 = 0; - sym_link *resType ; - LRTYPE ; + iCode *ic; + int p2 = 0; + sym_link *resType; + LRTYPE; - /* if they are both literal then we know the result */ - if (IS_LITERAL(letype) && IS_LITERAL(retype)) - return operandFromValue (valMult(left->operand.valOperand, - right->operand.valOperand)); + /* if they are both literal then we know the result */ + if (IS_LITERAL (letype) && IS_LITERAL (retype)) + return operandFromValue (valMult (left->operand.valOperand, + right->operand.valOperand)); - resType = usualBinaryConversions(&left, &right); + if (IS_LITERAL(retype)) { + p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand)); + } - /* if the right is a literal & power of 2 */ - /* then make it a left shift */ - if (IS_LITERAL(retype) && !IS_FLOAT(letype) && - (p2 = powof2 ((unsigned long)floatFromVal(right->operand.valOperand)))) - ic = newiCode(LEFT_OP, left,operandFromLit(p2)); /* left shift */ - 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; + resType = usualBinaryConversions (&left, &right); +#if 1 + rtype = operandType (right); + retype = getSpec (rtype); + ltype = operandType (left); + letype = getSpec (ltype); +#endif + if (resultIsInt) + { + SPEC_NOUN(getSpec(resType))=V_INT; + } + /* if the right is a literal & power of 2 */ + /* then make it a left shift */ + /* 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) && + !((resultIsInt) && (getSize (resType) != getSize (ltype)) && + (port->support.muldiv == 1))) + { + if ((resultIsInt) && (getSize (resType) != getSize (ltype))) + { + /* LEFT_OP need same size for left and result, */ + left = geniCodeCast (resType, left, TRUE); + ltype = operandType (left); + } + ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */ } - IC_RESULT(ic) = newiTempOperand(resType,1); + 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; - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + } + IC_RESULT (ic) = newiTempOperand (resType, 1); + + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeDivision - gen intermediate code for division */ /*-----------------------------------------------------------------*/ -operand *geniCodeDivision (operand *left, operand *right) -{ - iCode *ic ; - int p2 = 0; - sym_link *resType; - sym_link *rtype = operandType(right); - sym_link *retype= getSpec(rtype); - sym_link *ltype = operandType(left); - sym_link *letype= getSpec(ltype); - - resType = usualBinaryConversions(&left, &right); - - /* if the right is a literal & power of 2 */ - /* then make it a right shift */ - if (IS_LITERAL(retype) && - !IS_FLOAT(letype) && - (p2 = powof2 ((unsigned long) - floatFromVal(right->operand.valOperand)))) - ic = newiCode(RIGHT_OP, left,operandFromLit(p2)); /* right shift */ - else { - ic = newiCode('/',left,right); /* normal division */ - /* if the size left or right > 1 then support routine */ - if (getSize(ltype) > 1 || getSize(rtype) > 1) - ic->supportRtn = 1; +operand * +geniCodeDivision (operand * left, operand * right) +{ + iCode *ic; + int p2 = 0; + sym_link *resType; + sym_link *rtype = operandType (right); + sym_link *retype = getSpec (rtype); + sym_link *ltype = operandType (left); + sym_link *letype = getSpec (ltype); + + resType = usualBinaryConversions (&left, &right); + + /* 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 */ + } + else + { + ic = newiCode ('/', left, right); /* normal division */ + /* if the size left or right > 1 then support routine */ + if (getSize (ltype) > 1 || getSize (rtype) > 1) + ic->supportRtn = 1; } - IC_RESULT(ic) = newiTempOperand(resType,0); + IC_RESULT (ic) = newiTempOperand (resType, 0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeModulus - gen intermediate code for modulus */ /*-----------------------------------------------------------------*/ -operand *geniCodeModulus (operand *left, operand *right) +operand * +geniCodeModulus (operand * left, operand * right) { - iCode *ic ; - sym_link *resType; - LRTYPE ; + iCode *ic; + sym_link *resType; + LRTYPE; - /* if they are both literal then we know the result */ - if (IS_LITERAL(letype) && IS_LITERAL(retype)) - return operandFromValue (valMod(left->operand.valOperand, - right->operand.valOperand)); + /* if they are both literal then we know the result */ + if (IS_LITERAL (letype) && IS_LITERAL (retype)) + return operandFromValue (valMod (left->operand.valOperand, + right->operand.valOperand)); - resType = usualBinaryConversions(&left, &right); + resType = usualBinaryConversions (&left, &right); - /* now they are the same size */ - ic = newiCode('%',left,right); + /* now they are the same size */ + ic = newiCode ('%', left, right); - /* if the size left or right > 1 then support routine */ - if (getSize(ltype) > 1 || getSize(rtype) > 1) - ic->supportRtn = 1; - IC_RESULT(ic) = newiTempOperand(resType,0); + /* if the size left or right > 1 then support routine */ + if (getSize (ltype) > 1 || getSize (rtype) > 1) + ic->supportRtn = 1; + IC_RESULT (ic) = newiTempOperand (resType, 0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodePtrPtrSubtract - subtracts pointer from pointer */ /*-----------------------------------------------------------------*/ -operand *geniCodePtrPtrSubtract (operand *left, operand *right) +operand * +geniCodePtrPtrSubtract (operand * left, operand * right) { - iCode *ic ; - operand *result; - LRTYPE ; + iCode *ic; + operand *result; + LRTYPE; - /* if they are both literals then */ - if (IS_LITERAL(letype) && IS_LITERAL(retype)) { - result = operandFromValue (valMinus(left->operand.valOperand, - right->operand.valOperand)); - goto subtractExit; + /* if they are both literals then */ + if (IS_LITERAL (letype) && IS_LITERAL (retype)) + { + result = operandFromValue (valMinus (left->operand.valOperand, + right->operand.valOperand)); + goto subtractExit; } - ic = newiCode('-',left,right); + ic = newiCode ('-', left, right); + + IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1); + ADDTOCHAIN (ic); - IC_RESULT(ic) = result = newiTempOperand(newIntLink(),1); - ADDTOCHAIN(ic); +subtractExit: + if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) { + return result; + } - subtractExit: - return geniCodeDivision (result, - operandFromLit(getSize(ltype->next))); + // should we really do this? is this ANSI? + return geniCodeDivision (result, + operandFromLit (getSize (ltype->next))); } /*-----------------------------------------------------------------*/ /* geniCodeSubtract - generates code for subtraction */ /*-----------------------------------------------------------------*/ -operand *geniCodeSubtract (operand *left, operand *right) +operand * +geniCodeSubtract (operand * left, operand * right) { - iCode *ic ; - int isarray= 0; - sym_link *resType; - LRTYPE ; + iCode *ic; + int isarray = 0; + sym_link *resType; + LRTYPE; - /* if they both pointers then */ - if ((IS_PTR(ltype) || IS_ARRAY(ltype)) && - (IS_PTR(rtype) || IS_ARRAY(rtype))) - return geniCodePtrPtrSubtract (left,right); + /* if they both pointers then */ + if ((IS_PTR (ltype) || IS_ARRAY (ltype)) && + (IS_PTR (rtype) || IS_ARRAY (rtype))) + return geniCodePtrPtrSubtract (left, right); - /* if they are both literal then we know the result */ - if (IS_LITERAL(letype) && IS_LITERAL(retype) - && left->isLiteral && right->isLiteral) - return operandFromValue (valMinus(left->operand.valOperand, - right->operand.valOperand)); + /* if they are both literal then we know the result */ + if (IS_LITERAL (letype) && IS_LITERAL (retype) + && left->isLiteral && right->isLiteral) + return operandFromValue (valMinus (left->operand.valOperand, + right->operand.valOperand)); - /* if left is an array or pointer */ - if ( IS_PTR(ltype) || IS_ARRAY(ltype) ) { - isarray = left->isaddr ; - right = geniCodeMultiply (right, - operandFromLit(getSize(ltype->next))); - resType = copyLinkChain(IS_ARRAY(ltype) ? ltype->next : ltype); + /* if left is an array or pointer */ + if (IS_PTR (ltype) || IS_ARRAY (ltype)) + { + isarray = left->isaddr; + right = geniCodeMultiply (right, + operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE)); + resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype); } - else { /* make them the same size */ - resType = usualBinaryConversions(&left, &right); + else + { /* make them the same size */ + resType = usualBinaryConversions (&left, &right); } - ic = newiCode('-',left,right); + ic = newiCode ('-', left, right); - IC_RESULT(ic)= newiTempOperand(resType,1); - IC_RESULT(ic)->isaddr = (isarray ? 1 : 0); + IC_RESULT (ic) = newiTempOperand (resType, 1); + IC_RESULT (ic)->isaddr = (isarray ? 1 : 0); - /* if left or right is a float */ - if (IS_FLOAT(ltype) || IS_FLOAT(rtype)) - ic->supportRtn = 1; + /* if left or right is a float */ + if (IS_FLOAT (ltype) || IS_FLOAT (rtype)) + ic->supportRtn = 1; - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeAdd - generates iCode for addition */ /*-----------------------------------------------------------------*/ -operand *geniCodeAdd (operand *left, operand *right ) +operand * +geniCodeAdd (operand * left, operand * right, int lvl) { - iCode *ic ; - 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) && right->isLiteral && !floatFromVal(valFromType(retype))) - return left; + iCode *ic; + sym_link *resType; + operand *size; + int isarray = 0; + LRTYPE; - /* if left is literal zero return right */ - if (IS_LITERAL(letype) && left->isLiteral && !floatFromVal(valFromType(letype))) - return right ; +#if 0 + /* if left is an array then array access */ + if (IS_ARRAY (ltype)) + return geniCodeArray (left, right,lvl); +#endif - /* if left is an array or pointer then size */ - if (IS_PTR(ltype)) { + /* if the right side is LITERAL zero */ + /* return the left side */ + if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype))) + return left; - isarray = left->isaddr; - size = - operandFromLit(getSize(ltype->next)); - if (getSize(ltype) > 1 && (getSize(rtype) < INTSIZE)) - { - right = geniCodeCast(INTTYPE,right,TRUE); - } - right = geniCodeMultiply (right ,size); + /* if left is literal zero return right */ + if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype))) + return right; - resType = copyLinkChain(ltype); + /* if left is a pointer then size */ + if (IS_PTR (ltype) || IS_ARRAY(ltype)) + { + isarray = left->isaddr; + // there is no need to multiply with 1 + if (getSize(ltype->next)!=1) { + size = operandFromLit (getSize (ltype->next)); + right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE)); + } + resType = copyLinkChain (ltype); } - else { /* make them the same size */ - resType = usualBinaryConversions(&left, &right); + else + { // make them the same size + resType = usualBinaryConversions (&left, &right); } - /* if they are both literals then we know */ - if (IS_LITERAL(letype) && IS_LITERAL(retype) - && left->isLiteral && right->isLiteral) - return operandFromValue (valPlus(valFromType(letype), - valFromType(retype))); + /* if they are both literals then we know */ + if (IS_LITERAL (letype) && IS_LITERAL (retype) + && left->isLiteral && right->isLiteral) + return operandFromValue (valPlus (valFromType (letype), + valFromType (retype))); - ic = newiCode('+',left,right); + ic = newiCode ('+', left, right); - IC_RESULT(ic) = newiTempOperand(resType,1); - IC_RESULT(ic)->isaddr = ( isarray ? 1 : 0); + IC_RESULT (ic) = newiTempOperand (resType, 1); + IC_RESULT (ic)->isaddr = (isarray ? 1 : 0); - /* if left or right is a float then support - routine */ - if (IS_FLOAT(ltype) || IS_FLOAT(rtype)) - ic->supportRtn = 1; + /* if left or right is a float then support + routine */ + if (IS_FLOAT (ltype) || IS_FLOAT (rtype)) + ic->supportRtn = 1; - ADDTOCHAIN(ic); + ADDTOCHAIN (ic); - return IC_RESULT(ic) ; + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* aggrToPtr - changes an aggregate to pointer to an aggregate */ /*-----------------------------------------------------------------*/ -sym_link *aggrToPtr ( sym_link *type, bool force) +sym_link * +aggrToPtr (sym_link * type, bool force) { - sym_link *etype ; - sym_link *ptype ; + sym_link *etype; + sym_link *ptype; + + + if (IS_PTR (type) && !force) + return type; + etype = getSpec (type); + ptype = newLink (DECLARATOR); - if (IS_PTR(type) && !force) - return type; + ptype->next = type; - etype = getSpec(type); - ptype = newLink(); +#ifdef JWK + /* if the output class is code */ + if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER) + DCL_PTR_CONST (ptype) = port->mem.code_ro; - ptype->next = type; - /* if the output class is generic */ - 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)) + DCL_PTR_CONST (ptype) = 1; - /* if the variable was declared a constant */ - /* then the pointer points to a constant */ - if (IS_CONSTANT(etype) ) - DCL_PTR_CONST(ptype) = 1; + /* the variable was volatile then pointer to volatile */ + if (IS_VOLATILE (etype)) + DCL_PTR_VOLATILE (ptype) = 1; +#else + DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype)); +#endif - /* the variable was volatile then pointer to volatile */ - if (IS_VOLATILE(etype)) - DCL_PTR_VOLATILE(ptype) = 1; - return ptype; + return ptype; } /*-----------------------------------------------------------------*/ /* geniCodeArray2Ptr - array to pointer */ /*-----------------------------------------------------------------*/ -operand *geniCodeArray2Ptr (operand *op) +operand * +geniCodeArray2Ptr (operand * op) { - sym_link *optype = operandType(op); - sym_link *opetype = getSpec(optype); + 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; +#ifdef JWK + /* 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 */ + if (IS_CONSTANT (opetype)) + DCL_PTR_CONST (optype) = 1; - /* if the variable was declared a constant */ - /* then the pointer points to a constant */ - if (IS_CONSTANT(opetype) ) - DCL_PTR_CONST(optype) = 1; + /* the variable was volatile then pointer to volatile */ + if (IS_VOLATILE (opetype)) + DCL_PTR_VOLATILE (optype) = 1; +#else + DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype)); +#endif - /* the variable was volatile then pointer to volatile */ - if (IS_VOLATILE(opetype)) - DCL_PTR_VOLATILE(optype) = 1; - op->isaddr = 0; - return op; + op->isaddr = 0; + return op; } /*-----------------------------------------------------------------*/ /* geniCodeArray - array access */ /*-----------------------------------------------------------------*/ -operand *geniCodeArray (operand *left,operand *right) +operand * +geniCodeArray (operand * left, operand * right,int lvl) { - iCode *ic; - sym_link *ltype = operandType(left); + iCode *ic; + sym_link *ltype = operandType (left); - if (IS_PTR(ltype)) { - if (IS_PTR(ltype->next) && left->isaddr) - { - left = geniCodeRValue(left,FALSE); - } - return geniCodeDerefPtr(geniCodeAdd(left,right)); + if (IS_PTR (ltype)) + { + if (IS_PTR (ltype->next) && left->isaddr) + { + left = geniCodeRValue (left, FALSE); + } + return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl); } - /* array access */ - right = usualUnaryConversions(right); - right = geniCodeMultiply(right, - operandFromLit(getSize(ltype->next))); + right = geniCodeMultiply (right, + operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE)); - /* we can check for limits here */ - if (isOperandLiteral(right) && - IS_ARRAY(ltype) && - DCL_ELEM(ltype) && - (operandLitValue(right)/getSize(ltype->next)) >= DCL_ELEM(ltype)) { - werror(E_ARRAY_BOUND); - right = operandFromLit(0); + /* we can check for limits here */ + if (isOperandLiteral (right) && + IS_ARRAY (ltype) && + DCL_ELEM (ltype) && + (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype)) + { + werror (E_ARRAY_BOUND); + right = operandFromLit (0); } - ic = newiCode('+',left,right); + ic = newiCode ('+', left, right); - IC_RESULT(ic) = newiTempOperand(((IS_PTR(ltype) && - !IS_AGGREGATE(ltype->next) && - !IS_PTR(ltype->next)) - ? ltype : ltype->next),0); + IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) && + !IS_AGGREGATE (ltype->next) && + !IS_PTR (ltype->next)) + ? ltype : ltype->next), 0); - IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(ltype->next)); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next)); + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeStruct - generates intermediate code for structres */ /*-----------------------------------------------------------------*/ -operand *geniCodeStruct (operand *left, operand *right, bool islval) +operand * +geniCodeStruct (operand * left, operand * right, bool islval) { - iCode *ic ; - sym_link *type = operandType(left); - sym_link *etype = getSpec(type); - sym_link *retype ; - symbol *element = getStructElement(SPEC_STRUCT(etype), - right->operand.symOperand); + iCode *ic; + sym_link *type = operandType (left); + sym_link *etype = getSpec (type); + sym_link *retype; + symbol *element = getStructElement (SPEC_STRUCT (etype), + right->operand.symOperand); - /* add the offset */ - ic = newiCode('+',left,operandFromLit(element->offset)); + wassert(IS_SYMOP(right)); + + /* add the offset */ + ic = newiCode ('+', left, operandFromLit (element->offset)); - IC_RESULT(ic) = newiTempOperand(element->type,0); + IC_RESULT (ic) = newiTempOperand (element->type, 0); - /* preserve the storage & output class of the struct */ - /* as well as the volatile attribute */ - retype = getSpec(operandType(IC_RESULT(ic))); - SPEC_SCLS(retype) = SPEC_SCLS(etype); - SPEC_OCLS(retype) = SPEC_OCLS(etype); - SPEC_VOLATILE(retype) |= SPEC_VOLATILE(etype); + /* preserve the storage & output class of the struct */ + /* as well as the volatile attribute */ + retype = getSpec (operandType (IC_RESULT (ic))); + SPEC_SCLS (retype) = SPEC_SCLS (etype); + SPEC_OCLS (retype) = SPEC_OCLS (etype); + SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype); - if (IS_PTR(element->type)) - setOperandType(IC_RESULT(ic),aggrToPtr(operandType(IC_RESULT(ic)),TRUE)); + if (IS_PTR (element->type)) + setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE)); - IC_RESULT(ic)->isaddr = (!IS_AGGREGATE(element->type)); + IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type)); - ADDTOCHAIN(ic); - return (islval ? IC_RESULT(ic) : geniCodeRValue(IC_RESULT(ic),TRUE)); + ADDTOCHAIN (ic); + return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE)); } /*-----------------------------------------------------------------*/ /* geniCodePostInc - generate int code for Post increment */ /*-----------------------------------------------------------------*/ -operand *geniCodePostInc (operand *op) -{ - iCode *ic ; - operand *rOp ; - sym_link *optype = operandType(op); - operand *result ; - operand *rv = (IS_ITEMP(op) ? - geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) : - op); - sym_link *rvtype = operandType(rv); - int size = 0; - - /* if this is not an address we have trouble */ - if ( ! op->isaddr ) { - werror (E_LVALUE_REQUIRED,"++"); - return op ; +operand * +geniCodePostInc (operand * op) +{ + iCode *ic; + operand *rOp; + sym_link *optype = operandType (op); + operand *result; + operand *rv = (IS_ITEMP (op) ? + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); + sym_link *rvtype = operandType (rv); + int size = 0; + + /* if this is not an address we have trouble */ + if (!op->isaddr) + { + werror (E_LVALUE_REQUIRED, "++"); + return op; } - rOp = newiTempOperand(rvtype,0); - rOp->noSpilLoc = 1; + rOp = newiTempOperand (rvtype, 0); + OP_SYMBOL(rOp)->noSpilLoc = 1; - if (IS_ITEMP(rv)) - rv->noSpilLoc = 1; + if (IS_ITEMP (rv)) + OP_SYMBOL(rv)->noSpilLoc = 1; - geniCodeAssign(rOp,rv,0); + geniCodeAssign (rOp, rv, 0); + + size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1); + if (IS_FLOAT (rvtype)) + ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0"))); + else + ic = newiCode ('+', rv, operandFromLit (size)); - size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1); - ic = newiCode('+',rv,operandFromLit(size)); - IC_RESULT(ic) = result =newiTempOperand(rvtype,0); - ADDTOCHAIN(ic); + IC_RESULT (ic) = result = newiTempOperand (rvtype, 0); + ADDTOCHAIN (ic); - geniCodeAssign(op,result,0); + geniCodeAssign (op, result, 0); - return rOp; + return rOp; } /*-----------------------------------------------------------------*/ /* geniCodePreInc - generate code for preIncrement */ /*-----------------------------------------------------------------*/ -operand *geniCodePreInc (operand *op) +operand * +geniCodePreInc (operand * op) { - iCode *ic ; - sym_link *optype = operandType(op); - operand *rop = (IS_ITEMP(op) ? - geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) : - op); - sym_link *roptype = operandType(rop); - operand *result; - int size = 0; + iCode *ic; + sym_link *optype = operandType (op); + operand *rop = (IS_ITEMP (op) ? + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); + sym_link *roptype = operandType (rop); + operand *result; + int size = 0; - if ( ! op->isaddr ) { - werror(E_LVALUE_REQUIRED,"++"); - return op ; + if (!op->isaddr) + { + werror (E_LVALUE_REQUIRED, "++"); + return op; } - size = (IS_PTR(roptype) ? getSize(roptype->next) : 1); - ic = newiCode('+',rop,operandFromLit(size)); - IC_RESULT(ic) = result = newiTempOperand(roptype,0) ; - ADDTOCHAIN(ic); + size = (IS_PTR (roptype) ? getSize (roptype->next) : 1); + if (IS_FLOAT (roptype)) + ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0"))); + else + ic = newiCode ('+', rop, operandFromLit (size)); + IC_RESULT (ic) = result = newiTempOperand (roptype, 0); + ADDTOCHAIN (ic); - return geniCodeAssign(op,result,0) ; + return geniCodeAssign (op, result, 0); } /*-----------------------------------------------------------------*/ /* geniCodePostDec - generates code for Post decrement */ /*-----------------------------------------------------------------*/ -operand *geniCodePostDec (operand *op) -{ - iCode *ic ; - operand *rOp ; - sym_link *optype = operandType(op); - operand *result ; - operand *rv = (IS_ITEMP(op) ? - geniCodeRValue(op,(IS_PTR(optype) ? TRUE : FALSE)) : - op); - sym_link *rvtype = operandType(rv); - int size = 0; - - /* if this is not an address we have trouble */ - if ( ! op->isaddr ) { - werror (E_LVALUE_REQUIRED,"++"); - return op ; +operand * +geniCodePostDec (operand * op) +{ + iCode *ic; + operand *rOp; + sym_link *optype = operandType (op); + operand *result; + operand *rv = (IS_ITEMP (op) ? + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); + sym_link *rvtype = operandType (rv); + int size = 0; + + /* if this is not an address we have trouble */ + if (!op->isaddr) + { + werror (E_LVALUE_REQUIRED, "--"); + return op; } - rOp = newiTempOperand(rvtype,0); - rOp->noSpilLoc = 1; + rOp = newiTempOperand (rvtype, 0); + OP_SYMBOL(rOp)->noSpilLoc = 1; + + if (IS_ITEMP (rv)) + OP_SYMBOL(rv)->noSpilLoc = 1; - if (IS_ITEMP(rv)) - rv->noSpilLoc = 1; + geniCodeAssign (rOp, rv, 0); - geniCodeAssign(rOp,rv,0); + size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1); + if (IS_FLOAT (rvtype)) + ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0"))); + else + ic = newiCode ('-', rv, operandFromLit (size)); - size = (IS_PTR(rvtype) ? getSize(rvtype->next) : 1); - ic = newiCode('-',rv,operandFromLit(size)); - IC_RESULT(ic) = result =newiTempOperand(rvtype,0); - ADDTOCHAIN(ic); + IC_RESULT (ic) = result = newiTempOperand (rvtype, 0); + ADDTOCHAIN (ic); - geniCodeAssign(op,result,0); + geniCodeAssign (op, result, 0); - return rOp; + return rOp; } /*-----------------------------------------------------------------*/ /* geniCodePreDec - generate code for pre decrement */ /*-----------------------------------------------------------------*/ -operand *geniCodePreDec (operand *op) +operand * +geniCodePreDec (operand * op) { - iCode *ic ; - sym_link *optype = operandType(op); - operand *rop = (IS_ITEMP(op) ? - geniCodeRValue (op,(IS_PTR(optype) ? TRUE : FALSE)) : - op); - sym_link *roptype = operandType(rop); - operand *result; - int size = 0; + iCode *ic; + sym_link *optype = operandType (op); + operand *rop = (IS_ITEMP (op) ? + geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) : + op); + sym_link *roptype = operandType (rop); + operand *result; + int size = 0; - if ( ! op->isaddr ) { - werror(E_LVALUE_REQUIRED,"++"); - return op ; + if (!op->isaddr) + { + werror (E_LVALUE_REQUIRED, "--"); + return op; } - size = (IS_PTR(roptype) ? getSize(roptype->next) : 1); - ic = newiCode('-',rop,operandFromLit(size)); - IC_RESULT(ic) = result = newiTempOperand(roptype,0) ; - ADDTOCHAIN(ic); + size = (IS_PTR (roptype) ? getSize (roptype->next) : 1); + if (IS_FLOAT (roptype)) + ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0"))); + else + ic = newiCode ('-', rop, operandFromLit (size)); + IC_RESULT (ic) = result = newiTempOperand (roptype, 0); + ADDTOCHAIN (ic); - return geniCodeAssign(op,result,0) ; + return geniCodeAssign (op, result, 0); } /*-----------------------------------------------------------------*/ /* geniCodeBitwise - gen int code for bitWise operators */ /*-----------------------------------------------------------------*/ -operand *geniCodeBitwise (operand *left, operand *right, - int oper, sym_link *resType) +operand * +geniCodeBitwise (operand * left, operand * right, + int oper, sym_link * resType) { - iCode *ic; + iCode *ic; - left = geniCodeCast(resType,left,TRUE); - right= geniCodeCast(resType,right,TRUE); + left = geniCodeCast (resType, left, TRUE); + right = geniCodeCast (resType, right, TRUE); - ic = newiCode(oper,left,right); - IC_RESULT(ic) = newiTempOperand(resType,0); + ic = newiCode (oper, left, right); + IC_RESULT (ic) = newiTempOperand (resType, 0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeAddressOf - gens icode for '&' address of operator */ /*-----------------------------------------------------------------*/ -operand *geniCodeAddressOf (operand *op) +operand * +geniCodeAddressOf (operand * op) { - iCode *ic; - sym_link *p ; - sym_link *optype = operandType(op); - sym_link *opetype= getSpec(optype); + iCode *ic; + sym_link *p; + sym_link *optype = operandType (op); + sym_link *opetype = getSpec (optype); - /* lvalue check already done in decorateType */ - /* this must be a lvalue */ + /* lvalue check already done in decorateType */ + /* this must be a lvalue */ /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */ /* werror (E_LVALUE_REQUIRED,"&"); */ /* return op; */ /* } */ - p = newLink(); - p->class = DECLARATOR ; + p = newLink (DECLARATOR); - /* set the pointer depending on the storage class */ - if ((DCL_TYPE(p) = PTR_TYPE(SPEC_OCLS(opetype))) == CPOINTER) - DCL_PTR_CONST(p) = port->mem.code_ro; +#ifdef JWK + /* 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; + /* make sure we preserve the const & volatile */ + if (IS_CONSTANT (opetype)) + DCL_PTR_CONST (p) = 1; - if (IS_VOLATILE(opetype)) - DCL_PTR_VOLATILE(p) = 1; + if (IS_VOLATILE (opetype)) + DCL_PTR_VOLATILE (p) = 1; +#else + DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype)); +#endif - p->next = copyLinkChain(optype); - /* if already a temp */ - if (IS_ITEMP(op)) { - setOperandType (op,p); - op->isaddr= 0; - return op; + p->next = copyLinkChain (optype); + + /* if already a temp */ + if (IS_ITEMP (op)) + { + setOperandType (op, p); + op->isaddr = 0; + return op; } - /* other wise 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); + /* other wise 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 */ /*-----------------------------------------------------------------*/ -void setOClass (sym_link *ptr, sym_link *spec) +void +setOClass (sym_link * ptr, sym_link * spec) { - switch (DCL_TYPE(ptr)) { + switch (DCL_TYPE (ptr)) + { case POINTER: - SPEC_OCLS(spec) = data ; - break ; + SPEC_OCLS (spec) = data; + break; case GPOINTER: - SPEC_OCLS(spec) = generic; - break; + SPEC_OCLS (spec) = generic; + break; case FPOINTER: - SPEC_OCLS(spec) = xdata ; - break ; + SPEC_OCLS (spec) = xdata; + break; case CPOINTER: - SPEC_OCLS(spec) = code ; - break ; + SPEC_OCLS (spec) = code; + break; case IPOINTER: - SPEC_OCLS(spec) = idata; - break; + SPEC_OCLS (spec) = idata; + break; case PPOINTER: - SPEC_OCLS(spec) = xstack; - break; + SPEC_OCLS (spec) = xstack; + break; case EEPPOINTER: - SPEC_OCLS(spec) = eeprom; - break; + SPEC_OCLS (spec) = eeprom; + break; default: - break; + break; } } @@ -2168,1084 +2531,1265 @@ void setOClass (sym_link *ptr, sym_link *spec) /*-----------------------------------------------------------------*/ /* geniCodeDerefPtr - dereference pointer with '*' */ /*-----------------------------------------------------------------*/ -operand *geniCodeDerefPtr (operand *op) +operand * +geniCodeDerefPtr (operand * op,int lvl) { - sym_link *rtype , *retype ; - sym_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)) { - if (IS_TRUE_SYMOP(op)) { - op->isaddr = 1; - op = geniCodeRValue(op,TRUE); - } - else - op = geniCodeRValue(op,TRUE); + /* if this is a pointer then generate the rvalue */ + if (IS_PTR (optype)) + { + if (IS_TRUE_SYMOP (op)) + { + op->isaddr = 1; + op = geniCodeRValue (op, TRUE); + } + else + op = geniCodeRValue (op, TRUE); } - /* now get rid of the pointer part */ - if (lvaluereq && IS_ITEMP(op) ) + /* now get rid of the pointer part */ + if (isLvaluereq(lvl) && IS_ITEMP (op)) { - retype = getSpec(rtype = copyLinkChain(optype)) ; + retype = getSpec (rtype = copyLinkChain (optype)); } - else + else { - retype = getSpec(rtype = copyLinkChain(optype->next)) ; + retype = getSpec (rtype = copyLinkChain (optype->next)); } - /* if this is a pointer then outputclass needs 2b updated */ - if (IS_PTR(optype)) - setOClass(optype,retype); + /* if this is a pointer then outputclass needs 2b updated */ + if (IS_PTR (optype)) + setOClass (optype, retype); - op->isGptr = IS_GENPTR(optype); + op->isGptr = IS_GENPTR (optype); - /* if the pointer was declared as a constant */ - /* then we cannot allow assignment to the derefed */ - if (IS_PTR_CONST(optype)) - SPEC_CONST(retype) = 1; + /* if the pointer was declared as a constant */ + /* then we cannot allow assignment to the derefed */ + if (IS_PTR_CONST (optype)) + SPEC_CONST (retype) = 1; - op->isaddr = (IS_PTR(rtype) || - IS_STRUCT(rtype) || - IS_INT(rtype) || - IS_CHAR(rtype) || - IS_FLOAT(rtype) ); + op->isaddr = (IS_PTR (rtype) || + IS_STRUCT (rtype) || + IS_INT (rtype) || + IS_CHAR (rtype) || + IS_FLOAT (rtype)); - if (!lvaluereq) - op = geniCodeRValue(op,TRUE); + if (!isLvaluereq(lvl)) + op = geniCodeRValue (op, TRUE); - setOperandType(op,rtype); + setOperandType (op, rtype); - return op; + return op; } /*-----------------------------------------------------------------*/ /* geniCodeUnaryMinus - does a unary minus of the operand */ /*-----------------------------------------------------------------*/ -operand *geniCodeUnaryMinus (operand *op) +operand * +geniCodeUnaryMinus (operand * op) { - iCode *ic ; - sym_link *optype = operandType(op); + iCode *ic; + sym_link *optype = operandType (op); - if (IS_LITERAL(optype)) - return operandFromLit(- floatFromVal(op->operand.valOperand)); + if (IS_LITERAL (optype)) + return operandFromLit (-floatFromVal (op->operand.valOperand)); - ic = newiCode(UNARYMINUS,op,NULL); - IC_RESULT(ic) = newiTempOperand(optype,0); - ADDTOCHAIN(ic); - return IC_RESULT(ic); + ic = newiCode (UNARYMINUS, op, NULL); + IC_RESULT (ic) = newiTempOperand (optype, 0); + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeLeftShift - gen i code for left shift */ /*-----------------------------------------------------------------*/ -operand *geniCodeLeftShift (operand *left, operand *right) +operand * +geniCodeLeftShift (operand * left, operand * right) { - iCode *ic; - - /* Note that we don't use the usual binary conversions for the - * shift operations, in accordance with our ANSI friends. - */ - if (options.ANSIint) - { - right = usualUnaryConversions(right); - left = usualUnaryConversions(left); - } + iCode *ic; - ic = newiCode(LEFT_OP,left,right); - IC_RESULT(ic) = newiTempOperand(operandType(left),0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ic = newiCode (LEFT_OP, left, right); + IC_RESULT (ic) = newiTempOperand (operandType (left), 0); + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeRightShift - gen i code for right shift */ /*-----------------------------------------------------------------*/ -operand *geniCodeRightShift (operand *left, operand *right) +operand * +geniCodeRightShift (operand * left, operand * right) { - iCode *ic; - - /* Note that we don't use the usual binary conversions for the - * shift operations, in accordance with our ANSI friends. - */ - if (options.ANSIint) - { - right = usualUnaryConversions(right); - left = usualUnaryConversions(left); - } + iCode *ic; - ic = newiCode(RIGHT_OP,left,right); - IC_RESULT(ic) = newiTempOperand(operandType(left),0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + ic = newiCode (RIGHT_OP, left, right); + 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 ) +operand * +geniCodeLogic (operand * left, operand * right, int op) { - iCode *ic ; - sym_link *ctype; - sym_link *rtype = operandType(right); - sym_link *ltype = operandType(left); + iCode *ic; + 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 */ - if (IS_INTEGRAL(ltype) && IS_LITERAL(rtype)) { - int nbits = bitsForType(ltype); - long v = operandLitValue(right); - - if (v > ((LONG_LONG) 1 << nbits) && v > 0) - werror(W_CONST_RANGE," compare operation "); + /* left is integral type and right is literal then + 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); } - ctype = usualBinaryConversions(&left, &right); + ctype = usualBinaryConversions (&left, &right); - ic = newiCode(op,left,right); - IC_RESULT(ic) = newiTempOperand (newCharLink(),1); + ic = newiCode (op, left, right); + IC_RESULT (ic) = newiTempOperand (newCharLink (), 1); - /* if comparing anything greater than one byte - and not a '==' || '!=' || '&&' || '||' (these - will be inlined */ - if (getSize(ctype) > 1 && - op != EQ_OP && - op != NE_OP && - op != AND_OP && - op != OR_OP ) - ic->supportRtn = 1; + /* if comparing float + and not a '==' || '!=' || '&&' || '||' (these + will be inlined */ + if (IS_FLOAT(ctype) && + op != EQ_OP && + op != NE_OP && + op != AND_OP && + op != OR_OP) + ic->supportRtn = 1; - ADDTOCHAIN(ic); - return IC_RESULT(ic); + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeUnary - for a a generic unary operation */ /*-----------------------------------------------------------------*/ -operand *geniCodeUnary (operand *op, int oper ) +operand * +geniCodeUnary (operand * op, int oper) { - iCode *ic = newiCode (oper,op,NULL); + iCode *ic = newiCode (oper, op, NULL); - IC_RESULT(ic)= newiTempOperand(operandType(op),0); - ADDTOCHAIN(ic); - return IC_RESULT(ic) ; + IC_RESULT (ic) = newiTempOperand (operandType (op), 0); + ADDTOCHAIN (ic); + return IC_RESULT (ic); } /*-----------------------------------------------------------------*/ /* geniCodeConditional - geniCode for '?' ':' operation */ /*-----------------------------------------------------------------*/ -operand *geniCodeConditional (ast *tree) +operand * +geniCodeConditional (ast * tree,int lvl) { - iCode *ic ; - symbol *falseLabel = newiTempLabel(NULL); - symbol *exitLabel = newiTempLabel(NULL); - operand *cond = ast2iCode(tree->left); - operand *true, *false , *result; + iCode *ic; + symbol *falseLabel = newiTempLabel (NULL); + symbol *exitLabel = newiTempLabel (NULL); + operand *cond = ast2iCode (tree->left,lvl+1); + operand *true, *false, *result; - ic = newiCodeCondition(geniCodeRValue(cond,FALSE), - NULL,falseLabel); - ADDTOCHAIN(ic); + ic = newiCodeCondition (geniCodeRValue (cond, FALSE), + NULL, falseLabel); + ADDTOCHAIN (ic); - true = ast2iCode(tree->right->left); + true = ast2iCode (tree->right->left,lvl+1); - /* move the value to a new Operand */ - result = newiTempOperand(operandType(true),0); - geniCodeAssign(result,geniCodeRValue(true,FALSE),0); + /* move the value to a new Operand */ + result = newiTempOperand (tree->right->ftype, 0); + geniCodeAssign (result, geniCodeRValue (true, FALSE), 0); - /* generate an unconditional goto */ - geniCodeGoto(exitLabel); + /* generate an unconditional goto */ + geniCodeGoto (exitLabel); - /* now for the right side */ - geniCodeLabel(falseLabel); + /* now for the right side */ + geniCodeLabel (falseLabel); - false = ast2iCode(tree->right->right); - geniCodeAssign(result,geniCodeRValue(false,FALSE),0); + false = ast2iCode (tree->right->right,lvl+1); + geniCodeAssign (result, geniCodeRValue (false, FALSE), 0); - /* create the exit label */ - geniCodeLabel(exitLabel); + /* create the exit label */ + geniCodeLabel (exitLabel); - return result ; + return result; } /*-----------------------------------------------------------------*/ /* geniCodeAssign - generate code for assignment */ /*-----------------------------------------------------------------*/ -operand *geniCodeAssign (operand *left, operand *right, int nosupdate) +operand * +geniCodeAssign (operand * left, operand * right, int nosupdate) { - iCode *ic ; - sym_link *ltype = operandType(left); - sym_link *rtype = operandType(right); + iCode *ic; + sym_link *ltype = operandType (left); + sym_link *rtype = operandType (right); - if (!left->isaddr && !IS_ITEMP(left)) { - werror(E_LVALUE_REQUIRED,"assignment"); - return left; + if (!left->isaddr && !IS_ITEMP (left)) + { + werror (E_LVALUE_REQUIRED, "assignment"); + return left; } - /* 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)) { - int nbits = bitsForType(ltype); - long v = operandLitValue(right); - - 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 */ - /* then cast rights type to left */ - - /* first check the type for pointer assignement */ - if (left->isaddr && IS_PTR(ltype) && IS_ITEMP(left) && - checkType(ltype,rtype)<0) { - if (checkType(ltype->next,rtype) < 0) - right = geniCodeCast(ltype->next,right,TRUE); - } else - if (checkType(ltype,rtype) < 0 ) - right = geniCodeCast(ltype,right,TRUE); - - /* if left is a true symbol & ! volatile - create an assignment to temporary for - the right & then assign this temporary - to the symbol this is SSA . isn't it simple - and folks have published mountains of paper on it */ - if (IS_TRUE_SYMOP(left) && - !isOperandVolatile(left,FALSE) && - isOperandGlobal(left)) { - symbol *sym = NULL; - - if (IS_TRUE_SYMOP(right)) - sym = OP_SYMBOL(right); - ic = newiCode('=',NULL,right); - IC_RESULT(ic) = right = newiTempOperand(ltype,0); - SPIL_LOC(right) = sym ; - ADDTOCHAIN(ic); - } - - ic = newiCode('=',NULL,right); - IC_RESULT(ic) = left; - ADDTOCHAIN(ic); - - /* if left isgptr flag is set then support - routine will be required */ - if (left->isGptr) - ic->supportRtn = 1; - - ic->nosupdate = nosupdate; - return left; + /* 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)) + { + checkConstantRange(ltype, + OP_VALUE(right), "= operation", 0); + } + + /* 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 */ + /* then cast rights type to left */ + + /* first check the type for pointer assignement */ + if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) && + compareType (ltype, rtype) <= 0) + { + if (compareType (ltype->next, rtype) < 0) + right = geniCodeCast (ltype->next, right, TRUE); + } + else if (compareType (ltype, rtype) < 0) + right = geniCodeCast (ltype, right, TRUE); + + /* if left is a true symbol & ! volatile + create an assignment to temporary for + the right & then assign this temporary + to the symbol this is SSA . isn't it simple + and folks have published mountains of paper on it */ + if (IS_TRUE_SYMOP (left) && + !isOperandVolatile (left, FALSE) && + isOperandGlobal (left)) + { + symbol *sym = NULL; + + if (IS_TRUE_SYMOP (right)) + sym = OP_SYMBOL (right); + ic = newiCode ('=', NULL, right); + IC_RESULT (ic) = right = newiTempOperand (ltype, 0); + SPIL_LOC (right) = sym; + ADDTOCHAIN (ic); + } + + ic = newiCode ('=', NULL, right); + IC_RESULT (ic) = left; + ADDTOCHAIN (ic); + + /* if left isgptr flag is set then support + routine will be required */ + if (left->isGptr) + ic->supportRtn = 1; + + ic->nosupdate = nosupdate; + return left; } /*-----------------------------------------------------------------*/ /* geniCodeSEParms - generate code for side effecting fcalls */ /*-----------------------------------------------------------------*/ -static void geniCodeSEParms (ast *parms) +static void +geniCodeSEParms (ast * parms,int lvl) { - if (!parms) - return ; + if (!parms) + return; - if (parms->type == EX_OP && parms->opval.op == PARAM) { - geniCodeSEParms (parms->left) ; - geniCodeSEParms (parms->right); - return ; + if (parms->type == EX_OP && parms->opval.op == PARAM) + { + geniCodeSEParms (parms->left,lvl); + geniCodeSEParms (parms->right,lvl); + return; } - /* hack don't like this but too lazy to think of - something better */ - if (IS_ADDRESS_OF_OP(parms)) - parms->left->lvalue = 1; - - if (IS_CAST_OP(parms) && - IS_PTR(parms->ftype) && - IS_ADDRESS_OF_OP(parms->right)) - parms->right->left->lvalue = 1; + /* hack don't like this but too lazy to think of + something better */ + if (IS_ADDRESS_OF_OP (parms)) + parms->left->lvalue = 1; - parms->opval.oprnd = - geniCodeRValue(ast2iCode (parms),FALSE); + if (IS_CAST_OP (parms) && + IS_PTR (parms->ftype) && + IS_ADDRESS_OF_OP (parms->right)) + parms->right->left->lvalue = 1; - parms->type = EX_OPERAND ; + 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); } /*-----------------------------------------------------------------*/ /* geniCodeParms - generates parameters */ /*-----------------------------------------------------------------*/ -static void geniCodeParms ( ast *parms , int *stack, sym_link *fetype, symbol *func) +value * +geniCodeParms (ast * parms, value *argVals, int *stack, + sym_link * fetype, symbol * func,int lvl) { - iCode *ic ; - operand *pval ; + iCode *ic; + operand *pval; + + if (!parms) + return argVals; - if ( ! parms ) - return ; + 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) ; - geniCodeParms (parms->right, stack,fetype,func); - return ; + /* if this is a param node then do the left & right */ + if (parms->type == EX_OP && parms->opval.op == PARAM) + { + 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 (parms->type == EX_OPERAND) - pval = parms->opval.oprnd ; - else { - /* maybe this else should go away ?? */ - /* hack don't like this but too lazy to think of - something better */ - if (IS_ADDRESS_OF_OP(parms)) - parms->left->lvalue = 1; + /* get the parameter value */ + if (parms->type == EX_OPERAND) + pval = parms->opval.oprnd; + else + { + /* maybe this else should go away ?? */ + /* hack don't like this but too lazy to think of + something better */ + if (IS_ADDRESS_OF_OP (parms)) + parms->left->lvalue = 1; - if (IS_CAST_OP(parms) && - IS_PTR(parms->ftype) && - IS_ADDRESS_OF_OP(parms->right)) - parms->right->left->lvalue = 1; + if (IS_CAST_OP (parms) && + IS_PTR (parms->ftype) && + IS_ADDRESS_OF_OP (parms->right)) + parms->right->left->lvalue = 1; - pval = geniCodeRValue(ast2iCode (parms),FALSE); + pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE); } - /* if register parm then make it a send */ - if (((parms->argSym && IS_REGPARM(parms->argSym->etype)) || - IS_REGPARM(parms->etype)) && !func->hasVargs ) { - ic = newiCode(SEND,pval,NULL); - ADDTOCHAIN(ic); - } else { - /* now decide whether to push or assign */ - if (!(options.stackAuto || IS_RENT(fetype))) { - - /* assign */ - operand *top = operandFromSymbol(parms->argSym); - 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(IS_AGGREGATE(p)? aggrToPtr(p,FALSE):p); - ADDTOCHAIN(ic); - } + /* if register parm then make it a send */ + if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) || + IFFUNC_ISBUILTIN(func->type)) + { + ic = newiCode (SEND, pval, NULL); + ic->argreg = SPEC_ARGREG(parms->etype); + ic->builtinSEND = FUNC_ISBUILTIN(func->type); + ADDTOCHAIN (ic); + } + else + { + /* now decide whether to push or assign */ + if (!(options.stackAuto || IFFUNC_ISREENT (func->type))) + { + + /* assign */ + 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 + { + sym_link *p = operandType (pval); + /* push */ + ic = newiCode (IPUSH, pval, NULL); + ic->parmPush = 1; + /* update the stack adjustment */ + *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p); + ADDTOCHAIN (ic); + } } + argVals=argVals->next; + return argVals; } /*-----------------------------------------------------------------*/ /* geniCodeCall - generates temp code for calling */ /*-----------------------------------------------------------------*/ -operand *geniCodeCall (operand *left, ast *parms) +operand * +geniCodeCall (operand * left, ast * parms,int lvl) { - iCode *ic ; - operand *result ; - sym_link *type, *etype; - int stack = 0 ; + iCode *ic; + operand *result; + sym_link *type, *etype; + int stack = 0; + + if (!IS_FUNC(OP_SYMBOL(left)->type) && + !IS_CODEPTR(OP_SYMBOL(left)->type)) { + werror (E_FUNCTION_EXPECTED); + return NULL; + } - /* take care of parameters with side-effecting - function calls in them, this is required to take care - of overlaying function parameters */ - geniCodeSEParms ( parms ); + /* take care of parameters with side-effecting + function calls in them, this is required to take care + of overlaying function parameters */ + geniCodeSEParms (parms,lvl); - /* first the parameters */ - geniCodeParms ( parms , &stack , getSpec(operandType(left)), OP_SYMBOL(left)); + /* first the parameters */ + geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl); - /* now call : if symbol then pcall */ - if (IS_ITEMP(left)) - ic = newiCode(PCALL,left,NULL); - else - ic = newiCode(CALL,left,NULL); + /* now call : if symbol then pcall */ + if (IS_OP_POINTER (left) || IS_ITEMP(left)) { + ic = newiCode (PCALL, left, NULL); + } 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; - IC_RESULT(ic) = result = newiTempOperand(type,1); + type = copyLinkChain (operandType (left)->next); + etype = getSpec (type); + SPEC_EXTR (etype) = 0; + IC_RESULT (ic) = result = newiTempOperand (type, 1); - ADDTOCHAIN(ic); + ADDTOCHAIN (ic); - /* stack adjustment after call */ - left->parmBytes = stack; + /* stack adjustment after call */ + ic->parmBytes = stack; - return result; + return result; } /*-----------------------------------------------------------------*/ /* geniCodeReceive - generate intermediate code for "receive" */ /*-----------------------------------------------------------------*/ -static void geniCodeReceive (value *args) +static void +geniCodeReceive (value * args) { - /* for all arguments that are passed in registers */ - while (args) { - - if (IS_REGPARM(args->etype)) { - operand *opr = operandFromValue(args); - operand *opl ; - symbol *sym = OP_SYMBOL(opr); - iCode *ic ; - - /* we will use it after all optimizations - and before liveRange calculation */ - 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); - currFunc->recvSize = getSize(sym->etype); - IC_RESULT(ic) = opr; - ADDTOCHAIN(ic); - } - - args = args->next; + /* for all arguments that are passed in registers */ + while (args) + { + int first = 1; + if (IS_REGPARM (args->etype)) + { + operand *opr = operandFromValue (args); + operand *opl; + symbol *sym = OP_SYMBOL (opr); + iCode *ic; + + /* we will use it after all optimizations + and before liveRange calculation */ + if (!sym->addrtaken && !IS_VOLATILE (sym->etype)) + { + + if (IN_FARSPACE (SPEC_OCLS (sym->etype)) && + options.stackAuto == 0 && + (!(options.model == MODEL_FLAT24)) ) + { + } + 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); + ic->argreg = SPEC_ARGREG(args->etype); + if (first) { + currFunc->recvSize = getSize (sym->type); + first = 0; + } + IC_RESULT (ic) = opr; + ADDTOCHAIN (ic); + } + + args = args->next; } } /*-----------------------------------------------------------------*/ /* geniCodeFunctionBody - create the function body */ /*-----------------------------------------------------------------*/ -void geniCodeFunctionBody (ast *tree) +void +geniCodeFunctionBody (ast * tree,int lvl) { - iCode *ic ; - operand *func ; - sym_link *fetype ; - int savelineno ; + iCode *ic; + operand *func; + sym_link *fetype; + int savelineno; - /* reset the auto generation */ - /* numbers */ - iTempNum = 0 ; - iTempLblNum = 0; - operandKey = 0 ; - iCodeKey = 0 ; - func = ast2iCode(tree->left); - fetype = getSpec(operandType(func)); + /* reset the auto generation */ + /* numbers */ + iTempNum = 0; + iTempLblNum = 0; + operandKey = 0; + iCodeKey = 0; + func = ast2iCode (tree->left,lvl+1); + fetype = getSpec (operandType (func)); - savelineno = lineno; - lineno = OP_SYMBOL(func)->lineDef; - /* create an entry label */ - geniCodeLabel(entryLabel); - lineno = savelineno; + savelineno = lineno; + lineno = OP_SYMBOL (func)->lineDef; + /* create an entry label */ + geniCodeLabel (entryLabel); + lineno = savelineno; - /* 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; + /* create a proc icode */ + ic = newiCode (FUNCTION, func, NULL); + lineno=ic->lineno = OP_SYMBOL (func)->lineDef; - ADDTOCHAIN(ic); + ADDTOCHAIN (ic); - /* for all parameters that are passed - on registers add a "receive" */ - geniCodeReceive( tree->values.args ); + /* for all parameters that are passed + on registers add a "receive" */ + geniCodeReceive (tree->values.args); - /* generate code for the body */ - ast2iCode(tree->right); + /* generate code for the body */ + ast2iCode (tree->right,lvl+1); - /* create a label for return */ - geniCodeLabel(returnLabel); + /* create a label for return */ + geniCodeLabel (returnLabel); - /* now generate the end proc */ - ic = newiCode(ENDFUNCTION,func,NULL); - ADDTOCHAIN(ic); - return ; + /* now generate the end proc */ + ic = newiCode (ENDFUNCTION, func, NULL); + ADDTOCHAIN (ic); + return; } /*-----------------------------------------------------------------*/ /* geniCodeReturn - gen icode for 'return' statement */ /*-----------------------------------------------------------------*/ -void geniCodeReturn (operand *op) +void +geniCodeReturn (operand * op) { - iCode *ic; + iCode *ic; - /* if the operand is present force an rvalue */ - if (op) - op = geniCodeRValue(op,FALSE); + /* if the operand is present force an rvalue */ + if (op) + op = geniCodeRValue (op, FALSE); - ic = newiCode(RETURN,op,NULL); - ADDTOCHAIN(ic); + ic = newiCode (RETURN, op, NULL); + ADDTOCHAIN (ic); } /*-----------------------------------------------------------------*/ /* geniCodeIfx - generates code for extended if statement */ /*-----------------------------------------------------------------*/ -void geniCodeIfx (ast *tree) +void +geniCodeIfx (ast * tree,int lvl) { - iCode *ic; - operand *condition = ast2iCode(tree->left); - sym_link *cetype; + iCode *ic; + operand *condition = ast2iCode (tree->left,lvl+1); + sym_link *cetype; - /* if condition is null then exit */ - if (!condition) - goto exit ; - else - condition = geniCodeRValue(condition,FALSE); + /* if condition is null then exit */ + if (!condition) + goto exit; + else + condition = geniCodeRValue (condition, FALSE); - cetype = getSpec(operandType(condition)); - /* if the condition is a literal */ - if (IS_LITERAL(cetype)) { - if (floatFromVal(condition->operand.valOperand)) { - if (tree->trueLabel) - geniCodeGoto(tree->trueLabel); - else - assert(1); - } - else { - if (tree->falseLabel) - geniCodeGoto (tree->falseLabel); + cetype = getSpec (operandType (condition)); + /* if the condition is a literal */ + if (IS_LITERAL (cetype)) + { + if (floatFromVal (condition->operand.valOperand)) + { + if (tree->trueLabel) + geniCodeGoto (tree->trueLabel); + else + assert (0); + } else - assert(1); - } - goto exit; + { + if (tree->falseLabel) + geniCodeGoto (tree->falseLabel); + else + assert (0); + } + goto exit; } - if ( tree->trueLabel ) { - ic = newiCodeCondition(condition, - tree->trueLabel, - NULL ); - ADDTOCHAIN(ic); + if (tree->trueLabel) + { + ic = newiCodeCondition (condition, + tree->trueLabel, + NULL); + ADDTOCHAIN (ic); - if ( tree->falseLabel) - geniCodeGoto(tree->falseLabel); + if (tree->falseLabel) + geniCodeGoto (tree->falseLabel); } - else { - ic = newiCodeCondition (condition, - NULL, - tree->falseLabel); - ADDTOCHAIN(ic); + else + { + ic = newiCodeCondition (condition, + NULL, + tree->falseLabel); + ADDTOCHAIN (ic); } - exit: - ast2iCode(tree->right); +exit: + ast2iCode (tree->right,lvl+1); } /*-----------------------------------------------------------------*/ /* geniCodeJumpTable - tries to create a jump table for switch */ /*-----------------------------------------------------------------*/ -int geniCodeJumpTable (operand *cond, value *caseVals, ast *tree) +int +geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) { - int min = 0 ,max = 0, t, cnt = 0; - value *vch; - iCode *ic; - operand *boundary; - symbol *falseLabel; - set *labels = NULL ; - - if (!tree || !caseVals) - return 0; + int min = 0, max = 0, t, cnt = 0; + value *vch; + iCode *ic; + operand *boundary; + symbol *falseLabel; + set *labels = NULL; - /* the criteria for creating a jump table is */ - /* 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", - tree->values.switchVals.swNum, - min); - addSet(&labels,newiTempLabel(buffer)); - - /* if there is only one case value then no need */ - if (!(vch = vch->next )) - return 0; + if (!tree || !caseVals) + return 0; - while (vch) { - if (((t = (int)floatFromVal(vch)) - max) != 1) - return 0; - sprintf(buffer,"_case_%d_%d", - tree->values.switchVals.swNum, - t); - addSet(&labels,newiTempLabel(buffer)); - max = t; - cnt++ ; - vch = vch->next ; - } - - /* if the number of case statements <= 2 then */ - /* it is not economical to create the jump table */ - /* since two compares are needed for boundary conditions */ - if ((! optimize.noJTabBoundary && cnt <= 2) || max > (255/3)) - return 0; + /* the criteria for creating a jump table is */ + /* all integer numbers between the maximum & minimum must */ + /* be present , the maximum value should not exceed 255 */ + min = max = (int) floatFromVal (vch = caseVals); + SNPRINTF (buffer, sizeof(buffer), + "_case_%d_%d", + tree->values.switchVals.swNum, + min); + addSet (&labels, newiTempLabel (buffer)); + + /* if there is only one case value then no need */ + if (!(vch = vch->next)) + return 0; - if ( tree->values.switchVals.swDefault ) - sprintf (buffer,"_default_%d",tree->values.switchVals.swNum); - else - sprintf (buffer,"_swBrk_%d",tree->values.switchVals.swNum ); - - falseLabel = newiTempLabel (buffer); - - /* so we can create a jumptable */ - /* first we rule out the boundary conditions */ - /* if only optimization says so */ - if ( ! optimize.noJTabBoundary ) { - 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))) { - boundary = geniCodeLogic (cond,operandFromLit(min),'<'); - ic = newiCodeCondition (boundary,falseLabel,NULL); - ADDTOCHAIN(ic); - } + while (vch) + { + if (((t = (int) floatFromVal (vch)) - max) != 1) + return 0; + SNPRINTF (buffer, sizeof(buffer), + "_case_%d_%d", + tree->values.switchVals.swNum, + t); + addSet (&labels, newiTempLabel (buffer)); + max = t; + cnt++; + vch = vch->next; + } + + /* if the number of case statements <= 2 then */ + /* it is not economical to create the jump table */ + /* since two compares are needed for boundary conditions */ + if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3)) + return 0; - /* now for upper bounds */ - boundary = geniCodeLogic(cond,operandFromLit(max),'>'); - ic = newiCodeCondition (boundary,falseLabel,NULL); - ADDTOCHAIN(ic); + if (tree->values.switchVals.swDefault) + { + SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum); } + else + { + SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum); + } + + + falseLabel = newiTempLabel (buffer); - /* if the min is not zero then we no make it zero */ - if (min) { - cond = geniCodeSubtract(cond,operandFromLit(min)); - setOperandType(cond, UCHARTYPE); + /* so we can create a jumptable */ + /* first we rule out the boundary conditions */ + /* if only optimization says so */ + if (!optimize.noJTabBoundary) + { + 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))) + { + boundary = geniCodeLogic (cond, operandFromLit (min), '<'); + ic = newiCodeCondition (boundary, falseLabel, NULL); + ADDTOCHAIN (ic); + } + + /* now for upper bounds */ + boundary = geniCodeLogic (cond, operandFromLit (max), '>'); + ic = newiCodeCondition (boundary, falseLabel, NULL); + ADDTOCHAIN (ic); + } + + /* if the min is not zero then we no make it zero */ + if (min) + { + cond = geniCodeSubtract (cond, operandFromLit (min)); + setOperandType (cond, UCHARTYPE); } - /* now create the jumptable */ - ic = newiCode(JUMPTABLE,NULL,NULL); - IC_JTCOND(ic) = cond; - IC_JTLABELS(ic) = labels; - ADDTOCHAIN(ic); - return 1; + /* now create the jumptable */ + ic = newiCode (JUMPTABLE, NULL, NULL); + IC_JTCOND (ic) = cond; + IC_JTLABELS (ic) = labels; + ADDTOCHAIN (ic); + return 1; } /*-----------------------------------------------------------------*/ /* geniCodeSwitch - changes a switch to a if statement */ /*-----------------------------------------------------------------*/ -void geniCodeSwitch (ast *tree) +void +geniCodeSwitch (ast * tree,int lvl) { - iCode *ic ; - operand *cond = geniCodeRValue(ast2iCode (tree->left),FALSE); - value *caseVals = tree->values.switchVals.swVals ; - symbol *trueLabel , *falseLabel; + iCode *ic; + operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE); + value *caseVals = tree->values.switchVals.swVals; + symbol *trueLabel, *falseLabel; - /* if we can make this a jump table */ - if ( geniCodeJumpTable (cond,caseVals,tree) ) - goto jumpTable ; /* no need for the comparison */ + /* if we can make this a jump table */ + if (geniCodeJumpTable (cond, caseVals, tree)) + goto jumpTable; /* no need for the comparison */ - /* for the cases defined do */ - while (caseVals) { + /* for the cases defined do */ + while (caseVals) + { - operand *compare = geniCodeLogic (cond, - operandFromValue(caseVals), - EQ_OP); + operand *compare = geniCodeLogic (cond, + operandFromValue (caseVals), + EQ_OP); - sprintf(buffer,"_case_%d_%d", - tree->values.switchVals.swNum, - (int) floatFromVal(caseVals)); - trueLabel = newiTempLabel(buffer); + SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d", + tree->values.switchVals.swNum, + (int) floatFromVal (caseVals)); + trueLabel = newiTempLabel (buffer); - ic = newiCodeCondition(compare,trueLabel,NULL); - ADDTOCHAIN(ic); - caseVals = caseVals->next; + ic = newiCodeCondition (compare, trueLabel, NULL); + ADDTOCHAIN (ic); + caseVals = caseVals->next; } - /* if default is present then goto break else break */ - if ( tree->values.switchVals.swDefault ) - sprintf (buffer,"_default_%d",tree->values.switchVals.swNum); - else - sprintf (buffer,"_swBrk_%d",tree->values.switchVals.swNum ); + /* if default is present then goto break else break */ + if (tree->values.switchVals.swDefault) + { + SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum); + } + else + { + SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum); + } - falseLabel = newiTempLabel (buffer); - geniCodeGoto(falseLabel); + falseLabel = newiTempLabel (buffer); + geniCodeGoto (falseLabel); - jumpTable: - ast2iCode(tree->right); +jumpTable: + ast2iCode (tree->right,lvl+1); } /*-----------------------------------------------------------------*/ /* geniCodeInline - intermediate code for inline assembler */ /*-----------------------------------------------------------------*/ -static void geniCodeInline (ast *tree) +static void +geniCodeInline (ast * tree) { - iCode *ic; + iCode *ic; - ic = newiCode(INLINEASM,NULL,NULL); - IC_INLINE(ic) = tree->values.inlineasm; - ADDTOCHAIN(ic); + ic = newiCode (INLINEASM, NULL, NULL); + IC_INLINE (ic) = tree->values.inlineasm; + ADDTOCHAIN (ic); } /*-----------------------------------------------------------------*/ -/* ast2iCode - creates an icodeList from an ast */ +/* geniCodeArrayInit - intermediate code for array initializer */ /*-----------------------------------------------------------------*/ -operand *ast2iCode (ast *tree) -{ - operand *left = NULL; - operand *right= NULL; - - if (!tree) - return NULL ; - - /* set the global variables for filename & line number */ - if ( tree->filename ) - filename = tree->filename ; - if ( tree->lineno) - lineno = tree->lineno ; - if (tree->block) - block = tree->block ; - if (tree->level) - scopeLevel = tree->level; - - if (tree->type == EX_VALUE ) - return operandFromValue(tree->opval.val); - - if (tree->type == EX_LINK ) - return operandFromLink (tree->opval.lnk); - - /* if we find a nullop */ - if (tree->type == EX_OP && - ( tree->opval.op == NULLOP || - tree->opval.op == BLOCK )) { - ast2iCode (tree->left); - ast2iCode (tree->right); - return NULL ; - } - - /* special cases for not evaluating */ - if ( tree->opval.op != ':' && - tree->opval.op != '?' && - tree->opval.op != CALL && - tree->opval.op != IFX && - tree->opval.op != LABEL && - tree->opval.op != GOTO && - tree->opval.op != SWITCH && - tree->opval.op != FUNCTION && - tree->opval.op != INLINEASM ) { - - 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++; - right= operandFromAst(tree->right); - lvaluereq--; +static void +geniCodeArrayInit (ast * tree, operand *array) +{ + iCode *ic; + + if (!getenv("TRY_THE_NEW_INITIALIZER")) { + ic = newiCode (ARRAYINIT, array, NULL); + IC_ARRAYILIST (ic) = tree->values.constlist; } else { - right= operandFromAst(tree->right); + operand *left=newOperand(), *right=newOperand(); + left->type=right->type=SYMBOL; + OP_SYMBOL(left)=AST_SYMBOL(tree->left); + OP_SYMBOL(right)=AST_SYMBOL(tree->right); + ic = newiCode (ARRAYINIT, left, right); } - } - - /* now depending on the type of operand */ - /* this will be a biggy */ - switch (tree->opval.op) { + ADDTOCHAIN (ic); +} - case '[' : /* array operation */ +/*-----------------------------------------------------------------*/ +/* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */ +/* particular case. Ie : assigning or dereferencing array or ptr */ +/*-----------------------------------------------------------------*/ +set * lvaluereqSet = NULL; +typedef struct lvalItem { - sym_link *ltype = operandType(left); - left= geniCodeRValue (left,IS_PTR(ltype->next) ? TRUE : FALSE); - right=geniCodeRValue (right,TRUE); + int req; + int lvl; } +lvalItem; - return geniCodeArray (left,right); +/*-----------------------------------------------------------------*/ +/* addLvaluereq - add a flag for lvalreq for current ast level */ +/*-----------------------------------------------------------------*/ +void addLvaluereq(int lvl) +{ + lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem)); + lpItem->req=1; + lpItem->lvl=lvl; + addSetHead(&lvaluereqSet,lpItem); - case '.' : /* structure dereference */ - if (IS_PTR(operandType(left))) - left = geniCodeRValue(left,TRUE); - else - left = geniCodeRValue(left,FALSE); +} +/*-----------------------------------------------------------------*/ +/* delLvaluereq - del a flag for lvalreq for current ast level */ +/*-----------------------------------------------------------------*/ +void delLvaluereq() +{ + lvalItem * lpItem; + lpItem = getSet(&lvaluereqSet); + if(lpItem) Safe_free(lpItem); +} +/*-----------------------------------------------------------------*/ +/* clearLvaluereq - clear lvalreq flag */ +/*-----------------------------------------------------------------*/ +void clearLvaluereq() +{ + lvalItem * lpItem; + lpItem = peekSet(lvaluereqSet); + if(lpItem) lpItem->req = 0; +} +/*-----------------------------------------------------------------*/ +/* getLvaluereq - get the last lvalreq level */ +/*-----------------------------------------------------------------*/ +int getLvaluereqLvl() +{ + lvalItem * lpItem; + lpItem = peekSet(lvaluereqSet); + if(lpItem) return lpItem->lvl; + return 0; +} +/*-----------------------------------------------------------------*/ +/* isLvaluereq - is lvalreq valid for this level ? */ +/*-----------------------------------------------------------------*/ +int isLvaluereq(int lvl) +{ + lvalItem * lpItem; + lpItem = peekSet(lvaluereqSet); + if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1))); + return 0; +} - return geniCodeStruct (left,right,tree->lvalue); +/*-----------------------------------------------------------------*/ +/* ast2iCode - creates an icodeList from an ast */ +/*-----------------------------------------------------------------*/ +operand * +ast2iCode (ast * tree,int lvl) +{ + operand *left = NULL; + operand *right = NULL; + if (!tree) + return NULL; - case PTR_OP: /* structure pointer dereference */ - { - sym_link *pType; - pType = operandType(left); - left = geniCodeRValue(left,TRUE); + /* set the global variables for filename & line number */ + if (tree->filename) + filename = tree->filename; + if (tree->lineno) + lineno = tree->lineno; + if (tree->block) + block = tree->block; + if (tree->level) + scopeLevel = tree->level; + + if (tree->type == EX_VALUE) + return operandFromValue (tree->opval.val); + + if (tree->type == EX_LINK) + return operandFromLink (tree->opval.lnk); + + /* if we find a nullop */ + if (tree->type == EX_OP && + (tree->opval.op == NULLOP || + tree->opval.op == BLOCK)) + { + ast2iCode (tree->left,lvl+1); + ast2iCode (tree->right,lvl+1); + return NULL; + } + + /* special cases for not evaluating */ + if (tree->opval.op != ':' && + tree->opval.op != '?' && + tree->opval.op != CALL && + tree->opval.op != IFX && + tree->opval.op != LABEL && + tree->opval.op != GOTO && + tree->opval.op != SWITCH && + tree->opval.op != FUNCTION && + tree->opval.op != INLINEASM) + { - setOClass (pType,getSpec(operandType(left))); - } + if (IS_ASSIGN_OP (tree->opval.op) || + IS_DEREF_OP (tree) || + (tree->opval.op == '&' && !tree->right) || + tree->opval.op == PTR_OP) + { + addLvaluereq(lvl); + if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) || + (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left))) + clearLvaluereq(); + + left = operandFromAst (tree->left,lvl); + delLvaluereq(); + if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left)) + left = geniCodeRValue (left, TRUE); + } + else + { + left = operandFromAst (tree->left,lvl); + } + if (tree->opval.op == INC_OP || + tree->opval.op == DEC_OP) + { + addLvaluereq(lvl); + right = operandFromAst (tree->right,lvl); + delLvaluereq(); + } + else + { + right = operandFromAst (tree->right,lvl); + } + } - return geniCodeStruct (left, right,tree->lvalue); + /* now depending on the type of operand */ + /* this will be a biggy */ + switch (tree->opval.op) + { - case INC_OP: /* increment operator */ - if ( left ) - return geniCodePostInc (left); - else - return geniCodePreInc (right); + case '[': /* array operation */ + { + //sym_link *ltype = operandType (left); + //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE); + left = geniCodeRValue (left, FALSE); + right = geniCodeRValue (right, TRUE); + } - case DEC_OP: /* decrement operator */ - if ( left ) - return geniCodePostDec (left); - else - return geniCodePreDec (right); + return geniCodeArray (left, right,lvl); + + case '.': /* structure dereference */ + if (IS_PTR (operandType (left))) + left = geniCodeRValue (left, TRUE); + else + left = geniCodeRValue (left, FALSE); + + return geniCodeStruct (left, right, tree->lvalue); + + case PTR_OP: /* structure pointer dereference */ + { + sym_link *pType; + pType = operandType (left); + left = geniCodeRValue (left, TRUE); + + setOClass (pType, getSpec (operandType (left))); + } + + return geniCodeStruct (left, right, tree->lvalue); + + case INC_OP: /* increment operator */ + if (left) + return geniCodePostInc (left); + else + return geniCodePreInc (right); - case '&' : /* bitwise and or address of operator */ - if ( right ) { /* this is a bitwise operator */ - left= geniCodeRValue(left,FALSE); - right= geniCodeRValue(right,FALSE); - return geniCodeBitwise (left,right,BITWISEAND,tree->ftype); - } else - return geniCodeAddressOf (left); + case DEC_OP: /* decrement operator */ + if (left) + return geniCodePostDec (left); + else + return geniCodePreDec (right); + + case '&': /* bitwise and or address of operator */ + if (right) + { /* this is a bitwise operator */ + left = geniCodeRValue (left, FALSE); + right = geniCodeRValue (right, FALSE); + return geniCodeBitwise (left, right, BITWISEAND, tree->ftype); + } + else + return geniCodeAddressOf (left); - case '|': /* bitwise or & xor */ + case '|': /* bitwise or & xor */ case '^': - return geniCodeBitwise (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE), - tree->opval.op, - tree->ftype); + return geniCodeBitwise (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE), + tree->opval.op, + tree->ftype); case '/': - return geniCodeDivision (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); + return geniCodeDivision (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE)); - case '%' : - return geniCodeModulus (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); + case '%': + return geniCodeModulus (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE)); case '*': - if ( right ) - return geniCodeMultiply (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); - else - return geniCodeDerefPtr (geniCodeRValue(left,FALSE)); + if (right) + return geniCodeMultiply (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE),IS_INT(tree->ftype)); + else + return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl); - case '-' : - if ( right ) - return geniCodeSubtract (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); - else - return geniCodeUnaryMinus (geniCodeRValue(left,FALSE)); + case '-': + if (right) + return geniCodeSubtract (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE)); + else + return geniCodeUnaryMinus (geniCodeRValue (left, FALSE)); - case '+' : - if ( right ) - return geniCodeAdd (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); - else - return geniCodeRValue(left,FALSE) ; /* unary '+' has no meaning */ + case '+': + if (right) + return geniCodeAdd (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE),lvl); + else + return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */ case LEFT_OP: - return geniCodeLeftShift (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); + return geniCodeLeftShift (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE)); case RIGHT_OP: - return geniCodeRightShift (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE)); + return geniCodeRightShift (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE)); case CAST: - return geniCodeCast (operandType(left), - geniCodeRValue(right,FALSE),FALSE); + return geniCodeCast (operandType (left), + geniCodeRValue (right, FALSE), FALSE); - case '~' : - case '!' : + case '~': + case '!': case RRC: case RLC: - return geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op); + return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op); case GETHBIT: - { - operand *op = geniCodeUnary (geniCodeRValue(left,FALSE),tree->opval.op); - setOperandType(op, UCHARTYPE); - return op; - } - case '>' : - case '<' : + { + operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op); + setOperandType (op, UCHARTYPE); + return op; + } + case '>': + case '<': case LE_OP: case GE_OP: case EQ_OP: case NE_OP: case AND_OP: case OR_OP: - return geniCodeLogic (geniCodeRValue(left,FALSE), - geniCodeRValue(right,FALSE), - tree->opval.op); - case '?' : - return geniCodeConditional (tree); + return geniCodeLogic (geniCodeRValue (left, FALSE), + geniCodeRValue (right, FALSE), + tree->opval.op); + case '?': + return geniCodeConditional (tree,lvl); case SIZEOF: - return operandFromLit(getSize(tree->right->ftype)); + return operandFromLit (getSize (tree->right->ftype)); - case '=' : - { - 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); - else - right = geniCodeRValue(right,FALSE); - - geniCodeAssign (left,right,0); - return right ; - } + case '=': + { + sym_link *rtype = operandType (right); + sym_link *ltype = operandType (left); + if (IS_PTR (rtype) && IS_ITEMP (right) + && right->isaddr && compareType (rtype->next, ltype) == 1) + right = geniCodeRValue (right, TRUE); + else + right = geniCodeRValue (right, FALSE); + + geniCodeAssign (left, right, 0); + return right; + } case MUL_ASSIGN: - return - geniCodeAssign(left, - geniCodeMultiply(geniCodeRValue (operandFromOperand(left), - FALSE), - geniCodeRValue(right,FALSE)),0); + return + geniCodeAssign (left, + geniCodeMultiply (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE),FALSE), 0); case DIV_ASSIGN: - return - geniCodeAssign(left, - geniCodeDivision(geniCodeRValue(operandFromOperand(left), - FALSE), - geniCodeRValue(right,FALSE)),0); + return + geniCodeAssign (left, + geniCodeDivision (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE)), 0); case MOD_ASSIGN: - return - geniCodeAssign(left, - geniCodeModulus(geniCodeRValue(operandFromOperand(left), - FALSE), - geniCodeRValue(right,FALSE)),0); + return + geniCodeAssign (left, + geniCodeModulus (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE)), 0); case ADD_ASSIGN: - { - 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); - else - right = geniCodeRValue(right,FALSE); - - - return geniCodeAssign(left, - geniCodeAdd (geniCodeRValue(operandFromOperand(left), - FALSE), - right),0); - } - case SUB_ASSIGN: - { - 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); + { + sym_link *rtype = operandType (right); + sym_link *ltype = operandType (left); + if (IS_PTR (rtype) && IS_ITEMP (right) + && right->isaddr && compareType (rtype->next, ltype) == 1) + right = geniCodeRValue (right, TRUE); + else + right = geniCodeRValue (right, FALSE); + + + return geniCodeAssign (left, + geniCodeAdd (geniCodeRValue (operandFromOperand (left), + FALSE), + right,lvl), 0); } - else { - right = geniCodeRValue(right,FALSE); + case SUB_ASSIGN: + { + sym_link *rtype = operandType (right); + sym_link *ltype = operandType (left); + if (IS_PTR (rtype) && IS_ITEMP (right) + && right->isaddr && compareType (rtype->next, ltype) == 1) + { + right = geniCodeRValue (right, TRUE); + } + else + { + right = geniCodeRValue (right, FALSE); + } + return + geniCodeAssign (left, + geniCodeSubtract (geniCodeRValue (operandFromOperand (left), + FALSE), + right), 0); } - return - geniCodeAssign (left, - geniCodeSubtract(geniCodeRValue(operandFromOperand(left), - FALSE), - right),0); - } case LEFT_ASSIGN: - return - geniCodeAssign (left, - geniCodeLeftShift(geniCodeRValue(operandFromOperand(left) - ,FALSE), - geniCodeRValue(right,FALSE)),0); + return + geniCodeAssign (left, + geniCodeLeftShift (geniCodeRValue (operandFromOperand (left) + ,FALSE), + geniCodeRValue (right, FALSE)), 0); case RIGHT_ASSIGN: - return - geniCodeAssign(left, - geniCodeRightShift(geniCodeRValue(operandFromOperand(left) - ,FALSE), - geniCodeRValue(right,FALSE)),0); + return + geniCodeAssign (left, + geniCodeRightShift (geniCodeRValue (operandFromOperand (left) + ,FALSE), + geniCodeRValue (right, FALSE)), 0); case AND_ASSIGN: return - geniCodeAssign (left, - geniCodeBitwise(geniCodeRValue(operandFromOperand(left), - FALSE), - geniCodeRValue(right,FALSE), - BITWISEAND, - operandType(left)),0); + geniCodeAssign (left, + geniCodeBitwise (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE), + BITWISEAND, + operandType (left)), 0); case XOR_ASSIGN: return - geniCodeAssign (left, - geniCodeBitwise (geniCodeRValue(operandFromOperand(left), - FALSE), - geniCodeRValue(right,FALSE), - '^', - operandType(left)),0); + geniCodeAssign (left, + geniCodeBitwise (geniCodeRValue (operandFromOperand (left), + FALSE), + geniCodeRValue (right, FALSE), + '^', + operandType (left)), 0); case OR_ASSIGN: return - geniCodeAssign (left, - geniCodeBitwise (geniCodeRValue(operandFromOperand(left) - ,FALSE), - geniCodeRValue(right,FALSE), - '|', - operandType(left)),0); - case ',' : - return geniCodeRValue(right,FALSE); + geniCodeAssign (left, + geniCodeBitwise (geniCodeRValue (operandFromOperand (left) + ,FALSE), + geniCodeRValue (right, FALSE), + '|', + operandType (left)), 0); + case ',': + return geniCodeRValue (right, FALSE); case CALL: - return geniCodeCall (ast2iCode(tree->left), - tree->right); + return geniCodeCall (ast2iCode (tree->left,lvl+1), + tree->right,lvl); case LABEL: - geniCodeLabel(ast2iCode(tree->left)->operand.symOperand); - return ast2iCode (tree->right); + geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand); + return ast2iCode (tree->right,lvl+1); case GOTO: - geniCodeGoto (ast2iCode(tree->left)->operand.symOperand); - return ast2iCode (tree->right); + geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand); + return ast2iCode (tree->right,lvl+1); case FUNCTION: - geniCodeFunctionBody ( tree ); - return NULL ; + geniCodeFunctionBody (tree,lvl); + return NULL; case RETURN: - geniCodeReturn (right); - return NULL ; + geniCodeReturn (right); + return NULL; case IFX: - geniCodeIfx (tree); - return NULL ; + geniCodeIfx (tree,lvl); + return NULL; case SWITCH: - geniCodeSwitch (tree); - return NULL; + geniCodeSwitch (tree,lvl); + return NULL; case INLINEASM: - geniCodeInline (tree); - return NULL ; + geniCodeInline (tree); + return NULL; + + case ARRAYINIT: + geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1)); + return NULL; } - return NULL; + return NULL; } /*-----------------------------------------------------------------*/ /* reverseICChain - gets from the list and creates a linkedlist */ /*-----------------------------------------------------------------*/ -iCode *reverseiCChain () +iCode * +reverseiCChain () { - iCode *loop = NULL ; - iCode *prev = NULL ; + iCode *loop = NULL; + iCode *prev = NULL; - while ((loop = getSet(&iCodeChain))) { - loop->next = prev ; - if ( prev ) - prev->prev = loop; - prev = loop ; + while ((loop = getSet (&iCodeChain))) + { + loop->next = prev; + if (prev) + prev->prev = loop; + prev = loop; } - return prev; + return prev; } /*-----------------------------------------------------------------*/ /* iCodeFromAst - given an ast will convert it to iCode */ /*-----------------------------------------------------------------*/ -iCode *iCodeFromAst ( ast *tree ) +iCode * +iCodeFromAst (ast * tree) +{ + returnLabel = newiTempLabel ("_return"); + entryLabel = newiTempLabel ("_entry"); + ast2iCode (tree,0); + return reverseiCChain (); +} + +static const char *opTypeToStr(OPTYPE op) { - returnLabel = newiTempLabel("_return"); - entryLabel = newiTempLabel("_entry") ; - ast2iCode (tree); - return reverseiCChain (); + 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. +}