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}
126 /*-----------------------------------------------------------------*/
127 /* checkConstantRange: check a constant against the type */
128 /*-----------------------------------------------------------------*/
131 /* pedantic=0: allmost anything is allowed as long as the absolute
132 value is within the bit range of the type, and -1 is treated as
133 0xf..f for unsigned types (e.g. in assign)
134 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
135 pedantic>1: "char c=200" is not allowed (evaluates to -56)
138 void checkConstantRange(sym_link *ltype, value *val, char *msg,
145 max = pow ((double)2.0, (double)bitsForType(ltype));
147 if (IS_LONG(val->type)) {
148 if (IS_UNSIGNED(val->type)) {
149 v=SPEC_CVAL(val->type).v_ulong;
151 v=SPEC_CVAL(val->type).v_long;
154 if (IS_UNSIGNED(val->type)) {
155 v=SPEC_CVAL(val->type).v_uint;
157 v=SPEC_CVAL(val->type).v_int;
163 // this could be a good idea
164 if (options.pedantic)
168 if (IS_FLOAT(ltype)) {
173 if (!IS_UNSIGNED(val->type) && v<0) {
175 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
181 // if very pedantic: "char c=200" is not allowed
182 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
183 max = max/2 + negative;
190 #if 0 // temporary disabled, leaving the warning as a reminder
192 SNPRINTF (message, sizeof(message), "for %s %s in %s",
193 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
194 nounName(ltype), msg);
195 werror (W_CONST_RANGE, message);
203 /*-----------------------------------------------------------------*/
204 /* operandName - returns the name of the operand */
205 /*-----------------------------------------------------------------*/
207 printOperand (operand * op, FILE * file)
224 opetype = getSpec (operandType (op));
225 if (IS_FLOAT (opetype))
226 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
228 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
229 printTypeChain (operandType (op), file);
236 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
237 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
239 OP_LIVEFROM (op), OP_LIVETO (op),
240 OP_SYMBOL (op)->stack,
241 op->isaddr, OP_SYMBOL (op)->isreqv,
242 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
243 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
247 printTypeChain (operandType (op), file);
248 if (SPIL_LOC (op) && IS_ITEMP (op))
249 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
254 /* if assigned to registers */
255 if (OP_SYMBOL (op)->nRegs)
257 if (OP_SYMBOL (op)->isspilt)
259 if (!OP_SYMBOL (op)->remat)
260 if (OP_SYMBOL (op)->usl.spillLoc)
261 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
262 OP_SYMBOL (op)->usl.spillLoc->rname :
263 OP_SYMBOL (op)->usl.spillLoc->name));
265 fprintf (file, "[err]");
267 fprintf (file, "[remat]");
273 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
274 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
279 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
280 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
281 /* if assigned to registers */
282 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
286 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
287 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
288 OP_SYMBOL (op)->regs[i]->name :
297 printTypeChain (op->operand.typeOperand, file);
303 fprintf (file, "\n");
308 /*-----------------------------------------------------------------*/
309 /* print functions */
310 /*-----------------------------------------------------------------*/
311 PRINTFUNC (picGetValueAtAddr)
314 printOperand (IC_RESULT (ic), of);
317 printOperand (IC_LEFT (ic), of);
323 PRINTFUNC (picSetValueAtAddr)
327 printOperand (IC_LEFT (ic), of);
328 fprintf (of, "] = ");
329 printOperand (IC_RIGHT (ic), of);
333 PRINTFUNC (picAddrOf)
336 printOperand (IC_RESULT (ic), of);
337 if (IS_ITEMP (IC_LEFT (ic)))
340 fprintf (of, " = &[");
341 printOperand (IC_LEFT (ic), of);
344 if (IS_ITEMP (IC_LEFT (ic)))
345 fprintf (of, " offsetAdd ");
348 printOperand (IC_RIGHT (ic), of);
350 if (IS_ITEMP (IC_LEFT (ic)))
356 PRINTFUNC (picJumpTable)
361 fprintf (of, "%s\t", s);
362 printOperand (IC_JTCOND (ic), of);
364 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
365 sym = setNextItem (IC_JTLABELS (ic)))
366 fprintf (of, "\t\t\t%s\n", sym->name);
369 PRINTFUNC (picGeneric)
372 printOperand (IC_RESULT (ic), of);
374 printOperand (IC_LEFT (ic), of);
375 fprintf (of, " %s ", s);
376 printOperand (IC_RIGHT (ic), of);
380 PRINTFUNC (picGenericOne)
385 printOperand (IC_RESULT (ic), of);
391 fprintf (of, "%s ", s);
392 printOperand (IC_LEFT (ic), of);
395 if (!IC_RESULT (ic) && !IC_LEFT (ic))
398 if (ic->op == SEND || ic->op == RECEIVE) {
399 fprintf(of,"{argreg = %d}",ic->argreg);
407 printOperand (IC_RESULT (ic), of);
409 printOperand (IC_LEFT (ic), of);
410 printOperand (IC_RIGHT (ic), of);
415 PRINTFUNC (picAssign)
419 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
422 printOperand (IC_RESULT (ic), of);
424 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
427 fprintf (of, " %s ", s);
428 printOperand (IC_RIGHT (ic), of);
435 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
441 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
448 printOperand (IC_COND (ic), of);
451 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
454 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
456 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
460 PRINTFUNC (picInline)
462 fprintf (of, "%s", IC_INLINE (ic));
465 PRINTFUNC (picReceive)
467 printOperand (IC_RESULT (ic), of);
468 fprintf (of, " = %s ", s);
469 printOperand (IC_LEFT (ic), of);
473 PRINTFUNC (picDummyRead)
476 fprintf (of, "%s ", s);
477 printOperand (IC_RIGHT (ic), of);
481 PRINTFUNC (picCritical)
485 printOperand (IC_RESULT (ic), of);
487 fprintf (of, "(stack)");
488 fprintf (of, " = %s ", s);
492 PRINTFUNC (picEndCritical)
495 fprintf (of, "%s = ", s);
497 printOperand (IC_RIGHT (ic), of);
499 fprintf (of, "(stack)");
503 /*-----------------------------------------------------------------*/
504 /* piCode - prints one iCode */
505 /*-----------------------------------------------------------------*/
507 piCode (void *item, FILE * of)
515 icTab = getTableEntry (ic->op);
516 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
517 ic->filename, ic->lineno,
518 ic->seq, ic->key, ic->depth, ic->supportRtn);
519 icTab->iCodePrint (of, ic, icTab->printName);
525 printiCChain(ic,stdout);
527 /*-----------------------------------------------------------------*/
528 /* printiCChain - prints intermediate code for humans */
529 /*-----------------------------------------------------------------*/
531 printiCChain (iCode * icChain, FILE * of)
538 for (loop = icChain; loop; loop = loop->next)
540 if ((icTab = getTableEntry (loop->op)))
542 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
543 loop->filename, loop->lineno,
544 loop->seq, loop->key, loop->depth, loop->supportRtn);
546 icTab->iCodePrint (of, loop, icTab->printName);
552 /*-----------------------------------------------------------------*/
553 /* newOperand - allocate, init & return a new iCode */
554 /*-----------------------------------------------------------------*/
560 op = Safe_alloc ( sizeof (operand));
566 /*-----------------------------------------------------------------*/
567 /* newiCode - create and return a new iCode entry initialised */
568 /*-----------------------------------------------------------------*/
570 newiCode (int op, operand * left, operand * right)
574 ic = Safe_alloc ( sizeof (iCode));
576 ic->seqPoint = seqPoint;
578 ic->filename = filename;
580 ic->level = scopeLevel;
582 ic->key = iCodeKey++;
584 IC_RIGHT (ic) = right;
589 /*-----------------------------------------------------------------*/
590 /* newiCode for conditional statements */
591 /*-----------------------------------------------------------------*/
593 newiCodeCondition (operand * condition,
599 if (IS_VOID(operandType(condition))) {
600 werror(E_VOID_VALUE_USED);
603 ic = newiCode (IFX, NULL, NULL);
604 IC_COND (ic) = condition;
605 IC_TRUE (ic) = trueLabel;
606 IC_FALSE (ic) = falseLabel;
610 /*-----------------------------------------------------------------*/
611 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
612 /*-----------------------------------------------------------------*/
614 newiCodeLabelGoto (int op, symbol * label)
618 ic = newiCode (op, NULL, NULL);
622 IC_RIGHT (ic) = NULL;
623 IC_RESULT (ic) = NULL;
627 /*-----------------------------------------------------------------*/
628 /* newiTemp - allocate & return a newItemp Variable */
629 /*-----------------------------------------------------------------*/
637 SNPRINTF (buffer, sizeof(buffer), "%s", s);
641 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
644 itmp = newSymbol (buffer, 1);
645 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
651 /*-----------------------------------------------------------------*/
652 /* newiTempLabel - creates a temp variable label */
653 /*-----------------------------------------------------------------*/
655 newiTempLabel (char *s)
659 /* check if this alredy exists */
660 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
665 itmplbl = newSymbol (s, 1);
669 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
670 itmplbl = newSymbol (buffer, 1);
675 itmplbl->key = labelKey++;
676 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
680 /*-----------------------------------------------------------------*/
681 /* newiTempPreheaderLabel - creates a new preheader label */
682 /*-----------------------------------------------------------------*/
684 newiTempPreheaderLabel ()
688 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
689 itmplbl = newSymbol (buffer, 1);
693 itmplbl->key = labelKey++;
694 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
699 /*-----------------------------------------------------------------*/
700 /* initiCode - initialises some iCode related stuff */
701 /*-----------------------------------------------------------------*/
708 /*-----------------------------------------------------------------*/
709 /* copyiCode - make a copy of the iCode given */
710 /*-----------------------------------------------------------------*/
712 copyiCode (iCode * ic)
714 iCode *nic = newiCode (ic->op, NULL, NULL);
716 nic->lineno = ic->lineno;
717 nic->filename = ic->filename;
718 nic->block = ic->block;
719 nic->level = ic->level;
720 nic->parmBytes = ic->parmBytes;
722 /* deal with the special cases first */
726 IC_COND (nic) = operandFromOperand (IC_COND (ic));
727 IC_TRUE (nic) = IC_TRUE (ic);
728 IC_FALSE (nic) = IC_FALSE (ic);
732 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
733 IC_JTLABELS (nic) = IC_JTLABELS (ic);
738 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
739 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
743 IC_INLINE (nic) = IC_INLINE (ic);
747 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
751 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
752 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
753 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
759 /*-----------------------------------------------------------------*/
760 /* getTableEntry - gets the table entry for the given operator */
761 /*-----------------------------------------------------------------*/
763 getTableEntry (int oper)
767 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
768 if (oper == codeTable[i].icode)
769 return &codeTable[i];
774 /*-----------------------------------------------------------------*/
775 /* newiTempOperand - new intermediate temp operand */
776 /*-----------------------------------------------------------------*/
778 newiTempOperand (sym_link * type, char throwType)
781 operand *op = newOperand ();
785 itmp = newiTemp (NULL);
787 etype = getSpec (type);
789 if (IS_LITERAL (etype))
792 /* copy the type information */
794 itmp->etype = getSpec (itmp->type = (throwType ? type :
795 copyLinkChain (type)));
796 if (IS_LITERAL (itmp->etype))
798 SPEC_SCLS (itmp->etype) = S_REGISTER;
799 SPEC_OCLS (itmp->etype) = reg;
802 op->operand.symOperand = itmp;
803 op->key = itmp->key = ++operandKey;
807 /*-----------------------------------------------------------------*/
808 /* operandType - returns the type chain for an operand */
809 /*-----------------------------------------------------------------*/
811 operandType (operand * op)
813 /* depending on type of operand */
818 return op->operand.valOperand->type;
821 return op->operand.symOperand->type;
824 return op->operand.typeOperand;
826 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
827 " operand type not known ");
828 assert (0); /* should never come here */
829 /* Just to keep the compiler happy */
830 return (sym_link *) 0;
834 /*-----------------------------------------------------------------*/
835 /* isParamterToCall - will return 1 if op is a parameter to args */
836 /*-----------------------------------------------------------------*/
838 isParameterToCall (value * args, operand * op)
842 wassert (IS_SYMOP(op));
847 isSymbolEqual (op->operand.symOperand, tval->sym))
854 /*-----------------------------------------------------------------*/
855 /* isOperandGlobal - return 1 if operand is a global variable */
856 /*-----------------------------------------------------------------*/
858 isOperandGlobal (operand * op)
867 (op->operand.symOperand->level == 0 ||
868 IS_STATIC (op->operand.symOperand->etype) ||
869 IS_EXTERN (op->operand.symOperand->etype))
876 /*-----------------------------------------------------------------*/
877 /* isOperandVolatile - return 1 if the operand is volatile */
878 /*-----------------------------------------------------------------*/
880 isOperandVolatile (operand * op, bool chkTemp)
885 if (IS_ITEMP (op) && !chkTemp)
888 opetype = getSpec (optype = operandType (op));
890 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
893 if (IS_VOLATILE (opetype))
898 /*-----------------------------------------------------------------*/
899 /* isOperandLiteral - returns 1 if an operand contains a literal */
900 /*-----------------------------------------------------------------*/
902 isOperandLiteral (operand * op)
909 opetype = getSpec (operandType (op));
911 if (IS_LITERAL (opetype))
917 /*-----------------------------------------------------------------*/
918 /* isOperandInFarSpace - will return true if operand is in farSpace */
919 /*-----------------------------------------------------------------*/
921 isOperandInFarSpace (operand * op)
931 if (!IS_TRUE_SYMOP (op))
934 etype = SPIL_LOC (op)->etype;
940 etype = getSpec (operandType (op));
942 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
945 /*------------------------------------------------------------------*/
946 /* isOperandInDirSpace - will return true if operand is in dirSpace */
947 /*------------------------------------------------------------------*/
949 isOperandInDirSpace (operand * op)
959 if (!IS_TRUE_SYMOP (op))
962 etype = SPIL_LOC (op)->etype;
968 etype = getSpec (operandType (op));
970 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
973 /*--------------------------------------------------------------------*/
974 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
975 /*--------------------------------------------------------------------*/
977 isOperandInCodeSpace (operand * op)
987 etype = getSpec (operandType (op));
989 if (!IS_TRUE_SYMOP (op))
992 etype = SPIL_LOC (op)->etype;
998 etype = getSpec (operandType (op));
1000 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1003 /*-----------------------------------------------------------------*/
1004 /* isOperandOnStack - will return true if operand is on stack */
1005 /*-----------------------------------------------------------------*/
1007 isOperandOnStack (operand * op)
1017 etype = getSpec (operandType (op));
1018 if (IN_STACK (etype) ||
1019 OP_SYMBOL(op)->onStack ||
1020 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1026 /*-----------------------------------------------------------------*/
1027 /* isOclsExpensive - will return true if accesses to an output */
1028 /* storage class are expensive */
1029 /*-----------------------------------------------------------------*/
1031 isOclsExpensive (struct memmap *oclass)
1033 if (port->oclsExpense)
1034 return port->oclsExpense (oclass) > 0;
1036 /* In the absence of port specific guidance, assume only */
1037 /* farspace is expensive. */
1038 return IN_FARSPACE (oclass);
1041 /*-----------------------------------------------------------------*/
1042 /* operandLitValue - literal value of an operand */
1043 /*-----------------------------------------------------------------*/
1045 operandLitValue (operand * op)
1047 assert (isOperandLiteral (op));
1049 return floatFromVal (op->operand.valOperand);
1052 /*-----------------------------------------------------------------*/
1053 /* getBuiltInParms - returns parameters to a builtin functions */
1054 /*-----------------------------------------------------------------*/
1055 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1060 /* builtin functions uses only SEND for parameters */
1061 while (ic->op != CALL) {
1062 assert(ic->op == SEND && ic->builtinSEND);
1063 ic->generated = 1; /* mark the icode as generated */
1064 parms[*pcount] = IC_LEFT(ic);
1070 /* make sure this is a builtin function call */
1071 assert(IS_SYMOP(IC_LEFT(ic)));
1072 ftype = operandType(IC_LEFT(ic));
1073 assert(IFFUNC_ISBUILTIN(ftype));
1077 /*-----------------------------------------------------------------*/
1078 /* operandOperation - performs operations on operands */
1079 /*-----------------------------------------------------------------*/
1081 operandOperation (operand * left, operand * right,
1082 int op, sym_link * type)
1084 sym_link *let , *ret=NULL;
1085 operand *retval = (operand *) 0;
1087 assert (isOperandLiteral (left));
1088 let = getSpec(operandType(left));
1090 assert (isOperandLiteral (right));
1091 ret = getSpec(operandType(right));
1097 retval = operandFromValue (valCastLiteral (type,
1098 operandLitValue (left) +
1099 operandLitValue (right)));
1102 retval = operandFromValue (valCastLiteral (type,
1103 operandLitValue (left) -
1104 operandLitValue (right)));
1108 retval = operandFromValue (valCastLiteral (type,
1109 operandLitValue (left) *
1110 operandLitValue (right)));
1111 This could be all we've to do, but with gcc we've to take care about
1112 overflows. Two examples:
1113 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1114 significant bits are lost (52 in fraction, 63 bits would be
1115 necessary to keep full precision).
1116 If the resulting double value is greater than ULONG_MAX (resp.
1117 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1120 /* if it is not a specifier then we can assume that */
1121 /* it will be an unsigned long */
1122 if (IS_INT (type) ||
1125 /* long is handled here, because it can overflow with double */
1126 if (IS_LONG (type) ||
1128 /* signed and unsigned mul are the same, as long as the precision
1129 of the result isn't bigger than the precision of the operands. */
1130 retval = operandFromValue (valCastLiteral (type,
1131 (TYPE_UDWORD) operandLitValue (left) *
1132 (TYPE_UDWORD) operandLitValue (right)));
1133 else if (IS_UNSIGNED (type)) /* unsigned int */
1135 /* unsigned int is handled here in order to detect overflow */
1136 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1137 (TYPE_UWORD) operandLitValue (right);
1139 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1140 if (ul != (TYPE_UWORD) ul)
1143 else /* signed int */
1145 /* signed int is handled here in order to detect overflow */
1146 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1147 (TYPE_WORD) operandLitValue (right);
1149 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1150 if (l != (TYPE_WORD) l)
1155 /* all others go here: */
1156 retval = operandFromValue (valCastLiteral (type,
1157 operandLitValue (left) *
1158 operandLitValue (right)));
1161 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1163 werror (E_DIVIDE_BY_ZERO);
1169 if (IS_UNSIGNED (type))
1171 SPEC_USIGN (let) = 1;
1172 SPEC_USIGN (ret) = 1;
1173 retval = operandFromValue (valCastLiteral (type,
1174 (TYPE_UDWORD) operandLitValue (left) /
1175 (TYPE_UDWORD) operandLitValue (right)));
1179 retval = operandFromValue (valCastLiteral (type,
1180 operandLitValue (left) /
1181 operandLitValue (right)));
1186 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1188 werror (E_DIVIDE_BY_ZERO);
1193 if (IS_UNSIGNED (type))
1194 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1195 (TYPE_UDWORD) operandLitValue (right));
1197 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1198 (TYPE_DWORD) operandLitValue (right));
1202 /* The number of left shifts is always unsigned. Signed doesn't make
1203 sense here. Shifting by a negative number is impossible. */
1204 retval = operandFromValue (valCastLiteral (type,
1205 ((TYPE_UDWORD) operandLitValue (left) <<
1206 (TYPE_UDWORD) operandLitValue (right))));
1209 /* The number of right shifts is always unsigned. Signed doesn't make
1210 sense here. Shifting by a negative number is impossible. */
1211 if (IS_UNSIGNED(let))
1212 /* unsigned: logic shift right */
1213 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1214 (TYPE_UDWORD) operandLitValue (right));
1216 /* signed: arithmetic shift right */
1217 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1218 (TYPE_UDWORD) operandLitValue (right));
1221 if (IS_FLOAT (let) ||
1224 retval = operandFromLit (operandLitValue (left) ==
1225 operandLitValue (right));
1229 /* this op doesn't care about signedness */
1232 l = (TYPE_UDWORD) operandLitValue (left);
1233 r = (TYPE_UDWORD) operandLitValue (right);
1234 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1235 neccessary to strip them to 16 bit.
1236 Literals are reduced to their cheapest type, therefore left and
1237 right might have different types. It's neccessary to find a
1238 common type: int (used for char too) or long */
1239 if (!IS_LONG (let) &&
1245 retval = operandFromLit (l == r);
1249 retval = operandFromLit (operandLitValue (left) <
1250 operandLitValue (right));
1253 retval = operandFromLit (operandLitValue (left) <=
1254 operandLitValue (right));
1257 retval = operandFromLit (operandLitValue (left) !=
1258 operandLitValue (right));
1261 retval = operandFromLit (operandLitValue (left) >
1262 operandLitValue (right));
1265 retval = operandFromLit (operandLitValue (left) >=
1266 operandLitValue (right));
1269 retval = operandFromValue (valCastLiteral (type,
1270 (TYPE_UDWORD)operandLitValue(left) &
1271 (TYPE_UDWORD)operandLitValue(right)));
1274 retval = operandFromValue (valCastLiteral (type,
1275 (TYPE_UDWORD)operandLitValue(left) |
1276 (TYPE_UDWORD)operandLitValue(right)));
1279 retval = operandFromValue (valCastLiteral (type,
1280 (TYPE_UDWORD)operandLitValue(left) ^
1281 (TYPE_UDWORD)operandLitValue(right)));
1284 retval = operandFromLit (operandLitValue (left) &&
1285 operandLitValue (right));
1288 retval = operandFromLit (operandLitValue (left) ||
1289 operandLitValue (right));
1293 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1295 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1301 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1303 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1309 retval = operandFromValue (valCastLiteral (type,
1310 -1 * operandLitValue (left)));
1314 retval = operandFromValue (valCastLiteral (type,
1316 operandLitValue (left))));
1320 retval = operandFromLit (!operandLitValue (left));
1324 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1325 " operandOperation invalid operator ");
1333 /*-----------------------------------------------------------------*/
1334 /* isOperandEqual - compares two operand & return 1 if they r = */
1335 /*-----------------------------------------------------------------*/
1337 isOperandEqual (operand * left, operand * right)
1339 /* if the pointers are equal then they are equal */
1343 /* if either of them null then false */
1344 if (!left || !right)
1347 if (left->type != right->type)
1350 if (IS_SYMOP (left) && IS_SYMOP (right))
1351 return left->key == right->key;
1353 /* if types are the same */
1357 return isSymbolEqual (left->operand.symOperand,
1358 right->operand.symOperand);
1360 return (floatFromVal (left->operand.valOperand) ==
1361 floatFromVal (right->operand.valOperand));
1363 if (compareType (left->operand.typeOperand,
1364 right->operand.typeOperand) == 1)
1371 /*-------------------------------------------------------------------*/
1372 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1373 /*-------------------------------------------------------------------*/
1375 isiCodeEqual (iCode * left, iCode * right)
1377 /* if the same pointer */
1381 /* if either of them null */
1382 if (!left || !right)
1385 /* if operand are the same */
1386 if (left->op == right->op)
1389 /* compare all the elements depending on type */
1390 if (left->op != IFX)
1392 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1394 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1400 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1402 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1404 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1413 /*-----------------------------------------------------------------*/
1414 /* newiTempFromOp - create a temp Operand with same attributes */
1415 /*-----------------------------------------------------------------*/
1417 newiTempFromOp (operand * op)
1427 nop = newiTempOperand (operandType (op), TRUE);
1428 nop->isaddr = op->isaddr;
1429 nop->isvolatile = op->isvolatile;
1430 nop->isGlobal = op->isGlobal;
1431 nop->isLiteral = op->isLiteral;
1432 nop->usesDefs = op->usesDefs;
1433 nop->isParm = op->isParm;
1437 /*-----------------------------------------------------------------*/
1438 /* operand from operand - creates an operand holder for the type */
1439 /*-----------------------------------------------------------------*/
1441 operandFromOperand (operand * op)
1447 nop = newOperand ();
1448 nop->type = op->type;
1449 nop->isaddr = op->isaddr;
1451 nop->isvolatile = op->isvolatile;
1452 nop->isGlobal = op->isGlobal;
1453 nop->isLiteral = op->isLiteral;
1454 nop->usesDefs = op->usesDefs;
1455 nop->isParm = op->isParm;
1460 nop->operand.symOperand = op->operand.symOperand;
1463 nop->operand.valOperand = op->operand.valOperand;
1466 nop->operand.typeOperand = op->operand.typeOperand;
1473 /*-----------------------------------------------------------------*/
1474 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1475 /*-----------------------------------------------------------------*/
1477 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1479 operand *nop = operandFromOperand (op);
1481 if (nop->type == SYMBOL)
1483 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1484 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1490 /*-----------------------------------------------------------------*/
1491 /* operandFromSymbol - creates an operand from a symbol */
1492 /*-----------------------------------------------------------------*/
1494 operandFromSymbol (symbol * sym)
1499 /* if the symbol's type is a literal */
1500 /* then it is an enumerator type */
1501 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1502 return operandFromValue (valFromType (sym->etype));
1505 sym->key = ++operandKey;
1507 /* if this an implicit variable, means struct/union */
1508 /* member so just return it */
1509 if (sym->implicit || IS_FUNC (sym->type))
1513 op->operand.symOperand = sym;
1515 op->isvolatile = isOperandVolatile (op, TRUE);
1516 op->isGlobal = isOperandGlobal (op);
1520 /* under the following conditions create a
1521 register equivalent for a local symbol */
1522 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1523 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1525 (!(options.model == MODEL_FLAT24)) ) &&
1526 options.stackAuto == 0)
1529 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1530 !IS_FUNC (sym->type) && /* not a function */
1531 !sym->_isparm && /* not a parameter */
1532 IS_AUTO (sym) && /* is a local auto variable */
1533 !sym->addrtaken && /* whose address has not been taken */
1534 !sym->reqv && /* does not already have a reg equivalence */
1535 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1536 !sym->islbl && /* not a label */
1537 ok && /* farspace check */
1538 !IS_BITVAR (sym->etype) /* not a bit variable */
1542 /* we will use it after all optimizations
1543 and before liveRange calculation */
1544 sym->reqv = newiTempOperand (sym->type, 0);
1545 sym->reqv->key = sym->key;
1546 OP_SYMBOL (sym->reqv)->prereqv = sym;
1547 OP_SYMBOL (sym->reqv)->key = sym->key;
1548 OP_SYMBOL (sym->reqv)->isreqv = 1;
1549 OP_SYMBOL (sym->reqv)->islocal = 1;
1550 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1551 SPIL_LOC (sym->reqv) = sym;
1554 if (!IS_AGGREGATE (sym->type))
1558 op->operand.symOperand = sym;
1561 op->isvolatile = isOperandVolatile (op, TRUE);
1562 op->isGlobal = isOperandGlobal (op);
1563 op->isPtr = IS_PTR (operandType (op));
1564 op->isParm = sym->_isparm;
1569 /* itemp = &[_symbol] */
1571 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1572 IC_LEFT (ic)->type = SYMBOL;
1573 IC_LEFT (ic)->operand.symOperand = sym;
1574 IC_LEFT (ic)->key = sym->key;
1575 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1576 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1577 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1580 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1581 if (IS_ARRAY (sym->type))
1583 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1584 IC_RESULT (ic)->isaddr = 0;
1587 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1591 return IC_RESULT (ic);
1594 /*-----------------------------------------------------------------*/
1595 /* operandFromValue - creates an operand from value */
1596 /*-----------------------------------------------------------------*/
1598 operandFromValue (value * val)
1602 /* if this is a symbol then do the symbol thing */
1604 return operandFromSymbol (val->sym);
1606 /* this is not a symbol */
1609 op->operand.valOperand = val;
1610 op->isLiteral = isOperandLiteral (op);
1614 /*-----------------------------------------------------------------*/
1615 /* operandFromLink - operand from typeChain */
1616 /*-----------------------------------------------------------------*/
1618 operandFromLink (sym_link * type)
1622 /* operand from sym_link */
1628 op->operand.typeOperand = copyLinkChain (type);
1632 /*-----------------------------------------------------------------*/
1633 /* operandFromLit - makes an operand from a literal value */
1634 /*-----------------------------------------------------------------*/
1636 operandFromLit (double i)
1638 return operandFromValue (valueFromLit (i));
1641 /*-----------------------------------------------------------------*/
1642 /* operandFromAst - creates an operand from an ast */
1643 /*-----------------------------------------------------------------*/
1645 operandFromAst (ast * tree,int lvl)
1651 /* depending on type do */
1655 return ast2iCode (tree,lvl+1);
1659 return operandFromValue (tree->opval.val);
1663 return operandFromLink (tree->opval.lnk);
1670 /* Just to keep the compiler happy */
1671 return (operand *) 0;
1674 /*-----------------------------------------------------------------*/
1675 /* setOperandType - sets the operand's type to the given type */
1676 /*-----------------------------------------------------------------*/
1678 setOperandType (operand * op, sym_link * type)
1680 /* depending on the type of operand */
1685 op->operand.valOperand->etype =
1686 getSpec (op->operand.valOperand->type =
1687 copyLinkChain (type));
1691 if (op->operand.symOperand->isitmp)
1692 op->operand.symOperand->etype =
1693 getSpec (op->operand.symOperand->type =
1694 copyLinkChain (type));
1696 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1697 "attempt to modify type of source");
1701 op->operand.typeOperand = copyLinkChain (type);
1707 /*-----------------------------------------------------------------*/
1708 /* Get size in byte of ptr need to access an array */
1709 /*-----------------------------------------------------------------*/
1711 getArraySizePtr (operand * op)
1713 sym_link *ltype = operandType(op);
1717 int size = getSize(ltype);
1718 return(IS_GENPTR(ltype)?(size-1):size);
1723 sym_link *letype = getSpec(ltype);
1724 switch (PTR_TYPE (SPEC_OCLS (letype)))
1736 return (GPTRSIZE-1);
1745 /*-----------------------------------------------------------------*/
1746 /* perform "usual unary conversions" */
1747 /*-----------------------------------------------------------------*/
1750 usualUnaryConversions (operand * op)
1752 if (IS_INTEGRAL (operandType (op)))
1754 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1757 return geniCodeCast (INTTYPE, op, TRUE);
1764 /*-----------------------------------------------------------------*/
1765 /* perform "usual binary conversions" */
1766 /*-----------------------------------------------------------------*/
1769 usualBinaryConversions (operand ** op1, operand ** op2,
1770 RESULT_TYPE resultType, int op)
1773 sym_link *rtype = operandType (*op2);
1774 sym_link *ltype = operandType (*op1);
1776 ctype = computeType (ltype, rtype, resultType, op);
1783 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1785 /* one byte operations: keep signedness for code generator */
1793 *op1 = geniCodeCast (ctype, *op1, TRUE);
1794 *op2 = geniCodeCast (ctype, *op2, TRUE);
1799 /*-----------------------------------------------------------------*/
1800 /* geniCodeValueAtAddress - generate intermeditate code for value */
1802 /*-----------------------------------------------------------------*/
1804 geniCodeRValue (operand * op, bool force)
1807 sym_link *type = operandType (op);
1808 sym_link *etype = getSpec (type);
1810 /* if this is an array & already */
1811 /* an address then return this */
1812 if (IS_AGGREGATE (type) ||
1813 (IS_PTR (type) && !force && !op->isaddr))
1814 return operandFromOperand (op);
1816 /* if this is not an address then must be */
1817 /* rvalue already so return this one */
1821 /* if this is not a temp symbol then */
1822 if (!IS_ITEMP (op) &&
1824 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1826 op = operandFromOperand (op);
1831 if (IS_SPEC (type) &&
1832 IS_TRUE_SYMOP (op) &&
1833 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1834 (options.model == MODEL_FLAT24) ))
1836 op = operandFromOperand (op);
1841 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1842 if (IS_PTR (type) && op->isaddr && force)
1845 type = copyLinkChain (type);
1847 IC_RESULT (ic) = newiTempOperand (type, 1);
1848 IC_RESULT (ic)->isaddr = 0;
1850 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1854 return IC_RESULT (ic);
1857 /*-----------------------------------------------------------------*/
1858 /* geniCodeCast - changes the value from one type to another */
1859 /*-----------------------------------------------------------------*/
1861 geniCodeCast (sym_link * type, operand * op, bool implicit)
1865 sym_link *opetype = getSpec (optype = operandType (op));
1869 /* one of them has size zero then error */
1870 if (IS_VOID (optype))
1872 werror (E_CAST_ZERO);
1876 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1878 geniCodeArray2Ptr (op);
1882 /* if the operand is already the desired type then do nothing */
1883 if (compareType (type, optype) == 1)
1886 /* if this is a literal then just change the type & return */
1887 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1889 return operandFromValue (valCastLiteral (type,
1890 operandLitValue (op)));
1893 /* if casting to/from pointers, do some checking */
1894 if (IS_PTR(type)) { // to a pointer
1895 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1896 if (IS_INTEGRAL(optype)) {
1897 // maybe this is NULL, than it's ok.
1898 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1899 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1900 // no way to set the storage
1901 if (IS_LITERAL(optype)) {
1902 werror(E_LITERAL_GENERIC);
1905 werror(E_NONPTR2_GENPTR);
1908 } else if (implicit) {
1909 werror(W_INTEGRAL2PTR_NOCAST);
1914 // shouldn't do that with float, array or structure unless to void
1915 if (!IS_VOID(getSpec(type)) &&
1916 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1917 werror(E_INCOMPAT_TYPES);
1921 } else { // from a pointer to a pointer
1922 if (IS_GENPTR(type) && IS_VOID(type->next))
1923 { // cast to void* is always allowed
1925 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
1926 { // cast from void* is always allowed
1928 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1929 // if not a pointer to a function
1930 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1931 if (implicit) { // if not to generic, they have to match
1932 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1933 werror(E_INCOMPAT_PTYPES);
1940 } else { // to a non pointer
1941 if (IS_PTR(optype)) { // from a pointer
1942 if (implicit) { // sneaky
1943 if (IS_INTEGRAL(type)) {
1944 werror(W_PTR2INTEGRAL_NOCAST);
1946 } else { // shouldn't do that with float, array or structure
1947 werror(E_INCOMPAT_TYPES);
1954 printFromToType (optype, type);
1957 /* if they are the same size create an assignment */
1959 /* This seems very dangerous to me, since there are several */
1960 /* optimizations (for example, gcse) that don't notice the */
1961 /* cast hidden in this assignement and may simplify an */
1962 /* iCode to use the original (uncasted) operand. */
1963 /* Unfortunately, other things break when this cast is */
1964 /* made explicit. Need to fix this someday. */
1965 /* -- EEP, 2004/01/21 */
1966 if (getSize (type) == getSize (optype) &&
1967 !IS_BITFIELD (type) &&
1969 !IS_FLOAT (optype) &&
1970 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1971 (!IS_SPEC (type) && !IS_SPEC (optype))))
1973 ic = newiCode ('=', NULL, op);
1974 IC_RESULT (ic) = newiTempOperand (type, 0);
1975 SPIL_LOC (IC_RESULT (ic)) =
1976 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1977 IC_RESULT (ic)->isaddr = 0;
1981 ic = newiCode (CAST, operandFromLink (type),
1982 geniCodeRValue (op, FALSE));
1984 IC_RESULT (ic) = newiTempOperand (type, 0);
1987 /* preserve the storage class & output class */
1988 /* of the original variable */
1989 restype = getSpec (operandType (IC_RESULT (ic)));
1990 if (!IS_LITERAL(opetype) &&
1992 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1993 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1996 return IC_RESULT (ic);
1999 /*-----------------------------------------------------------------*/
2000 /* geniCodeLabel - will create a Label */
2001 /*-----------------------------------------------------------------*/
2003 geniCodeLabel (symbol * label)
2007 ic = newiCodeLabelGoto (LABEL, label);
2011 /*-----------------------------------------------------------------*/
2012 /* geniCodeGoto - will create a Goto */
2013 /*-----------------------------------------------------------------*/
2015 geniCodeGoto (symbol * label)
2019 ic = newiCodeLabelGoto (GOTO, label);
2023 /*-----------------------------------------------------------------*/
2024 /* geniCodeMultiply - gen intermediate code for multiplication */
2025 /*-----------------------------------------------------------------*/
2027 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2034 /* if they are both literal then we know the result */
2035 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2036 return operandFromValue (valMult (left->operand.valOperand,
2037 right->operand.valOperand));
2039 if (IS_LITERAL(retype)) {
2040 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2043 resType = usualBinaryConversions (&left, &right, resultType, '*');
2045 rtype = operandType (right);
2046 retype = getSpec (rtype);
2047 ltype = operandType (left);
2048 letype = getSpec (ltype);
2051 /* if the right is a literal & power of 2 */
2052 /* then make it a left shift */
2053 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2054 efficient in most cases than 2 bytes result = 2 bytes << literal
2055 if port has 1 byte muldiv */
2056 if (p2 && !IS_FLOAT (letype)
2057 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2058 && (port->support.muldiv == 1))
2059 && strcmp (port->target, "pic14") != 0 /* don't shift for pic */
2060 && strcmp (port->target, "pic16") != 0)
2062 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2064 /* LEFT_OP need same size for left and result, */
2065 left = geniCodeCast (resType, left, TRUE);
2066 ltype = operandType (left);
2068 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2072 ic = newiCode ('*', left, right); /* normal multiplication */
2073 /* if the size left or right > 1 then support routine */
2074 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2078 IC_RESULT (ic) = newiTempOperand (resType, 1);
2081 return IC_RESULT (ic);
2084 /*-----------------------------------------------------------------*/
2085 /* geniCodeDivision - gen intermediate code for division */
2086 /*-----------------------------------------------------------------*/
2088 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2093 sym_link *rtype = operandType (right);
2094 sym_link *retype = getSpec (rtype);
2095 sym_link *ltype = operandType (left);
2096 sym_link *letype = getSpec (ltype);
2098 resType = usualBinaryConversions (&left, &right, resultType, '/');
2100 /* if the right is a literal & power of 2
2101 and left is unsigned then make it a
2103 if (IS_LITERAL (retype) &&
2104 !IS_FLOAT (letype) &&
2105 IS_UNSIGNED(letype) &&
2106 (p2 = powof2 ((TYPE_UDWORD)
2107 floatFromVal (right->operand.valOperand)))) {
2108 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2112 ic = newiCode ('/', left, right); /* normal division */
2113 /* if the size left or right > 1 then support routine */
2114 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2117 IC_RESULT (ic) = newiTempOperand (resType, 0);
2120 return IC_RESULT (ic);
2122 /*-----------------------------------------------------------------*/
2123 /* geniCodeModulus - gen intermediate code for modulus */
2124 /*-----------------------------------------------------------------*/
2126 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2132 /* if they are both literal then we know the result */
2133 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2134 return operandFromValue (valMod (left->operand.valOperand,
2135 right->operand.valOperand));
2137 resType = usualBinaryConversions (&left, &right, resultType, '%');
2139 /* now they are the same size */
2140 ic = newiCode ('%', left, right);
2142 /* if the size left or right > 1 then support routine */
2143 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2145 IC_RESULT (ic) = newiTempOperand (resType, 0);
2148 return IC_RESULT (ic);
2151 /*-----------------------------------------------------------------*/
2152 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2153 /*-----------------------------------------------------------------*/
2155 geniCodePtrPtrSubtract (operand * left, operand * right)
2161 /* if they are both literals then */
2162 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2164 result = operandFromValue (valMinus (left->operand.valOperand,
2165 right->operand.valOperand));
2169 ic = newiCode ('-', left, right);
2171 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2175 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2179 // should we really do this? is this ANSI?
2180 return geniCodeDivision (result,
2181 operandFromLit (getSize (ltype->next)),
2185 /*-----------------------------------------------------------------*/
2186 /* geniCodeSubtract - generates code for subtraction */
2187 /*-----------------------------------------------------------------*/
2189 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2196 /* if they both pointers then */
2197 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2198 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2199 return geniCodePtrPtrSubtract (left, right);
2201 /* if they are both literal then we know the result */
2202 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2203 && left->isLiteral && right->isLiteral)
2204 return operandFromValue (valMinus (left->operand.valOperand,
2205 right->operand.valOperand));
2207 /* if left is an array or pointer */
2208 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2210 isarray = left->isaddr;
2211 right = geniCodeMultiply (right,
2212 operandFromLit (getSize (ltype->next)),
2213 (getArraySizePtr(left) >= INTSIZE) ?
2216 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2219 { /* make them the same size */
2220 resType = usualBinaryConversions (&left, &right, resultType, '-');
2223 ic = newiCode ('-', left, right);
2225 IC_RESULT (ic) = newiTempOperand (resType, 1);
2226 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2228 /* if left or right is a float */
2229 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2233 return IC_RESULT (ic);
2236 /*-----------------------------------------------------------------*/
2237 /* geniCodeAdd - generates iCode for addition */
2238 /*-----------------------------------------------------------------*/
2240 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2249 /* if the right side is LITERAL zero */
2250 /* return the left side */
2251 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2254 /* if left is literal zero return right */
2255 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2258 /* if left is a pointer then size */
2259 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2261 isarray = left->isaddr;
2262 // there is no need to multiply with 1
2263 if (getSize (ltype->next) != 1)
2265 size = operandFromLit (getSize (ltype->next));
2266 SPEC_USIGN (getSpec (operandType (size))) = 1;
2267 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2268 right = geniCodeMultiply (right,
2270 (getArraySizePtr(left) >= INTSIZE) ?
2273 /* Even if right is a 'unsigned char',
2274 the result will be a 'signed int' due to the promotion rules.
2275 It doesn't make sense when accessing arrays, so let's fix it here: */
2277 SPEC_USIGN (getSpec (operandType (right))) = 1;
2279 resType = copyLinkChain (ltype);
2282 { // make them the same size
2283 resType = usualBinaryConversions (&left, &right, resultType, '+');
2286 /* if they are both literals then we know */
2287 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2288 && left->isLiteral && right->isLiteral)
2289 return operandFromValue (valPlus (valFromType (ltype),
2290 valFromType (rtype)));
2292 ic = newiCode ('+', left, right);
2294 IC_RESULT (ic) = newiTempOperand (resType, 1);
2295 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2297 /* if left or right is a float then support
2299 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2304 return IC_RESULT (ic);
2308 /*-----------------------------------------------------------------*/
2309 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2310 /*-----------------------------------------------------------------*/
2312 aggrToPtr (sym_link * type, bool force)
2317 if (IS_PTR (type) && !force)
2320 etype = getSpec (type);
2321 ptype = newLink (DECLARATOR);
2325 /* set the pointer depending on the storage class */
2326 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2330 /*------------------------------------------------------------------*/
2331 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2332 /*------------------------------------------------------------------*/
2334 aggrToPtrDclType (sym_link * type, bool force)
2336 if (IS_PTR (type) && !force)
2337 return DCL_TYPE (type);
2339 /* return the pointer depending on the storage class */
2340 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2343 /*-----------------------------------------------------------------*/
2344 /* geniCodeArray2Ptr - array to pointer */
2345 /*-----------------------------------------------------------------*/
2347 geniCodeArray2Ptr (operand * op)
2349 sym_link *optype = operandType (op);
2350 sym_link *opetype = getSpec (optype);
2352 /* set the pointer depending on the storage class */
2353 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2360 /*-----------------------------------------------------------------*/
2361 /* geniCodeArray - array access */
2362 /*-----------------------------------------------------------------*/
2364 geniCodeArray (operand * left, operand * right, int lvl)
2368 sym_link *ltype = operandType (left);
2373 if (IS_PTR (ltype->next) && left->isaddr)
2375 left = geniCodeRValue (left, FALSE);
2378 return geniCodeDerefPtr (geniCodeAdd (left,
2380 (getArraySizePtr(left) >= INTSIZE) ?
2386 size = operandFromLit (getSize (ltype->next));
2387 SPEC_USIGN (getSpec (operandType (size))) = 1;
2388 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2389 right = geniCodeMultiply (right,
2391 (getArraySizePtr(left) >= INTSIZE) ?
2394 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2395 It doesn't make sense when accessing arrays, so let's fix it here: */
2397 SPEC_USIGN (getSpec (operandType (right))) = 1;
2398 /* we can check for limits here */
2399 /* already done in SDCCast.c
2400 if (isOperandLiteral (right) &&
2403 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2405 werror (W_IDX_OUT_OF_BOUNDS,
2406 (int) operandLitValue (right) / getSize (ltype->next),
2411 ic = newiCode ('+', left, right);
2413 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2414 !IS_AGGREGATE (ltype->next) &&
2415 !IS_PTR (ltype->next))
2416 ? ltype : ltype->next), 0);
2418 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2421 return IC_RESULT (ic);
2424 /*-----------------------------------------------------------------*/
2425 /* geniCodeStruct - generates intermediate code for structures */
2426 /*-----------------------------------------------------------------*/
2428 geniCodeStruct (operand * left, operand * right, bool islval)
2431 sym_link *type = operandType (left);
2432 sym_link *etype = getSpec (type);
2434 symbol *element = getStructElement (SPEC_STRUCT (etype),
2435 right->operand.symOperand);
2437 wassert(IS_SYMOP(right));
2439 /* add the offset */
2440 ic = newiCode ('+', left, operandFromLit (element->offset));
2442 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2444 /* preserve the storage & output class of the struct */
2445 /* as well as the volatile attribute */
2446 retype = getSpec (operandType (IC_RESULT (ic)));
2447 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2448 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2449 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2450 SPEC_CONST (retype) |= SPEC_CONST (etype);
2452 if (IS_PTR (element->type))
2453 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2455 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2458 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2461 /*-----------------------------------------------------------------*/
2462 /* geniCodePostInc - generate int code for Post increment */
2463 /*-----------------------------------------------------------------*/
2465 geniCodePostInc (operand * op)
2469 sym_link *optype = operandType (op);
2471 operand *rv = (IS_ITEMP (op) ?
2472 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2474 sym_link *rvtype = operandType (rv);
2477 /* if this is not an address we have trouble */
2480 werror (E_LVALUE_REQUIRED, "++");
2484 rOp = newiTempOperand (rvtype, 0);
2485 OP_SYMBOL(rOp)->noSpilLoc = 1;
2488 OP_SYMBOL(rv)->noSpilLoc = 1;
2490 geniCodeAssign (rOp, rv, 0, 0);
2492 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2493 if (IS_FLOAT (rvtype))
2494 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2496 ic = newiCode ('+', rv, operandFromLit (size));
2498 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2501 geniCodeAssign (op, result, 0, 0);
2507 /*-----------------------------------------------------------------*/
2508 /* geniCodePreInc - generate code for preIncrement */
2509 /*-----------------------------------------------------------------*/
2511 geniCodePreInc (operand * op, bool lvalue)
2514 sym_link *optype = operandType (op);
2515 operand *rop = (IS_ITEMP (op) ?
2516 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2518 sym_link *roptype = operandType (rop);
2524 werror (E_LVALUE_REQUIRED, "++");
2529 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2530 if (IS_FLOAT (roptype))
2531 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2533 ic = newiCode ('+', rop, operandFromLit (size));
2534 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2537 (void) geniCodeAssign (op, result, 0, 0);
2538 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2544 /*-----------------------------------------------------------------*/
2545 /* geniCodePostDec - generates code for Post decrement */
2546 /*-----------------------------------------------------------------*/
2548 geniCodePostDec (operand * op)
2552 sym_link *optype = operandType (op);
2554 operand *rv = (IS_ITEMP (op) ?
2555 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2557 sym_link *rvtype = operandType (rv);
2560 /* if this is not an address we have trouble */
2563 werror (E_LVALUE_REQUIRED, "--");
2567 rOp = newiTempOperand (rvtype, 0);
2568 OP_SYMBOL(rOp)->noSpilLoc = 1;
2571 OP_SYMBOL(rv)->noSpilLoc = 1;
2573 geniCodeAssign (rOp, rv, 0, 0);
2575 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2576 if (IS_FLOAT (rvtype))
2577 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2579 ic = newiCode ('-', rv, operandFromLit (size));
2581 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2584 geniCodeAssign (op, result, 0, 0);
2590 /*-----------------------------------------------------------------*/
2591 /* geniCodePreDec - generate code for pre decrement */
2592 /*-----------------------------------------------------------------*/
2594 geniCodePreDec (operand * op, bool lvalue)
2597 sym_link *optype = operandType (op);
2598 operand *rop = (IS_ITEMP (op) ?
2599 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2601 sym_link *roptype = operandType (rop);
2607 werror (E_LVALUE_REQUIRED, "--");
2612 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2613 if (IS_FLOAT (roptype))
2614 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2616 ic = newiCode ('-', rop, operandFromLit (size));
2617 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2620 (void) geniCodeAssign (op, result, 0, 0);
2621 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2628 /*-----------------------------------------------------------------*/
2629 /* geniCodeBitwise - gen int code for bitWise operators */
2630 /*-----------------------------------------------------------------*/
2632 geniCodeBitwise (operand * left, operand * right,
2633 int oper, sym_link * resType)
2637 left = geniCodeCast (resType, left, TRUE);
2638 right = geniCodeCast (resType, right, TRUE);
2640 ic = newiCode (oper, left, right);
2641 IC_RESULT (ic) = newiTempOperand (resType, 0);
2644 return IC_RESULT (ic);
2647 /*-----------------------------------------------------------------*/
2648 /* geniCodeAddressOf - gens icode for '&' address of operator */
2649 /*-----------------------------------------------------------------*/
2651 geniCodeAddressOf (operand * op)
2655 sym_link *optype = operandType (op);
2656 sym_link *opetype = getSpec (optype);
2658 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2660 op = operandFromOperand (op);
2665 /* lvalue check already done in decorateType */
2666 /* this must be a lvalue */
2667 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2668 /* werror (E_LVALUE_REQUIRED,"&"); */
2672 p = newLink (DECLARATOR);
2674 /* set the pointer depending on the storage class */
2675 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2677 p->next = copyLinkChain (optype);
2679 /* if already a temp */
2682 setOperandType (op, p);
2687 /* other wise make this of the type coming in */
2688 ic = newiCode (ADDRESS_OF, op, NULL);
2689 IC_RESULT (ic) = newiTempOperand (p, 1);
2690 IC_RESULT (ic)->isaddr = 0;
2692 return IC_RESULT (ic);
2694 /*-----------------------------------------------------------------*/
2695 /* setOClass - sets the output class depending on the pointer type */
2696 /*-----------------------------------------------------------------*/
2698 setOClass (sym_link * ptr, sym_link * spec)
2700 switch (DCL_TYPE (ptr))
2703 SPEC_OCLS (spec) = data;
2707 SPEC_OCLS (spec) = generic;
2711 SPEC_OCLS (spec) = xdata;
2715 SPEC_OCLS (spec) = code;
2719 SPEC_OCLS (spec) = idata;
2723 SPEC_OCLS (spec) = xstack;
2727 SPEC_OCLS (spec) = eeprom;
2736 /*-----------------------------------------------------------------*/
2737 /* geniCodeDerefPtr - dereference pointer with '*' */
2738 /*-----------------------------------------------------------------*/
2740 geniCodeDerefPtr (operand * op,int lvl)
2742 sym_link *rtype, *retype;
2743 sym_link *optype = operandType (op);
2745 // if this is an array then array access
2746 if (IS_ARRAY (optype)) {
2747 // don't worry, this will be optimized out later
2748 return geniCodeArray (op, operandFromLit (0), lvl);
2751 // just in case someone screws up
2752 wassert (IS_PTR (optype));
2754 if (IS_TRUE_SYMOP (op))
2757 op = geniCodeRValue (op, TRUE);
2760 /* now get rid of the pointer part */
2761 if (isLvaluereq(lvl) && IS_ITEMP (op))
2763 retype = getSpec (rtype = copyLinkChain (optype));
2767 retype = getSpec (rtype = copyLinkChain (optype->next));
2768 /* outputclass needs 2b updated */
2769 setOClass (optype, retype);
2772 op->isGptr = IS_GENPTR (optype);
2774 op->isaddr = (IS_PTR (rtype) ||
2775 IS_STRUCT (rtype) ||
2780 if (!isLvaluereq(lvl))
2781 op = geniCodeRValue (op, TRUE);
2783 setOperandType (op, rtype);
2788 /*-----------------------------------------------------------------*/
2789 /* geniCodeUnaryMinus - does a unary minus of the operand */
2790 /*-----------------------------------------------------------------*/
2792 geniCodeUnaryMinus (operand * op)
2795 sym_link *optype = operandType (op);
2797 if (IS_LITERAL (optype))
2798 return operandFromLit (-floatFromVal (op->operand.valOperand));
2800 ic = newiCode (UNARYMINUS, op, NULL);
2801 IC_RESULT (ic) = newiTempOperand (optype, 0);
2803 return IC_RESULT (ic);
2806 /*-----------------------------------------------------------------*/
2807 /* geniCodeLeftShift - gen i code for left shift */
2808 /*-----------------------------------------------------------------*/
2810 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2815 ic = newiCode (LEFT_OP, left, right);
2817 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2818 IC_RESULT (ic) = newiTempOperand (resType, 0);
2820 return IC_RESULT (ic);
2823 /*-----------------------------------------------------------------*/
2824 /* geniCodeRightShift - gen i code for right shift */
2825 /*-----------------------------------------------------------------*/
2827 geniCodeRightShift (operand * left, operand * right)
2831 ic = newiCode (RIGHT_OP, left, right);
2832 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2834 return IC_RESULT (ic);
2837 /*-----------------------------------------------------------------*/
2838 /* geniCodeLogic- logic code */
2839 /*-----------------------------------------------------------------*/
2841 geniCodeLogic (operand * left, operand * right, int op)
2845 sym_link *rtype = operandType (right);
2846 sym_link *ltype = operandType (left);
2848 /* left is integral type and right is literal then
2849 check if the literal value is within bounds */
2850 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2852 checkConstantRange(ltype,
2853 OP_VALUE(right), "compare operation", 1);
2856 /* if one operand is a pointer and the other is a literal generic void pointer,
2857 change the type of the literal generic void pointer to match the other pointer */
2858 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2859 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2861 /* find left's definition */
2862 ic = (iCode *) setFirstItem (iCodeChain);
2865 if (((ic->op == CAST) || (ic->op == '='))
2866 && isOperandEqual(left, IC_RESULT (ic)))
2869 ic = setNextItem (iCodeChain);
2871 /* if casting literal to generic pointer, then cast to rtype instead */
2872 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2874 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2875 ltype = operandType(left);
2878 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2879 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2881 /* find right's definition */
2882 ic = (iCode *) setFirstItem (iCodeChain);
2885 if (((ic->op == CAST) || (ic->op == '='))
2886 && isOperandEqual(right, IC_RESULT (ic)))
2889 ic = setNextItem (iCodeChain);
2891 /* if casting literal to generic pointer, then cast to rtype instead */
2892 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2894 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2895 rtype = operandType(right);
2899 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
2901 ic = newiCode (op, left, right);
2902 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2904 /* if comparing float
2905 and not a '==' || '!=' || '&&' || '||' (these
2907 if (IS_FLOAT(ctype) &&
2915 return IC_RESULT (ic);
2918 /*-----------------------------------------------------------------*/
2919 /* geniCodeLogicAndOr - && || operations */
2920 /*-----------------------------------------------------------------*/
2922 geniCodeLogicAndOr (ast *tree, int lvl)
2925 symbol *falseLabel = newiTempLabel (NULL);
2926 symbol *trueLabel = newiTempLabel (NULL);
2927 symbol *exitLabel = newiTempLabel (NULL);
2928 operand *op, *result, *condition;
2930 /* AND_OP and OR_OP are no longer generated because of bug-905492.
2931 They can be reenabled by executing the following block. If you find
2932 a decent optimization you could start right here:
2937 operand *leftOp, *rightOp;
2939 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
2940 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
2942 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
2946 /* generate two IFX for the '&&' or '||' op */
2948 /* evaluate left operand */
2949 condition = ast2iCode (tree->left, lvl + 1);
2950 op = geniCodeRValue (condition, FALSE);
2952 /* test left operand */
2953 if (tree->opval.op == AND_OP)
2954 ic = newiCodeCondition (op, NULL, falseLabel);
2956 ic = newiCodeCondition (op, trueLabel, NULL);
2959 /* evaluate right operand */
2960 condition = ast2iCode (tree->right, lvl + 1);
2961 op = geniCodeRValue (condition, FALSE);
2963 /* test right operand */
2964 ic = newiCodeCondition (op, trueLabel, NULL);
2967 /* store 0 or 1 in result */
2968 result = newiTempOperand (newCharLink(), 1);
2970 geniCodeLabel (falseLabel);
2971 geniCodeAssign (result, operandFromLit (0), 0, 0);
2972 /* generate an unconditional goto */
2973 geniCodeGoto (exitLabel);
2975 geniCodeLabel (trueLabel);
2976 geniCodeAssign (result, operandFromLit (1), 0, 0);
2978 geniCodeLabel (exitLabel);
2983 /*-----------------------------------------------------------------*/
2984 /* geniCodeUnary - for a a generic unary operation */
2985 /*-----------------------------------------------------------------*/
2987 geniCodeUnary (operand * op, int oper)
2989 iCode *ic = newiCode (oper, op, NULL);
2991 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2993 return IC_RESULT (ic);
2996 /*-----------------------------------------------------------------*/
2997 /* geniCodeConditional - geniCode for '?' ':' operation */
2998 /*-----------------------------------------------------------------*/
3000 geniCodeConditional (ast * tree,int lvl)
3003 symbol *falseLabel = newiTempLabel (NULL);
3004 symbol *exitLabel = newiTempLabel (NULL);
3005 operand *cond = ast2iCode (tree->left,lvl+1);
3006 operand *true, *false, *result;
3008 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3012 true = ast2iCode (tree->right->left,lvl+1);
3014 /* move the value to a new Operand */
3015 result = newiTempOperand (tree->right->ftype, 0);
3016 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3018 /* generate an unconditional goto */
3019 geniCodeGoto (exitLabel);
3021 /* now for the right side */
3022 geniCodeLabel (falseLabel);
3024 false = ast2iCode (tree->right->right,lvl+1);
3025 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3027 /* create the exit label */
3028 geniCodeLabel (exitLabel);
3033 /*-----------------------------------------------------------------*/
3034 /* geniCodeAssign - generate code for assignment */
3035 /*-----------------------------------------------------------------*/
3037 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3040 sym_link *ltype = operandType (left);
3041 sym_link *rtype = operandType (right);
3043 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3045 werror (E_LVALUE_REQUIRED, "assignment");
3049 /* left is integral type and right is literal then
3050 check if the literal value is within bounds */
3051 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3053 checkConstantRange(ltype,
3054 OP_VALUE(right), "= operation", 0);
3057 /* if the left & right type don't exactly match */
3058 /* if pointer set then make sure the check is
3059 done with the type & not the pointer */
3060 /* then cast rights type to left */
3062 /* first check the type for pointer assignement */
3063 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3064 compareType (ltype, rtype) <= 0)
3066 if (compareType (ltype->next, rtype) < 0)
3067 right = geniCodeCast (ltype->next, right, TRUE);
3069 else if (compareType (ltype, rtype) < 0)
3070 right = geniCodeCast (ltype, right, TRUE);
3072 /* If left is a true symbol & ! volatile
3073 create an assignment to temporary for
3074 the right & then assign this temporary
3075 to the symbol. This is SSA (static single
3076 assignment). Isn't it simple and folks have
3077 published mountains of paper on it */
3078 if (IS_TRUE_SYMOP (left) &&
3079 !isOperandVolatile (left, FALSE) &&
3080 isOperandGlobal (left))
3084 if (IS_TRUE_SYMOP (right))
3085 sym = OP_SYMBOL (right);
3086 ic = newiCode ('=', NULL, right);
3087 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3088 SPIL_LOC (right) = sym;
3092 ic = newiCode ('=', NULL, right);
3093 IC_RESULT (ic) = left;
3096 /* if left isgptr flag is set then support
3097 routine will be required */
3101 ic->nosupdate = nosupdate;
3105 /*-----------------------------------------------------------------*/
3106 /* geniCodeDummyRead - generate code for dummy read */
3107 /*-----------------------------------------------------------------*/
3109 geniCodeDummyRead (operand * op)
3112 sym_link *type = operandType (op);
3114 if (!IS_VOLATILE(type))
3117 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3123 /*-----------------------------------------------------------------*/
3124 /* geniCodeSEParms - generate code for side effecting fcalls */
3125 /*-----------------------------------------------------------------*/
3127 geniCodeSEParms (ast * parms,int lvl)
3132 if (parms->type == EX_OP && parms->opval.op == PARAM)
3134 geniCodeSEParms (parms->left,lvl);
3135 geniCodeSEParms (parms->right,lvl);
3139 /* hack don't like this but too lazy to think of
3141 if (IS_ADDRESS_OF_OP (parms))
3142 parms->left->lvalue = 1;
3144 if (IS_CAST_OP (parms) &&
3145 IS_PTR (parms->ftype) &&
3146 IS_ADDRESS_OF_OP (parms->right))
3147 parms->right->left->lvalue = 1;
3149 parms->opval.oprnd =
3150 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3152 parms->type = EX_OPERAND;
3153 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3154 SPEC_ARGREG(parms->ftype);
3157 /*-----------------------------------------------------------------*/
3158 /* geniCodeParms - generates parameters */
3159 /*-----------------------------------------------------------------*/
3161 geniCodeParms (ast * parms, value *argVals, int *stack,
3162 sym_link * ftype, int lvl)
3170 if (argVals==NULL) {
3172 argVals = FUNC_ARGS (ftype);
3175 /* if this is a param node then do the left & right */
3176 if (parms->type == EX_OP && parms->opval.op == PARAM)
3178 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3179 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3183 /* get the parameter value */
3184 if (parms->type == EX_OPERAND)
3185 pval = parms->opval.oprnd;
3188 /* maybe this else should go away ?? */
3189 /* hack don't like this but too lazy to think of
3191 if (IS_ADDRESS_OF_OP (parms))
3192 parms->left->lvalue = 1;
3194 if (IS_CAST_OP (parms) &&
3195 IS_PTR (parms->ftype) &&
3196 IS_ADDRESS_OF_OP (parms->right))
3197 parms->right->left->lvalue = 1;
3199 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3202 /* if register parm then make it a send */
3203 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3204 IFFUNC_ISBUILTIN(ftype))
3206 ic = newiCode (SEND, pval, NULL);
3207 ic->argreg = SPEC_ARGREG(parms->etype);
3208 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3213 /* now decide whether to push or assign */
3214 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3218 operand *top = operandFromSymbol (argVals->sym);
3219 /* clear useDef and other bitVectors */
3220 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3221 geniCodeAssign (top, pval, 1, 0);
3225 sym_link *p = operandType (pval);
3227 ic = newiCode (IPUSH, pval, NULL);
3229 /* update the stack adjustment */
3230 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3235 argVals=argVals->next;
3239 /*-----------------------------------------------------------------*/
3240 /* geniCodeCall - generates temp code for calling */
3241 /*-----------------------------------------------------------------*/
3243 geniCodeCall (operand * left, ast * parms,int lvl)
3247 sym_link *type, *etype;
3251 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3252 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3253 werror (E_FUNCTION_EXPECTED);
3254 return operandFromValue(valueFromLit(0));
3257 /* take care of parameters with side-effecting
3258 function calls in them, this is required to take care
3259 of overlaying function parameters */
3260 geniCodeSEParms (parms,lvl);
3262 ftype = operandType (left);
3263 if (IS_CODEPTR (ftype))
3264 ftype = ftype->next;
3266 /* first the parameters */
3267 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3269 /* now call : if symbol then pcall */
3270 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3271 ic = newiCode (PCALL, left, NULL);
3273 ic = newiCode (CALL, left, NULL);
3276 type = copyLinkChain (ftype->next);
3277 etype = getSpec (type);
3278 SPEC_EXTR (etype) = 0;
3279 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3283 /* stack adjustment after call */
3284 ic->parmBytes = stack;
3289 /*-----------------------------------------------------------------*/
3290 /* geniCodeReceive - generate intermediate code for "receive" */
3291 /*-----------------------------------------------------------------*/
3293 geniCodeReceive (value * args)
3295 /* for all arguments that are passed in registers */
3299 if (IS_REGPARM (args->etype))
3301 operand *opr = operandFromValue (args);
3303 symbol *sym = OP_SYMBOL (opr);
3306 /* we will use it after all optimizations
3307 and before liveRange calculation */
3308 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3311 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3312 options.stackAuto == 0 &&
3313 (!(options.model == MODEL_FLAT24)) )
3318 opl = newiTempOperand (args->type, 0);
3320 sym->reqv->key = sym->key;
3321 OP_SYMBOL (sym->reqv)->key = sym->key;
3322 OP_SYMBOL (sym->reqv)->isreqv = 1;
3323 OP_SYMBOL (sym->reqv)->islocal = 0;
3324 SPIL_LOC (sym->reqv) = sym;
3328 ic = newiCode (RECEIVE, NULL, NULL);
3329 ic->argreg = SPEC_ARGREG(args->etype);
3331 currFunc->recvSize = getSize (sym->type);
3334 IC_RESULT (ic) = opr;
3342 /*-----------------------------------------------------------------*/
3343 /* geniCodeFunctionBody - create the function body */
3344 /*-----------------------------------------------------------------*/
3346 geniCodeFunctionBody (ast * tree,int lvl)
3353 /* reset the auto generation */
3359 func = ast2iCode (tree->left,lvl+1);
3360 fetype = getSpec (operandType (func));
3362 savelineno = lineno;
3363 lineno = OP_SYMBOL (func)->lineDef;
3364 /* create an entry label */
3365 geniCodeLabel (entryLabel);
3366 lineno = savelineno;
3368 /* create a proc icode */
3369 ic = newiCode (FUNCTION, func, NULL);
3370 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3375 /* for all parameters that are passed
3376 on registers add a "receive" */
3377 geniCodeReceive (tree->values.args);
3379 /* generate code for the body */
3380 ast2iCode (tree->right,lvl+1);
3382 /* create a label for return */
3383 geniCodeLabel (returnLabel);
3385 /* now generate the end proc */
3386 ic = newiCode (ENDFUNCTION, func, NULL);
3392 /*-----------------------------------------------------------------*/
3393 /* geniCodeReturn - gen icode for 'return' statement */
3394 /*-----------------------------------------------------------------*/
3396 geniCodeReturn (operand * op)
3400 /* if the operand is present force an rvalue */
3402 op = geniCodeRValue (op, FALSE);
3404 ic = newiCode (RETURN, op, NULL);
3408 /*-----------------------------------------------------------------*/
3409 /* geniCodeIfx - generates code for extended if statement */
3410 /*-----------------------------------------------------------------*/
3412 geniCodeIfx (ast * tree,int lvl)
3415 operand *condition = ast2iCode (tree->left,lvl+1);
3418 /* if condition is null then exit */
3422 condition = geniCodeRValue (condition, FALSE);
3424 cetype = getSpec (operandType (condition));
3425 /* if the condition is a literal */
3426 if (IS_LITERAL (cetype))
3428 if (floatFromVal (condition->operand.valOperand))
3430 if (tree->trueLabel)
3431 geniCodeGoto (tree->trueLabel);
3437 if (tree->falseLabel)
3438 geniCodeGoto (tree->falseLabel);
3445 if (tree->trueLabel)
3447 ic = newiCodeCondition (condition,
3452 if (tree->falseLabel)
3453 geniCodeGoto (tree->falseLabel);
3457 ic = newiCodeCondition (condition,
3464 ast2iCode (tree->right,lvl+1);
3467 /*-----------------------------------------------------------------*/
3468 /* geniCodeJumpTable - tries to create a jump table for switch */
3469 /*-----------------------------------------------------------------*/
3471 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3473 int min = 0, max = 0, t, cnt = 0;
3479 int needRangeCheck = !optimize.noJTabBoundary
3480 || tree->values.switchVals.swDefault;
3482 if (!tree || !caseVals)
3485 /* the criteria for creating a jump table is */
3486 /* all integer numbers between the maximum & minimum must */
3487 /* be present , the maximum value should not exceed 255 */
3488 min = max = (int) floatFromVal (vch = caseVals);
3489 SNPRINTF (buffer, sizeof(buffer),
3491 tree->values.switchVals.swNum,
3493 addSet (&labels, newiTempLabel (buffer));
3495 /* if there is only one case value then no need */
3496 if (!(vch = vch->next))
3501 if (((t = (int) floatFromVal (vch)) - max) != 1)
3503 SNPRINTF (buffer, sizeof(buffer),
3505 tree->values.switchVals.swNum,
3507 addSet (&labels, newiTempLabel (buffer));
3513 /* if the number of case statements <= 2 then */
3514 /* it is not economical to create the jump table */
3515 /* since two compares are needed for boundary conditions */
3516 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3519 if (tree->values.switchVals.swDefault)
3521 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3525 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3529 falseLabel = newiTempLabel (buffer);
3531 /* If cond is volatile, it might change after the boundary */
3532 /* conditions are tested to an out of bounds value, causing */
3533 /* a jump to a location outside of the jump table. To avoid */
3534 /* this possibility, use a non-volatile copy of it instead. */
3535 if (IS_OP_VOLATILE (cond))
3540 newcond = newiTempOperand (operandType (cond), TRUE);
3541 newcond->isvolatile = 0;
3542 ic = newiCode ('=', NULL, cond);
3543 IC_RESULT (ic) = newcond;
3548 /* so we can create a jumptable */
3549 /* first we rule out the boundary conditions */
3550 /* if only optimization says so */
3553 sym_link *cetype = getSpec (operandType (cond));
3554 /* no need to check the lower bound if
3555 the condition is unsigned & minimum value is zero */
3556 if (!(min == 0 && IS_UNSIGNED (cetype)))
3558 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3559 ic = newiCodeCondition (boundary, falseLabel, NULL);
3563 /* now for upper bounds */
3564 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3565 ic = newiCodeCondition (boundary, falseLabel, NULL);
3569 /* if the min is not zero then we no make it zero */
3572 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3573 if (!IS_LITERAL(getSpec(operandType(cond))))
3574 setOperandType (cond, UCHARTYPE);
3577 /* now create the jumptable */
3578 ic = newiCode (JUMPTABLE, NULL, NULL);
3579 IC_JTCOND (ic) = cond;
3580 IC_JTLABELS (ic) = labels;
3585 /*-----------------------------------------------------------------*/
3586 /* geniCodeSwitch - changes a switch to a if statement */
3587 /*-----------------------------------------------------------------*/
3589 geniCodeSwitch (ast * tree,int lvl)
3592 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3593 value *caseVals = tree->values.switchVals.swVals;
3594 symbol *trueLabel, *falseLabel;
3596 /* If the condition is a literal, then just jump to the */
3597 /* appropriate case label. */
3598 if (IS_LITERAL(getSpec(operandType(cond))))
3600 int switchVal, caseVal;
3602 switchVal = (int) floatFromVal (cond->operand.valOperand);
3605 caseVal = (int) floatFromVal (caseVals);
3606 if (caseVal == switchVal)
3608 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3609 tree->values.switchVals.swNum, caseVal);
3610 trueLabel = newiTempLabel (buffer);
3611 geniCodeGoto (trueLabel);
3614 caseVals = caseVals->next;
3616 goto defaultOrBreak;
3619 /* if we can make this a jump table */
3620 if (geniCodeJumpTable (cond, caseVals, tree))
3621 goto jumpTable; /* no need for the comparison */
3623 /* for the cases defined do */
3627 operand *compare = geniCodeLogic (cond,
3628 operandFromValue (caseVals),
3631 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3632 tree->values.switchVals.swNum,
3633 (int) floatFromVal (caseVals));
3634 trueLabel = newiTempLabel (buffer);
3636 ic = newiCodeCondition (compare, trueLabel, NULL);
3638 caseVals = caseVals->next;
3643 /* if default is present then goto break else break */
3644 if (tree->values.switchVals.swDefault)
3646 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3650 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3653 falseLabel = newiTempLabel (buffer);
3654 geniCodeGoto (falseLabel);
3657 ast2iCode (tree->right,lvl+1);
3660 /*-----------------------------------------------------------------*/
3661 /* geniCodeInline - intermediate code for inline assembler */
3662 /*-----------------------------------------------------------------*/
3664 geniCodeInline (ast * tree)
3668 ic = newiCode (INLINEASM, NULL, NULL);
3669 IC_INLINE (ic) = tree->values.inlineasm;
3673 /*-----------------------------------------------------------------*/
3674 /* geniCodeArrayInit - intermediate code for array initializer */
3675 /*-----------------------------------------------------------------*/
3677 geniCodeArrayInit (ast * tree, operand *array)
3681 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3682 ic = newiCode (ARRAYINIT, array, NULL);
3683 IC_ARRAYILIST (ic) = tree->values.constlist;
3685 operand *left=newOperand(), *right=newOperand();
3686 left->type=right->type=SYMBOL;
3687 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3688 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3689 ic = newiCode (ARRAYINIT, left, right);
3694 /*-----------------------------------------------------------------*/
3695 /* geniCodeCritical - intermediate code for a critical statement */
3696 /*-----------------------------------------------------------------*/
3698 geniCodeCritical (ast *tree, int lvl)
3703 /* If op is NULL, the original interrupt state will saved on */
3704 /* the stack. Otherwise, it will be saved in op. */
3706 /* Generate a save of the current interrupt state & disabled */
3707 ic = newiCode (CRITICAL, NULL, NULL);
3708 IC_RESULT (ic) = op;
3711 /* Generate the critical code sequence */
3712 if (tree->left && tree->left->type == EX_VALUE)
3713 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3715 ast2iCode (tree->left,lvl+1);
3717 /* Generate a restore of the original interrupt state */
3718 ic = newiCode (ENDCRITICAL, NULL, op);
3722 /*-----------------------------------------------------------------*/
3723 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3724 /* particular case. Ie : assigning or dereferencing array or ptr */
3725 /*-----------------------------------------------------------------*/
3726 set * lvaluereqSet = NULL;
3727 typedef struct lvalItem
3734 /*-----------------------------------------------------------------*/
3735 /* addLvaluereq - add a flag for lvalreq for current ast level */
3736 /*-----------------------------------------------------------------*/
3737 void addLvaluereq(int lvl)
3739 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3742 addSetHead(&lvaluereqSet,lpItem);
3745 /*-----------------------------------------------------------------*/
3746 /* delLvaluereq - del a flag for lvalreq for current ast level */
3747 /*-----------------------------------------------------------------*/
3751 lpItem = getSet(&lvaluereqSet);
3752 if(lpItem) Safe_free(lpItem);
3754 /*-----------------------------------------------------------------*/
3755 /* clearLvaluereq - clear lvalreq flag */
3756 /*-----------------------------------------------------------------*/
3757 void clearLvaluereq()
3760 lpItem = peekSet(lvaluereqSet);
3761 if(lpItem) lpItem->req = 0;
3763 /*-----------------------------------------------------------------*/
3764 /* getLvaluereq - get the last lvalreq level */
3765 /*-----------------------------------------------------------------*/
3766 int getLvaluereqLvl()
3769 lpItem = peekSet(lvaluereqSet);
3770 if(lpItem) return lpItem->lvl;
3773 /*-----------------------------------------------------------------*/
3774 /* isLvaluereq - is lvalreq valid for this level ? */
3775 /*-----------------------------------------------------------------*/
3776 int isLvaluereq(int lvl)
3779 lpItem = peekSet(lvaluereqSet);
3780 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3784 /*-----------------------------------------------------------------*/
3785 /* ast2iCode - creates an icodeList from an ast */
3786 /*-----------------------------------------------------------------*/
3788 ast2iCode (ast * tree,int lvl)
3790 operand *left = NULL;
3791 operand *right = NULL;
3795 /* set the global variables for filename & line number */
3797 filename = tree->filename;
3799 lineno = tree->lineno;
3801 block = tree->block;
3803 scopeLevel = tree->level;
3805 seqPoint = tree->seqPoint;
3807 if (tree->type == EX_VALUE)
3808 return operandFromValue (tree->opval.val);
3810 if (tree->type == EX_LINK)
3811 return operandFromLink (tree->opval.lnk);
3813 /* if we find a nullop */
3814 if (tree->type == EX_OP &&
3815 (tree->opval.op == NULLOP ||
3816 tree->opval.op == BLOCK))
3818 if (tree->left && tree->left->type == EX_VALUE)
3819 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3821 ast2iCode (tree->left,lvl+1);
3822 if (tree->right && tree->right->type == EX_VALUE)
3823 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3825 ast2iCode (tree->right,lvl+1);
3829 /* special cases for not evaluating */
3830 if (tree->opval.op != ':' &&
3831 tree->opval.op != '?' &&
3832 tree->opval.op != CALL &&
3833 tree->opval.op != IFX &&
3834 tree->opval.op != AND_OP &&
3835 tree->opval.op != OR_OP &&
3836 tree->opval.op != LABEL &&
3837 tree->opval.op != GOTO &&
3838 tree->opval.op != SWITCH &&
3839 tree->opval.op != FUNCTION &&
3840 tree->opval.op != INLINEASM &&
3841 tree->opval.op != CRITICAL)
3844 if (IS_ASSIGN_OP (tree->opval.op) ||
3845 IS_DEREF_OP (tree) ||
3846 (tree->opval.op == '&' && !tree->right) ||
3847 tree->opval.op == PTR_OP)
3850 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3851 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3854 left = operandFromAst (tree->left,lvl);
3856 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3857 left = geniCodeRValue (left, TRUE);
3861 left = operandFromAst (tree->left,lvl);
3863 if (tree->opval.op == INC_OP ||
3864 tree->opval.op == DEC_OP)
3867 right = operandFromAst (tree->right,lvl);
3872 right = operandFromAst (tree->right,lvl);
3876 /* now depending on the type of operand */
3877 /* this will be a biggy */
3878 switch (tree->opval.op)
3881 case '[': /* array operation */
3883 //sym_link *ltype = operandType (left);
3884 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3885 left = geniCodeRValue (left, FALSE);
3886 right = geniCodeRValue (right, TRUE);
3889 return geniCodeArray (left, right,lvl);
3891 case '.': /* structure dereference */
3892 if (IS_PTR (operandType (left)))
3893 left = geniCodeRValue (left, TRUE);
3895 left = geniCodeRValue (left, FALSE);
3897 return geniCodeStruct (left, right, tree->lvalue);
3899 case PTR_OP: /* structure pointer dereference */
3902 pType = operandType (left);
3903 left = geniCodeRValue (left, TRUE);
3905 setOClass (pType, getSpec (operandType (left)));
3908 return geniCodeStruct (left, right, tree->lvalue);
3910 case INC_OP: /* increment operator */
3912 return geniCodePostInc (left);
3914 return geniCodePreInc (right, tree->lvalue);
3916 case DEC_OP: /* decrement operator */
3918 return geniCodePostDec (left);
3920 return geniCodePreDec (right, tree->lvalue);
3922 case '&': /* bitwise and or address of operator */
3924 { /* this is a bitwise operator */
3925 left = geniCodeRValue (left, FALSE);
3926 right = geniCodeRValue (right, FALSE);
3927 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3930 return geniCodeAddressOf (left);
3932 case '|': /* bitwise or & xor */
3934 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3935 geniCodeRValue (right, FALSE),
3940 return geniCodeDivision (geniCodeRValue (left, FALSE),
3941 geniCodeRValue (right, FALSE),
3942 getResultTypeFromType (tree->ftype));
3945 return geniCodeModulus (geniCodeRValue (left, FALSE),
3946 geniCodeRValue (right, FALSE),
3947 getResultTypeFromType (tree->ftype));
3950 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3951 geniCodeRValue (right, FALSE),
3952 getResultTypeFromType (tree->ftype));
3954 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3958 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3959 geniCodeRValue (right, FALSE),
3960 getResultTypeFromType (tree->ftype));
3962 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3966 return geniCodeAdd (geniCodeRValue (left, FALSE),
3967 geniCodeRValue (right, FALSE),
3968 getResultTypeFromType (tree->ftype),
3971 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3974 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3975 geniCodeRValue (right, FALSE),
3976 getResultTypeFromType (tree->ftype));
3979 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3980 geniCodeRValue (right, FALSE));
3982 #if 0 // this indeed needs a second thought
3986 // let's keep this simple: get the rvalue we need
3987 op=geniCodeRValue (right, FALSE);
3988 // now cast it to whatever we want
3989 op=geniCodeCast (operandType(left), op, FALSE);
3990 // if this is going to be used as an lvalue, make it so
3996 #else // bug #604575, is it a bug ????
3997 return geniCodeCast (operandType (left),
3998 geniCodeRValue (right, FALSE), FALSE);
4005 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4010 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4011 setOperandType (op, UCHARTYPE);
4016 return geniCodeLogicAndOr (tree, lvl);
4023 /* different compilers (even different gccs) evaluate
4024 the two calls in a different order. to get the same
4025 result on all machines we've to specify a clear sequence.
4026 return geniCodeLogic (geniCodeRValue (left, FALSE),
4027 geniCodeRValue (right, FALSE),
4031 operand *leftOp, *rightOp;
4033 leftOp = geniCodeRValue (left , FALSE);
4034 rightOp = geniCodeRValue (right, FALSE);
4036 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4039 return geniCodeConditional (tree,lvl);
4042 return operandFromLit (getSize (tree->right->ftype));
4046 sym_link *rtype = operandType (right);
4047 sym_link *ltype = operandType (left);
4048 if (IS_PTR (rtype) && IS_ITEMP (right)
4049 && right->isaddr && compareType (rtype->next, ltype) == 1)
4050 right = geniCodeRValue (right, TRUE);
4052 right = geniCodeRValue (right, FALSE);
4054 geniCodeAssign (left, right, 0, 1);
4059 geniCodeAssign (left,
4060 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4062 geniCodeRValue (right, FALSE),
4063 getResultTypeFromType (tree->ftype)),
4068 geniCodeAssign (left,
4069 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4071 geniCodeRValue (right, FALSE),
4072 getResultTypeFromType (tree->ftype)),
4076 geniCodeAssign (left,
4077 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4079 geniCodeRValue (right, FALSE),
4080 getResultTypeFromType (tree->ftype)),
4084 sym_link *rtype = operandType (right);
4085 sym_link *ltype = operandType (left);
4086 if (IS_PTR (rtype) && IS_ITEMP (right)
4087 && right->isaddr && compareType (rtype->next, ltype) == 1)
4088 right = geniCodeRValue (right, TRUE);
4090 right = geniCodeRValue (right, FALSE);
4093 return geniCodeAssign (left,
4094 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4097 getResultTypeFromType (tree->ftype),
4103 sym_link *rtype = operandType (right);
4104 sym_link *ltype = operandType (left);
4105 if (IS_PTR (rtype) && IS_ITEMP (right)
4106 && right->isaddr && compareType (rtype->next, ltype) == 1)
4108 right = geniCodeRValue (right, TRUE);
4112 right = geniCodeRValue (right, FALSE);
4115 geniCodeAssign (left,
4116 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4119 getResultTypeFromType (tree->ftype)),
4124 geniCodeAssign (left,
4125 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4127 geniCodeRValue (right, FALSE),
4128 getResultTypeFromType (tree->ftype)),
4132 geniCodeAssign (left,
4133 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4135 geniCodeRValue (right, FALSE)), 0, 1);
4138 geniCodeAssign (left,
4139 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4141 geniCodeRValue (right, FALSE),
4143 operandType (left)), 0, 1);
4146 geniCodeAssign (left,
4147 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4149 geniCodeRValue (right, FALSE),
4151 operandType (left)), 0, 1);
4154 geniCodeAssign (left,
4155 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4157 geniCodeRValue (right, FALSE),
4159 operandType (left)), 0, 1);
4161 return geniCodeRValue (right, FALSE);
4164 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4167 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4168 return ast2iCode (tree->right,lvl+1);
4171 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4172 return ast2iCode (tree->right,lvl+1);
4175 geniCodeFunctionBody (tree,lvl);
4179 geniCodeReturn (right);
4183 geniCodeIfx (tree,lvl);
4187 geniCodeSwitch (tree,lvl);
4191 geniCodeInline (tree);
4195 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4199 geniCodeCritical (tree, lvl);
4205 /*-----------------------------------------------------------------*/
4206 /* reverseICChain - gets from the list and creates a linkedlist */
4207 /*-----------------------------------------------------------------*/
4214 while ((loop = getSet (&iCodeChain)))
4226 /*-----------------------------------------------------------------*/
4227 /* iCodeFromAst - given an ast will convert it to iCode */
4228 /*-----------------------------------------------------------------*/
4230 iCodeFromAst (ast * tree)
4232 returnLabel = newiTempLabel ("_return");
4233 entryLabel = newiTempLabel ("_entry");
4235 return reverseiCChain ();
4238 static const char *opTypeToStr(OPTYPE op)
4242 case SYMBOL: return "symbol";
4243 case VALUE: return "value";
4244 case TYPE: return "type";
4246 return "undefined type";
4250 operand *validateOpType(operand *op,
4257 if (op && op->type == type)
4262 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4263 " expected %s, got %s\n",
4264 macro, args, file, line,
4265 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4267 return op; // never reached, makes compiler happy.