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);
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 = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1318 retval = operandFromLit (!operandLitValue (left));
1322 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1323 " operandOperation invalid operator ");
1331 /*-----------------------------------------------------------------*/
1332 /* isOperandEqual - compares two operand & return 1 if they r = */
1333 /*-----------------------------------------------------------------*/
1335 isOperandEqual (operand * left, operand * right)
1337 /* if the pointers are equal then they are equal */
1341 /* if either of them null then false */
1342 if (!left || !right)
1345 if (left->type != right->type)
1348 if (IS_SYMOP (left) && IS_SYMOP (right))
1349 return left->key == right->key;
1351 /* if types are the same */
1355 return isSymbolEqual (left->operand.symOperand,
1356 right->operand.symOperand);
1358 return (floatFromVal (left->operand.valOperand) ==
1359 floatFromVal (right->operand.valOperand));
1361 if (compareType (left->operand.typeOperand,
1362 right->operand.typeOperand) == 1)
1369 /*-------------------------------------------------------------------*/
1370 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1371 /*-------------------------------------------------------------------*/
1373 isiCodeEqual (iCode * left, iCode * right)
1375 /* if the same pointer */
1379 /* if either of them null */
1380 if (!left || !right)
1383 /* if operand are the same */
1384 if (left->op == right->op)
1387 /* compare all the elements depending on type */
1388 if (left->op != IFX)
1390 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1392 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1398 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1400 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1402 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1411 /*-----------------------------------------------------------------*/
1412 /* newiTempFromOp - create a temp Operand with same attributes */
1413 /*-----------------------------------------------------------------*/
1415 newiTempFromOp (operand * op)
1425 nop = newiTempOperand (operandType (op), TRUE);
1426 nop->isaddr = op->isaddr;
1427 nop->isvolatile = op->isvolatile;
1428 nop->isGlobal = op->isGlobal;
1429 nop->isLiteral = op->isLiteral;
1430 nop->usesDefs = op->usesDefs;
1431 nop->isParm = op->isParm;
1435 /*-----------------------------------------------------------------*/
1436 /* operand from operand - creates an operand holder for the type */
1437 /*-----------------------------------------------------------------*/
1439 operandFromOperand (operand * op)
1445 nop = newOperand ();
1446 nop->type = op->type;
1447 nop->isaddr = op->isaddr;
1449 nop->isvolatile = op->isvolatile;
1450 nop->isGlobal = op->isGlobal;
1451 nop->isLiteral = op->isLiteral;
1452 nop->usesDefs = op->usesDefs;
1453 nop->isParm = op->isParm;
1458 nop->operand.symOperand = op->operand.symOperand;
1461 nop->operand.valOperand = op->operand.valOperand;
1464 nop->operand.typeOperand = op->operand.typeOperand;
1471 /*-----------------------------------------------------------------*/
1472 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1473 /*-----------------------------------------------------------------*/
1475 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1477 operand *nop = operandFromOperand (op);
1479 if (nop->type == SYMBOL)
1481 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1482 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1488 /*-----------------------------------------------------------------*/
1489 /* operandFromSymbol - creates an operand from a symbol */
1490 /*-----------------------------------------------------------------*/
1492 operandFromSymbol (symbol * sym)
1497 /* if the symbol's type is a literal */
1498 /* then it is an enumerator type */
1499 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1500 return operandFromValue (valFromType (sym->etype));
1503 sym->key = ++operandKey;
1505 /* if this an implicit variable, means struct/union */
1506 /* member so just return it */
1507 if (sym->implicit || IS_FUNC (sym->type))
1511 op->operand.symOperand = sym;
1513 op->isvolatile = isOperandVolatile (op, TRUE);
1514 op->isGlobal = isOperandGlobal (op);
1518 /* under the following conditions create a
1519 register equivalent for a local symbol */
1520 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1521 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1523 (!(options.model == MODEL_FLAT24)) ) &&
1524 options.stackAuto == 0)
1527 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1528 !IS_FUNC (sym->type) && /* not a function */
1529 !sym->_isparm && /* not a parameter */
1530 sym->level && /* is a local variable */
1531 !sym->addrtaken && /* whose address has not been taken */
1532 !sym->reqv && /* does not already have a reg equivalence */
1533 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1534 !IS_STATIC (sym->etype) && /* and not declared static */
1535 !sym->islbl && /* not a label */
1536 ok && /* farspace check */
1537 !IS_BITVAR (sym->etype) /* not a bit variable */
1541 /* we will use it after all optimizations
1542 and before liveRange calculation */
1543 sym->reqv = newiTempOperand (sym->type, 0);
1544 sym->reqv->key = sym->key;
1545 OP_SYMBOL (sym->reqv)->prereqv = sym;
1546 OP_SYMBOL (sym->reqv)->key = sym->key;
1547 OP_SYMBOL (sym->reqv)->isreqv = 1;
1548 OP_SYMBOL (sym->reqv)->islocal = 1;
1549 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1550 SPIL_LOC (sym->reqv) = sym;
1553 if (!IS_AGGREGATE (sym->type))
1557 op->operand.symOperand = sym;
1560 op->isvolatile = isOperandVolatile (op, TRUE);
1561 op->isGlobal = isOperandGlobal (op);
1562 op->isPtr = IS_PTR (operandType (op));
1563 op->isParm = sym->_isparm;
1568 /* itemp = &[_symbol] */
1570 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1571 IC_LEFT (ic)->type = SYMBOL;
1572 IC_LEFT (ic)->operand.symOperand = sym;
1573 IC_LEFT (ic)->key = sym->key;
1574 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1575 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1576 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1579 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1580 if (IS_ARRAY (sym->type))
1582 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1583 IC_RESULT (ic)->isaddr = 0;
1586 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1590 return IC_RESULT (ic);
1593 /*-----------------------------------------------------------------*/
1594 /* operandFromValue - creates an operand from value */
1595 /*-----------------------------------------------------------------*/
1597 operandFromValue (value * val)
1601 /* if this is a symbol then do the symbol thing */
1603 return operandFromSymbol (val->sym);
1605 /* this is not a symbol */
1608 op->operand.valOperand = val;
1609 op->isLiteral = isOperandLiteral (op);
1613 /*-----------------------------------------------------------------*/
1614 /* operandFromLink - operand from typeChain */
1615 /*-----------------------------------------------------------------*/
1617 operandFromLink (sym_link * type)
1621 /* operand from sym_link */
1627 op->operand.typeOperand = copyLinkChain (type);
1631 /*-----------------------------------------------------------------*/
1632 /* operandFromLit - makes an operand from a literal value */
1633 /*-----------------------------------------------------------------*/
1635 operandFromLit (double i)
1637 return operandFromValue (valueFromLit (i));
1640 /*-----------------------------------------------------------------*/
1641 /* operandFromAst - creates an operand from an ast */
1642 /*-----------------------------------------------------------------*/
1644 operandFromAst (ast * tree,int lvl)
1650 /* depending on type do */
1654 return ast2iCode (tree,lvl+1);
1658 return operandFromValue (tree->opval.val);
1662 return operandFromLink (tree->opval.lnk);
1669 /* Just to keep the compiler happy */
1670 return (operand *) 0;
1673 /*-----------------------------------------------------------------*/
1674 /* setOperandType - sets the operand's type to the given type */
1675 /*-----------------------------------------------------------------*/
1677 setOperandType (operand * op, sym_link * type)
1679 /* depending on the type of operand */
1684 op->operand.valOperand->etype =
1685 getSpec (op->operand.valOperand->type =
1686 copyLinkChain (type));
1690 if (op->operand.symOperand->isitmp)
1691 op->operand.symOperand->etype =
1692 getSpec (op->operand.symOperand->type =
1693 copyLinkChain (type));
1695 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1696 "attempt to modify type of source");
1700 op->operand.typeOperand = copyLinkChain (type);
1706 /*-----------------------------------------------------------------*/
1707 /* Get size in byte of ptr need to access an array */
1708 /*-----------------------------------------------------------------*/
1710 getArraySizePtr (operand * op)
1712 sym_link *ltype = operandType(op);
1716 int size = getSize(ltype);
1717 return(IS_GENPTR(ltype)?(size-1):size);
1722 sym_link *letype = getSpec(ltype);
1723 switch (PTR_TYPE (SPEC_OCLS (letype)))
1735 return (GPTRSIZE-1);
1744 /*-----------------------------------------------------------------*/
1745 /* perform "usual unary conversions" */
1746 /*-----------------------------------------------------------------*/
1749 usualUnaryConversions (operand * op)
1751 if (IS_INTEGRAL (operandType (op)))
1753 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1756 return geniCodeCast (INTTYPE, op, TRUE);
1763 /*-----------------------------------------------------------------*/
1764 /* perform "usual binary conversions" */
1765 /*-----------------------------------------------------------------*/
1768 usualBinaryConversions (operand ** op1, operand ** op2,
1769 RESULT_TYPE resultType, int op)
1772 sym_link *rtype = operandType (*op2);
1773 sym_link *ltype = operandType (*op1);
1775 ctype = computeType (ltype, rtype, resultType, op);
1782 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1784 /* one byte operations: keep signedness for code generator */
1792 *op1 = geniCodeCast (ctype, *op1, TRUE);
1793 *op2 = geniCodeCast (ctype, *op2, TRUE);
1798 /*-----------------------------------------------------------------*/
1799 /* geniCodeValueAtAddress - generate intermeditate code for value */
1801 /*-----------------------------------------------------------------*/
1803 geniCodeRValue (operand * op, bool force)
1806 sym_link *type = operandType (op);
1807 sym_link *etype = getSpec (type);
1809 /* if this is an array & already */
1810 /* an address then return this */
1811 if (IS_AGGREGATE (type) ||
1812 (IS_PTR (type) && !force && !op->isaddr))
1813 return operandFromOperand (op);
1815 /* if this is not an address then must be */
1816 /* rvalue already so return this one */
1820 /* if this is not a temp symbol then */
1821 if (!IS_ITEMP (op) &&
1823 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1825 op = operandFromOperand (op);
1830 if (IS_SPEC (type) &&
1831 IS_TRUE_SYMOP (op) &&
1832 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1833 (options.model == MODEL_FLAT24) ))
1835 op = operandFromOperand (op);
1840 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1841 if (IS_PTR (type) && op->isaddr && force)
1844 type = copyLinkChain (type);
1846 IC_RESULT (ic) = newiTempOperand (type, 1);
1847 IC_RESULT (ic)->isaddr = 0;
1849 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1853 return IC_RESULT (ic);
1856 /*-----------------------------------------------------------------*/
1857 /* geniCodeCast - changes the value from one type to another */
1858 /*-----------------------------------------------------------------*/
1860 geniCodeCast (sym_link * type, operand * op, bool implicit)
1864 sym_link *opetype = getSpec (optype = operandType (op));
1868 /* one of them has size zero then error */
1869 if (IS_VOID (optype))
1871 werror (E_CAST_ZERO);
1875 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1877 geniCodeArray2Ptr (op);
1881 /* if the operand is already the desired type then do nothing */
1882 if (compareType (type, optype) == 1)
1885 /* if this is a literal then just change the type & return */
1886 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1888 return operandFromValue (valCastLiteral (type,
1889 operandLitValue (op)));
1892 /* if casting to/from pointers, do some checking */
1893 if (IS_PTR(type)) { // to a pointer
1894 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1895 if (IS_INTEGRAL(optype)) {
1896 // maybe this is NULL, than it's ok.
1897 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1898 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1899 // no way to set the storage
1900 if (IS_LITERAL(optype)) {
1901 werror(E_LITERAL_GENERIC);
1904 werror(E_NONPTR2_GENPTR);
1907 } else if (implicit) {
1908 werror(W_INTEGRAL2PTR_NOCAST);
1913 // shouldn't do that with float, array or structure unless to void
1914 if (!IS_VOID(getSpec(type)) &&
1915 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1916 werror(E_INCOMPAT_TYPES);
1920 } else { // from a pointer to a pointer
1921 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1922 // if not a pointer to a function
1923 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1924 if (implicit) { // if not to generic, they have to match
1925 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1926 werror(E_INCOMPAT_PTYPES);
1933 } else { // to a non pointer
1934 if (IS_PTR(optype)) { // from a pointer
1935 if (implicit) { // sneaky
1936 if (IS_INTEGRAL(type)) {
1937 werror(W_PTR2INTEGRAL_NOCAST);
1939 } else { // shouldn't do that with float, array or structure
1940 werror(E_INCOMPAT_TYPES);
1947 printFromToType (optype, type);
1950 /* if they are the same size create an assignment */
1952 /* This seems very dangerous to me, since there are several */
1953 /* optimizations (for example, gcse) that don't notice the */
1954 /* cast hidden in this assignement and may simplify an */
1955 /* iCode to use the original (uncasted) operand. */
1956 /* Unfortunately, other things break when this cast is */
1957 /* made explicit. Need to fix this someday. */
1958 /* -- EEP, 2004/01/21 */
1959 if (getSize (type) == getSize (optype) &&
1960 !IS_BITFIELD (type) &&
1962 !IS_FLOAT (optype) &&
1963 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1964 (!IS_SPEC (type) && !IS_SPEC (optype))))
1966 ic = newiCode ('=', NULL, op);
1967 IC_RESULT (ic) = newiTempOperand (type, 0);
1968 SPIL_LOC (IC_RESULT (ic)) =
1969 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1970 IC_RESULT (ic)->isaddr = 0;
1974 ic = newiCode (CAST, operandFromLink (type),
1975 geniCodeRValue (op, FALSE));
1977 IC_RESULT (ic) = newiTempOperand (type, 0);
1980 /* preserve the storage class & output class */
1981 /* of the original variable */
1982 restype = getSpec (operandType (IC_RESULT (ic)));
1983 if (!IS_LITERAL(opetype) &&
1985 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1986 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1989 return IC_RESULT (ic);
1992 /*-----------------------------------------------------------------*/
1993 /* geniCodeLabel - will create a Label */
1994 /*-----------------------------------------------------------------*/
1996 geniCodeLabel (symbol * label)
2000 ic = newiCodeLabelGoto (LABEL, label);
2004 /*-----------------------------------------------------------------*/
2005 /* geniCodeGoto - will create a Goto */
2006 /*-----------------------------------------------------------------*/
2008 geniCodeGoto (symbol * label)
2012 ic = newiCodeLabelGoto (GOTO, label);
2016 /*-----------------------------------------------------------------*/
2017 /* geniCodeMultiply - gen intermediate code for multiplication */
2018 /*-----------------------------------------------------------------*/
2020 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2027 /* if they are both literal then we know the result */
2028 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2029 return operandFromValue (valMult (left->operand.valOperand,
2030 right->operand.valOperand));
2032 if (IS_LITERAL(retype)) {
2033 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2036 resType = usualBinaryConversions (&left, &right, resultType, '*');
2038 rtype = operandType (right);
2039 retype = getSpec (rtype);
2040 ltype = operandType (left);
2041 letype = getSpec (ltype);
2044 /* if the right is a literal & power of 2 */
2045 /* then make it a left shift */
2046 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2047 efficient in most cases than 2 bytes result = 2 bytes << literal
2048 if port has 1 byte muldiv */
2049 if (p2 && !IS_FLOAT (letype)
2050 && !((resultType != RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2051 && (port->support.muldiv == 1))
2052 && strcmp (port->target, "pic14") != 0 /* don't shift for pic */
2053 && strcmp (port->target, "pic16") != 0)
2055 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2057 /* LEFT_OP need same size for left and result, */
2058 left = geniCodeCast (resType, left, TRUE);
2059 ltype = operandType (left);
2061 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2065 ic = newiCode ('*', left, right); /* normal multiplication */
2066 /* if the size left or right > 1 then support routine */
2067 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2071 IC_RESULT (ic) = newiTempOperand (resType, 1);
2074 return IC_RESULT (ic);
2077 /*-----------------------------------------------------------------*/
2078 /* geniCodeDivision - gen intermediate code for division */
2079 /*-----------------------------------------------------------------*/
2081 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2086 sym_link *rtype = operandType (right);
2087 sym_link *retype = getSpec (rtype);
2088 sym_link *ltype = operandType (left);
2089 sym_link *letype = getSpec (ltype);
2091 resType = usualBinaryConversions (&left, &right, resultType, '/');
2093 /* if the right is a literal & power of 2
2094 and left is unsigned then make it a
2096 if (IS_LITERAL (retype) &&
2097 !IS_FLOAT (letype) &&
2098 IS_UNSIGNED(letype) &&
2099 (p2 = powof2 ((TYPE_UDWORD)
2100 floatFromVal (right->operand.valOperand)))) {
2101 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2105 ic = newiCode ('/', left, right); /* normal division */
2106 /* if the size left or right > 1 then support routine */
2107 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2110 IC_RESULT (ic) = newiTempOperand (resType, 0);
2113 return IC_RESULT (ic);
2115 /*-----------------------------------------------------------------*/
2116 /* geniCodeModulus - gen intermediate code for modulus */
2117 /*-----------------------------------------------------------------*/
2119 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2125 /* if they are both literal then we know the result */
2126 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2127 return operandFromValue (valMod (left->operand.valOperand,
2128 right->operand.valOperand));
2130 resType = usualBinaryConversions (&left, &right, resultType, '%');
2132 /* now they are the same size */
2133 ic = newiCode ('%', left, right);
2135 /* if the size left or right > 1 then support routine */
2136 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2138 IC_RESULT (ic) = newiTempOperand (resType, 0);
2141 return IC_RESULT (ic);
2144 /*-----------------------------------------------------------------*/
2145 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2146 /*-----------------------------------------------------------------*/
2148 geniCodePtrPtrSubtract (operand * left, operand * right)
2154 /* if they are both literals then */
2155 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2157 result = operandFromValue (valMinus (left->operand.valOperand,
2158 right->operand.valOperand));
2162 ic = newiCode ('-', left, right);
2164 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2168 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2172 // should we really do this? is this ANSI?
2173 return geniCodeDivision (result,
2174 operandFromLit (getSize (ltype->next)),
2178 /*-----------------------------------------------------------------*/
2179 /* geniCodeSubtract - generates code for subtraction */
2180 /*-----------------------------------------------------------------*/
2182 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2189 /* if they both pointers then */
2190 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2191 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2192 return geniCodePtrPtrSubtract (left, right);
2194 /* if they are both literal then we know the result */
2195 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2196 && left->isLiteral && right->isLiteral)
2197 return operandFromValue (valMinus (left->operand.valOperand,
2198 right->operand.valOperand));
2200 /* if left is an array or pointer */
2201 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2203 isarray = left->isaddr;
2204 right = geniCodeMultiply (right,
2205 operandFromLit (getSize (ltype->next)),
2206 (getArraySizePtr(left) >= INTSIZE) ?
2209 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2212 { /* make them the same size */
2213 resType = usualBinaryConversions (&left, &right, resultType, '-');
2216 ic = newiCode ('-', left, right);
2218 IC_RESULT (ic) = newiTempOperand (resType, 1);
2219 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2221 /* if left or right is a float */
2222 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2226 return IC_RESULT (ic);
2229 /*-----------------------------------------------------------------*/
2230 /* geniCodeAdd - generates iCode for addition */
2231 /*-----------------------------------------------------------------*/
2233 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2242 /* if the right side is LITERAL zero */
2243 /* return the left side */
2244 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2247 /* if left is literal zero return right */
2248 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2251 /* if left is a pointer then size */
2252 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2254 isarray = left->isaddr;
2255 // there is no need to multiply with 1
2256 if (getSize (ltype->next) != 1)
2258 size = operandFromLit (getSize (ltype->next));
2259 SPEC_USIGN (getSpec (operandType (size))) = 1;
2260 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2261 right = geniCodeMultiply (right,
2263 (getArraySizePtr(left) >= INTSIZE) ?
2266 /* Even if right is a 'unsigned char',
2267 the result will be a 'signed int' due to the promotion rules.
2268 It doesn't make sense when accessing arrays, so let's fix it here: */
2270 SPEC_USIGN (getSpec (operandType (right))) = 1;
2272 resType = copyLinkChain (ltype);
2275 { // make them the same size
2276 resType = usualBinaryConversions (&left, &right, resultType, '+');
2279 /* if they are both literals then we know */
2280 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2281 && left->isLiteral && right->isLiteral)
2282 return operandFromValue (valPlus (valFromType (ltype),
2283 valFromType (rtype)));
2285 ic = newiCode ('+', left, right);
2287 IC_RESULT (ic) = newiTempOperand (resType, 1);
2288 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2290 /* if left or right is a float then support
2292 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2297 return IC_RESULT (ic);
2301 /*-----------------------------------------------------------------*/
2302 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2303 /*-----------------------------------------------------------------*/
2305 aggrToPtr (sym_link * type, bool force)
2310 if (IS_PTR (type) && !force)
2313 etype = getSpec (type);
2314 ptype = newLink (DECLARATOR);
2318 /* set the pointer depending on the storage class */
2319 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2323 /*-----------------------------------------------------------------*/
2324 /* geniCodeArray2Ptr - array to pointer */
2325 /*-----------------------------------------------------------------*/
2327 geniCodeArray2Ptr (operand * op)
2329 sym_link *optype = operandType (op);
2330 sym_link *opetype = getSpec (optype);
2332 /* set the pointer depending on the storage class */
2333 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2340 /*-----------------------------------------------------------------*/
2341 /* geniCodeArray - array access */
2342 /*-----------------------------------------------------------------*/
2344 geniCodeArray (operand * left, operand * right, int lvl)
2348 sym_link *ltype = operandType (left);
2353 if (IS_PTR (ltype->next) && left->isaddr)
2355 left = geniCodeRValue (left, FALSE);
2358 return geniCodeDerefPtr (geniCodeAdd (left,
2360 (getArraySizePtr(left) >= INTSIZE) ?
2366 size = operandFromLit (getSize (ltype->next));
2367 SPEC_USIGN (getSpec (operandType (size))) = 1;
2368 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2369 right = geniCodeMultiply (right,
2371 (getArraySizePtr(left) >= INTSIZE) ?
2374 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2375 It doesn't make sense when accessing arrays, so let's fix it here: */
2377 SPEC_USIGN (getSpec (operandType (right))) = 1;
2378 /* we can check for limits here */
2379 /* already done in SDCCast.c
2380 if (isOperandLiteral (right) &&
2383 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2385 werror (W_IDX_OUT_OF_BOUNDS,
2386 (int) operandLitValue (right) / getSize (ltype->next),
2391 ic = newiCode ('+', left, right);
2393 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2394 !IS_AGGREGATE (ltype->next) &&
2395 !IS_PTR (ltype->next))
2396 ? ltype : ltype->next), 0);
2398 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2401 return IC_RESULT (ic);
2404 /*-----------------------------------------------------------------*/
2405 /* geniCodeStruct - generates intermediate code for structures */
2406 /*-----------------------------------------------------------------*/
2408 geniCodeStruct (operand * left, operand * right, bool islval)
2411 sym_link *type = operandType (left);
2412 sym_link *etype = getSpec (type);
2414 symbol *element = getStructElement (SPEC_STRUCT (etype),
2415 right->operand.symOperand);
2417 wassert(IS_SYMOP(right));
2419 /* add the offset */
2420 ic = newiCode ('+', left, operandFromLit (element->offset));
2422 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2424 /* preserve the storage & output class of the struct */
2425 /* as well as the volatile attribute */
2426 retype = getSpec (operandType (IC_RESULT (ic)));
2427 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2428 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2429 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2430 SPEC_CONST (retype) |= SPEC_CONST (etype);
2432 if (IS_PTR (element->type))
2433 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2435 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2438 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2441 /*-----------------------------------------------------------------*/
2442 /* geniCodePostInc - generate int code for Post increment */
2443 /*-----------------------------------------------------------------*/
2445 geniCodePostInc (operand * op)
2449 sym_link *optype = operandType (op);
2451 operand *rv = (IS_ITEMP (op) ?
2452 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2454 sym_link *rvtype = operandType (rv);
2457 /* if this is not an address we have trouble */
2460 werror (E_LVALUE_REQUIRED, "++");
2464 rOp = newiTempOperand (rvtype, 0);
2465 OP_SYMBOL(rOp)->noSpilLoc = 1;
2468 OP_SYMBOL(rv)->noSpilLoc = 1;
2470 geniCodeAssign (rOp, rv, 0);
2472 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2473 if (IS_FLOAT (rvtype))
2474 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2476 ic = newiCode ('+', rv, operandFromLit (size));
2478 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2481 geniCodeAssign (op, result, 0);
2487 /*-----------------------------------------------------------------*/
2488 /* geniCodePreInc - generate code for preIncrement */
2489 /*-----------------------------------------------------------------*/
2491 geniCodePreInc (operand * op, bool lvalue)
2494 sym_link *optype = operandType (op);
2495 operand *rop = (IS_ITEMP (op) ?
2496 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2498 sym_link *roptype = operandType (rop);
2504 werror (E_LVALUE_REQUIRED, "++");
2509 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2510 if (IS_FLOAT (roptype))
2511 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2513 ic = newiCode ('+', rop, operandFromLit (size));
2514 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2517 (void) geniCodeAssign (op, result, 0);
2518 if (lvalue || IS_TRUE_SYMOP (op))
2524 /*-----------------------------------------------------------------*/
2525 /* geniCodePostDec - generates code for Post decrement */
2526 /*-----------------------------------------------------------------*/
2528 geniCodePostDec (operand * op)
2532 sym_link *optype = operandType (op);
2534 operand *rv = (IS_ITEMP (op) ?
2535 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2537 sym_link *rvtype = operandType (rv);
2540 /* if this is not an address we have trouble */
2543 werror (E_LVALUE_REQUIRED, "--");
2547 rOp = newiTempOperand (rvtype, 0);
2548 OP_SYMBOL(rOp)->noSpilLoc = 1;
2551 OP_SYMBOL(rv)->noSpilLoc = 1;
2553 geniCodeAssign (rOp, rv, 0);
2555 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2556 if (IS_FLOAT (rvtype))
2557 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2559 ic = newiCode ('-', rv, operandFromLit (size));
2561 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2564 geniCodeAssign (op, result, 0);
2570 /*-----------------------------------------------------------------*/
2571 /* geniCodePreDec - generate code for pre decrement */
2572 /*-----------------------------------------------------------------*/
2574 geniCodePreDec (operand * op, bool lvalue)
2577 sym_link *optype = operandType (op);
2578 operand *rop = (IS_ITEMP (op) ?
2579 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2581 sym_link *roptype = operandType (rop);
2587 werror (E_LVALUE_REQUIRED, "--");
2592 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2593 if (IS_FLOAT (roptype))
2594 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2596 ic = newiCode ('-', rop, operandFromLit (size));
2597 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2600 (void) geniCodeAssign (op, result, 0);
2601 if (lvalue || IS_TRUE_SYMOP (op))
2608 /*-----------------------------------------------------------------*/
2609 /* geniCodeBitwise - gen int code for bitWise operators */
2610 /*-----------------------------------------------------------------*/
2612 geniCodeBitwise (operand * left, operand * right,
2613 int oper, sym_link * resType)
2617 left = geniCodeCast (resType, left, TRUE);
2618 right = geniCodeCast (resType, right, TRUE);
2620 ic = newiCode (oper, left, right);
2621 IC_RESULT (ic) = newiTempOperand (resType, 0);
2624 return IC_RESULT (ic);
2627 /*-----------------------------------------------------------------*/
2628 /* geniCodeAddressOf - gens icode for '&' address of operator */
2629 /*-----------------------------------------------------------------*/
2631 geniCodeAddressOf (operand * op)
2635 sym_link *optype = operandType (op);
2636 sym_link *opetype = getSpec (optype);
2638 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2640 op = operandFromOperand (op);
2645 /* lvalue check already done in decorateType */
2646 /* this must be a lvalue */
2647 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2648 /* werror (E_LVALUE_REQUIRED,"&"); */
2652 p = newLink (DECLARATOR);
2654 /* set the pointer depending on the storage class */
2655 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2657 p->next = copyLinkChain (optype);
2659 /* if already a temp */
2662 setOperandType (op, p);
2667 /* other wise make this of the type coming in */
2668 ic = newiCode (ADDRESS_OF, op, NULL);
2669 IC_RESULT (ic) = newiTempOperand (p, 1);
2670 IC_RESULT (ic)->isaddr = 0;
2672 return IC_RESULT (ic);
2674 /*-----------------------------------------------------------------*/
2675 /* setOClass - sets the output class depending on the pointer type */
2676 /*-----------------------------------------------------------------*/
2678 setOClass (sym_link * ptr, sym_link * spec)
2680 switch (DCL_TYPE (ptr))
2683 SPEC_OCLS (spec) = data;
2687 SPEC_OCLS (spec) = generic;
2691 SPEC_OCLS (spec) = xdata;
2695 SPEC_OCLS (spec) = code;
2699 SPEC_OCLS (spec) = idata;
2703 SPEC_OCLS (spec) = xstack;
2707 SPEC_OCLS (spec) = eeprom;
2716 /*-----------------------------------------------------------------*/
2717 /* geniCodeDerefPtr - dereference pointer with '*' */
2718 /*-----------------------------------------------------------------*/
2720 geniCodeDerefPtr (operand * op,int lvl)
2722 sym_link *rtype, *retype;
2723 sym_link *optype = operandType (op);
2725 // if this is an array then array access
2726 if (IS_ARRAY (optype)) {
2727 // don't worry, this will be optimized out later
2728 return geniCodeArray (op, operandFromLit (0), lvl);
2731 // just in case someone screws up
2732 wassert (IS_PTR (optype));
2734 if (IS_TRUE_SYMOP (op))
2737 op = geniCodeRValue (op, TRUE);
2740 /* now get rid of the pointer part */
2741 if (isLvaluereq(lvl) && IS_ITEMP (op))
2743 retype = getSpec (rtype = copyLinkChain (optype));
2747 retype = getSpec (rtype = copyLinkChain (optype->next));
2748 /* outputclass needs 2b updated */
2749 setOClass (optype, retype);
2752 op->isGptr = IS_GENPTR (optype);
2754 op->isaddr = (IS_PTR (rtype) ||
2755 IS_STRUCT (rtype) ||
2760 if (!isLvaluereq(lvl))
2761 op = geniCodeRValue (op, TRUE);
2763 setOperandType (op, rtype);
2768 /*-----------------------------------------------------------------*/
2769 /* geniCodeUnaryMinus - does a unary minus of the operand */
2770 /*-----------------------------------------------------------------*/
2772 geniCodeUnaryMinus (operand * op)
2775 sym_link *optype = operandType (op);
2777 if (IS_LITERAL (optype))
2778 return operandFromLit (-floatFromVal (op->operand.valOperand));
2780 ic = newiCode (UNARYMINUS, op, NULL);
2781 IC_RESULT (ic) = newiTempOperand (optype, 0);
2783 return IC_RESULT (ic);
2786 /*-----------------------------------------------------------------*/
2787 /* geniCodeLeftShift - gen i code for left shift */
2788 /*-----------------------------------------------------------------*/
2790 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2795 ic = newiCode (LEFT_OP, left, right);
2797 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2798 IC_RESULT (ic) = newiTempOperand (resType, 0);
2800 return IC_RESULT (ic);
2803 /*-----------------------------------------------------------------*/
2804 /* geniCodeRightShift - gen i code for right shift */
2805 /*-----------------------------------------------------------------*/
2807 geniCodeRightShift (operand * left, operand * right)
2811 ic = newiCode (RIGHT_OP, left, right);
2812 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2814 return IC_RESULT (ic);
2817 /*-----------------------------------------------------------------*/
2818 /* geniCodeLogic- logic code */
2819 /*-----------------------------------------------------------------*/
2821 geniCodeLogic (operand * left, operand * right, int op)
2825 sym_link *rtype = operandType (right);
2826 sym_link *ltype = operandType (left);
2828 /* left is integral type and right is literal then
2829 check if the literal value is within bounds */
2830 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2832 checkConstantRange(ltype,
2833 OP_VALUE(right), "compare operation", 1);
2836 /* if one operand is a pointer and the other is a literal generic void pointer,
2837 change the type of the literal generic void pointer to match the other pointer */
2838 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2839 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2841 /* find left's definition */
2842 ic = (iCode *) setFirstItem (iCodeChain);
2845 if (((ic->op == CAST) || (ic->op == '='))
2846 && isOperandEqual(left, IC_RESULT (ic)))
2849 ic = setNextItem (iCodeChain);
2851 /* if casting literal to generic pointer, then cast to rtype instead */
2852 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2854 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2855 ltype = operandType(left);
2858 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2859 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2861 /* find right's definition */
2862 ic = (iCode *) setFirstItem (iCodeChain);
2865 if (((ic->op == CAST) || (ic->op == '='))
2866 && isOperandEqual(right, 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 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2875 rtype = operandType(right);
2879 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NOPROM, 0);
2881 ic = newiCode (op, left, right);
2882 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2884 /* if comparing float
2885 and not a '==' || '!=' || '&&' || '||' (these
2887 if (IS_FLOAT(ctype) &&
2895 return IC_RESULT (ic);
2898 /*-----------------------------------------------------------------*/
2899 /* geniCodeUnary - for a a generic unary operation */
2900 /*-----------------------------------------------------------------*/
2902 geniCodeUnary (operand * op, int oper)
2904 iCode *ic = newiCode (oper, op, NULL);
2906 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2908 return IC_RESULT (ic);
2911 /*-----------------------------------------------------------------*/
2912 /* geniCodeConditional - geniCode for '?' ':' operation */
2913 /*-----------------------------------------------------------------*/
2915 geniCodeConditional (ast * tree,int lvl)
2918 symbol *falseLabel = newiTempLabel (NULL);
2919 symbol *exitLabel = newiTempLabel (NULL);
2920 operand *cond = ast2iCode (tree->left,lvl+1);
2921 operand *true, *false, *result;
2923 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2927 true = ast2iCode (tree->right->left,lvl+1);
2929 /* move the value to a new Operand */
2930 result = newiTempOperand (tree->right->ftype, 0);
2931 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2933 /* generate an unconditional goto */
2934 geniCodeGoto (exitLabel);
2936 /* now for the right side */
2937 geniCodeLabel (falseLabel);
2939 false = ast2iCode (tree->right->right,lvl+1);
2940 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2942 /* create the exit label */
2943 geniCodeLabel (exitLabel);
2948 /*-----------------------------------------------------------------*/
2949 /* geniCodeAssign - generate code for assignment */
2950 /*-----------------------------------------------------------------*/
2952 geniCodeAssign (operand * left, operand * right, int nosupdate)
2955 sym_link *ltype = operandType (left);
2956 sym_link *rtype = operandType (right);
2958 if (!left->isaddr && !IS_ITEMP (left))
2960 werror (E_LVALUE_REQUIRED, "assignment");
2964 /* left is integral type and right is literal then
2965 check if the literal value is within bounds */
2966 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2968 checkConstantRange(ltype,
2969 OP_VALUE(right), "= operation", 0);
2972 /* if the left & right type don't exactly match */
2973 /* if pointer set then make sure the check is
2974 done with the type & not the pointer */
2975 /* then cast rights type to left */
2977 /* first check the type for pointer assignement */
2978 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2979 compareType (ltype, rtype) <= 0)
2981 if (compareType (ltype->next, rtype) < 0)
2982 right = geniCodeCast (ltype->next, right, TRUE);
2984 else if (compareType (ltype, rtype) < 0)
2985 right = geniCodeCast (ltype, right, TRUE);
2987 /* If left is a true symbol & ! volatile
2988 create an assignment to temporary for
2989 the right & then assign this temporary
2990 to the symbol. This is SSA (static single
2991 assignment). Isn't it simple and folks have
2992 published mountains of paper on it */
2993 if (IS_TRUE_SYMOP (left) &&
2994 !isOperandVolatile (left, FALSE) &&
2995 isOperandGlobal (left))
2999 if (IS_TRUE_SYMOP (right))
3000 sym = OP_SYMBOL (right);
3001 ic = newiCode ('=', NULL, right);
3002 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3003 SPIL_LOC (right) = sym;
3007 ic = newiCode ('=', NULL, right);
3008 IC_RESULT (ic) = left;
3011 /* if left isgptr flag is set then support
3012 routine will be required */
3016 ic->nosupdate = nosupdate;
3020 /*-----------------------------------------------------------------*/
3021 /* geniCodeDummyRead - generate code for dummy read */
3022 /*-----------------------------------------------------------------*/
3024 geniCodeDummyRead (operand * op)
3027 sym_link *type = operandType (op);
3029 if (!IS_VOLATILE(type))
3032 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3038 /*-----------------------------------------------------------------*/
3039 /* geniCodeSEParms - generate code for side effecting fcalls */
3040 /*-----------------------------------------------------------------*/
3042 geniCodeSEParms (ast * parms,int lvl)
3047 if (parms->type == EX_OP && parms->opval.op == PARAM)
3049 geniCodeSEParms (parms->left,lvl);
3050 geniCodeSEParms (parms->right,lvl);
3054 /* hack don't like this but too lazy to think of
3056 if (IS_ADDRESS_OF_OP (parms))
3057 parms->left->lvalue = 1;
3059 if (IS_CAST_OP (parms) &&
3060 IS_PTR (parms->ftype) &&
3061 IS_ADDRESS_OF_OP (parms->right))
3062 parms->right->left->lvalue = 1;
3064 parms->opval.oprnd =
3065 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3067 parms->type = EX_OPERAND;
3068 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3069 SPEC_ARGREG(parms->ftype);
3072 /*-----------------------------------------------------------------*/
3073 /* geniCodeParms - generates parameters */
3074 /*-----------------------------------------------------------------*/
3076 geniCodeParms (ast * parms, value *argVals, int *stack,
3077 sym_link * ftype, int lvl)
3085 if (argVals==NULL) {
3087 argVals = FUNC_ARGS (ftype);
3090 /* if this is a param node then do the left & right */
3091 if (parms->type == EX_OP && parms->opval.op == PARAM)
3093 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3094 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3098 /* get the parameter value */
3099 if (parms->type == EX_OPERAND)
3100 pval = parms->opval.oprnd;
3103 /* maybe this else should go away ?? */
3104 /* hack don't like this but too lazy to think of
3106 if (IS_ADDRESS_OF_OP (parms))
3107 parms->left->lvalue = 1;
3109 if (IS_CAST_OP (parms) &&
3110 IS_PTR (parms->ftype) &&
3111 IS_ADDRESS_OF_OP (parms->right))
3112 parms->right->left->lvalue = 1;
3114 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3117 /* if register parm then make it a send */
3118 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3119 IFFUNC_ISBUILTIN(ftype))
3121 ic = newiCode (SEND, pval, NULL);
3122 ic->argreg = SPEC_ARGREG(parms->etype);
3123 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3128 /* now decide whether to push or assign */
3129 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3133 operand *top = operandFromSymbol (argVals->sym);
3134 /* clear useDef and other bitVectors */
3135 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3136 geniCodeAssign (top, pval, 1);
3140 sym_link *p = operandType (pval);
3142 ic = newiCode (IPUSH, pval, NULL);
3144 /* update the stack adjustment */
3145 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3150 argVals=argVals->next;
3154 /*-----------------------------------------------------------------*/
3155 /* geniCodeCall - generates temp code for calling */
3156 /*-----------------------------------------------------------------*/
3158 geniCodeCall (operand * left, ast * parms,int lvl)
3162 sym_link *type, *etype;
3166 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3167 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3168 werror (E_FUNCTION_EXPECTED);
3169 return operandFromValue(valueFromLit(0));
3172 /* take care of parameters with side-effecting
3173 function calls in them, this is required to take care
3174 of overlaying function parameters */
3175 geniCodeSEParms (parms,lvl);
3177 ftype = operandType (left);
3178 if (IS_CODEPTR (ftype))
3179 ftype = ftype->next;
3181 /* first the parameters */
3182 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3184 /* now call : if symbol then pcall */
3185 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3186 ic = newiCode (PCALL, left, NULL);
3188 ic = newiCode (CALL, left, NULL);
3191 type = copyLinkChain (ftype->next);
3192 etype = getSpec (type);
3193 SPEC_EXTR (etype) = 0;
3194 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3198 /* stack adjustment after call */
3199 ic->parmBytes = stack;
3204 /*-----------------------------------------------------------------*/
3205 /* geniCodeReceive - generate intermediate code for "receive" */
3206 /*-----------------------------------------------------------------*/
3208 geniCodeReceive (value * args)
3210 /* for all arguments that are passed in registers */
3214 if (IS_REGPARM (args->etype))
3216 operand *opr = operandFromValue (args);
3218 symbol *sym = OP_SYMBOL (opr);
3221 /* we will use it after all optimizations
3222 and before liveRange calculation */
3223 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3226 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3227 options.stackAuto == 0 &&
3228 (!(options.model == MODEL_FLAT24)) )
3233 opl = newiTempOperand (args->type, 0);
3235 sym->reqv->key = sym->key;
3236 OP_SYMBOL (sym->reqv)->key = sym->key;
3237 OP_SYMBOL (sym->reqv)->isreqv = 1;
3238 OP_SYMBOL (sym->reqv)->islocal = 0;
3239 SPIL_LOC (sym->reqv) = sym;
3243 ic = newiCode (RECEIVE, NULL, NULL);
3244 ic->argreg = SPEC_ARGREG(args->etype);
3246 currFunc->recvSize = getSize (sym->type);
3249 IC_RESULT (ic) = opr;
3257 /*-----------------------------------------------------------------*/
3258 /* geniCodeFunctionBody - create the function body */
3259 /*-----------------------------------------------------------------*/
3261 geniCodeFunctionBody (ast * tree,int lvl)
3268 /* reset the auto generation */
3274 func = ast2iCode (tree->left,lvl+1);
3275 fetype = getSpec (operandType (func));
3277 savelineno = lineno;
3278 lineno = OP_SYMBOL (func)->lineDef;
3279 /* create an entry label */
3280 geniCodeLabel (entryLabel);
3281 lineno = savelineno;
3283 /* create a proc icode */
3284 ic = newiCode (FUNCTION, func, NULL);
3285 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3289 /* for all parameters that are passed
3290 on registers add a "receive" */
3291 geniCodeReceive (tree->values.args);
3293 /* generate code for the body */
3294 ast2iCode (tree->right,lvl+1);
3296 /* create a label for return */
3297 geniCodeLabel (returnLabel);
3299 /* now generate the end proc */
3300 ic = newiCode (ENDFUNCTION, func, NULL);
3305 /*-----------------------------------------------------------------*/
3306 /* geniCodeReturn - gen icode for 'return' statement */
3307 /*-----------------------------------------------------------------*/
3309 geniCodeReturn (operand * op)
3313 /* if the operand is present force an rvalue */
3315 op = geniCodeRValue (op, FALSE);
3317 ic = newiCode (RETURN, op, NULL);
3321 /*-----------------------------------------------------------------*/
3322 /* geniCodeIfx - generates code for extended if statement */
3323 /*-----------------------------------------------------------------*/
3325 geniCodeIfx (ast * tree,int lvl)
3328 operand *condition = ast2iCode (tree->left,lvl+1);
3331 /* if condition is null then exit */
3335 condition = geniCodeRValue (condition, FALSE);
3337 cetype = getSpec (operandType (condition));
3338 /* if the condition is a literal */
3339 if (IS_LITERAL (cetype))
3341 if (floatFromVal (condition->operand.valOperand))
3343 if (tree->trueLabel)
3344 geniCodeGoto (tree->trueLabel);
3350 if (tree->falseLabel)
3351 geniCodeGoto (tree->falseLabel);
3358 if (tree->trueLabel)
3360 ic = newiCodeCondition (condition,
3365 if (tree->falseLabel)
3366 geniCodeGoto (tree->falseLabel);
3370 ic = newiCodeCondition (condition,
3377 ast2iCode (tree->right,lvl+1);
3380 /*-----------------------------------------------------------------*/
3381 /* geniCodeJumpTable - tries to create a jump table for switch */
3382 /*-----------------------------------------------------------------*/
3384 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3386 int min = 0, max = 0, t, cnt = 0;
3392 int needRangeCheck = !optimize.noJTabBoundary
3393 || tree->values.switchVals.swDefault;
3395 if (!tree || !caseVals)
3398 /* the criteria for creating a jump table is */
3399 /* all integer numbers between the maximum & minimum must */
3400 /* be present , the maximum value should not exceed 255 */
3401 min = max = (int) floatFromVal (vch = caseVals);
3402 SNPRINTF (buffer, sizeof(buffer),
3404 tree->values.switchVals.swNum,
3406 addSet (&labels, newiTempLabel (buffer));
3408 /* if there is only one case value then no need */
3409 if (!(vch = vch->next))
3414 if (((t = (int) floatFromVal (vch)) - max) != 1)
3416 SNPRINTF (buffer, sizeof(buffer),
3418 tree->values.switchVals.swNum,
3420 addSet (&labels, newiTempLabel (buffer));
3426 /* if the number of case statements <= 2 then */
3427 /* it is not economical to create the jump table */
3428 /* since two compares are needed for boundary conditions */
3429 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3432 if (tree->values.switchVals.swDefault)
3434 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3438 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3442 falseLabel = newiTempLabel (buffer);
3444 /* so we can create a jumptable */
3445 /* first we rule out the boundary conditions */
3446 /* if only optimization says so */
3449 sym_link *cetype = getSpec (operandType (cond));
3450 /* no need to check the lower bound if
3451 the condition is unsigned & minimum value is zero */
3452 if (!(min == 0 && IS_UNSIGNED (cetype)))
3454 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3455 ic = newiCodeCondition (boundary, falseLabel, NULL);
3459 /* now for upper bounds */
3460 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3461 ic = newiCodeCondition (boundary, falseLabel, NULL);
3465 /* if the min is not zero then we no make it zero */
3468 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3469 if (!IS_LITERAL(getSpec(operandType(cond))))
3470 setOperandType (cond, UCHARTYPE);
3473 /* now create the jumptable */
3474 ic = newiCode (JUMPTABLE, NULL, NULL);
3475 IC_JTCOND (ic) = cond;
3476 IC_JTLABELS (ic) = labels;
3481 /*-----------------------------------------------------------------*/
3482 /* geniCodeSwitch - changes a switch to a if statement */
3483 /*-----------------------------------------------------------------*/
3485 geniCodeSwitch (ast * tree,int lvl)
3488 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3489 value *caseVals = tree->values.switchVals.swVals;
3490 symbol *trueLabel, *falseLabel;
3492 /* If the condition is a literal, then just jump to the */
3493 /* appropriate case label. */
3494 if (IS_LITERAL(getSpec(operandType(cond))))
3496 int switchVal, caseVal;
3498 switchVal = (int) floatFromVal (cond->operand.valOperand);
3501 caseVal = (int) floatFromVal (caseVals);
3502 if (caseVal == switchVal)
3504 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3505 tree->values.switchVals.swNum, caseVal);
3506 trueLabel = newiTempLabel (buffer);
3507 geniCodeGoto (trueLabel);
3510 caseVals = caseVals->next;
3512 goto defaultOrBreak;
3515 /* if we can make this a jump table */
3516 if (geniCodeJumpTable (cond, caseVals, tree))
3517 goto jumpTable; /* no need for the comparison */
3519 /* for the cases defined do */
3523 operand *compare = geniCodeLogic (cond,
3524 operandFromValue (caseVals),
3527 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3528 tree->values.switchVals.swNum,
3529 (int) floatFromVal (caseVals));
3530 trueLabel = newiTempLabel (buffer);
3532 ic = newiCodeCondition (compare, trueLabel, NULL);
3534 caseVals = caseVals->next;
3539 /* if default is present then goto break else break */
3540 if (tree->values.switchVals.swDefault)
3542 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3546 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3549 falseLabel = newiTempLabel (buffer);
3550 geniCodeGoto (falseLabel);
3553 ast2iCode (tree->right,lvl+1);
3556 /*-----------------------------------------------------------------*/
3557 /* geniCodeInline - intermediate code for inline assembler */
3558 /*-----------------------------------------------------------------*/
3560 geniCodeInline (ast * tree)
3564 ic = newiCode (INLINEASM, NULL, NULL);
3565 IC_INLINE (ic) = tree->values.inlineasm;
3569 /*-----------------------------------------------------------------*/
3570 /* geniCodeArrayInit - intermediate code for array initializer */
3571 /*-----------------------------------------------------------------*/
3573 geniCodeArrayInit (ast * tree, operand *array)
3577 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3578 ic = newiCode (ARRAYINIT, array, NULL);
3579 IC_ARRAYILIST (ic) = tree->values.constlist;
3581 operand *left=newOperand(), *right=newOperand();
3582 left->type=right->type=SYMBOL;
3583 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3584 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3585 ic = newiCode (ARRAYINIT, left, right);
3590 /*-----------------------------------------------------------------*/
3591 /* geniCodeCritical - intermediate code for a critical statement */
3592 /*-----------------------------------------------------------------*/
3594 geniCodeCritical (ast *tree, int lvl)
3599 /* If op is NULL, the original interrupt state will saved on */
3600 /* the stack. Otherwise, it will be saved in op. */
3602 /* Generate a save of the current interrupt state & disabled */
3603 ic = newiCode (CRITICAL, NULL, NULL);
3604 IC_RESULT (ic) = op;
3607 /* Generate the critical code sequence */
3608 if (tree->left && tree->left->type == EX_VALUE)
3609 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3611 ast2iCode (tree->left,lvl+1);
3613 /* Generate a restore of the original interrupt state */
3614 ic = newiCode (ENDCRITICAL, NULL, op);
3618 /*-----------------------------------------------------------------*/
3619 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3620 /* particular case. Ie : assigning or dereferencing array or ptr */
3621 /*-----------------------------------------------------------------*/
3622 set * lvaluereqSet = NULL;
3623 typedef struct lvalItem
3630 /*-----------------------------------------------------------------*/
3631 /* addLvaluereq - add a flag for lvalreq for current ast level */
3632 /*-----------------------------------------------------------------*/
3633 void addLvaluereq(int lvl)
3635 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3638 addSetHead(&lvaluereqSet,lpItem);
3641 /*-----------------------------------------------------------------*/
3642 /* delLvaluereq - del a flag for lvalreq for current ast level */
3643 /*-----------------------------------------------------------------*/
3647 lpItem = getSet(&lvaluereqSet);
3648 if(lpItem) Safe_free(lpItem);
3650 /*-----------------------------------------------------------------*/
3651 /* clearLvaluereq - clear lvalreq flag */
3652 /*-----------------------------------------------------------------*/
3653 void clearLvaluereq()
3656 lpItem = peekSet(lvaluereqSet);
3657 if(lpItem) lpItem->req = 0;
3659 /*-----------------------------------------------------------------*/
3660 /* getLvaluereq - get the last lvalreq level */
3661 /*-----------------------------------------------------------------*/
3662 int getLvaluereqLvl()
3665 lpItem = peekSet(lvaluereqSet);
3666 if(lpItem) return lpItem->lvl;
3669 /*-----------------------------------------------------------------*/
3670 /* isLvaluereq - is lvalreq valid for this level ? */
3671 /*-----------------------------------------------------------------*/
3672 int isLvaluereq(int lvl)
3675 lpItem = peekSet(lvaluereqSet);
3676 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3680 /*-----------------------------------------------------------------*/
3681 /* ast2iCode - creates an icodeList from an ast */
3682 /*-----------------------------------------------------------------*/
3684 ast2iCode (ast * tree,int lvl)
3686 operand *left = NULL;
3687 operand *right = NULL;
3691 /* set the global variables for filename & line number */
3693 filename = tree->filename;
3695 lineno = tree->lineno;
3697 block = tree->block;
3699 scopeLevel = tree->level;
3701 seqPoint = tree->seqPoint;
3703 if (tree->type == EX_VALUE)
3704 return operandFromValue (tree->opval.val);
3706 if (tree->type == EX_LINK)
3707 return operandFromLink (tree->opval.lnk);
3709 /* if we find a nullop */
3710 if (tree->type == EX_OP &&
3711 (tree->opval.op == NULLOP ||
3712 tree->opval.op == BLOCK))
3714 if (tree->left && tree->left->type == EX_VALUE)
3715 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3717 ast2iCode (tree->left,lvl+1);
3718 if (tree->right && tree->right->type == EX_VALUE)
3719 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3721 ast2iCode (tree->right,lvl+1);
3725 /* special cases for not evaluating */
3726 if (tree->opval.op != ':' &&
3727 tree->opval.op != '?' &&
3728 tree->opval.op != CALL &&
3729 tree->opval.op != IFX &&
3730 tree->opval.op != LABEL &&
3731 tree->opval.op != GOTO &&
3732 tree->opval.op != SWITCH &&
3733 tree->opval.op != FUNCTION &&
3734 tree->opval.op != INLINEASM &&
3735 tree->opval.op != CRITICAL)
3738 if (IS_ASSIGN_OP (tree->opval.op) ||
3739 IS_DEREF_OP (tree) ||
3740 (tree->opval.op == '&' && !tree->right) ||
3741 tree->opval.op == PTR_OP)
3744 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3745 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3748 left = operandFromAst (tree->left,lvl);
3750 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3751 left = geniCodeRValue (left, TRUE);
3755 left = operandFromAst (tree->left,lvl);
3757 if (tree->opval.op == INC_OP ||
3758 tree->opval.op == DEC_OP)
3761 right = operandFromAst (tree->right,lvl);
3766 right = operandFromAst (tree->right,lvl);
3770 /* now depending on the type of operand */
3771 /* this will be a biggy */
3772 switch (tree->opval.op)
3775 case '[': /* array operation */
3777 //sym_link *ltype = operandType (left);
3778 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3779 left = geniCodeRValue (left, FALSE);
3780 right = geniCodeRValue (right, TRUE);
3783 return geniCodeArray (left, right,lvl);
3785 case '.': /* structure dereference */
3786 if (IS_PTR (operandType (left)))
3787 left = geniCodeRValue (left, TRUE);
3789 left = geniCodeRValue (left, FALSE);
3791 return geniCodeStruct (left, right, tree->lvalue);
3793 case PTR_OP: /* structure pointer dereference */
3796 pType = operandType (left);
3797 left = geniCodeRValue (left, TRUE);
3799 setOClass (pType, getSpec (operandType (left)));
3802 return geniCodeStruct (left, right, tree->lvalue);
3804 case INC_OP: /* increment operator */
3806 return geniCodePostInc (left);
3808 return geniCodePreInc (right, tree->lvalue);
3810 case DEC_OP: /* decrement operator */
3812 return geniCodePostDec (left);
3814 return geniCodePreDec (right, tree->lvalue);
3816 case '&': /* bitwise and or address of operator */
3818 { /* this is a bitwise operator */
3819 left = geniCodeRValue (left, FALSE);
3820 right = geniCodeRValue (right, FALSE);
3821 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3824 return geniCodeAddressOf (left);
3826 case '|': /* bitwise or & xor */
3828 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3829 geniCodeRValue (right, FALSE),
3834 return geniCodeDivision (geniCodeRValue (left, FALSE),
3835 geniCodeRValue (right, FALSE),
3836 getResultTypeFromType (tree->ftype));
3839 return geniCodeModulus (geniCodeRValue (left, FALSE),
3840 geniCodeRValue (right, FALSE),
3841 getResultTypeFromType (tree->ftype));
3844 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3845 geniCodeRValue (right, FALSE),
3846 getResultTypeFromType (tree->ftype));
3848 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3852 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3853 geniCodeRValue (right, FALSE),
3854 getResultTypeFromType (tree->ftype));
3856 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3860 return geniCodeAdd (geniCodeRValue (left, FALSE),
3861 geniCodeRValue (right, FALSE),
3862 getResultTypeFromType (tree->ftype),
3865 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3868 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3869 geniCodeRValue (right, FALSE),
3870 getResultTypeFromType (tree->ftype));
3873 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3874 geniCodeRValue (right, FALSE));
3876 #if 0 // this indeed needs a second thought
3880 // let's keep this simple: get the rvalue we need
3881 op=geniCodeRValue (right, FALSE);
3882 // now cast it to whatever we want
3883 op=geniCodeCast (operandType(left), op, FALSE);
3884 // if this is going to be used as an lvalue, make it so
3890 #else // bug #604575, is it a bug ????
3891 return geniCodeCast (operandType (left),
3892 geniCodeRValue (right, FALSE), FALSE);
3899 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3904 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3905 setOperandType (op, UCHARTYPE);
3916 /* different compilers (even different gccs) evaluate
3917 the two calls in a different order. to get the same
3918 result on all machines we've to specify a clear sequence.
3919 return geniCodeLogic (geniCodeRValue (left, FALSE),
3920 geniCodeRValue (right, FALSE),
3924 operand *leftOp, *rightOp;
3926 rightOp = geniCodeRValue (right, FALSE);
3927 leftOp = geniCodeRValue (left , FALSE);
3929 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3932 return geniCodeConditional (tree,lvl);
3935 return operandFromLit (getSize (tree->right->ftype));
3939 sym_link *rtype = operandType (right);
3940 sym_link *ltype = operandType (left);
3941 if (IS_PTR (rtype) && IS_ITEMP (right)
3942 && right->isaddr && compareType (rtype->next, ltype) == 1)
3943 right = geniCodeRValue (right, TRUE);
3945 right = geniCodeRValue (right, FALSE);
3947 geniCodeAssign (left, right, 0);
3952 geniCodeAssign (left,
3953 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3955 geniCodeRValue (right, FALSE), FALSE),
3956 getResultTypeFromType (tree->ftype));
3960 geniCodeAssign (left,
3961 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3963 geniCodeRValue (right, FALSE),
3964 getResultTypeFromType (tree->ftype)),
3968 geniCodeAssign (left,
3969 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3971 geniCodeRValue (right, FALSE),
3972 getResultTypeFromType (tree->ftype)),
3976 sym_link *rtype = operandType (right);
3977 sym_link *ltype = operandType (left);
3978 if (IS_PTR (rtype) && IS_ITEMP (right)
3979 && right->isaddr && compareType (rtype->next, ltype) == 1)
3980 right = geniCodeRValue (right, TRUE);
3982 right = geniCodeRValue (right, FALSE);
3985 return geniCodeAssign (left,
3986 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3989 getResultTypeFromType (tree->ftype),
3995 sym_link *rtype = operandType (right);
3996 sym_link *ltype = operandType (left);
3997 if (IS_PTR (rtype) && IS_ITEMP (right)
3998 && right->isaddr && compareType (rtype->next, ltype) == 1)
4000 right = geniCodeRValue (right, TRUE);
4004 right = geniCodeRValue (right, FALSE);
4007 geniCodeAssign (left,
4008 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4011 getResultTypeFromType (tree->ftype)),
4016 geniCodeAssign (left,
4017 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4019 geniCodeRValue (right, FALSE),
4020 getResultTypeFromType (tree->ftype)),
4024 geniCodeAssign (left,
4025 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4027 geniCodeRValue (right, FALSE)), 0);
4030 geniCodeAssign (left,
4031 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4033 geniCodeRValue (right, FALSE),
4035 operandType (left)), 0);
4038 geniCodeAssign (left,
4039 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4041 geniCodeRValue (right, FALSE),
4043 operandType (left)), 0);
4046 geniCodeAssign (left,
4047 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4049 geniCodeRValue (right, FALSE),
4051 operandType (left)), 0);
4053 return geniCodeRValue (right, FALSE);
4056 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4059 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4060 return ast2iCode (tree->right,lvl+1);
4063 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4064 return ast2iCode (tree->right,lvl+1);
4067 geniCodeFunctionBody (tree,lvl);
4071 geniCodeReturn (right);
4075 geniCodeIfx (tree,lvl);
4079 geniCodeSwitch (tree,lvl);
4083 geniCodeInline (tree);
4087 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4091 geniCodeCritical (tree, lvl);
4097 /*-----------------------------------------------------------------*/
4098 /* reverseICChain - gets from the list and creates a linkedlist */
4099 /*-----------------------------------------------------------------*/
4106 while ((loop = getSet (&iCodeChain)))
4118 /*-----------------------------------------------------------------*/
4119 /* iCodeFromAst - given an ast will convert it to iCode */
4120 /*-----------------------------------------------------------------*/
4122 iCodeFromAst (ast * tree)
4124 returnLabel = newiTempLabel ("_return");
4125 entryLabel = newiTempLabel ("_entry");
4127 return reverseiCChain ();
4130 static const char *opTypeToStr(OPTYPE op)
4134 case SYMBOL: return "symbol";
4135 case VALUE: return "value";
4136 case TYPE: return "type";
4138 return "undefined type";
4142 operand *validateOpType(operand *op,
4149 if (op && op->type == type)
4154 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4155 " expected %s, got %s\n",
4156 macro, args, file, line,
4157 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4159 return op; // never reached, makes compiler happy.