1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
43 symbol *returnLabel; /* function return label */
44 symbol *entryLabel; /* function entry label */
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeAssign (operand *, operand *, int, int);
49 static operand *geniCodeArray (operand *, operand *,int);
50 static operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
54 void setOClass (sym_link * ptr, sym_link * spec);
55 static operand *geniCodeCast (sym_link *, operand *, bool);
57 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
58 /* forward definition of ic print functions */
59 PRINTFUNC (picGetValueAtAddr);
60 PRINTFUNC (picSetValueAtAddr);
61 PRINTFUNC (picAddrOf);
62 PRINTFUNC (picGeneric);
63 PRINTFUNC (picGenericOne);
65 PRINTFUNC (picAssign);
69 PRINTFUNC (picJumpTable);
70 PRINTFUNC (picInline);
71 PRINTFUNC (picReceive);
72 PRINTFUNC (picDummyRead);
73 PRINTFUNC (picCritical);
74 PRINTFUNC (picEndCritical);
76 iCodeTable codeTable[] =
78 {'!', "not", picGenericOne, NULL},
79 {'~', "~", picGenericOne, NULL},
80 {RRC, "rrc", picGenericOne, NULL},
81 {RLC, "rlc", picGenericOne, NULL},
82 {GETHBIT, "ghbit", picGenericOne, NULL},
83 {UNARYMINUS, "-", picGenericOne, NULL},
84 {IPUSH, "push", picGenericOne, NULL},
85 {IPOP, "pop", picGenericOne, NULL},
86 {CALL, "call", picGenericOne, NULL},
87 {PCALL, "pcall", picGenericOne, NULL},
88 {FUNCTION, "proc", picGenericOne, NULL},
89 {ENDFUNCTION, "eproc", picGenericOne, NULL},
90 {RETURN, "ret", picGenericOne, NULL},
91 {'+', "+", picGeneric, NULL},
92 {'-', "-", picGeneric, NULL},
93 {'*', "*", picGeneric, NULL},
94 {'/', "/", picGeneric, NULL},
95 {'%', "%", picGeneric, NULL},
96 {'>', ">", picGeneric, NULL},
97 {'<', "<", picGeneric, NULL},
98 {LE_OP, "<=", picGeneric, NULL},
99 {GE_OP, ">=", picGeneric, NULL},
100 {EQ_OP, "==", picGeneric, NULL},
101 {NE_OP, "!=", picGeneric, NULL},
102 {AND_OP, "&&", picGeneric, NULL},
103 {OR_OP, "||", picGeneric, NULL},
104 {'^', "^", picGeneric, NULL},
105 {'|', "|", picGeneric, NULL},
106 {BITWISEAND, "&", picGeneric, NULL},
107 {LEFT_OP, "<<", picGeneric, NULL},
108 {RIGHT_OP, ">>", picGeneric, NULL},
109 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110 {ADDRESS_OF, "&", picAddrOf, NULL},
111 {CAST, "<>", picCast, NULL},
112 {'=', ":=", picAssign, NULL},
113 {LABEL, "", picLabel, NULL},
114 {GOTO, "", picGoto, NULL},
115 {JUMPTABLE, "jtab", picJumpTable, NULL},
116 {IFX, "if", picIfx, NULL},
117 {INLINEASM, "", picInline, NULL},
118 {RECEIVE, "recv", picReceive, NULL},
119 {SEND, "send", picGenericOne, NULL},
120 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
121 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
122 {CRITICAL, "critical_start", picCritical, NULL},
123 {ENDCRITICAL, "critical_end", picEndCritical, NULL},
124 {SWAP, "swap", picGenericOne, NULL}
127 /*-----------------------------------------------------------------*/
128 /* checkConstantRange: check a constant against the type */
129 /*-----------------------------------------------------------------*/
132 /* pedantic=0: allmost anything is allowed as long as the absolute
133 value is within the bit range of the type, and -1 is treated as
134 0xf..f for unsigned types (e.g. in assign)
135 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
136 pedantic>1: "char c=200" is not allowed (evaluates to -56)
139 void checkConstantRange(sym_link *ltype, value *val, char *msg,
146 max = pow ((double)2.0, (double)bitsForType(ltype));
148 if (IS_LONG(val->type)) {
149 if (IS_UNSIGNED(val->type)) {
150 v=SPEC_CVAL(val->type).v_ulong;
152 v=SPEC_CVAL(val->type).v_long;
155 if (IS_UNSIGNED(val->type)) {
156 v=SPEC_CVAL(val->type).v_uint;
158 v=SPEC_CVAL(val->type).v_int;
164 // this could be a good idea
165 if (options.pedantic)
169 if (IS_FLOAT(ltype)) {
174 if (!IS_UNSIGNED(val->type) && v<0) {
176 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
182 // if very pedantic: "char c=200" is not allowed
183 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
184 max = max/2 + negative;
191 #if 0 // temporary disabled, leaving the warning as a reminder
193 SNPRINTF (message, sizeof(message), "for %s %s in %s",
194 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
195 nounName(ltype), msg);
196 werror (W_CONST_RANGE, message);
204 /*-----------------------------------------------------------------*/
205 /* operandName - returns the name of the operand */
206 /*-----------------------------------------------------------------*/
208 printOperand (operand * op, FILE * file)
225 opetype = getSpec (operandType (op));
226 if (IS_FLOAT (opetype))
227 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
229 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
230 printTypeChain (operandType (op), file);
237 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
238 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
240 OP_LIVEFROM (op), OP_LIVETO (op),
241 OP_SYMBOL (op)->stack,
242 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
243 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
244 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
248 printTypeChain (operandType (op), file);
249 if (SPIL_LOC (op) && IS_ITEMP (op))
250 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
255 /* if assigned to registers */
256 if (OP_SYMBOL (op)->nRegs)
258 if (OP_SYMBOL (op)->isspilt)
260 if (!OP_SYMBOL (op)->remat)
261 if (OP_SYMBOL (op)->usl.spillLoc)
262 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
263 OP_SYMBOL (op)->usl.spillLoc->rname :
264 OP_SYMBOL (op)->usl.spillLoc->name));
266 fprintf (file, "[err]");
268 fprintf (file, "[remat]");
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
280 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
281 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
282 /* if assigned to registers */
283 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
287 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
288 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
289 OP_SYMBOL (op)->regs[i]->name :
298 printTypeChain (op->operand.typeOperand, file);
304 fprintf (file, "\n");
309 /*-----------------------------------------------------------------*/
310 /* print functions */
311 /*-----------------------------------------------------------------*/
312 PRINTFUNC (picGetValueAtAddr)
315 printOperand (IC_RESULT (ic), of);
318 printOperand (IC_LEFT (ic), of);
324 PRINTFUNC (picSetValueAtAddr)
328 printOperand (IC_LEFT (ic), of);
329 fprintf (of, "] = ");
330 printOperand (IC_RIGHT (ic), of);
334 PRINTFUNC (picAddrOf)
337 printOperand (IC_RESULT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
341 fprintf (of, " = &[");
342 printOperand (IC_LEFT (ic), of);
345 if (IS_ITEMP (IC_LEFT (ic)))
346 fprintf (of, " offsetAdd ");
349 printOperand (IC_RIGHT (ic), of);
351 if (IS_ITEMP (IC_LEFT (ic)))
357 PRINTFUNC (picJumpTable)
362 fprintf (of, "%s\t", s);
363 printOperand (IC_JTCOND (ic), of);
365 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
366 sym = setNextItem (IC_JTLABELS (ic)))
367 fprintf (of, "\t\t\t%s\n", sym->name);
370 PRINTFUNC (picGeneric)
373 printOperand (IC_RESULT (ic), of);
375 printOperand (IC_LEFT (ic), of);
376 fprintf (of, " %s ", s);
377 printOperand (IC_RIGHT (ic), of);
381 PRINTFUNC (picGenericOne)
386 printOperand (IC_RESULT (ic), of);
392 fprintf (of, "%s ", s);
393 printOperand (IC_LEFT (ic), of);
396 if (!IC_RESULT (ic) && !IC_LEFT (ic))
399 if (ic->op == SEND || ic->op == RECEIVE) {
400 fprintf(of,"{argreg = %d}",ic->argreg);
402 if (ic->op == IPUSH) {
403 fprintf(of,"{parmPush = %d}",ic->parmPush);
411 printOperand (IC_RESULT (ic), of);
413 printOperand (IC_LEFT (ic), of);
414 printOperand (IC_RIGHT (ic), of);
419 PRINTFUNC (picAssign)
423 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
426 printOperand (IC_RESULT (ic), of);
428 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
431 fprintf (of, " %s ", s);
432 printOperand (IC_RIGHT (ic), of);
439 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
445 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
452 printOperand (IC_COND (ic), of);
455 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
458 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
460 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
464 PRINTFUNC (picInline)
466 fprintf (of, "%s", IC_INLINE (ic));
469 PRINTFUNC (picReceive)
471 printOperand (IC_RESULT (ic), of);
472 fprintf (of, " = %s ", s);
473 printOperand (IC_LEFT (ic), of);
477 PRINTFUNC (picDummyRead)
480 fprintf (of, "%s ", s);
481 printOperand (IC_RIGHT (ic), of);
485 PRINTFUNC (picCritical)
489 printOperand (IC_RESULT (ic), of);
491 fprintf (of, "(stack)");
492 fprintf (of, " = %s ", s);
496 PRINTFUNC (picEndCritical)
499 fprintf (of, "%s = ", s);
501 printOperand (IC_RIGHT (ic), of);
503 fprintf (of, "(stack)");
507 /*-----------------------------------------------------------------*/
508 /* piCode - prints one iCode */
509 /*-----------------------------------------------------------------*/
511 piCode (void *item, FILE * of)
519 icTab = getTableEntry (ic->op);
520 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
521 ic->filename, ic->lineno,
522 ic->seq, ic->key, ic->depth, ic->supportRtn);
523 icTab->iCodePrint (of, ic, icTab->printName);
529 printiCChain(ic,stdout);
531 /*-----------------------------------------------------------------*/
532 /* printiCChain - prints intermediate code for humans */
533 /*-----------------------------------------------------------------*/
535 printiCChain (iCode * icChain, FILE * of)
542 for (loop = icChain; loop; loop = loop->next)
544 if ((icTab = getTableEntry (loop->op)))
546 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
547 loop->filename, loop->lineno,
548 loop->seq, loop->key, loop->depth, loop->supportRtn);
550 icTab->iCodePrint (of, loop, icTab->printName);
556 /*-----------------------------------------------------------------*/
557 /* newOperand - allocate, init & return a new iCode */
558 /*-----------------------------------------------------------------*/
564 op = Safe_alloc ( sizeof (operand));
570 /*-----------------------------------------------------------------*/
571 /* newiCode - create and return a new iCode entry initialised */
572 /*-----------------------------------------------------------------*/
574 newiCode (int op, operand * left, operand * right)
578 ic = Safe_alloc ( sizeof (iCode));
580 ic->seqPoint = seqPoint;
582 ic->filename = filename;
584 ic->level = scopeLevel;
586 ic->key = iCodeKey++;
588 IC_RIGHT (ic) = right;
593 /*-----------------------------------------------------------------*/
594 /* newiCode for conditional statements */
595 /*-----------------------------------------------------------------*/
597 newiCodeCondition (operand * condition,
603 if (IS_VOID(operandType(condition))) {
604 werror(E_VOID_VALUE_USED);
607 ic = newiCode (IFX, NULL, NULL);
608 IC_COND (ic) = condition;
609 IC_TRUE (ic) = trueLabel;
610 IC_FALSE (ic) = falseLabel;
614 /*-----------------------------------------------------------------*/
615 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
616 /*-----------------------------------------------------------------*/
618 newiCodeLabelGoto (int op, symbol * label)
622 ic = newiCode (op, NULL, NULL);
626 IC_RIGHT (ic) = NULL;
627 IC_RESULT (ic) = NULL;
631 /*-----------------------------------------------------------------*/
632 /* newiTemp - allocate & return a newItemp Variable */
633 /*-----------------------------------------------------------------*/
641 SNPRINTF (buffer, sizeof(buffer), "%s", s);
645 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
648 itmp = newSymbol (buffer, 1);
649 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
655 /*-----------------------------------------------------------------*/
656 /* newiTempLabel - creates a temp variable label */
657 /*-----------------------------------------------------------------*/
659 newiTempLabel (char *s)
663 /* check if this alredy exists */
664 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
669 itmplbl = newSymbol (s, 1);
673 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
674 itmplbl = newSymbol (buffer, 1);
679 itmplbl->key = labelKey++;
680 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
684 /*-----------------------------------------------------------------*/
685 /* newiTempPreheaderLabel - creates a new preheader label */
686 /*-----------------------------------------------------------------*/
688 newiTempPreheaderLabel ()
692 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
693 itmplbl = newSymbol (buffer, 1);
697 itmplbl->key = labelKey++;
698 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
703 /*-----------------------------------------------------------------*/
704 /* initiCode - initialises some iCode related stuff */
705 /*-----------------------------------------------------------------*/
712 /*-----------------------------------------------------------------*/
713 /* copyiCode - make a copy of the iCode given */
714 /*-----------------------------------------------------------------*/
716 copyiCode (iCode * ic)
718 iCode *nic = newiCode (ic->op, NULL, NULL);
720 nic->lineno = ic->lineno;
721 nic->filename = ic->filename;
722 nic->block = ic->block;
723 nic->level = ic->level;
724 nic->parmBytes = ic->parmBytes;
726 /* deal with the special cases first */
730 IC_COND (nic) = operandFromOperand (IC_COND (ic));
731 IC_TRUE (nic) = IC_TRUE (ic);
732 IC_FALSE (nic) = IC_FALSE (ic);
736 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
737 IC_JTLABELS (nic) = IC_JTLABELS (ic);
742 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
743 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
747 IC_INLINE (nic) = IC_INLINE (ic);
751 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
755 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
756 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
757 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
763 /*-----------------------------------------------------------------*/
764 /* getTableEntry - gets the table entry for the given operator */
765 /*-----------------------------------------------------------------*/
767 getTableEntry (int oper)
771 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
772 if (oper == codeTable[i].icode)
773 return &codeTable[i];
778 /*-----------------------------------------------------------------*/
779 /* newiTempOperand - new intermediate temp operand */
780 /*-----------------------------------------------------------------*/
782 newiTempOperand (sym_link * type, char throwType)
785 operand *op = newOperand ();
789 itmp = newiTemp (NULL);
791 etype = getSpec (type);
793 if (IS_LITERAL (etype))
796 /* copy the type information */
798 itmp->etype = getSpec (itmp->type = (throwType ? type :
799 copyLinkChain (type)));
800 if (IS_LITERAL (itmp->etype))
802 SPEC_SCLS (itmp->etype) = S_REGISTER;
803 SPEC_OCLS (itmp->etype) = reg;
806 op->operand.symOperand = itmp;
807 op->key = itmp->key = ++operandKey;
811 /*-----------------------------------------------------------------*/
812 /* operandType - returns the type chain for an operand */
813 /*-----------------------------------------------------------------*/
815 operandType (operand * op)
817 /* depending on type of operand */
822 return op->operand.valOperand->type;
825 return op->operand.symOperand->type;
828 return op->operand.typeOperand;
830 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
831 " operand type not known ");
832 assert (0); /* should never come here */
833 /* Just to keep the compiler happy */
834 return (sym_link *) 0;
838 /*-----------------------------------------------------------------*/
839 /* isParamterToCall - will return 1 if op is a parameter to args */
840 /*-----------------------------------------------------------------*/
842 isParameterToCall (value * args, operand * op)
846 wassert (IS_SYMOP(op));
851 isSymbolEqual (op->operand.symOperand, tval->sym))
858 /*-----------------------------------------------------------------*/
859 /* isOperandGlobal - return 1 if operand is a global variable */
860 /*-----------------------------------------------------------------*/
862 isOperandGlobal (operand * op)
871 (op->operand.symOperand->level == 0 ||
872 IS_STATIC (op->operand.symOperand->etype) ||
873 IS_EXTERN (op->operand.symOperand->etype))
880 /*-----------------------------------------------------------------*/
881 /* isOperandVolatile - return 1 if the operand is volatile */
882 /*-----------------------------------------------------------------*/
884 isOperandVolatile (operand * op, bool chkTemp)
889 if (IS_ITEMP (op) && !chkTemp)
892 opetype = getSpec (optype = operandType (op));
894 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
897 if (IS_VOLATILE (opetype))
902 /*-----------------------------------------------------------------*/
903 /* isOperandLiteral - returns 1 if an operand contains a literal */
904 /*-----------------------------------------------------------------*/
906 isOperandLiteral (operand * op)
913 opetype = getSpec (operandType (op));
915 if (IS_LITERAL (opetype))
921 /*-----------------------------------------------------------------*/
922 /* isOperandInFarSpace - will return true if operand is in farSpace */
923 /*-----------------------------------------------------------------*/
925 isOperandInFarSpace (operand * op)
935 if (!IS_TRUE_SYMOP (op))
938 etype = SPIL_LOC (op)->etype;
944 etype = getSpec (operandType (op));
946 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
949 /*------------------------------------------------------------------*/
950 /* isOperandInDirSpace - will return true if operand is in dirSpace */
951 /*------------------------------------------------------------------*/
953 isOperandInDirSpace (operand * op)
963 if (!IS_TRUE_SYMOP (op))
966 etype = SPIL_LOC (op)->etype;
972 etype = getSpec (operandType (op));
974 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
977 /*--------------------------------------------------------------------*/
978 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
979 /*--------------------------------------------------------------------*/
981 isOperandInCodeSpace (operand * op)
991 etype = getSpec (operandType (op));
993 if (!IS_TRUE_SYMOP (op))
996 etype = SPIL_LOC (op)->etype;
1002 etype = getSpec (operandType (op));
1004 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1007 /*-----------------------------------------------------------------*/
1008 /* isOperandOnStack - will return true if operand is on stack */
1009 /*-----------------------------------------------------------------*/
1011 isOperandOnStack (operand * op)
1021 etype = getSpec (operandType (op));
1022 if (IN_STACK (etype) ||
1023 OP_SYMBOL(op)->onStack ||
1024 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1030 /*-----------------------------------------------------------------*/
1031 /* isOclsExpensive - will return true if accesses to an output */
1032 /* storage class are expensive */
1033 /*-----------------------------------------------------------------*/
1035 isOclsExpensive (struct memmap *oclass)
1037 if (port->oclsExpense)
1038 return port->oclsExpense (oclass) > 0;
1040 /* In the absence of port specific guidance, assume only */
1041 /* farspace is expensive. */
1042 return IN_FARSPACE (oclass);
1045 /*-----------------------------------------------------------------*/
1046 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1047 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1048 /*-----------------------------------------------------------------*/
1050 isiCodeInFunctionCall (iCode * ic)
1054 /* Find the next CALL/PCALL */
1057 if (lic->op == CALL || lic->op == PCALL)
1065 /* A function call was found. Scan backwards and see if an */
1066 /* IPUSH or SEND is encountered */
1069 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1071 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1079 /*-----------------------------------------------------------------*/
1080 /* operandLitValue - literal value of an operand */
1081 /*-----------------------------------------------------------------*/
1083 operandLitValue (operand * op)
1085 assert (isOperandLiteral (op));
1087 return floatFromVal (op->operand.valOperand);
1090 /*-----------------------------------------------------------------*/
1091 /* getBuiltInParms - returns parameters to a builtin functions */
1092 /*-----------------------------------------------------------------*/
1093 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1098 /* builtin functions uses only SEND for parameters */
1099 while (ic->op != CALL) {
1100 assert(ic->op == SEND && ic->builtinSEND);
1101 ic->generated = 1; /* mark the icode as generated */
1102 parms[*pcount] = IC_LEFT(ic);
1108 /* make sure this is a builtin function call */
1109 assert(IS_SYMOP(IC_LEFT(ic)));
1110 ftype = operandType(IC_LEFT(ic));
1111 assert(IFFUNC_ISBUILTIN(ftype));
1115 /*-----------------------------------------------------------------*/
1116 /* operandOperation - performs operations on operands */
1117 /*-----------------------------------------------------------------*/
1119 operandOperation (operand * left, operand * right,
1120 int op, sym_link * type)
1122 sym_link *let , *ret=NULL;
1123 operand *retval = (operand *) 0;
1125 assert (isOperandLiteral (left));
1126 let = getSpec(operandType(left));
1128 assert (isOperandLiteral (right));
1129 ret = getSpec(operandType(right));
1135 retval = operandFromValue (valCastLiteral (type,
1136 operandLitValue (left) +
1137 operandLitValue (right)));
1140 retval = operandFromValue (valCastLiteral (type,
1141 operandLitValue (left) -
1142 operandLitValue (right)));
1146 retval = operandFromValue (valCastLiteral (type,
1147 operandLitValue (left) *
1148 operandLitValue (right)));
1149 This could be all we've to do, but with gcc we've to take care about
1150 overflows. Two examples:
1151 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1152 significant bits are lost (52 in fraction, 63 bits would be
1153 necessary to keep full precision).
1154 If the resulting double value is greater than ULONG_MAX (resp.
1155 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1158 /* if it is not a specifier then we can assume that */
1159 /* it will be an unsigned long */
1160 if (IS_INT (type) ||
1163 /* long is handled here, because it can overflow with double */
1164 if (IS_LONG (type) ||
1166 /* signed and unsigned mul are the same, as long as the precision
1167 of the result isn't bigger than the precision of the operands. */
1168 retval = operandFromValue (valCastLiteral (type,
1169 (TYPE_UDWORD) operandLitValue (left) *
1170 (TYPE_UDWORD) operandLitValue (right)));
1171 else if (IS_UNSIGNED (type)) /* unsigned int */
1173 /* unsigned int is handled here in order to detect overflow */
1174 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1175 (TYPE_UWORD) operandLitValue (right);
1177 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1178 if (ul != (TYPE_UWORD) ul)
1181 else /* signed int */
1183 /* signed int is handled here in order to detect overflow */
1184 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1185 (TYPE_WORD) operandLitValue (right);
1187 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1188 if (l != (TYPE_WORD) l)
1193 /* all others go here: */
1194 retval = operandFromValue (valCastLiteral (type,
1195 operandLitValue (left) *
1196 operandLitValue (right)));
1199 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1201 werror (E_DIVIDE_BY_ZERO);
1207 if (IS_UNSIGNED (type))
1209 SPEC_USIGN (let) = 1;
1210 SPEC_USIGN (ret) = 1;
1211 retval = operandFromValue (valCastLiteral (type,
1212 (TYPE_UDWORD) operandLitValue (left) /
1213 (TYPE_UDWORD) operandLitValue (right)));
1217 retval = operandFromValue (valCastLiteral (type,
1218 operandLitValue (left) /
1219 operandLitValue (right)));
1224 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1226 werror (E_DIVIDE_BY_ZERO);
1231 if (IS_UNSIGNED (type))
1232 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1233 (TYPE_UDWORD) operandLitValue (right));
1235 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1236 (TYPE_DWORD) operandLitValue (right));
1240 /* The number of left shifts is always unsigned. Signed doesn't make
1241 sense here. Shifting by a negative number is impossible. */
1242 retval = operandFromValue (valCastLiteral (type,
1243 ((TYPE_UDWORD) operandLitValue (left) <<
1244 (TYPE_UDWORD) operandLitValue (right))));
1247 /* The number of right shifts is always unsigned. Signed doesn't make
1248 sense here. Shifting by a negative number is impossible. */
1249 if (IS_UNSIGNED(let))
1250 /* unsigned: logic shift right */
1251 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1252 (TYPE_UDWORD) operandLitValue (right));
1254 /* signed: arithmetic shift right */
1255 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1256 (TYPE_UDWORD) operandLitValue (right));
1259 if (IS_FLOAT (let) ||
1262 retval = operandFromLit (operandLitValue (left) ==
1263 operandLitValue (right));
1267 /* this op doesn't care about signedness */
1270 l = (TYPE_UDWORD) operandLitValue (left);
1271 r = (TYPE_UDWORD) operandLitValue (right);
1272 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1273 neccessary to strip them to 16 bit.
1274 Literals are reduced to their cheapest type, therefore left and
1275 right might have different types. It's neccessary to find a
1276 common type: int (used for char too) or long */
1277 if (!IS_LONG (let) &&
1283 retval = operandFromLit (l == r);
1287 retval = operandFromLit (operandLitValue (left) <
1288 operandLitValue (right));
1291 retval = operandFromLit (operandLitValue (left) <=
1292 operandLitValue (right));
1295 retval = operandFromLit (operandLitValue (left) !=
1296 operandLitValue (right));
1299 retval = operandFromLit (operandLitValue (left) >
1300 operandLitValue (right));
1303 retval = operandFromLit (operandLitValue (left) >=
1304 operandLitValue (right));
1307 retval = operandFromValue (valCastLiteral (type,
1308 (TYPE_UDWORD)operandLitValue(left) &
1309 (TYPE_UDWORD)operandLitValue(right)));
1312 retval = operandFromValue (valCastLiteral (type,
1313 (TYPE_UDWORD)operandLitValue(left) |
1314 (TYPE_UDWORD)operandLitValue(right)));
1317 retval = operandFromValue (valCastLiteral (type,
1318 (TYPE_UDWORD)operandLitValue(left) ^
1319 (TYPE_UDWORD)operandLitValue(right)));
1322 retval = operandFromLit (operandLitValue (left) &&
1323 operandLitValue (right));
1326 retval = operandFromLit (operandLitValue (left) ||
1327 operandLitValue (right));
1331 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1333 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1339 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1341 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1347 retval = operandFromValue (valCastLiteral (type,
1348 -1 * operandLitValue (left)));
1352 retval = operandFromValue (valCastLiteral (type,
1354 operandLitValue (left))));
1358 retval = operandFromLit (!operandLitValue (left));
1362 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1363 " operandOperation invalid operator ");
1371 /*-----------------------------------------------------------------*/
1372 /* isOperandEqual - compares two operand & return 1 if they r = */
1373 /*-----------------------------------------------------------------*/
1375 isOperandEqual (operand * left, operand * right)
1377 /* if the pointers are equal then they are equal */
1381 /* if either of them null then false */
1382 if (!left || !right)
1385 if (left->type != right->type)
1388 if (IS_SYMOP (left) && IS_SYMOP (right))
1389 return left->key == right->key;
1391 /* if types are the same */
1395 return isSymbolEqual (left->operand.symOperand,
1396 right->operand.symOperand);
1398 return (floatFromVal (left->operand.valOperand) ==
1399 floatFromVal (right->operand.valOperand));
1401 if (compareType (left->operand.typeOperand,
1402 right->operand.typeOperand) == 1)
1409 /*-------------------------------------------------------------------*/
1410 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1411 /*-------------------------------------------------------------------*/
1413 isiCodeEqual (iCode * left, iCode * right)
1415 /* if the same pointer */
1419 /* if either of them null */
1420 if (!left || !right)
1423 /* if operand are the same */
1424 if (left->op == right->op)
1427 /* compare all the elements depending on type */
1428 if (left->op != IFX)
1430 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1432 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1438 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1440 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1442 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1451 /*-----------------------------------------------------------------*/
1452 /* newiTempFromOp - create a temp Operand with same attributes */
1453 /*-----------------------------------------------------------------*/
1455 newiTempFromOp (operand * op)
1465 nop = newiTempOperand (operandType (op), TRUE);
1466 nop->isaddr = op->isaddr;
1467 nop->isvolatile = op->isvolatile;
1468 nop->isGlobal = op->isGlobal;
1469 nop->isLiteral = op->isLiteral;
1470 nop->usesDefs = op->usesDefs;
1471 nop->isParm = op->isParm;
1475 /*-----------------------------------------------------------------*/
1476 /* operand from operand - creates an operand holder for the type */
1477 /*-----------------------------------------------------------------*/
1479 operandFromOperand (operand * op)
1485 nop = newOperand ();
1486 nop->type = op->type;
1487 nop->isaddr = op->isaddr;
1489 nop->isvolatile = op->isvolatile;
1490 nop->isGlobal = op->isGlobal;
1491 nop->isLiteral = op->isLiteral;
1492 nop->usesDefs = op->usesDefs;
1493 nop->isParm = op->isParm;
1498 nop->operand.symOperand = op->operand.symOperand;
1501 nop->operand.valOperand = op->operand.valOperand;
1504 nop->operand.typeOperand = op->operand.typeOperand;
1511 /*-----------------------------------------------------------------*/
1512 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1513 /*-----------------------------------------------------------------*/
1515 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1517 operand *nop = operandFromOperand (op);
1519 if (nop->type == SYMBOL)
1521 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1522 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1528 /*-----------------------------------------------------------------*/
1529 /* operandFromSymbol - creates an operand from a symbol */
1530 /*-----------------------------------------------------------------*/
1532 operandFromSymbol (symbol * sym)
1537 /* if the symbol's type is a literal */
1538 /* then it is an enumerator type */
1539 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1540 return operandFromValue (valFromType (sym->etype));
1543 sym->key = ++operandKey;
1545 /* if this an implicit variable, means struct/union */
1546 /* member so just return it */
1547 if (sym->implicit || IS_FUNC (sym->type))
1551 op->operand.symOperand = sym;
1553 op->isvolatile = isOperandVolatile (op, TRUE);
1554 op->isGlobal = isOperandGlobal (op);
1558 /* under the following conditions create a
1559 register equivalent for a local symbol */
1560 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1561 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1563 (!(options.model == MODEL_FLAT24)) ) &&
1564 options.stackAuto == 0)
1567 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1568 !IS_FUNC (sym->type) && /* not a function */
1569 !sym->_isparm && /* not a parameter */
1570 IS_AUTO (sym) && /* is a local auto variable */
1571 !sym->addrtaken && /* whose address has not been taken */
1572 !sym->reqv && /* does not already have a reg equivalence */
1573 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1574 !sym->islbl && /* not a label */
1575 ok && /* farspace check */
1576 !IS_BITVAR (sym->etype) /* not a bit variable */
1580 /* we will use it after all optimizations
1581 and before liveRange calculation */
1582 sym->reqv = newiTempOperand (sym->type, 0);
1583 sym->reqv->key = sym->key;
1584 OP_SYMBOL (sym->reqv)->prereqv = sym;
1585 OP_SYMBOL (sym->reqv)->key = sym->key;
1586 OP_SYMBOL (sym->reqv)->isreqv = 1;
1587 OP_SYMBOL (sym->reqv)->islocal = 1;
1588 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1589 SPIL_LOC (sym->reqv) = sym;
1592 if (!IS_AGGREGATE (sym->type))
1596 op->operand.symOperand = sym;
1599 op->isvolatile = isOperandVolatile (op, TRUE);
1600 op->isGlobal = isOperandGlobal (op);
1601 op->isPtr = IS_PTR (operandType (op));
1602 op->isParm = sym->_isparm;
1607 /* itemp = &[_symbol] */
1609 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1610 IC_LEFT (ic)->type = SYMBOL;
1611 IC_LEFT (ic)->operand.symOperand = sym;
1612 IC_LEFT (ic)->key = sym->key;
1613 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1614 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1615 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1618 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1619 if (IS_ARRAY (sym->type))
1621 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1622 IC_RESULT (ic)->isaddr = 0;
1625 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1629 return IC_RESULT (ic);
1632 /*-----------------------------------------------------------------*/
1633 /* operandFromValue - creates an operand from value */
1634 /*-----------------------------------------------------------------*/
1636 operandFromValue (value * val)
1640 /* if this is a symbol then do the symbol thing */
1642 return operandFromSymbol (val->sym);
1644 /* this is not a symbol */
1647 op->operand.valOperand = val;
1648 op->isLiteral = isOperandLiteral (op);
1652 /*-----------------------------------------------------------------*/
1653 /* operandFromLink - operand from typeChain */
1654 /*-----------------------------------------------------------------*/
1656 operandFromLink (sym_link * type)
1660 /* operand from sym_link */
1666 op->operand.typeOperand = copyLinkChain (type);
1670 /*-----------------------------------------------------------------*/
1671 /* operandFromLit - makes an operand from a literal value */
1672 /*-----------------------------------------------------------------*/
1674 operandFromLit (double i)
1676 return operandFromValue (valueFromLit (i));
1679 /*-----------------------------------------------------------------*/
1680 /* operandFromAst - creates an operand from an ast */
1681 /*-----------------------------------------------------------------*/
1683 operandFromAst (ast * tree,int lvl)
1689 /* depending on type do */
1693 return ast2iCode (tree,lvl+1);
1697 return operandFromValue (tree->opval.val);
1701 return operandFromLink (tree->opval.lnk);
1708 /* Just to keep the compiler happy */
1709 return (operand *) 0;
1712 /*-----------------------------------------------------------------*/
1713 /* setOperandType - sets the operand's type to the given type */
1714 /*-----------------------------------------------------------------*/
1716 setOperandType (operand * op, sym_link * type)
1718 /* depending on the type of operand */
1723 op->operand.valOperand->etype =
1724 getSpec (op->operand.valOperand->type =
1725 copyLinkChain (type));
1729 if (op->operand.symOperand->isitmp)
1730 op->operand.symOperand->etype =
1731 getSpec (op->operand.symOperand->type =
1732 copyLinkChain (type));
1734 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1735 "attempt to modify type of source");
1739 op->operand.typeOperand = copyLinkChain (type);
1745 /*-----------------------------------------------------------------*/
1746 /* Get size in byte of ptr need to access an array */
1747 /*-----------------------------------------------------------------*/
1749 getArraySizePtr (operand * op)
1751 sym_link *ltype = operandType(op);
1755 int size = getSize(ltype);
1756 return(IS_GENPTR(ltype)?(size-1):size);
1761 sym_link *letype = getSpec(ltype);
1762 switch (PTR_TYPE (SPEC_OCLS (letype)))
1774 return (GPTRSIZE-1);
1783 /*-----------------------------------------------------------------*/
1784 /* perform "usual unary conversions" */
1785 /*-----------------------------------------------------------------*/
1788 usualUnaryConversions (operand * op)
1790 if (IS_INTEGRAL (operandType (op)))
1792 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1795 return geniCodeCast (INTTYPE, op, TRUE);
1802 /*-----------------------------------------------------------------*/
1803 /* perform "usual binary conversions" */
1804 /*-----------------------------------------------------------------*/
1807 usualBinaryConversions (operand ** op1, operand ** op2,
1808 RESULT_TYPE resultType, int op)
1811 sym_link *rtype = operandType (*op2);
1812 sym_link *ltype = operandType (*op1);
1814 ctype = computeType (ltype, rtype, resultType, op);
1821 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1823 /* one byte operations: keep signedness for code generator */
1831 *op1 = geniCodeCast (ctype, *op1, TRUE);
1832 *op2 = geniCodeCast (ctype, *op2, TRUE);
1837 /*-----------------------------------------------------------------*/
1838 /* geniCodeValueAtAddress - generate intermeditate code for value */
1840 /*-----------------------------------------------------------------*/
1842 geniCodeRValue (operand * op, bool force)
1845 sym_link *type = operandType (op);
1846 sym_link *etype = getSpec (type);
1848 /* if this is an array & already */
1849 /* an address then return this */
1850 if (IS_AGGREGATE (type) ||
1851 (IS_PTR (type) && !force && !op->isaddr))
1852 return operandFromOperand (op);
1854 /* if this is not an address then must be */
1855 /* rvalue already so return this one */
1859 /* if this is not a temp symbol then */
1860 if (!IS_ITEMP (op) &&
1862 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1864 op = operandFromOperand (op);
1869 if (IS_SPEC (type) &&
1870 IS_TRUE_SYMOP (op) &&
1871 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1872 (options.model == MODEL_FLAT24) ))
1874 op = operandFromOperand (op);
1879 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1880 if (IS_PTR (type) && op->isaddr && force)
1883 type = copyLinkChain (type);
1885 IC_RESULT (ic) = newiTempOperand (type, 1);
1886 IC_RESULT (ic)->isaddr = 0;
1888 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1892 return IC_RESULT (ic);
1895 /*-----------------------------------------------------------------*/
1896 /* geniCodeCast - changes the value from one type to another */
1897 /*-----------------------------------------------------------------*/
1899 geniCodeCast (sym_link * type, operand * op, bool implicit)
1903 sym_link *opetype = getSpec (optype = operandType (op));
1907 /* one of them has size zero then error */
1908 if (IS_VOID (optype))
1910 werror (E_CAST_ZERO);
1914 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1916 geniCodeArray2Ptr (op);
1920 /* if the operand is already the desired type then do nothing */
1921 if (compareType (type, optype) == 1)
1924 /* if this is a literal then just change the type & return */
1925 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1927 return operandFromValue (valCastLiteral (type,
1928 operandLitValue (op)));
1931 /* if casting to/from pointers, do some checking */
1932 if (IS_PTR(type)) { // to a pointer
1933 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1934 if (IS_INTEGRAL(optype)) {
1935 // maybe this is NULL, than it's ok.
1936 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1937 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1938 // no way to set the storage
1939 if (IS_LITERAL(optype)) {
1940 werror(E_LITERAL_GENERIC);
1943 werror(E_NONPTR2_GENPTR);
1946 } else if (implicit) {
1947 werror(W_INTEGRAL2PTR_NOCAST);
1952 // shouldn't do that with float, array or structure unless to void
1953 if (!IS_VOID(getSpec(type)) &&
1954 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1955 werror(E_INCOMPAT_TYPES);
1959 } else { // from a pointer to a pointer
1960 if (IS_GENPTR(type) && IS_VOID(type->next))
1961 { // cast to void* is always allowed
1963 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
1964 { // cast from void* is always allowed
1966 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1967 // if not a pointer to a function
1968 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1969 if (implicit) { // if not to generic, they have to match
1970 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1971 werror(E_INCOMPAT_PTYPES);
1978 } else { // to a non pointer
1979 if (IS_PTR(optype)) { // from a pointer
1980 if (implicit) { // sneaky
1981 if (IS_INTEGRAL(type)) {
1982 werror(W_PTR2INTEGRAL_NOCAST);
1984 } else { // shouldn't do that with float, array or structure
1985 werror(E_INCOMPAT_TYPES);
1992 printFromToType (optype, type);
1995 /* if they are the same size create an assignment */
1997 /* This seems very dangerous to me, since there are several */
1998 /* optimizations (for example, gcse) that don't notice the */
1999 /* cast hidden in this assignement and may simplify an */
2000 /* iCode to use the original (uncasted) operand. */
2001 /* Unfortunately, other things break when this cast is */
2002 /* made explicit. Need to fix this someday. */
2003 /* -- EEP, 2004/01/21 */
2004 if (getSize (type) == getSize (optype) &&
2005 !IS_BITFIELD (type) &&
2007 !IS_FLOAT (optype) &&
2008 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2009 (!IS_SPEC (type) && !IS_SPEC (optype))))
2011 ic = newiCode ('=', NULL, op);
2012 IC_RESULT (ic) = newiTempOperand (type, 0);
2013 SPIL_LOC (IC_RESULT (ic)) =
2014 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2015 IC_RESULT (ic)->isaddr = 0;
2019 ic = newiCode (CAST, operandFromLink (type),
2020 geniCodeRValue (op, FALSE));
2022 IC_RESULT (ic) = newiTempOperand (type, 0);
2025 /* preserve the storage class & output class */
2026 /* of the original variable */
2027 restype = getSpec (operandType (IC_RESULT (ic)));
2028 if (!IS_LITERAL(opetype) &&
2030 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2031 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2034 return IC_RESULT (ic);
2037 /*-----------------------------------------------------------------*/
2038 /* geniCodeLabel - will create a Label */
2039 /*-----------------------------------------------------------------*/
2041 geniCodeLabel (symbol * label)
2045 ic = newiCodeLabelGoto (LABEL, label);
2049 /*-----------------------------------------------------------------*/
2050 /* geniCodeGoto - will create a Goto */
2051 /*-----------------------------------------------------------------*/
2053 geniCodeGoto (symbol * label)
2057 ic = newiCodeLabelGoto (GOTO, label);
2061 /*-----------------------------------------------------------------*/
2062 /* geniCodeMultiply - gen intermediate code for multiplication */
2063 /*-----------------------------------------------------------------*/
2065 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2072 /* if they are both literal then we know the result */
2073 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2074 return operandFromValue (valMult (left->operand.valOperand,
2075 right->operand.valOperand));
2077 if (IS_LITERAL(retype)) {
2078 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2081 resType = usualBinaryConversions (&left, &right, resultType, '*');
2083 rtype = operandType (right);
2084 retype = getSpec (rtype);
2085 ltype = operandType (left);
2086 letype = getSpec (ltype);
2089 /* if the right is a literal & power of 2 */
2090 /* then make it a left shift */
2091 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2092 efficient in most cases than 2 bytes result = 2 bytes << literal
2093 if port has 1 byte muldiv */
2094 if (p2 && !IS_FLOAT (letype)
2095 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2096 && (port->support.muldiv == 1))
2097 && strcmp (port->target, "pic14") != 0 /* don't shift for pic */
2098 && strcmp (port->target, "pic16") != 0)
2100 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2102 /* LEFT_OP need same size for left and result, */
2103 left = geniCodeCast (resType, left, TRUE);
2104 ltype = operandType (left);
2106 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2110 ic = newiCode ('*', left, right); /* normal multiplication */
2111 /* if the size left or right > 1 then support routine */
2112 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2116 IC_RESULT (ic) = newiTempOperand (resType, 1);
2119 return IC_RESULT (ic);
2122 /*-----------------------------------------------------------------*/
2123 /* geniCodeDivision - gen intermediate code for division */
2124 /*-----------------------------------------------------------------*/
2126 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2131 sym_link *rtype = operandType (right);
2132 sym_link *retype = getSpec (rtype);
2133 sym_link *ltype = operandType (left);
2134 sym_link *letype = getSpec (ltype);
2136 resType = usualBinaryConversions (&left, &right, resultType, '/');
2138 /* if the right is a literal & power of 2
2139 and left is unsigned then make it a
2141 if (IS_LITERAL (retype) &&
2142 !IS_FLOAT (letype) &&
2143 IS_UNSIGNED(letype) &&
2144 (p2 = powof2 ((TYPE_UDWORD)
2145 floatFromVal (right->operand.valOperand)))) {
2146 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2150 ic = newiCode ('/', left, right); /* normal division */
2151 /* if the size left or right > 1 then support routine */
2152 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2155 IC_RESULT (ic) = newiTempOperand (resType, 0);
2158 return IC_RESULT (ic);
2160 /*-----------------------------------------------------------------*/
2161 /* geniCodeModulus - gen intermediate code for modulus */
2162 /*-----------------------------------------------------------------*/
2164 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2170 /* if they are both literal then we know the result */
2171 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2172 return operandFromValue (valMod (left->operand.valOperand,
2173 right->operand.valOperand));
2175 resType = usualBinaryConversions (&left, &right, resultType, '%');
2177 /* now they are the same size */
2178 ic = newiCode ('%', left, right);
2180 /* if the size left or right > 1 then support routine */
2181 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2183 IC_RESULT (ic) = newiTempOperand (resType, 0);
2186 return IC_RESULT (ic);
2189 /*-----------------------------------------------------------------*/
2190 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2191 /*-----------------------------------------------------------------*/
2193 geniCodePtrPtrSubtract (operand * left, operand * right)
2199 /* if they are both literals then */
2200 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2202 result = operandFromValue (valMinus (left->operand.valOperand,
2203 right->operand.valOperand));
2207 ic = newiCode ('-', left, right);
2209 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2213 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2217 // should we really do this? is this ANSI?
2218 return geniCodeDivision (result,
2219 operandFromLit (getSize (ltype->next)),
2223 /*-----------------------------------------------------------------*/
2224 /* geniCodeSubtract - generates code for subtraction */
2225 /*-----------------------------------------------------------------*/
2227 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2234 /* if they both pointers then */
2235 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2236 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2237 return geniCodePtrPtrSubtract (left, right);
2239 /* if they are both literal then we know the result */
2240 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2241 && left->isLiteral && right->isLiteral)
2242 return operandFromValue (valMinus (left->operand.valOperand,
2243 right->operand.valOperand));
2245 /* if left is an array or pointer */
2246 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2248 isarray = left->isaddr;
2249 right = geniCodeMultiply (right,
2250 operandFromLit (getSize (ltype->next)),
2251 (getArraySizePtr(left) >= INTSIZE) ?
2254 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2257 { /* make them the same size */
2258 resType = usualBinaryConversions (&left, &right, resultType, '-');
2261 ic = newiCode ('-', left, right);
2263 IC_RESULT (ic) = newiTempOperand (resType, 1);
2264 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2266 /* if left or right is a float */
2267 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2271 return IC_RESULT (ic);
2274 /*-----------------------------------------------------------------*/
2275 /* geniCodeAdd - generates iCode for addition */
2276 /*-----------------------------------------------------------------*/
2278 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2287 /* if the right side is LITERAL zero */
2288 /* return the left side */
2289 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2292 /* if left is literal zero return right */
2293 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2296 /* if left is a pointer then size */
2297 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2299 isarray = left->isaddr;
2300 // there is no need to multiply with 1
2301 if (getSize (ltype->next) != 1)
2303 size = operandFromLit (getSize (ltype->next));
2304 SPEC_USIGN (getSpec (operandType (size))) = 1;
2305 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2306 right = geniCodeMultiply (right,
2308 (getArraySizePtr(left) >= INTSIZE) ?
2311 /* Even if right is a 'unsigned char',
2312 the result will be a 'signed int' due to the promotion rules.
2313 It doesn't make sense when accessing arrays, so let's fix it here: */
2315 SPEC_USIGN (getSpec (operandType (right))) = 1;
2317 resType = copyLinkChain (ltype);
2320 { // make them the same size
2321 resType = usualBinaryConversions (&left, &right, resultType, '+');
2324 /* if they are both literals then we know */
2325 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2326 && left->isLiteral && right->isLiteral)
2327 return operandFromValue (valPlus (valFromType (ltype),
2328 valFromType (rtype)));
2330 ic = newiCode ('+', left, right);
2332 IC_RESULT (ic) = newiTempOperand (resType, 1);
2333 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2335 /* if left or right is a float then support
2337 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2342 return IC_RESULT (ic);
2346 /*-----------------------------------------------------------------*/
2347 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2348 /*-----------------------------------------------------------------*/
2350 aggrToPtr (sym_link * type, bool force)
2355 if (IS_PTR (type) && !force)
2358 etype = getSpec (type);
2359 ptype = newLink (DECLARATOR);
2363 /* set the pointer depending on the storage class */
2364 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2368 /*------------------------------------------------------------------*/
2369 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2370 /*------------------------------------------------------------------*/
2372 aggrToPtrDclType (sym_link * type, bool force)
2374 if (IS_PTR (type) && !force)
2375 return DCL_TYPE (type);
2377 /* return the pointer depending on the storage class */
2378 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2381 /*-----------------------------------------------------------------*/
2382 /* geniCodeArray2Ptr - array to pointer */
2383 /*-----------------------------------------------------------------*/
2385 geniCodeArray2Ptr (operand * op)
2387 sym_link *optype = operandType (op);
2388 sym_link *opetype = getSpec (optype);
2390 /* set the pointer depending on the storage class */
2391 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2398 /*-----------------------------------------------------------------*/
2399 /* geniCodeArray - array access */
2400 /*-----------------------------------------------------------------*/
2402 geniCodeArray (operand * left, operand * right, int lvl)
2406 sym_link *ltype = operandType (left);
2411 if (IS_PTR (ltype->next) && left->isaddr)
2413 left = geniCodeRValue (left, FALSE);
2416 return geniCodeDerefPtr (geniCodeAdd (left,
2418 (getArraySizePtr(left) >= INTSIZE) ?
2424 size = operandFromLit (getSize (ltype->next));
2425 SPEC_USIGN (getSpec (operandType (size))) = 1;
2426 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2427 right = geniCodeMultiply (right,
2429 (getArraySizePtr(left) >= INTSIZE) ?
2432 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2433 It doesn't make sense when accessing arrays, so let's fix it here: */
2435 SPEC_USIGN (getSpec (operandType (right))) = 1;
2436 /* we can check for limits here */
2437 /* already done in SDCCast.c
2438 if (isOperandLiteral (right) &&
2441 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2443 werror (W_IDX_OUT_OF_BOUNDS,
2444 (int) operandLitValue (right) / getSize (ltype->next),
2449 ic = newiCode ('+', left, right);
2451 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2452 !IS_AGGREGATE (ltype->next) &&
2453 !IS_PTR (ltype->next))
2454 ? ltype : ltype->next), 0);
2456 if (!IS_AGGREGATE (ltype->next))
2458 IC_RESULT (ic)->isaddr = 1;
2459 IC_RESULT (ic)->aggr2ptr = 1;
2463 return IC_RESULT (ic);
2466 /*-----------------------------------------------------------------*/
2467 /* geniCodeStruct - generates intermediate code for structures */
2468 /*-----------------------------------------------------------------*/
2470 geniCodeStruct (operand * left, operand * right, bool islval)
2473 sym_link *type = operandType (left);
2474 sym_link *etype = getSpec (type);
2476 symbol *element = getStructElement (SPEC_STRUCT (etype),
2477 right->operand.symOperand);
2479 wassert(IS_SYMOP(right));
2481 /* add the offset */
2482 ic = newiCode ('+', left, operandFromLit (element->offset));
2484 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2486 /* preserve the storage & output class of the struct */
2487 /* as well as the volatile attribute */
2488 retype = getSpec (operandType (IC_RESULT (ic)));
2489 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2490 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2491 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2492 SPEC_CONST (retype) |= SPEC_CONST (etype);
2494 if (IS_PTR (element->type))
2495 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2497 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2500 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2503 /*-----------------------------------------------------------------*/
2504 /* geniCodePostInc - generate int code for Post increment */
2505 /*-----------------------------------------------------------------*/
2507 geniCodePostInc (operand * op)
2511 sym_link *optype = operandType (op);
2513 operand *rv = (IS_ITEMP (op) ?
2514 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2516 sym_link *rvtype = operandType (rv);
2519 /* if this is not an address we have trouble */
2522 werror (E_LVALUE_REQUIRED, "++");
2526 rOp = newiTempOperand (rvtype, 0);
2527 OP_SYMBOL(rOp)->noSpilLoc = 1;
2530 OP_SYMBOL(rv)->noSpilLoc = 1;
2532 geniCodeAssign (rOp, rv, 0, 0);
2534 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2536 werror(W_SIZEOF_VOID);
2537 if (IS_FLOAT (rvtype))
2538 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2540 ic = newiCode ('+', rv, operandFromLit (size));
2542 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2545 geniCodeAssign (op, result, 0, 0);
2551 /*-----------------------------------------------------------------*/
2552 /* geniCodePreInc - generate code for preIncrement */
2553 /*-----------------------------------------------------------------*/
2555 geniCodePreInc (operand * op, bool lvalue)
2558 sym_link *optype = operandType (op);
2559 operand *rop = (IS_ITEMP (op) ?
2560 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2562 sym_link *roptype = operandType (rop);
2568 werror (E_LVALUE_REQUIRED, "++");
2572 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2574 werror(W_SIZEOF_VOID);
2575 if (IS_FLOAT (roptype))
2576 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2578 ic = newiCode ('+', rop, operandFromLit (size));
2579 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2582 (void) geniCodeAssign (op, result, 0, 0);
2583 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2589 /*-----------------------------------------------------------------*/
2590 /* geniCodePostDec - generates code for Post decrement */
2591 /*-----------------------------------------------------------------*/
2593 geniCodePostDec (operand * op)
2597 sym_link *optype = operandType (op);
2599 operand *rv = (IS_ITEMP (op) ?
2600 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2602 sym_link *rvtype = operandType (rv);
2605 /* if this is not an address we have trouble */
2608 werror (E_LVALUE_REQUIRED, "--");
2612 rOp = newiTempOperand (rvtype, 0);
2613 OP_SYMBOL(rOp)->noSpilLoc = 1;
2616 OP_SYMBOL(rv)->noSpilLoc = 1;
2618 geniCodeAssign (rOp, rv, 0, 0);
2620 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2622 werror(W_SIZEOF_VOID);
2623 if (IS_FLOAT (rvtype))
2624 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2626 ic = newiCode ('-', rv, operandFromLit (size));
2628 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2631 geniCodeAssign (op, result, 0, 0);
2637 /*-----------------------------------------------------------------*/
2638 /* geniCodePreDec - generate code for pre decrement */
2639 /*-----------------------------------------------------------------*/
2641 geniCodePreDec (operand * op, bool lvalue)
2644 sym_link *optype = operandType (op);
2645 operand *rop = (IS_ITEMP (op) ?
2646 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2648 sym_link *roptype = operandType (rop);
2654 werror (E_LVALUE_REQUIRED, "--");
2658 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2660 werror(W_SIZEOF_VOID);
2661 if (IS_FLOAT (roptype))
2662 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2664 ic = newiCode ('-', rop, operandFromLit (size));
2665 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2668 (void) geniCodeAssign (op, result, 0, 0);
2669 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2676 /*-----------------------------------------------------------------*/
2677 /* geniCodeBitwise - gen int code for bitWise operators */
2678 /*-----------------------------------------------------------------*/
2680 geniCodeBitwise (operand * left, operand * right,
2681 int oper, sym_link * resType)
2685 left = geniCodeCast (resType, left, TRUE);
2686 right = geniCodeCast (resType, right, TRUE);
2688 ic = newiCode (oper, left, right);
2689 IC_RESULT (ic) = newiTempOperand (resType, 0);
2692 return IC_RESULT (ic);
2695 /*-----------------------------------------------------------------*/
2696 /* geniCodeAddressOf - gens icode for '&' address of operator */
2697 /*-----------------------------------------------------------------*/
2699 geniCodeAddressOf (operand * op)
2703 sym_link *optype = operandType (op);
2704 sym_link *opetype = getSpec (optype);
2706 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2708 op = operandFromOperand (op);
2713 /* lvalue check already done in decorateType */
2714 /* this must be a lvalue */
2715 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2716 /* werror (E_LVALUE_REQUIRED,"&"); */
2720 p = newLink (DECLARATOR);
2722 /* set the pointer depending on the storage class */
2723 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2725 p->next = copyLinkChain (optype);
2727 /* if already a temp */
2730 setOperandType (op, p);
2735 /* other wise make this of the type coming in */
2736 ic = newiCode (ADDRESS_OF, op, NULL);
2737 IC_RESULT (ic) = newiTempOperand (p, 1);
2738 IC_RESULT (ic)->isaddr = 0;
2740 return IC_RESULT (ic);
2742 /*-----------------------------------------------------------------*/
2743 /* setOClass - sets the output class depending on the pointer type */
2744 /*-----------------------------------------------------------------*/
2746 setOClass (sym_link * ptr, sym_link * spec)
2748 switch (DCL_TYPE (ptr))
2751 SPEC_OCLS (spec) = data;
2755 SPEC_OCLS (spec) = generic;
2759 SPEC_OCLS (spec) = xdata;
2763 SPEC_OCLS (spec) = code;
2767 SPEC_OCLS (spec) = idata;
2771 SPEC_OCLS (spec) = xstack;
2775 SPEC_OCLS (spec) = eeprom;
2784 /*-----------------------------------------------------------------*/
2785 /* geniCodeDerefPtr - dereference pointer with '*' */
2786 /*-----------------------------------------------------------------*/
2788 geniCodeDerefPtr (operand * op,int lvl)
2790 sym_link *rtype, *retype;
2791 sym_link *optype = operandType (op);
2793 // if this is an array then array access
2794 if (IS_ARRAY (optype)) {
2795 // don't worry, this will be optimized out later
2796 return geniCodeArray (op, operandFromLit (0), lvl);
2799 // just in case someone screws up
2800 wassert (IS_PTR (optype));
2802 if (IS_TRUE_SYMOP (op))
2805 op = geniCodeRValue (op, TRUE);
2808 /* now get rid of the pointer part */
2809 if (isLvaluereq(lvl) && IS_ITEMP (op))
2811 retype = getSpec (rtype = copyLinkChain (optype));
2815 retype = getSpec (rtype = copyLinkChain (optype->next));
2816 /* outputclass needs 2b updated */
2817 setOClass (optype, retype);
2820 op->isGptr = IS_GENPTR (optype);
2822 op->isaddr = (IS_PTR (rtype) ||
2823 IS_STRUCT (rtype) ||
2828 if (!isLvaluereq(lvl))
2829 op = geniCodeRValue (op, TRUE);
2831 setOperandType (op, rtype);
2836 /*-----------------------------------------------------------------*/
2837 /* geniCodeUnaryMinus - does a unary minus of the operand */
2838 /*-----------------------------------------------------------------*/
2840 geniCodeUnaryMinus (operand * op)
2843 sym_link *optype = operandType (op);
2845 if (IS_LITERAL (optype))
2846 return operandFromLit (-floatFromVal (op->operand.valOperand));
2848 ic = newiCode (UNARYMINUS, op, NULL);
2849 IC_RESULT (ic) = newiTempOperand (optype, 0);
2851 return IC_RESULT (ic);
2854 /*-----------------------------------------------------------------*/
2855 /* geniCodeLeftShift - gen i code for left shift */
2856 /*-----------------------------------------------------------------*/
2858 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2863 ic = newiCode (LEFT_OP, left, right);
2865 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2866 IC_RESULT (ic) = newiTempOperand (resType, 0);
2868 return IC_RESULT (ic);
2871 /*-----------------------------------------------------------------*/
2872 /* geniCodeRightShift - gen i code for right shift */
2873 /*-----------------------------------------------------------------*/
2875 geniCodeRightShift (operand * left, operand * right)
2879 ic = newiCode (RIGHT_OP, left, right);
2880 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2882 return IC_RESULT (ic);
2885 /*-----------------------------------------------------------------*/
2886 /* geniCodeLogic- logic code */
2887 /*-----------------------------------------------------------------*/
2889 geniCodeLogic (operand * left, operand * right, int op)
2893 sym_link *rtype = operandType (right);
2894 sym_link *ltype = operandType (left);
2896 /* left is integral type and right is literal then
2897 check if the literal value is within bounds */
2898 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2900 checkConstantRange(ltype,
2901 OP_VALUE(right), "compare operation", 1);
2904 /* if one operand is a pointer and the other is a literal generic void pointer,
2905 change the type of the literal generic void pointer to match the other pointer */
2906 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2907 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2909 /* find left's definition */
2910 ic = (iCode *) setFirstItem (iCodeChain);
2913 if (((ic->op == CAST) || (ic->op == '='))
2914 && isOperandEqual(left, IC_RESULT (ic)))
2917 ic = setNextItem (iCodeChain);
2919 /* if casting literal to generic pointer, then cast to rtype instead */
2920 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2922 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2923 ltype = operandType(left);
2926 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2927 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2929 /* find right's definition */
2930 ic = (iCode *) setFirstItem (iCodeChain);
2933 if (((ic->op == CAST) || (ic->op == '='))
2934 && isOperandEqual(right, IC_RESULT (ic)))
2937 ic = setNextItem (iCodeChain);
2939 /* if casting literal to generic pointer, then cast to rtype instead */
2940 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2942 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2943 rtype = operandType(right);
2947 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
2949 ic = newiCode (op, left, right);
2950 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2952 /* if comparing float
2953 and not a '==' || '!=' || '&&' || '||' (these
2955 if (IS_FLOAT(ctype) &&
2963 return IC_RESULT (ic);
2966 /*-----------------------------------------------------------------*/
2967 /* geniCodeLogicAndOr - && || operations */
2968 /*-----------------------------------------------------------------*/
2970 geniCodeLogicAndOr (ast *tree, int lvl)
2973 symbol *falseLabel = newiTempLabel (NULL);
2974 symbol *trueLabel = newiTempLabel (NULL);
2975 symbol *exitLabel = newiTempLabel (NULL);
2976 operand *op, *result, *condition;
2978 /* AND_OP and OR_OP are no longer generated because of bug-905492.
2979 They can be reenabled by executing the following block. If you find
2980 a decent optimization you could start right here:
2985 operand *leftOp, *rightOp;
2987 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
2988 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
2990 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
2994 /* generate two IFX for the '&&' or '||' op */
2996 /* evaluate left operand */
2997 condition = ast2iCode (tree->left, lvl + 1);
2998 op = geniCodeRValue (condition, FALSE);
3000 /* test left operand */
3001 if (tree->opval.op == AND_OP)
3002 ic = newiCodeCondition (op, NULL, falseLabel);
3004 ic = newiCodeCondition (op, trueLabel, NULL);
3007 /* evaluate right operand */
3008 condition = ast2iCode (tree->right, lvl + 1);
3009 op = geniCodeRValue (condition, FALSE);
3011 /* test right operand */
3012 ic = newiCodeCondition (op, trueLabel, NULL);
3015 /* store 0 or 1 in result */
3016 result = newiTempOperand (newCharLink(), 1);
3018 geniCodeLabel (falseLabel);
3019 geniCodeAssign (result, operandFromLit (0), 0, 0);
3020 /* generate an unconditional goto */
3021 geniCodeGoto (exitLabel);
3023 geniCodeLabel (trueLabel);
3024 geniCodeAssign (result, operandFromLit (1), 0, 0);
3026 geniCodeLabel (exitLabel);
3031 /*-----------------------------------------------------------------*/
3032 /* geniCodeUnary - for a a generic unary operation */
3033 /*-----------------------------------------------------------------*/
3035 geniCodeUnary (operand * op, int oper)
3037 iCode *ic = newiCode (oper, op, NULL);
3039 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3041 return IC_RESULT (ic);
3044 /*-----------------------------------------------------------------*/
3045 /* geniCodeConditional - geniCode for '?' ':' operation */
3046 /*-----------------------------------------------------------------*/
3048 geniCodeConditional (ast * tree,int lvl)
3051 symbol *falseLabel = newiTempLabel (NULL);
3052 symbol *exitLabel = newiTempLabel (NULL);
3053 operand *cond = ast2iCode (tree->left,lvl+1);
3054 operand *true, *false, *result;
3056 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3060 true = ast2iCode (tree->right->left,lvl+1);
3062 /* move the value to a new Operand */
3063 result = newiTempOperand (tree->right->ftype, 0);
3064 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3066 /* generate an unconditional goto */
3067 geniCodeGoto (exitLabel);
3069 /* now for the right side */
3070 geniCodeLabel (falseLabel);
3072 false = ast2iCode (tree->right->right,lvl+1);
3073 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3075 /* create the exit label */
3076 geniCodeLabel (exitLabel);
3081 /*-----------------------------------------------------------------*/
3082 /* geniCodeAssign - generate code for assignment */
3083 /*-----------------------------------------------------------------*/
3085 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3088 sym_link *ltype = operandType (left);
3089 sym_link *rtype = operandType (right);
3091 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3093 werror (E_LVALUE_REQUIRED, "assignment");
3097 /* left is integral type and right is literal then
3098 check if the literal value is within bounds */
3099 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3101 checkConstantRange(ltype,
3102 OP_VALUE(right), "= operation", 0);
3105 /* if the left & right type don't exactly match */
3106 /* if pointer set then make sure the check is
3107 done with the type & not the pointer */
3108 /* then cast rights type to left */
3110 /* first check the type for pointer assignement */
3111 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3112 compareType (ltype, rtype) <= 0)
3114 if (compareType (ltype->next, rtype) < 0)
3115 right = geniCodeCast (ltype->next, right, TRUE);
3117 else if (compareType (ltype, rtype) < 0)
3118 right = geniCodeCast (ltype, right, TRUE);
3120 /* If left is a true symbol & ! volatile
3121 create an assignment to temporary for
3122 the right & then assign this temporary
3123 to the symbol. This is SSA (static single
3124 assignment). Isn't it simple and folks have
3125 published mountains of paper on it */
3126 if (IS_TRUE_SYMOP (left) &&
3127 !isOperandVolatile (left, FALSE) &&
3128 isOperandGlobal (left))
3132 if (IS_TRUE_SYMOP (right))
3133 sym = OP_SYMBOL (right);
3134 ic = newiCode ('=', NULL, right);
3135 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3136 SPIL_LOC (right) = sym;
3140 ic = newiCode ('=', NULL, right);
3141 IC_RESULT (ic) = left;
3144 /* if left isgptr flag is set then support
3145 routine will be required */
3149 ic->nosupdate = nosupdate;
3153 /*-----------------------------------------------------------------*/
3154 /* geniCodeDummyRead - generate code for dummy read */
3155 /*-----------------------------------------------------------------*/
3157 geniCodeDummyRead (operand * op)
3160 sym_link *type = operandType (op);
3162 if (!IS_VOLATILE(type))
3165 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3171 /*-----------------------------------------------------------------*/
3172 /* geniCodeSEParms - generate code for side effecting fcalls */
3173 /*-----------------------------------------------------------------*/
3175 geniCodeSEParms (ast * parms,int lvl)
3180 if (parms->type == EX_OP && parms->opval.op == PARAM)
3182 geniCodeSEParms (parms->left,lvl);
3183 geniCodeSEParms (parms->right,lvl);
3187 /* hack don't like this but too lazy to think of
3189 if (IS_ADDRESS_OF_OP (parms))
3190 parms->left->lvalue = 1;
3192 if (IS_CAST_OP (parms) &&
3193 IS_PTR (parms->ftype) &&
3194 IS_ADDRESS_OF_OP (parms->right))
3195 parms->right->left->lvalue = 1;
3197 parms->opval.oprnd =
3198 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3200 parms->type = EX_OPERAND;
3201 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3202 SPEC_ARGREG(parms->ftype);
3205 /*-----------------------------------------------------------------*/
3206 /* geniCodeParms - generates parameters */
3207 /*-----------------------------------------------------------------*/
3209 geniCodeParms (ast * parms, value *argVals, int *stack,
3210 sym_link * ftype, int lvl)
3218 if (argVals==NULL) {
3220 argVals = FUNC_ARGS (ftype);
3223 /* if this is a param node then do the left & right */
3224 if (parms->type == EX_OP && parms->opval.op == PARAM)
3226 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3227 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3231 /* get the parameter value */
3232 if (parms->type == EX_OPERAND)
3233 pval = parms->opval.oprnd;
3236 /* maybe this else should go away ?? */
3237 /* hack don't like this but too lazy to think of
3239 if (IS_ADDRESS_OF_OP (parms))
3240 parms->left->lvalue = 1;
3242 if (IS_CAST_OP (parms) &&
3243 IS_PTR (parms->ftype) &&
3244 IS_ADDRESS_OF_OP (parms->right))
3245 parms->right->left->lvalue = 1;
3247 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3250 /* if register parm then make it a send */
3251 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3252 IFFUNC_ISBUILTIN(ftype))
3254 ic = newiCode (SEND, pval, NULL);
3255 ic->argreg = SPEC_ARGREG(parms->etype);
3256 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3261 /* now decide whether to push or assign */
3262 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3266 operand *top = operandFromSymbol (argVals->sym);
3267 /* clear useDef and other bitVectors */
3268 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3269 geniCodeAssign (top, pval, 1, 0);
3273 sym_link *p = operandType (pval);
3275 ic = newiCode (IPUSH, pval, NULL);
3277 /* update the stack adjustment */
3278 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3283 argVals=argVals->next;
3287 /*-----------------------------------------------------------------*/
3288 /* geniCodeCall - generates temp code for calling */
3289 /*-----------------------------------------------------------------*/
3291 geniCodeCall (operand * left, ast * parms,int lvl)
3295 sym_link *type, *etype;
3299 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3300 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3301 werror (E_FUNCTION_EXPECTED);
3302 return operandFromValue(valueFromLit(0));
3305 /* take care of parameters with side-effecting
3306 function calls in them, this is required to take care
3307 of overlaying function parameters */
3308 geniCodeSEParms (parms,lvl);
3310 ftype = operandType (left);
3311 if (IS_CODEPTR (ftype))
3312 ftype = ftype->next;
3314 /* first the parameters */
3315 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3317 /* now call : if symbol then pcall */
3318 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3319 ic = newiCode (PCALL, left, NULL);
3321 ic = newiCode (CALL, left, NULL);
3324 type = copyLinkChain (ftype->next);
3325 etype = getSpec (type);
3326 SPEC_EXTR (etype) = 0;
3327 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3331 /* stack adjustment after call */
3332 ic->parmBytes = stack;
3337 /*-----------------------------------------------------------------*/
3338 /* geniCodeReceive - generate intermediate code for "receive" */
3339 /*-----------------------------------------------------------------*/
3341 geniCodeReceive (value * args)
3343 /* for all arguments that are passed in registers */
3347 if (IS_REGPARM (args->etype))
3349 operand *opr = operandFromValue (args);
3351 symbol *sym = OP_SYMBOL (opr);
3354 /* we will use it after all optimizations
3355 and before liveRange calculation */
3356 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3359 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3360 options.stackAuto == 0 &&
3361 (!(options.model == MODEL_FLAT24)) )
3366 opl = newiTempOperand (args->type, 0);
3368 sym->reqv->key = sym->key;
3369 OP_SYMBOL (sym->reqv)->key = sym->key;
3370 OP_SYMBOL (sym->reqv)->isreqv = 1;
3371 OP_SYMBOL (sym->reqv)->islocal = 0;
3372 SPIL_LOC (sym->reqv) = sym;
3376 ic = newiCode (RECEIVE, NULL, NULL);
3377 ic->argreg = SPEC_ARGREG(args->etype);
3379 currFunc->recvSize = getSize (sym->type);
3382 IC_RESULT (ic) = opr;
3390 /*-----------------------------------------------------------------*/
3391 /* geniCodeFunctionBody - create the function body */
3392 /*-----------------------------------------------------------------*/
3394 geniCodeFunctionBody (ast * tree,int lvl)
3401 /* reset the auto generation */
3407 func = ast2iCode (tree->left,lvl+1);
3408 fetype = getSpec (operandType (func));
3410 savelineno = lineno;
3411 lineno = OP_SYMBOL (func)->lineDef;
3412 /* create an entry label */
3413 geniCodeLabel (entryLabel);
3414 lineno = savelineno;
3416 /* create a proc icode */
3417 ic = newiCode (FUNCTION, func, NULL);
3418 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3423 /* for all parameters that are passed
3424 on registers add a "receive" */
3425 geniCodeReceive (tree->values.args);
3427 /* generate code for the body */
3428 ast2iCode (tree->right,lvl+1);
3430 /* create a label for return */
3431 geniCodeLabel (returnLabel);
3433 /* now generate the end proc */
3434 ic = newiCode (ENDFUNCTION, func, NULL);
3440 /*-----------------------------------------------------------------*/
3441 /* geniCodeReturn - gen icode for 'return' statement */
3442 /*-----------------------------------------------------------------*/
3444 geniCodeReturn (operand * op)
3448 /* if the operand is present force an rvalue */
3450 op = geniCodeRValue (op, FALSE);
3452 ic = newiCode (RETURN, op, NULL);
3456 /*-----------------------------------------------------------------*/
3457 /* geniCodeIfx - generates code for extended if statement */
3458 /*-----------------------------------------------------------------*/
3460 geniCodeIfx (ast * tree,int lvl)
3463 operand *condition = ast2iCode (tree->left,lvl+1);
3466 /* if condition is null then exit */
3470 condition = geniCodeRValue (condition, FALSE);
3472 cetype = getSpec (operandType (condition));
3473 /* if the condition is a literal */
3474 if (IS_LITERAL (cetype))
3476 if (floatFromVal (condition->operand.valOperand))
3478 if (tree->trueLabel)
3479 geniCodeGoto (tree->trueLabel);
3485 if (tree->falseLabel)
3486 geniCodeGoto (tree->falseLabel);
3493 if (tree->trueLabel)
3495 ic = newiCodeCondition (condition,
3500 if (tree->falseLabel)
3501 geniCodeGoto (tree->falseLabel);
3505 ic = newiCodeCondition (condition,
3512 ast2iCode (tree->right,lvl+1);
3515 /*-----------------------------------------------------------------*/
3516 /* geniCodeJumpTable - tries to create a jump table for switch */
3517 /*-----------------------------------------------------------------*/
3519 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3521 int min, max, cnt = 1;
3528 int needRangeCheck = !optimize.noJTabBoundary
3529 || tree->values.switchVals.swDefault;
3530 sym_link *cetype = getSpec (operandType (cond));
3531 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3532 int sizeofMatchJump, sizeofJumpTable;
3535 if (!tree || !caseVals)
3538 /* the criteria for creating a jump table is */
3539 /* all integer numbers between the maximum & minimum must */
3540 /* be present , the maximum value should not exceed 255 */
3541 /* If not all integer numbers are present the algorithm */
3542 /* inserts jumps to the default label for the missing numbers */
3543 /* and decides later whether it is worth it */
3544 min = (int) floatFromVal (vch = caseVals);
3551 max = (int) floatFromVal (vch);
3553 /* Exit if the range is too large to handle with a jump table. */
3554 if (1 + max - min > port->jumptableCost.maxCount)
3557 switch (getSize (operandType (cond)))
3559 case 1: sizeIndex = 0; break;
3560 case 2: sizeIndex = 1; break;
3561 case 4: sizeIndex = 2; break;
3565 /* Compute the size cost of the range check and subtraction. */
3567 sizeofZeroMinCost = 0;
3571 if (!(min==0 && IS_UNSIGNED (cetype)))
3572 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3573 if (!IS_UNSIGNED (cetype))
3574 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3575 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3578 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3580 /* If the size cost of handling a non-zero minimum exceeds the */
3581 /* cost of extending the range down to zero, then it might be */
3582 /* better to extend the range to zero. */
3583 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3584 >= (min * port->jumptableCost.sizeofElement))
3586 /* Only extend the jump table if it would still be manageable. */
3587 if (1 + max <= port->jumptableCost.maxCount)
3590 if (IS_UNSIGNED (cetype))
3593 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3597 /* Compute the total size cost of a jump table. */
3598 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3599 + port->jumptableCost.sizeofDispatch
3600 + sizeofMinCost + sizeofMaxCost;
3602 /* Compute the total size cost of a match & jump sequence */
3603 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3605 /* If the size cost of the jump table is uneconomical then exit */
3606 if (sizeofMatchJump < sizeofJumpTable)
3609 /* The jump table is preferable. */
3611 /* First, a label for the default or missing cases. */
3612 if (tree->values.switchVals.swDefault)
3614 SNPRINTF (buffer, sizeof(buffer),
3616 tree->values.switchVals.swNum);
3620 SNPRINTF (buffer, sizeof(buffer),
3622 tree->values.switchVals.swNum);
3624 falseLabel = newiTempLabel (buffer);
3626 /* Build the list of labels for the jump table. */
3628 t = (int) floatFromVal (vch);
3629 for (i=min; i<=max; i++)
3633 /* Explicit case: make a new label for it. */
3634 SNPRINTF (buffer, sizeof(buffer),
3636 tree->values.switchVals.swNum,
3638 addSet (&labels, newiTempLabel (buffer));
3641 t = (int) floatFromVal (vch);
3645 /* Implicit case: use the default label. */
3646 addSet (&labels, falseLabel);
3650 /* If cond is volatile, it might change after the boundary */
3651 /* conditions are tested to an out of bounds value, causing */
3652 /* a jump to a location outside of the jump table. To avoid */
3653 /* this possibility, use a non-volatile copy of it instead. */
3654 if (IS_OP_VOLATILE (cond))
3659 newcond = newiTempOperand (operandType (cond), TRUE);
3660 newcond->isvolatile = 0;
3661 ic = newiCode ('=', NULL, cond);
3662 IC_RESULT (ic) = newcond;
3667 /* first we rule out the boundary conditions */
3668 /* if only optimization says so */
3671 sym_link *cetype = getSpec (operandType (cond));
3672 /* no need to check the lower bound if
3673 the condition is unsigned & minimum value is zero */
3674 if (!(min == 0 && IS_UNSIGNED (cetype)))
3676 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3677 ic = newiCodeCondition (boundary, falseLabel, NULL);
3681 /* now for upper bounds */
3682 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3683 ic = newiCodeCondition (boundary, falseLabel, NULL);
3687 /* if the min is not zero then we no make it zero */
3690 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3691 if (!IS_LITERAL(getSpec(operandType(cond))))
3692 setOperandType (cond, UCHARTYPE);
3695 /* now create the jumptable */
3696 ic = newiCode (JUMPTABLE, NULL, NULL);
3697 IC_JTCOND (ic) = cond;
3698 IC_JTLABELS (ic) = labels;
3703 /*-----------------------------------------------------------------*/
3704 /* geniCodeSwitch - changes a switch to a if statement */
3705 /*-----------------------------------------------------------------*/
3707 geniCodeSwitch (ast * tree,int lvl)
3710 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3711 value *caseVals = tree->values.switchVals.swVals;
3712 symbol *trueLabel, *falseLabel;
3714 /* If the condition is a literal, then just jump to the */
3715 /* appropriate case label. */
3716 if (IS_LITERAL(getSpec(operandType(cond))))
3718 int switchVal, caseVal;
3720 switchVal = (int) floatFromVal (cond->operand.valOperand);
3723 caseVal = (int) floatFromVal (caseVals);
3724 if (caseVal == switchVal)
3726 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3727 tree->values.switchVals.swNum, caseVal);
3728 trueLabel = newiTempLabel (buffer);
3729 geniCodeGoto (trueLabel);
3732 caseVals = caseVals->next;
3734 goto defaultOrBreak;
3737 /* if we can make this a jump table */
3738 if (geniCodeJumpTable (cond, caseVals, tree))
3739 goto jumpTable; /* no need for the comparison */
3741 /* for the cases defined do */
3745 operand *compare = geniCodeLogic (cond,
3746 operandFromValue (caseVals),
3749 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3750 tree->values.switchVals.swNum,
3751 (int) floatFromVal (caseVals));
3752 trueLabel = newiTempLabel (buffer);
3754 ic = newiCodeCondition (compare, trueLabel, NULL);
3756 caseVals = caseVals->next;
3761 /* if default is present then goto break else break */
3762 if (tree->values.switchVals.swDefault)
3764 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3768 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3771 falseLabel = newiTempLabel (buffer);
3772 geniCodeGoto (falseLabel);
3775 ast2iCode (tree->right,lvl+1);
3778 /*-----------------------------------------------------------------*/
3779 /* geniCodeInline - intermediate code for inline assembler */
3780 /*-----------------------------------------------------------------*/
3782 geniCodeInline (ast * tree)
3786 ic = newiCode (INLINEASM, NULL, NULL);
3787 IC_INLINE (ic) = tree->values.inlineasm;
3791 /*-----------------------------------------------------------------*/
3792 /* geniCodeArrayInit - intermediate code for array initializer */
3793 /*-----------------------------------------------------------------*/
3795 geniCodeArrayInit (ast * tree, operand *array)
3799 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3800 ic = newiCode (ARRAYINIT, array, NULL);
3801 IC_ARRAYILIST (ic) = tree->values.constlist;
3803 operand *left=newOperand(), *right=newOperand();
3804 left->type=right->type=SYMBOL;
3805 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3806 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3807 ic = newiCode (ARRAYINIT, left, right);
3812 /*-----------------------------------------------------------------*/
3813 /* geniCodeCritical - intermediate code for a critical statement */
3814 /*-----------------------------------------------------------------*/
3816 geniCodeCritical (ast *tree, int lvl)
3821 /* If op is NULL, the original interrupt state will saved on */
3822 /* the stack. Otherwise, it will be saved in op. */
3824 /* Generate a save of the current interrupt state & disabled */
3825 ic = newiCode (CRITICAL, NULL, NULL);
3826 IC_RESULT (ic) = op;
3829 /* Generate the critical code sequence */
3830 if (tree->left && tree->left->type == EX_VALUE)
3831 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3833 ast2iCode (tree->left,lvl+1);
3835 /* Generate a restore of the original interrupt state */
3836 ic = newiCode (ENDCRITICAL, NULL, op);
3840 /*-----------------------------------------------------------------*/
3841 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3842 /* particular case. Ie : assigning or dereferencing array or ptr */
3843 /*-----------------------------------------------------------------*/
3844 set * lvaluereqSet = NULL;
3845 typedef struct lvalItem
3852 /*-----------------------------------------------------------------*/
3853 /* addLvaluereq - add a flag for lvalreq for current ast level */
3854 /*-----------------------------------------------------------------*/
3855 void addLvaluereq(int lvl)
3857 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3860 addSetHead(&lvaluereqSet,lpItem);
3863 /*-----------------------------------------------------------------*/
3864 /* delLvaluereq - del a flag for lvalreq for current ast level */
3865 /*-----------------------------------------------------------------*/
3869 lpItem = getSet(&lvaluereqSet);
3870 if(lpItem) Safe_free(lpItem);
3872 /*-----------------------------------------------------------------*/
3873 /* clearLvaluereq - clear lvalreq flag */
3874 /*-----------------------------------------------------------------*/
3875 void clearLvaluereq()
3878 lpItem = peekSet(lvaluereqSet);
3879 if(lpItem) lpItem->req = 0;
3881 /*-----------------------------------------------------------------*/
3882 /* getLvaluereq - get the last lvalreq level */
3883 /*-----------------------------------------------------------------*/
3884 int getLvaluereqLvl()
3887 lpItem = peekSet(lvaluereqSet);
3888 if(lpItem) return lpItem->lvl;
3891 /*-----------------------------------------------------------------*/
3892 /* isLvaluereq - is lvalreq valid for this level ? */
3893 /*-----------------------------------------------------------------*/
3894 int isLvaluereq(int lvl)
3897 lpItem = peekSet(lvaluereqSet);
3898 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3902 /*-----------------------------------------------------------------*/
3903 /* ast2iCode - creates an icodeList from an ast */
3904 /*-----------------------------------------------------------------*/
3906 ast2iCode (ast * tree,int lvl)
3908 operand *left = NULL;
3909 operand *right = NULL;
3913 /* set the global variables for filename & line number */
3915 filename = tree->filename;
3917 lineno = tree->lineno;
3919 block = tree->block;
3921 scopeLevel = tree->level;
3923 seqPoint = tree->seqPoint;
3925 if (tree->type == EX_VALUE)
3926 return operandFromValue (tree->opval.val);
3928 if (tree->type == EX_LINK)
3929 return operandFromLink (tree->opval.lnk);
3931 /* if we find a nullop */
3932 if (tree->type == EX_OP &&
3933 (tree->opval.op == NULLOP ||
3934 tree->opval.op == BLOCK))
3936 if (tree->left && tree->left->type == EX_VALUE)
3937 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3939 ast2iCode (tree->left,lvl+1);
3940 if (tree->right && tree->right->type == EX_VALUE)
3941 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3943 ast2iCode (tree->right,lvl+1);
3947 /* special cases for not evaluating */
3948 if (tree->opval.op != ':' &&
3949 tree->opval.op != '?' &&
3950 tree->opval.op != CALL &&
3951 tree->opval.op != IFX &&
3952 tree->opval.op != AND_OP &&
3953 tree->opval.op != OR_OP &&
3954 tree->opval.op != LABEL &&
3955 tree->opval.op != GOTO &&
3956 tree->opval.op != SWITCH &&
3957 tree->opval.op != FUNCTION &&
3958 tree->opval.op != INLINEASM &&
3959 tree->opval.op != CRITICAL)
3962 if (IS_ASSIGN_OP (tree->opval.op) ||
3963 IS_DEREF_OP (tree) ||
3964 (tree->opval.op == '&' && !tree->right) ||
3965 tree->opval.op == PTR_OP)
3968 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3969 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3972 left = operandFromAst (tree->left,lvl);
3974 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3975 left = geniCodeRValue (left, TRUE);
3979 left = operandFromAst (tree->left,lvl);
3981 if (tree->opval.op == INC_OP ||
3982 tree->opval.op == DEC_OP)
3985 right = operandFromAst (tree->right,lvl);
3990 right = operandFromAst (tree->right,lvl);
3994 /* now depending on the type of operand */
3995 /* this will be a biggy */
3996 switch (tree->opval.op)
3999 case '[': /* array operation */
4001 //sym_link *ltype = operandType (left);
4002 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4003 left = geniCodeRValue (left, FALSE);
4004 right = geniCodeRValue (right, TRUE);
4007 return geniCodeArray (left, right,lvl);
4009 case '.': /* structure dereference */
4010 if (IS_PTR (operandType (left)))
4011 left = geniCodeRValue (left, TRUE);
4013 left = geniCodeRValue (left, FALSE);
4015 return geniCodeStruct (left, right, tree->lvalue);
4017 case PTR_OP: /* structure pointer dereference */
4020 pType = operandType (left);
4021 left = geniCodeRValue (left, TRUE);
4023 setOClass (pType, getSpec (operandType (left)));
4026 return geniCodeStruct (left, right, tree->lvalue);
4028 case INC_OP: /* increment operator */
4030 return geniCodePostInc (left);
4032 return geniCodePreInc (right, tree->lvalue);
4034 case DEC_OP: /* decrement operator */
4036 return geniCodePostDec (left);
4038 return geniCodePreDec (right, tree->lvalue);
4040 case '&': /* bitwise and or address of operator */
4042 { /* this is a bitwise operator */
4043 left = geniCodeRValue (left, FALSE);
4044 right = geniCodeRValue (right, FALSE);
4045 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4048 return geniCodeAddressOf (left);
4050 case '|': /* bitwise or & xor */
4052 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4053 geniCodeRValue (right, FALSE),
4058 return geniCodeDivision (geniCodeRValue (left, FALSE),
4059 geniCodeRValue (right, FALSE),
4060 getResultTypeFromType (tree->ftype));
4063 return geniCodeModulus (geniCodeRValue (left, FALSE),
4064 geniCodeRValue (right, FALSE),
4065 getResultTypeFromType (tree->ftype));
4068 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4069 geniCodeRValue (right, FALSE),
4070 getResultTypeFromType (tree->ftype));
4072 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4076 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4077 geniCodeRValue (right, FALSE),
4078 getResultTypeFromType (tree->ftype));
4080 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4084 return geniCodeAdd (geniCodeRValue (left, FALSE),
4085 geniCodeRValue (right, FALSE),
4086 getResultTypeFromType (tree->ftype),
4089 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4092 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4093 geniCodeRValue (right, FALSE),
4094 getResultTypeFromType (tree->ftype));
4097 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4098 geniCodeRValue (right, FALSE));
4100 #if 0 // this indeed needs a second thought
4104 // let's keep this simple: get the rvalue we need
4105 op=geniCodeRValue (right, FALSE);
4106 // now cast it to whatever we want
4107 op=geniCodeCast (operandType(left), op, FALSE);
4108 // if this is going to be used as an lvalue, make it so
4114 #else // bug #604575, is it a bug ????
4115 return geniCodeCast (operandType (left),
4116 geniCodeRValue (right, FALSE), FALSE);
4123 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4128 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4129 setOperandType (op, UCHARTYPE);
4134 return geniCodeLogicAndOr (tree, lvl);
4141 /* different compilers (even different gccs) evaluate
4142 the two calls in a different order. to get the same
4143 result on all machines we've to specify a clear sequence.
4144 return geniCodeLogic (geniCodeRValue (left, FALSE),
4145 geniCodeRValue (right, FALSE),
4149 operand *leftOp, *rightOp;
4151 leftOp = geniCodeRValue (left , FALSE);
4152 rightOp = geniCodeRValue (right, FALSE);
4154 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4157 return geniCodeConditional (tree,lvl);
4160 return operandFromLit (getSize (tree->right->ftype));
4164 sym_link *rtype = operandType (right);
4165 sym_link *ltype = operandType (left);
4166 if (IS_PTR (rtype) && IS_ITEMP (right)
4167 && right->isaddr && compareType (rtype->next, ltype) == 1)
4168 right = geniCodeRValue (right, TRUE);
4170 right = geniCodeRValue (right, FALSE);
4172 geniCodeAssign (left, right, 0, 1);
4177 geniCodeAssign (left,
4178 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4180 geniCodeRValue (right, FALSE),
4181 getResultTypeFromType (tree->ftype)),
4186 geniCodeAssign (left,
4187 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4189 geniCodeRValue (right, FALSE),
4190 getResultTypeFromType (tree->ftype)),
4194 geniCodeAssign (left,
4195 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4197 geniCodeRValue (right, FALSE),
4198 getResultTypeFromType (tree->ftype)),
4202 sym_link *rtype = operandType (right);
4203 sym_link *ltype = operandType (left);
4204 if (IS_PTR (rtype) && IS_ITEMP (right)
4205 && right->isaddr && compareType (rtype->next, ltype) == 1)
4206 right = geniCodeRValue (right, TRUE);
4208 right = geniCodeRValue (right, FALSE);
4211 return geniCodeAssign (left,
4212 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4215 getResultTypeFromType (tree->ftype),
4221 sym_link *rtype = operandType (right);
4222 sym_link *ltype = operandType (left);
4223 if (IS_PTR (rtype) && IS_ITEMP (right)
4224 && right->isaddr && compareType (rtype->next, ltype) == 1)
4226 right = geniCodeRValue (right, TRUE);
4230 right = geniCodeRValue (right, FALSE);
4233 geniCodeAssign (left,
4234 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4237 getResultTypeFromType (tree->ftype)),
4242 geniCodeAssign (left,
4243 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4245 geniCodeRValue (right, FALSE),
4246 getResultTypeFromType (tree->ftype)),
4250 geniCodeAssign (left,
4251 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4253 geniCodeRValue (right, FALSE)), 0, 1);
4256 geniCodeAssign (left,
4257 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4259 geniCodeRValue (right, FALSE),
4261 operandType (left)), 0, 1);
4264 geniCodeAssign (left,
4265 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4267 geniCodeRValue (right, FALSE),
4269 operandType (left)), 0, 1);
4272 geniCodeAssign (left,
4273 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4275 geniCodeRValue (right, FALSE),
4277 operandType (left)), 0, 1);
4279 return geniCodeRValue (right, FALSE);
4282 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4285 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4286 return ast2iCode (tree->right,lvl+1);
4289 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4290 return ast2iCode (tree->right,lvl+1);
4293 geniCodeFunctionBody (tree,lvl);
4297 geniCodeReturn (right);
4301 geniCodeIfx (tree,lvl);
4305 geniCodeSwitch (tree,lvl);
4309 geniCodeInline (tree);
4313 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4317 geniCodeCritical (tree, lvl);
4323 /*-----------------------------------------------------------------*/
4324 /* reverseICChain - gets from the list and creates a linkedlist */
4325 /*-----------------------------------------------------------------*/
4332 while ((loop = getSet (&iCodeChain)))
4344 /*-----------------------------------------------------------------*/
4345 /* iCodeFromAst - given an ast will convert it to iCode */
4346 /*-----------------------------------------------------------------*/
4348 iCodeFromAst (ast * tree)
4350 returnLabel = newiTempLabel ("_return");
4351 entryLabel = newiTempLabel ("_entry");
4353 return reverseiCChain ();
4356 static const char *opTypeToStr(OPTYPE op)
4360 case SYMBOL: return "symbol";
4361 case VALUE: return "value";
4362 case TYPE: return "type";
4364 return "undefined type";
4368 operand *validateOpType(operand *op,
4375 if (op && op->type == type)
4380 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4381 " expected %s, got %s\n",
4382 macro, args, file, line,
4383 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4385 return op; // never reached, makes compiler happy.