1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
43 symbol *returnLabel; /* function return label */
44 symbol *entryLabel; /* function entry label */
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeAssign (operand *, operand *, int, int);
49 static operand *geniCodeArray (operand *, operand *,int);
50 static operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
54 void setOClass (sym_link * ptr, sym_link * spec);
55 static operand *geniCodeCast (sym_link *, operand *, bool);
57 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
58 /* forward definition of ic print functions */
59 PRINTFUNC (picGetValueAtAddr);
60 PRINTFUNC (picSetValueAtAddr);
61 PRINTFUNC (picAddrOf);
62 PRINTFUNC (picGeneric);
63 PRINTFUNC (picGenericOne);
65 PRINTFUNC (picAssign);
69 PRINTFUNC (picJumpTable);
70 PRINTFUNC (picInline);
71 PRINTFUNC (picReceive);
72 PRINTFUNC (picDummyRead);
73 PRINTFUNC (picCritical);
74 PRINTFUNC (picEndCritical);
76 iCodeTable codeTable[] =
78 {'!', "not", picGenericOne, NULL},
79 {'~', "~", picGenericOne, NULL},
80 {RRC, "rrc", picGenericOne, NULL},
81 {RLC, "rlc", picGenericOne, NULL},
82 {GETHBIT, "ghbit", picGenericOne, NULL},
83 {UNARYMINUS, "-", picGenericOne, NULL},
84 {IPUSH, "push", picGenericOne, NULL},
85 {IPOP, "pop", picGenericOne, NULL},
86 {CALL, "call", picGenericOne, NULL},
87 {PCALL, "pcall", picGenericOne, NULL},
88 {FUNCTION, "proc", picGenericOne, NULL},
89 {ENDFUNCTION, "eproc", picGenericOne, NULL},
90 {RETURN, "ret", picGenericOne, NULL},
91 {'+', "+", picGeneric, NULL},
92 {'-', "-", picGeneric, NULL},
93 {'*', "*", picGeneric, NULL},
94 {'/', "/", picGeneric, NULL},
95 {'%', "%", picGeneric, NULL},
96 {'>', ">", picGeneric, NULL},
97 {'<', "<", picGeneric, NULL},
98 {LE_OP, "<=", picGeneric, NULL},
99 {GE_OP, ">=", picGeneric, NULL},
100 {EQ_OP, "==", picGeneric, NULL},
101 {NE_OP, "!=", picGeneric, NULL},
102 {AND_OP, "&&", picGeneric, NULL},
103 {OR_OP, "||", picGeneric, NULL},
104 {'^', "^", picGeneric, NULL},
105 {'|', "|", picGeneric, NULL},
106 {BITWISEAND, "&", picGeneric, NULL},
107 {LEFT_OP, "<<", picGeneric, NULL},
108 {RIGHT_OP, ">>", picGeneric, NULL},
109 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110 {ADDRESS_OF, "&", picAddrOf, NULL},
111 {CAST, "<>", picCast, NULL},
112 {'=', ":=", picAssign, NULL},
113 {LABEL, "", picLabel, NULL},
114 {GOTO, "", picGoto, NULL},
115 {JUMPTABLE, "jtab", picJumpTable, NULL},
116 {IFX, "if", picIfx, NULL},
117 {INLINEASM, "", picInline, NULL},
118 {RECEIVE, "recv", picReceive, NULL},
119 {SEND, "send", picGenericOne, NULL},
120 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
121 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
122 {CRITICAL, "critical_start", picCritical, NULL},
123 {ENDCRITICAL, "critical_end", picEndCritical, NULL}
126 /*-----------------------------------------------------------------*/
127 /* checkConstantRange: check a constant against the type */
128 /*-----------------------------------------------------------------*/
131 /* pedantic=0: allmost anything is allowed as long as the absolute
132 value is within the bit range of the type, and -1 is treated as
133 0xf..f for unsigned types (e.g. in assign)
134 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
135 pedantic>1: "char c=200" is not allowed (evaluates to -56)
138 void checkConstantRange(sym_link *ltype, value *val, char *msg,
145 max = pow ((double)2.0, (double)bitsForType(ltype));
147 if (IS_LONG(val->type)) {
148 if (IS_UNSIGNED(val->type)) {
149 v=SPEC_CVAL(val->type).v_ulong;
151 v=SPEC_CVAL(val->type).v_long;
154 if (IS_UNSIGNED(val->type)) {
155 v=SPEC_CVAL(val->type).v_uint;
157 v=SPEC_CVAL(val->type).v_int;
163 // this could be a good idea
164 if (options.pedantic)
168 if (IS_FLOAT(ltype)) {
173 if (!IS_UNSIGNED(val->type) && v<0) {
175 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
181 // if very pedantic: "char c=200" is not allowed
182 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
183 max = max/2 + negative;
190 #if 0 // temporary disabled, leaving the warning as a reminder
192 SNPRINTF (message, sizeof(message), "for %s %s in %s",
193 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
194 nounName(ltype), msg);
195 werror (W_CONST_RANGE, message);
203 /*-----------------------------------------------------------------*/
204 /* operandName - returns the name of the operand */
205 /*-----------------------------------------------------------------*/
207 printOperand (operand * op, FILE * file)
224 opetype = getSpec (operandType (op));
225 if (IS_FLOAT (opetype))
226 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
228 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
229 printTypeChain (operandType (op), file);
236 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
237 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
239 OP_LIVEFROM (op), OP_LIVETO (op),
240 OP_SYMBOL (op)->stack,
241 op->isaddr, OP_SYMBOL (op)->isreqv,
242 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
243 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
247 printTypeChain (operandType (op), file);
248 if (SPIL_LOC (op) && IS_ITEMP (op))
249 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
254 /* if assigned to registers */
255 if (OP_SYMBOL (op)->nRegs)
257 if (OP_SYMBOL (op)->isspilt)
259 if (!OP_SYMBOL (op)->remat)
260 if (OP_SYMBOL (op)->usl.spillLoc)
261 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
262 OP_SYMBOL (op)->usl.spillLoc->rname :
263 OP_SYMBOL (op)->usl.spillLoc->name));
265 fprintf (file, "[err]");
267 fprintf (file, "[remat]");
273 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
274 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
279 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
280 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
281 /* if assigned to registers */
282 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
286 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
287 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
288 OP_SYMBOL (op)->regs[i]->name :
297 printTypeChain (op->operand.typeOperand, file);
303 fprintf (file, "\n");
308 /*-----------------------------------------------------------------*/
309 /* print functions */
310 /*-----------------------------------------------------------------*/
311 PRINTFUNC (picGetValueAtAddr)
314 printOperand (IC_RESULT (ic), of);
317 printOperand (IC_LEFT (ic), of);
323 PRINTFUNC (picSetValueAtAddr)
327 printOperand (IC_LEFT (ic), of);
328 fprintf (of, "] = ");
329 printOperand (IC_RIGHT (ic), of);
333 PRINTFUNC (picAddrOf)
336 printOperand (IC_RESULT (ic), of);
337 if (IS_ITEMP (IC_LEFT (ic)))
340 fprintf (of, " = &[");
341 printOperand (IC_LEFT (ic), of);
344 if (IS_ITEMP (IC_LEFT (ic)))
345 fprintf (of, " offsetAdd ");
348 printOperand (IC_RIGHT (ic), of);
350 if (IS_ITEMP (IC_LEFT (ic)))
356 PRINTFUNC (picJumpTable)
361 fprintf (of, "%s\t", s);
362 printOperand (IC_JTCOND (ic), of);
364 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
365 sym = setNextItem (IC_JTLABELS (ic)))
366 fprintf (of, "\t\t\t%s\n", sym->name);
369 PRINTFUNC (picGeneric)
372 printOperand (IC_RESULT (ic), of);
374 printOperand (IC_LEFT (ic), of);
375 fprintf (of, " %s ", s);
376 printOperand (IC_RIGHT (ic), of);
380 PRINTFUNC (picGenericOne)
385 printOperand (IC_RESULT (ic), of);
391 fprintf (of, "%s ", s);
392 printOperand (IC_LEFT (ic), of);
395 if (!IC_RESULT (ic) && !IC_LEFT (ic))
398 if (ic->op == SEND || ic->op == RECEIVE) {
399 fprintf(of,"{argreg = %d}",ic->argreg);
407 printOperand (IC_RESULT (ic), of);
409 printOperand (IC_LEFT (ic), of);
410 printOperand (IC_RIGHT (ic), of);
415 PRINTFUNC (picAssign)
419 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
422 printOperand (IC_RESULT (ic), of);
424 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
427 fprintf (of, " %s ", s);
428 printOperand (IC_RIGHT (ic), of);
435 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
441 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
448 printOperand (IC_COND (ic), of);
451 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
454 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
456 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
460 PRINTFUNC (picInline)
462 fprintf (of, "%s", IC_INLINE (ic));
465 PRINTFUNC (picReceive)
467 printOperand (IC_RESULT (ic), of);
468 fprintf (of, " = %s ", s);
469 printOperand (IC_LEFT (ic), of);
473 PRINTFUNC (picDummyRead)
476 fprintf (of, "%s ", s);
477 printOperand (IC_RIGHT (ic), of);
481 PRINTFUNC (picCritical)
485 printOperand (IC_RESULT (ic), of);
487 fprintf (of, "(stack)");
488 fprintf (of, " = %s ", s);
492 PRINTFUNC (picEndCritical)
495 fprintf (of, "%s = ", s);
497 printOperand (IC_RIGHT (ic), of);
499 fprintf (of, "(stack)");
503 /*-----------------------------------------------------------------*/
504 /* piCode - prints one iCode */
505 /*-----------------------------------------------------------------*/
507 piCode (void *item, FILE * of)
515 icTab = getTableEntry (ic->op);
516 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
517 ic->filename, ic->lineno,
518 ic->seq, ic->key, ic->depth, ic->supportRtn);
519 icTab->iCodePrint (of, ic, icTab->printName);
525 printiCChain(ic,stdout);
527 /*-----------------------------------------------------------------*/
528 /* printiCChain - prints intermediate code for humans */
529 /*-----------------------------------------------------------------*/
531 printiCChain (iCode * icChain, FILE * of)
538 for (loop = icChain; loop; loop = loop->next)
540 if ((icTab = getTableEntry (loop->op)))
542 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
543 loop->filename, loop->lineno,
544 loop->seq, loop->key, loop->depth, loop->supportRtn);
546 icTab->iCodePrint (of, loop, icTab->printName);
552 /*-----------------------------------------------------------------*/
553 /* newOperand - allocate, init & return a new iCode */
554 /*-----------------------------------------------------------------*/
560 op = Safe_alloc ( sizeof (operand));
566 /*-----------------------------------------------------------------*/
567 /* newiCode - create and return a new iCode entry initialised */
568 /*-----------------------------------------------------------------*/
570 newiCode (int op, operand * left, operand * right)
574 ic = Safe_alloc ( sizeof (iCode));
576 ic->seqPoint = seqPoint;
578 ic->filename = filename;
580 ic->level = scopeLevel;
582 ic->key = iCodeKey++;
584 IC_RIGHT (ic) = right;
589 /*-----------------------------------------------------------------*/
590 /* newiCode for conditional statements */
591 /*-----------------------------------------------------------------*/
593 newiCodeCondition (operand * condition,
599 if (IS_VOID(operandType(condition))) {
600 werror(E_VOID_VALUE_USED);
603 ic = newiCode (IFX, NULL, NULL);
604 IC_COND (ic) = condition;
605 IC_TRUE (ic) = trueLabel;
606 IC_FALSE (ic) = falseLabel;
610 /*-----------------------------------------------------------------*/
611 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
612 /*-----------------------------------------------------------------*/
614 newiCodeLabelGoto (int op, symbol * label)
618 ic = newiCode (op, NULL, NULL);
622 IC_RIGHT (ic) = NULL;
623 IC_RESULT (ic) = NULL;
627 /*-----------------------------------------------------------------*/
628 /* newiTemp - allocate & return a newItemp Variable */
629 /*-----------------------------------------------------------------*/
637 SNPRINTF (buffer, sizeof(buffer), "%s", s);
641 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
644 itmp = newSymbol (buffer, 1);
645 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
651 /*-----------------------------------------------------------------*/
652 /* newiTempLabel - creates a temp variable label */
653 /*-----------------------------------------------------------------*/
655 newiTempLabel (char *s)
659 /* check if this alredy exists */
660 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
665 itmplbl = newSymbol (s, 1);
669 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
670 itmplbl = newSymbol (buffer, 1);
675 itmplbl->key = labelKey++;
676 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
680 /*-----------------------------------------------------------------*/
681 /* newiTempPreheaderLabel - creates a new preheader label */
682 /*-----------------------------------------------------------------*/
684 newiTempPreheaderLabel ()
688 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
689 itmplbl = newSymbol (buffer, 1);
693 itmplbl->key = labelKey++;
694 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
699 /*-----------------------------------------------------------------*/
700 /* initiCode - initialises some iCode related stuff */
701 /*-----------------------------------------------------------------*/
708 /*-----------------------------------------------------------------*/
709 /* copyiCode - make a copy of the iCode given */
710 /*-----------------------------------------------------------------*/
712 copyiCode (iCode * ic)
714 iCode *nic = newiCode (ic->op, NULL, NULL);
716 nic->lineno = ic->lineno;
717 nic->filename = ic->filename;
718 nic->block = ic->block;
719 nic->level = ic->level;
720 nic->parmBytes = ic->parmBytes;
722 /* deal with the special cases first */
726 IC_COND (nic) = operandFromOperand (IC_COND (ic));
727 IC_TRUE (nic) = IC_TRUE (ic);
728 IC_FALSE (nic) = IC_FALSE (ic);
732 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
733 IC_JTLABELS (nic) = IC_JTLABELS (ic);
738 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
739 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
743 IC_INLINE (nic) = IC_INLINE (ic);
747 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
751 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
752 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
753 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
759 /*-----------------------------------------------------------------*/
760 /* getTableEntry - gets the table entry for the given operator */
761 /*-----------------------------------------------------------------*/
763 getTableEntry (int oper)
767 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
768 if (oper == codeTable[i].icode)
769 return &codeTable[i];
774 /*-----------------------------------------------------------------*/
775 /* newiTempOperand - new intermediate temp operand */
776 /*-----------------------------------------------------------------*/
778 newiTempOperand (sym_link * type, char throwType)
781 operand *op = newOperand ();
785 itmp = newiTemp (NULL);
787 etype = getSpec (type);
789 if (IS_LITERAL (etype))
792 /* copy the type information */
794 itmp->etype = getSpec (itmp->type = (throwType ? type :
795 copyLinkChain (type)));
796 if (IS_LITERAL (itmp->etype))
798 SPEC_SCLS (itmp->etype) = S_REGISTER;
799 SPEC_OCLS (itmp->etype) = reg;
802 op->operand.symOperand = itmp;
803 op->key = itmp->key = ++operandKey;
807 /*-----------------------------------------------------------------*/
808 /* operandType - returns the type chain for an operand */
809 /*-----------------------------------------------------------------*/
811 operandType (operand * op)
813 /* depending on type of operand */
818 return op->operand.valOperand->type;
821 return op->operand.symOperand->type;
824 return op->operand.typeOperand;
826 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
827 " operand type not known ");
828 assert (0); /* should never come here */
829 /* Just to keep the compiler happy */
830 return (sym_link *) 0;
834 /*-----------------------------------------------------------------*/
835 /* isParamterToCall - will return 1 if op is a parameter to args */
836 /*-----------------------------------------------------------------*/
838 isParameterToCall (value * args, operand * op)
842 wassert (IS_SYMOP(op));
847 isSymbolEqual (op->operand.symOperand, tval->sym))
854 /*-----------------------------------------------------------------*/
855 /* isOperandGlobal - return 1 if operand is a global variable */
856 /*-----------------------------------------------------------------*/
858 isOperandGlobal (operand * op)
867 (op->operand.symOperand->level == 0 ||
868 IS_STATIC (op->operand.symOperand->etype) ||
869 IS_EXTERN (op->operand.symOperand->etype))
876 /*-----------------------------------------------------------------*/
877 /* isOperandVolatile - return 1 if the operand is volatile */
878 /*-----------------------------------------------------------------*/
880 isOperandVolatile (operand * op, bool chkTemp)
885 if (IS_ITEMP (op) && !chkTemp)
888 opetype = getSpec (optype = operandType (op));
890 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
893 if (IS_VOLATILE (opetype))
898 /*-----------------------------------------------------------------*/
899 /* isOperandLiteral - returns 1 if an operand contains a literal */
900 /*-----------------------------------------------------------------*/
902 isOperandLiteral (operand * op)
909 opetype = getSpec (operandType (op));
911 if (IS_LITERAL (opetype))
917 /*-----------------------------------------------------------------*/
918 /* isOperandInFarSpace - will return true if operand is in farSpace */
919 /*-----------------------------------------------------------------*/
921 isOperandInFarSpace (operand * op)
931 if (!IS_TRUE_SYMOP (op))
934 etype = SPIL_LOC (op)->etype;
940 etype = getSpec (operandType (op));
942 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
945 /*------------------------------------------------------------------*/
946 /* isOperandInDirSpace - will return true if operand is in dirSpace */
947 /*------------------------------------------------------------------*/
949 isOperandInDirSpace (operand * op)
959 if (!IS_TRUE_SYMOP (op))
962 etype = SPIL_LOC (op)->etype;
968 etype = getSpec (operandType (op));
970 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
973 /*--------------------------------------------------------------------*/
974 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
975 /*--------------------------------------------------------------------*/
977 isOperandInCodeSpace (operand * op)
987 etype = getSpec (operandType (op));
989 if (!IS_TRUE_SYMOP (op))
992 etype = SPIL_LOC (op)->etype;
998 etype = getSpec (operandType (op));
1000 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1003 /*-----------------------------------------------------------------*/
1004 /* isOperandOnStack - will return true if operand is on stack */
1005 /*-----------------------------------------------------------------*/
1007 isOperandOnStack (operand * op)
1017 etype = getSpec (operandType (op));
1018 if (IN_STACK (etype) ||
1019 OP_SYMBOL(op)->onStack ||
1020 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1026 /*-----------------------------------------------------------------*/
1027 /* isOclsExpensive - will return true if accesses to an output */
1028 /* storage class are expensive */
1029 /*-----------------------------------------------------------------*/
1031 isOclsExpensive (struct memmap *oclass)
1033 if (port->oclsExpense)
1034 return port->oclsExpense (oclass) > 0;
1036 /* In the absence of port specific guidance, assume only */
1037 /* farspace is expensive. */
1038 return IN_FARSPACE (oclass);
1041 /*-----------------------------------------------------------------*/
1042 /* operandLitValue - literal value of an operand */
1043 /*-----------------------------------------------------------------*/
1045 operandLitValue (operand * op)
1047 assert (isOperandLiteral (op));
1049 return floatFromVal (op->operand.valOperand);
1052 /*-----------------------------------------------------------------*/
1053 /* getBuiltInParms - returns parameters to a builtin functions */
1054 /*-----------------------------------------------------------------*/
1055 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1060 /* builtin functions uses only SEND for parameters */
1061 while (ic->op != CALL) {
1062 assert(ic->op == SEND && ic->builtinSEND);
1063 ic->generated = 1; /* mark the icode as generated */
1064 parms[*pcount] = IC_LEFT(ic);
1070 /* make sure this is a builtin function call */
1071 assert(IS_SYMOP(IC_LEFT(ic)));
1072 ftype = operandType(IC_LEFT(ic));
1073 assert(IFFUNC_ISBUILTIN(ftype));
1077 /*-----------------------------------------------------------------*/
1078 /* operandOperation - performs operations on operands */
1079 /*-----------------------------------------------------------------*/
1081 operandOperation (operand * left, operand * right,
1082 int op, sym_link * type)
1084 sym_link *let , *ret=NULL;
1085 operand *retval = (operand *) 0;
1087 assert (isOperandLiteral (left));
1088 let = getSpec(operandType(left));
1090 assert (isOperandLiteral (right));
1091 ret = getSpec(operandType(right));
1097 retval = operandFromValue (valCastLiteral (type,
1098 operandLitValue (left) +
1099 operandLitValue (right)));
1102 retval = operandFromValue (valCastLiteral (type,
1103 operandLitValue (left) -
1104 operandLitValue (right)));
1108 retval = operandFromValue (valCastLiteral (type,
1109 operandLitValue (left) *
1110 operandLitValue (right)));
1111 This could be all we've to do, but with gcc we've to take care about
1112 overflows. Two examples:
1113 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1114 significant bits are lost (52 in fraction, 63 bits would be
1115 necessary to keep full precision).
1116 If the resulting double value is greater than ULONG_MAX (resp.
1117 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1120 /* if it is not a specifier then we can assume that */
1121 /* it will be an unsigned long */
1122 if (IS_INT (type) ||
1125 /* long is handled here, because it can overflow with double */
1126 if (IS_LONG (type) ||
1128 /* signed and unsigned mul are the same, as long as the precision
1129 of the result isn't bigger than the precision of the operands. */
1130 retval = operandFromValue (valCastLiteral (type,
1131 (TYPE_UDWORD) operandLitValue (left) *
1132 (TYPE_UDWORD) operandLitValue (right)));
1133 else if (IS_UNSIGNED (type)) /* unsigned int */
1135 /* unsigned int is handled here in order to detect overflow */
1136 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1137 (TYPE_UWORD) operandLitValue (right);
1139 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1140 if (ul != (TYPE_UWORD) ul)
1143 else /* signed int */
1145 /* signed int is handled here in order to detect overflow */
1146 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1147 (TYPE_WORD) operandLitValue (right);
1149 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1150 if (l != (TYPE_WORD) l)
1155 /* all others go here: */
1156 retval = operandFromValue (valCastLiteral (type,
1157 operandLitValue (left) *
1158 operandLitValue (right)));
1161 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1163 werror (E_DIVIDE_BY_ZERO);
1169 if (IS_UNSIGNED (type))
1171 SPEC_USIGN (let) = 1;
1172 SPEC_USIGN (ret) = 1;
1173 retval = operandFromValue (valCastLiteral (type,
1174 (TYPE_UDWORD) operandLitValue (left) /
1175 (TYPE_UDWORD) operandLitValue (right)));
1179 retval = operandFromValue (valCastLiteral (type,
1180 operandLitValue (left) /
1181 operandLitValue (right)));
1186 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1188 werror (E_DIVIDE_BY_ZERO);
1193 if (IS_UNSIGNED (type))
1194 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1195 (TYPE_UDWORD) operandLitValue (right));
1197 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1198 (TYPE_DWORD) operandLitValue (right));
1202 /* The number of left shifts is always unsigned. Signed doesn't make
1203 sense here. Shifting by a negative number is impossible. */
1204 retval = operandFromValue (valCastLiteral (type,
1205 ((TYPE_UDWORD) operandLitValue (left) <<
1206 (TYPE_UDWORD) operandLitValue (right))));
1209 /* The number of right shifts is always unsigned. Signed doesn't make
1210 sense here. Shifting by a negative number is impossible. */
1211 if (IS_UNSIGNED(let))
1212 /* unsigned: logic shift right */
1213 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1214 (TYPE_UDWORD) operandLitValue (right));
1216 /* signed: arithmetic shift right */
1217 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1218 (TYPE_UDWORD) operandLitValue (right));
1221 if (IS_FLOAT (let) ||
1224 retval = operandFromLit (operandLitValue (left) ==
1225 operandLitValue (right));
1229 /* this op doesn't care about signedness */
1232 l = (TYPE_UDWORD) operandLitValue (left);
1233 r = (TYPE_UDWORD) operandLitValue (right);
1234 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1235 neccessary to strip them to 16 bit.
1236 Literals are reduced to their cheapest type, therefore left and
1237 right might have different types. It's neccessary to find a
1238 common type: int (used for char too) or long */
1239 if (!IS_LONG (let) &&
1245 retval = operandFromLit (l == r);
1249 retval = operandFromLit (operandLitValue (left) <
1250 operandLitValue (right));
1253 retval = operandFromLit (operandLitValue (left) <=
1254 operandLitValue (right));
1257 retval = operandFromLit (operandLitValue (left) !=
1258 operandLitValue (right));
1261 retval = operandFromLit (operandLitValue (left) >
1262 operandLitValue (right));
1265 retval = operandFromLit (operandLitValue (left) >=
1266 operandLitValue (right));
1269 retval = operandFromValue (valCastLiteral (type,
1270 (TYPE_UDWORD)operandLitValue(left) &
1271 (TYPE_UDWORD)operandLitValue(right)));
1274 retval = operandFromValue (valCastLiteral (type,
1275 (TYPE_UDWORD)operandLitValue(left) |
1276 (TYPE_UDWORD)operandLitValue(right)));
1279 retval = operandFromValue (valCastLiteral (type,
1280 (TYPE_UDWORD)operandLitValue(left) ^
1281 (TYPE_UDWORD)operandLitValue(right)));
1284 retval = operandFromLit (operandLitValue (left) &&
1285 operandLitValue (right));
1288 retval = operandFromLit (operandLitValue (left) ||
1289 operandLitValue (right));
1293 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1295 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1301 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1303 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1309 retval = operandFromValue (valCastLiteral (type,
1310 -1 * operandLitValue (left)));
1314 retval = operandFromValue (valCastLiteral (type,
1316 operandLitValue (left))));
1320 retval = operandFromLit (!operandLitValue (left));
1324 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1325 " operandOperation invalid operator ");
1333 /*-----------------------------------------------------------------*/
1334 /* isOperandEqual - compares two operand & return 1 if they r = */
1335 /*-----------------------------------------------------------------*/
1337 isOperandEqual (operand * left, operand * right)
1339 /* if the pointers are equal then they are equal */
1343 /* if either of them null then false */
1344 if (!left || !right)
1347 if (left->type != right->type)
1350 if (IS_SYMOP (left) && IS_SYMOP (right))
1351 return left->key == right->key;
1353 /* if types are the same */
1357 return isSymbolEqual (left->operand.symOperand,
1358 right->operand.symOperand);
1360 return (floatFromVal (left->operand.valOperand) ==
1361 floatFromVal (right->operand.valOperand));
1363 if (compareType (left->operand.typeOperand,
1364 right->operand.typeOperand) == 1)
1371 /*-------------------------------------------------------------------*/
1372 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1373 /*-------------------------------------------------------------------*/
1375 isiCodeEqual (iCode * left, iCode * right)
1377 /* if the same pointer */
1381 /* if either of them null */
1382 if (!left || !right)
1385 /* if operand are the same */
1386 if (left->op == right->op)
1389 /* compare all the elements depending on type */
1390 if (left->op != IFX)
1392 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1394 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1400 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1402 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1404 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1413 /*-----------------------------------------------------------------*/
1414 /* newiTempFromOp - create a temp Operand with same attributes */
1415 /*-----------------------------------------------------------------*/
1417 newiTempFromOp (operand * op)
1427 nop = newiTempOperand (operandType (op), TRUE);
1428 nop->isaddr = op->isaddr;
1429 nop->isvolatile = op->isvolatile;
1430 nop->isGlobal = op->isGlobal;
1431 nop->isLiteral = op->isLiteral;
1432 nop->usesDefs = op->usesDefs;
1433 nop->isParm = op->isParm;
1437 /*-----------------------------------------------------------------*/
1438 /* operand from operand - creates an operand holder for the type */
1439 /*-----------------------------------------------------------------*/
1441 operandFromOperand (operand * op)
1447 nop = newOperand ();
1448 nop->type = op->type;
1449 nop->isaddr = op->isaddr;
1451 nop->isvolatile = op->isvolatile;
1452 nop->isGlobal = op->isGlobal;
1453 nop->isLiteral = op->isLiteral;
1454 nop->usesDefs = op->usesDefs;
1455 nop->isParm = op->isParm;
1460 nop->operand.symOperand = op->operand.symOperand;
1463 nop->operand.valOperand = op->operand.valOperand;
1466 nop->operand.typeOperand = op->operand.typeOperand;
1473 /*-----------------------------------------------------------------*/
1474 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1475 /*-----------------------------------------------------------------*/
1477 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1479 operand *nop = operandFromOperand (op);
1481 if (nop->type == SYMBOL)
1483 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1484 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1490 /*-----------------------------------------------------------------*/
1491 /* operandFromSymbol - creates an operand from a symbol */
1492 /*-----------------------------------------------------------------*/
1494 operandFromSymbol (symbol * sym)
1499 /* if the symbol's type is a literal */
1500 /* then it is an enumerator type */
1501 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1502 return operandFromValue (valFromType (sym->etype));
1505 sym->key = ++operandKey;
1507 /* if this an implicit variable, means struct/union */
1508 /* member so just return it */
1509 if (sym->implicit || IS_FUNC (sym->type))
1513 op->operand.symOperand = sym;
1515 op->isvolatile = isOperandVolatile (op, TRUE);
1516 op->isGlobal = isOperandGlobal (op);
1520 /* under the following conditions create a
1521 register equivalent for a local symbol */
1522 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1523 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1525 (!(options.model == MODEL_FLAT24)) ) &&
1526 options.stackAuto == 0)
1529 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1530 !IS_FUNC (sym->type) && /* not a function */
1531 !sym->_isparm && /* not a parameter */
1532 sym->level && /* is a local variable */
1533 !sym->addrtaken && /* whose address has not been taken */
1534 !sym->reqv && /* does not already have a reg equivalence */
1535 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1536 !IS_STATIC (sym->etype) && /* and not declared static */
1537 !sym->islbl && /* not a label */
1538 ok && /* farspace check */
1539 !IS_BITVAR (sym->etype) /* not a bit variable */
1543 /* we will use it after all optimizations
1544 and before liveRange calculation */
1545 sym->reqv = newiTempOperand (sym->type, 0);
1546 sym->reqv->key = sym->key;
1547 OP_SYMBOL (sym->reqv)->prereqv = sym;
1548 OP_SYMBOL (sym->reqv)->key = sym->key;
1549 OP_SYMBOL (sym->reqv)->isreqv = 1;
1550 OP_SYMBOL (sym->reqv)->islocal = 1;
1551 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1552 SPIL_LOC (sym->reqv) = sym;
1555 if (!IS_AGGREGATE (sym->type))
1559 op->operand.symOperand = sym;
1562 op->isvolatile = isOperandVolatile (op, TRUE);
1563 op->isGlobal = isOperandGlobal (op);
1564 op->isPtr = IS_PTR (operandType (op));
1565 op->isParm = sym->_isparm;
1570 /* itemp = &[_symbol] */
1572 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1573 IC_LEFT (ic)->type = SYMBOL;
1574 IC_LEFT (ic)->operand.symOperand = sym;
1575 IC_LEFT (ic)->key = sym->key;
1576 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1577 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1578 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1581 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1582 if (IS_ARRAY (sym->type))
1584 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1585 IC_RESULT (ic)->isaddr = 0;
1588 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1592 return IC_RESULT (ic);
1595 /*-----------------------------------------------------------------*/
1596 /* operandFromValue - creates an operand from value */
1597 /*-----------------------------------------------------------------*/
1599 operandFromValue (value * val)
1603 /* if this is a symbol then do the symbol thing */
1605 return operandFromSymbol (val->sym);
1607 /* this is not a symbol */
1610 op->operand.valOperand = val;
1611 op->isLiteral = isOperandLiteral (op);
1615 /*-----------------------------------------------------------------*/
1616 /* operandFromLink - operand from typeChain */
1617 /*-----------------------------------------------------------------*/
1619 operandFromLink (sym_link * type)
1623 /* operand from sym_link */
1629 op->operand.typeOperand = copyLinkChain (type);
1633 /*-----------------------------------------------------------------*/
1634 /* operandFromLit - makes an operand from a literal value */
1635 /*-----------------------------------------------------------------*/
1637 operandFromLit (double i)
1639 return operandFromValue (valueFromLit (i));
1642 /*-----------------------------------------------------------------*/
1643 /* operandFromAst - creates an operand from an ast */
1644 /*-----------------------------------------------------------------*/
1646 operandFromAst (ast * tree,int lvl)
1652 /* depending on type do */
1656 return ast2iCode (tree,lvl+1);
1660 return operandFromValue (tree->opval.val);
1664 return operandFromLink (tree->opval.lnk);
1671 /* Just to keep the compiler happy */
1672 return (operand *) 0;
1675 /*-----------------------------------------------------------------*/
1676 /* setOperandType - sets the operand's type to the given type */
1677 /*-----------------------------------------------------------------*/
1679 setOperandType (operand * op, sym_link * type)
1681 /* depending on the type of operand */
1686 op->operand.valOperand->etype =
1687 getSpec (op->operand.valOperand->type =
1688 copyLinkChain (type));
1692 if (op->operand.symOperand->isitmp)
1693 op->operand.symOperand->etype =
1694 getSpec (op->operand.symOperand->type =
1695 copyLinkChain (type));
1697 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1698 "attempt to modify type of source");
1702 op->operand.typeOperand = copyLinkChain (type);
1708 /*-----------------------------------------------------------------*/
1709 /* Get size in byte of ptr need to access an array */
1710 /*-----------------------------------------------------------------*/
1712 getArraySizePtr (operand * op)
1714 sym_link *ltype = operandType(op);
1718 int size = getSize(ltype);
1719 return(IS_GENPTR(ltype)?(size-1):size);
1724 sym_link *letype = getSpec(ltype);
1725 switch (PTR_TYPE (SPEC_OCLS (letype)))
1737 return (GPTRSIZE-1);
1746 /*-----------------------------------------------------------------*/
1747 /* perform "usual unary conversions" */
1748 /*-----------------------------------------------------------------*/
1751 usualUnaryConversions (operand * op)
1753 if (IS_INTEGRAL (operandType (op)))
1755 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1758 return geniCodeCast (INTTYPE, op, TRUE);
1765 /*-----------------------------------------------------------------*/
1766 /* perform "usual binary conversions" */
1767 /*-----------------------------------------------------------------*/
1770 usualBinaryConversions (operand ** op1, operand ** op2,
1771 RESULT_TYPE resultType, int op)
1774 sym_link *rtype = operandType (*op2);
1775 sym_link *ltype = operandType (*op1);
1777 ctype = computeType (ltype, rtype, resultType, op);
1784 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1786 /* one byte operations: keep signedness for code generator */
1794 *op1 = geniCodeCast (ctype, *op1, TRUE);
1795 *op2 = geniCodeCast (ctype, *op2, TRUE);
1800 /*-----------------------------------------------------------------*/
1801 /* geniCodeValueAtAddress - generate intermeditate code for value */
1803 /*-----------------------------------------------------------------*/
1805 geniCodeRValue (operand * op, bool force)
1808 sym_link *type = operandType (op);
1809 sym_link *etype = getSpec (type);
1811 /* if this is an array & already */
1812 /* an address then return this */
1813 if (IS_AGGREGATE (type) ||
1814 (IS_PTR (type) && !force && !op->isaddr))
1815 return operandFromOperand (op);
1817 /* if this is not an address then must be */
1818 /* rvalue already so return this one */
1822 /* if this is not a temp symbol then */
1823 if (!IS_ITEMP (op) &&
1825 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1827 op = operandFromOperand (op);
1832 if (IS_SPEC (type) &&
1833 IS_TRUE_SYMOP (op) &&
1834 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1835 (options.model == MODEL_FLAT24) ))
1837 op = operandFromOperand (op);
1842 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1843 if (IS_PTR (type) && op->isaddr && force)
1846 type = copyLinkChain (type);
1848 IC_RESULT (ic) = newiTempOperand (type, 1);
1849 IC_RESULT (ic)->isaddr = 0;
1851 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1855 return IC_RESULT (ic);
1858 /*-----------------------------------------------------------------*/
1859 /* geniCodeCast - changes the value from one type to another */
1860 /*-----------------------------------------------------------------*/
1862 geniCodeCast (sym_link * type, operand * op, bool implicit)
1866 sym_link *opetype = getSpec (optype = operandType (op));
1870 /* one of them has size zero then error */
1871 if (IS_VOID (optype))
1873 werror (E_CAST_ZERO);
1877 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1879 geniCodeArray2Ptr (op);
1883 /* if the operand is already the desired type then do nothing */
1884 if (compareType (type, optype) == 1)
1887 /* if this is a literal then just change the type & return */
1888 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1890 return operandFromValue (valCastLiteral (type,
1891 operandLitValue (op)));
1894 /* if casting to/from pointers, do some checking */
1895 if (IS_PTR(type)) { // to a pointer
1896 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1897 if (IS_INTEGRAL(optype)) {
1898 // maybe this is NULL, than it's ok.
1899 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1900 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1901 // no way to set the storage
1902 if (IS_LITERAL(optype)) {
1903 werror(E_LITERAL_GENERIC);
1906 werror(E_NONPTR2_GENPTR);
1909 } else if (implicit) {
1910 werror(W_INTEGRAL2PTR_NOCAST);
1915 // shouldn't do that with float, array or structure unless to void
1916 if (!IS_VOID(getSpec(type)) &&
1917 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1918 werror(E_INCOMPAT_TYPES);
1922 } else { // from a pointer to a pointer
1923 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1924 // if not a pointer to a function
1925 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1926 if (implicit) { // if not to generic, they have to match
1927 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1928 werror(E_INCOMPAT_PTYPES);
1935 } else { // to a non pointer
1936 if (IS_PTR(optype)) { // from a pointer
1937 if (implicit) { // sneaky
1938 if (IS_INTEGRAL(type)) {
1939 werror(W_PTR2INTEGRAL_NOCAST);
1941 } else { // shouldn't do that with float, array or structure
1942 werror(E_INCOMPAT_TYPES);
1949 printFromToType (optype, type);
1952 /* if they are the same size create an assignment */
1954 /* This seems very dangerous to me, since there are several */
1955 /* optimizations (for example, gcse) that don't notice the */
1956 /* cast hidden in this assignement and may simplify an */
1957 /* iCode to use the original (uncasted) operand. */
1958 /* Unfortunately, other things break when this cast is */
1959 /* made explicit. Need to fix this someday. */
1960 /* -- EEP, 2004/01/21 */
1961 if (getSize (type) == getSize (optype) &&
1962 !IS_BITFIELD (type) &&
1964 !IS_FLOAT (optype) &&
1965 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1966 (!IS_SPEC (type) && !IS_SPEC (optype))))
1968 ic = newiCode ('=', NULL, op);
1969 IC_RESULT (ic) = newiTempOperand (type, 0);
1970 SPIL_LOC (IC_RESULT (ic)) =
1971 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1972 IC_RESULT (ic)->isaddr = 0;
1976 ic = newiCode (CAST, operandFromLink (type),
1977 geniCodeRValue (op, FALSE));
1979 IC_RESULT (ic) = newiTempOperand (type, 0);
1982 /* preserve the storage class & output class */
1983 /* of the original variable */
1984 restype = getSpec (operandType (IC_RESULT (ic)));
1985 if (!IS_LITERAL(opetype) &&
1987 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1988 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1991 return IC_RESULT (ic);
1994 /*-----------------------------------------------------------------*/
1995 /* geniCodeLabel - will create a Label */
1996 /*-----------------------------------------------------------------*/
1998 geniCodeLabel (symbol * label)
2002 ic = newiCodeLabelGoto (LABEL, label);
2006 /*-----------------------------------------------------------------*/
2007 /* geniCodeGoto - will create a Goto */
2008 /*-----------------------------------------------------------------*/
2010 geniCodeGoto (symbol * label)
2014 ic = newiCodeLabelGoto (GOTO, label);
2018 /*-----------------------------------------------------------------*/
2019 /* geniCodeMultiply - gen intermediate code for multiplication */
2020 /*-----------------------------------------------------------------*/
2022 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2029 /* if they are both literal then we know the result */
2030 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2031 return operandFromValue (valMult (left->operand.valOperand,
2032 right->operand.valOperand));
2034 if (IS_LITERAL(retype)) {
2035 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2038 resType = usualBinaryConversions (&left, &right, resultType, '*');
2040 rtype = operandType (right);
2041 retype = getSpec (rtype);
2042 ltype = operandType (left);
2043 letype = getSpec (ltype);
2046 /* if the right is a literal & power of 2 */
2047 /* then make it a left shift */
2048 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2049 efficient in most cases than 2 bytes result = 2 bytes << literal
2050 if port has 1 byte muldiv */
2051 if (p2 && !IS_FLOAT (letype)
2052 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2053 && (port->support.muldiv == 1))
2054 && strcmp (port->target, "pic14") != 0 /* don't shift for pic */
2055 && strcmp (port->target, "pic16") != 0)
2057 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2059 /* LEFT_OP need same size for left and result, */
2060 left = geniCodeCast (resType, left, TRUE);
2061 ltype = operandType (left);
2063 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2067 ic = newiCode ('*', left, right); /* normal multiplication */
2068 /* if the size left or right > 1 then support routine */
2069 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2073 IC_RESULT (ic) = newiTempOperand (resType, 1);
2076 return IC_RESULT (ic);
2079 /*-----------------------------------------------------------------*/
2080 /* geniCodeDivision - gen intermediate code for division */
2081 /*-----------------------------------------------------------------*/
2083 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2088 sym_link *rtype = operandType (right);
2089 sym_link *retype = getSpec (rtype);
2090 sym_link *ltype = operandType (left);
2091 sym_link *letype = getSpec (ltype);
2093 resType = usualBinaryConversions (&left, &right, resultType, '/');
2095 /* if the right is a literal & power of 2
2096 and left is unsigned then make it a
2098 if (IS_LITERAL (retype) &&
2099 !IS_FLOAT (letype) &&
2100 IS_UNSIGNED(letype) &&
2101 (p2 = powof2 ((TYPE_UDWORD)
2102 floatFromVal (right->operand.valOperand)))) {
2103 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2107 ic = newiCode ('/', left, right); /* normal division */
2108 /* if the size left or right > 1 then support routine */
2109 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2112 IC_RESULT (ic) = newiTempOperand (resType, 0);
2115 return IC_RESULT (ic);
2117 /*-----------------------------------------------------------------*/
2118 /* geniCodeModulus - gen intermediate code for modulus */
2119 /*-----------------------------------------------------------------*/
2121 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2127 /* if they are both literal then we know the result */
2128 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2129 return operandFromValue (valMod (left->operand.valOperand,
2130 right->operand.valOperand));
2132 resType = usualBinaryConversions (&left, &right, resultType, '%');
2134 /* now they are the same size */
2135 ic = newiCode ('%', left, right);
2137 /* if the size left or right > 1 then support routine */
2138 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2140 IC_RESULT (ic) = newiTempOperand (resType, 0);
2143 return IC_RESULT (ic);
2146 /*-----------------------------------------------------------------*/
2147 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2148 /*-----------------------------------------------------------------*/
2150 geniCodePtrPtrSubtract (operand * left, operand * right)
2156 /* if they are both literals then */
2157 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2159 result = operandFromValue (valMinus (left->operand.valOperand,
2160 right->operand.valOperand));
2164 ic = newiCode ('-', left, right);
2166 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2170 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2174 // should we really do this? is this ANSI?
2175 return geniCodeDivision (result,
2176 operandFromLit (getSize (ltype->next)),
2180 /*-----------------------------------------------------------------*/
2181 /* geniCodeSubtract - generates code for subtraction */
2182 /*-----------------------------------------------------------------*/
2184 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2191 /* if they both pointers then */
2192 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2193 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2194 return geniCodePtrPtrSubtract (left, right);
2196 /* if they are both literal then we know the result */
2197 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2198 && left->isLiteral && right->isLiteral)
2199 return operandFromValue (valMinus (left->operand.valOperand,
2200 right->operand.valOperand));
2202 /* if left is an array or pointer */
2203 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2205 isarray = left->isaddr;
2206 right = geniCodeMultiply (right,
2207 operandFromLit (getSize (ltype->next)),
2208 (getArraySizePtr(left) >= INTSIZE) ?
2211 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2214 { /* make them the same size */
2215 resType = usualBinaryConversions (&left, &right, resultType, '-');
2218 ic = newiCode ('-', left, right);
2220 IC_RESULT (ic) = newiTempOperand (resType, 1);
2221 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2223 /* if left or right is a float */
2224 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2228 return IC_RESULT (ic);
2231 /*-----------------------------------------------------------------*/
2232 /* geniCodeAdd - generates iCode for addition */
2233 /*-----------------------------------------------------------------*/
2235 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2244 /* if the right side is LITERAL zero */
2245 /* return the left side */
2246 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2249 /* if left is literal zero return right */
2250 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2253 /* if left is a pointer then size */
2254 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2256 isarray = left->isaddr;
2257 // there is no need to multiply with 1
2258 if (getSize (ltype->next) != 1)
2260 size = operandFromLit (getSize (ltype->next));
2261 SPEC_USIGN (getSpec (operandType (size))) = 1;
2262 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2263 right = geniCodeMultiply (right,
2265 (getArraySizePtr(left) >= INTSIZE) ?
2268 /* Even if right is a 'unsigned char',
2269 the result will be a 'signed int' due to the promotion rules.
2270 It doesn't make sense when accessing arrays, so let's fix it here: */
2272 SPEC_USIGN (getSpec (operandType (right))) = 1;
2274 resType = copyLinkChain (ltype);
2277 { // make them the same size
2278 resType = usualBinaryConversions (&left, &right, resultType, '+');
2281 /* if they are both literals then we know */
2282 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2283 && left->isLiteral && right->isLiteral)
2284 return operandFromValue (valPlus (valFromType (ltype),
2285 valFromType (rtype)));
2287 ic = newiCode ('+', left, right);
2289 IC_RESULT (ic) = newiTempOperand (resType, 1);
2290 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2292 /* if left or right is a float then support
2294 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2299 return IC_RESULT (ic);
2303 /*-----------------------------------------------------------------*/
2304 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2305 /*-----------------------------------------------------------------*/
2307 aggrToPtr (sym_link * type, bool force)
2312 if (IS_PTR (type) && !force)
2315 etype = getSpec (type);
2316 ptype = newLink (DECLARATOR);
2320 /* set the pointer depending on the storage class */
2321 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2325 /*------------------------------------------------------------------*/
2326 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2327 /*------------------------------------------------------------------*/
2329 aggrToPtrDclType (sym_link * type, bool force)
2331 if (IS_PTR (type) && !force)
2332 return DCL_TYPE (type);
2334 /* return the pointer depending on the storage class */
2335 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2338 /*-----------------------------------------------------------------*/
2339 /* geniCodeArray2Ptr - array to pointer */
2340 /*-----------------------------------------------------------------*/
2342 geniCodeArray2Ptr (operand * op)
2344 sym_link *optype = operandType (op);
2345 sym_link *opetype = getSpec (optype);
2347 /* set the pointer depending on the storage class */
2348 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2355 /*-----------------------------------------------------------------*/
2356 /* geniCodeArray - array access */
2357 /*-----------------------------------------------------------------*/
2359 geniCodeArray (operand * left, operand * right, int lvl)
2363 sym_link *ltype = operandType (left);
2368 if (IS_PTR (ltype->next) && left->isaddr)
2370 left = geniCodeRValue (left, FALSE);
2373 return geniCodeDerefPtr (geniCodeAdd (left,
2375 (getArraySizePtr(left) >= INTSIZE) ?
2381 size = operandFromLit (getSize (ltype->next));
2382 SPEC_USIGN (getSpec (operandType (size))) = 1;
2383 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2384 right = geniCodeMultiply (right,
2386 (getArraySizePtr(left) >= INTSIZE) ?
2389 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2390 It doesn't make sense when accessing arrays, so let's fix it here: */
2392 SPEC_USIGN (getSpec (operandType (right))) = 1;
2393 /* we can check for limits here */
2394 /* already done in SDCCast.c
2395 if (isOperandLiteral (right) &&
2398 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2400 werror (W_IDX_OUT_OF_BOUNDS,
2401 (int) operandLitValue (right) / getSize (ltype->next),
2406 ic = newiCode ('+', left, right);
2408 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2409 !IS_AGGREGATE (ltype->next) &&
2410 !IS_PTR (ltype->next))
2411 ? ltype : ltype->next), 0);
2413 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2416 return IC_RESULT (ic);
2419 /*-----------------------------------------------------------------*/
2420 /* geniCodeStruct - generates intermediate code for structures */
2421 /*-----------------------------------------------------------------*/
2423 geniCodeStruct (operand * left, operand * right, bool islval)
2426 sym_link *type = operandType (left);
2427 sym_link *etype = getSpec (type);
2429 symbol *element = getStructElement (SPEC_STRUCT (etype),
2430 right->operand.symOperand);
2432 wassert(IS_SYMOP(right));
2434 /* add the offset */
2435 ic = newiCode ('+', left, operandFromLit (element->offset));
2437 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2439 /* preserve the storage & output class of the struct */
2440 /* as well as the volatile attribute */
2441 retype = getSpec (operandType (IC_RESULT (ic)));
2442 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2443 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2444 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2445 SPEC_CONST (retype) |= SPEC_CONST (etype);
2447 if (IS_PTR (element->type))
2448 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2450 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2453 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2456 /*-----------------------------------------------------------------*/
2457 /* geniCodePostInc - generate int code for Post increment */
2458 /*-----------------------------------------------------------------*/
2460 geniCodePostInc (operand * op)
2464 sym_link *optype = operandType (op);
2466 operand *rv = (IS_ITEMP (op) ?
2467 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2469 sym_link *rvtype = operandType (rv);
2472 /* if this is not an address we have trouble */
2475 werror (E_LVALUE_REQUIRED, "++");
2479 rOp = newiTempOperand (rvtype, 0);
2480 OP_SYMBOL(rOp)->noSpilLoc = 1;
2483 OP_SYMBOL(rv)->noSpilLoc = 1;
2485 geniCodeAssign (rOp, rv, 0, 0);
2487 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2488 if (IS_FLOAT (rvtype))
2489 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2491 ic = newiCode ('+', rv, operandFromLit (size));
2493 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2496 geniCodeAssign (op, result, 0, 0);
2502 /*-----------------------------------------------------------------*/
2503 /* geniCodePreInc - generate code for preIncrement */
2504 /*-----------------------------------------------------------------*/
2506 geniCodePreInc (operand * op, bool lvalue)
2509 sym_link *optype = operandType (op);
2510 operand *rop = (IS_ITEMP (op) ?
2511 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2513 sym_link *roptype = operandType (rop);
2519 werror (E_LVALUE_REQUIRED, "++");
2524 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2525 if (IS_FLOAT (roptype))
2526 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2528 ic = newiCode ('+', rop, operandFromLit (size));
2529 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2532 (void) geniCodeAssign (op, result, 0, 0);
2533 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2539 /*-----------------------------------------------------------------*/
2540 /* geniCodePostDec - generates code for Post decrement */
2541 /*-----------------------------------------------------------------*/
2543 geniCodePostDec (operand * op)
2547 sym_link *optype = operandType (op);
2549 operand *rv = (IS_ITEMP (op) ?
2550 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2552 sym_link *rvtype = operandType (rv);
2555 /* if this is not an address we have trouble */
2558 werror (E_LVALUE_REQUIRED, "--");
2562 rOp = newiTempOperand (rvtype, 0);
2563 OP_SYMBOL(rOp)->noSpilLoc = 1;
2566 OP_SYMBOL(rv)->noSpilLoc = 1;
2568 geniCodeAssign (rOp, rv, 0, 0);
2570 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2571 if (IS_FLOAT (rvtype))
2572 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2574 ic = newiCode ('-', rv, operandFromLit (size));
2576 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2579 geniCodeAssign (op, result, 0, 0);
2585 /*-----------------------------------------------------------------*/
2586 /* geniCodePreDec - generate code for pre decrement */
2587 /*-----------------------------------------------------------------*/
2589 geniCodePreDec (operand * op, bool lvalue)
2592 sym_link *optype = operandType (op);
2593 operand *rop = (IS_ITEMP (op) ?
2594 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2596 sym_link *roptype = operandType (rop);
2602 werror (E_LVALUE_REQUIRED, "--");
2607 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2608 if (IS_FLOAT (roptype))
2609 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2611 ic = newiCode ('-', rop, operandFromLit (size));
2612 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2615 (void) geniCodeAssign (op, result, 0, 0);
2616 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2623 /*-----------------------------------------------------------------*/
2624 /* geniCodeBitwise - gen int code for bitWise operators */
2625 /*-----------------------------------------------------------------*/
2627 geniCodeBitwise (operand * left, operand * right,
2628 int oper, sym_link * resType)
2632 left = geniCodeCast (resType, left, TRUE);
2633 right = geniCodeCast (resType, right, TRUE);
2635 ic = newiCode (oper, left, right);
2636 IC_RESULT (ic) = newiTempOperand (resType, 0);
2639 return IC_RESULT (ic);
2642 /*-----------------------------------------------------------------*/
2643 /* geniCodeAddressOf - gens icode for '&' address of operator */
2644 /*-----------------------------------------------------------------*/
2646 geniCodeAddressOf (operand * op)
2650 sym_link *optype = operandType (op);
2651 sym_link *opetype = getSpec (optype);
2653 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2655 op = operandFromOperand (op);
2660 /* lvalue check already done in decorateType */
2661 /* this must be a lvalue */
2662 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2663 /* werror (E_LVALUE_REQUIRED,"&"); */
2667 p = newLink (DECLARATOR);
2669 /* set the pointer depending on the storage class */
2670 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2672 p->next = copyLinkChain (optype);
2674 /* if already a temp */
2677 setOperandType (op, p);
2682 /* other wise make this of the type coming in */
2683 ic = newiCode (ADDRESS_OF, op, NULL);
2684 IC_RESULT (ic) = newiTempOperand (p, 1);
2685 IC_RESULT (ic)->isaddr = 0;
2687 return IC_RESULT (ic);
2689 /*-----------------------------------------------------------------*/
2690 /* setOClass - sets the output class depending on the pointer type */
2691 /*-----------------------------------------------------------------*/
2693 setOClass (sym_link * ptr, sym_link * spec)
2695 switch (DCL_TYPE (ptr))
2698 SPEC_OCLS (spec) = data;
2702 SPEC_OCLS (spec) = generic;
2706 SPEC_OCLS (spec) = xdata;
2710 SPEC_OCLS (spec) = code;
2714 SPEC_OCLS (spec) = idata;
2718 SPEC_OCLS (spec) = xstack;
2722 SPEC_OCLS (spec) = eeprom;
2731 /*-----------------------------------------------------------------*/
2732 /* geniCodeDerefPtr - dereference pointer with '*' */
2733 /*-----------------------------------------------------------------*/
2735 geniCodeDerefPtr (operand * op,int lvl)
2737 sym_link *rtype, *retype;
2738 sym_link *optype = operandType (op);
2740 // if this is an array then array access
2741 if (IS_ARRAY (optype)) {
2742 // don't worry, this will be optimized out later
2743 return geniCodeArray (op, operandFromLit (0), lvl);
2746 // just in case someone screws up
2747 wassert (IS_PTR (optype));
2749 if (IS_TRUE_SYMOP (op))
2752 op = geniCodeRValue (op, TRUE);
2755 /* now get rid of the pointer part */
2756 if (isLvaluereq(lvl) && IS_ITEMP (op))
2758 retype = getSpec (rtype = copyLinkChain (optype));
2762 retype = getSpec (rtype = copyLinkChain (optype->next));
2763 /* outputclass needs 2b updated */
2764 setOClass (optype, retype);
2767 op->isGptr = IS_GENPTR (optype);
2769 op->isaddr = (IS_PTR (rtype) ||
2770 IS_STRUCT (rtype) ||
2775 if (!isLvaluereq(lvl))
2776 op = geniCodeRValue (op, TRUE);
2778 setOperandType (op, rtype);
2783 /*-----------------------------------------------------------------*/
2784 /* geniCodeUnaryMinus - does a unary minus of the operand */
2785 /*-----------------------------------------------------------------*/
2787 geniCodeUnaryMinus (operand * op)
2790 sym_link *optype = operandType (op);
2792 if (IS_LITERAL (optype))
2793 return operandFromLit (-floatFromVal (op->operand.valOperand));
2795 ic = newiCode (UNARYMINUS, op, NULL);
2796 IC_RESULT (ic) = newiTempOperand (optype, 0);
2798 return IC_RESULT (ic);
2801 /*-----------------------------------------------------------------*/
2802 /* geniCodeLeftShift - gen i code for left shift */
2803 /*-----------------------------------------------------------------*/
2805 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2810 ic = newiCode (LEFT_OP, left, right);
2812 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2813 IC_RESULT (ic) = newiTempOperand (resType, 0);
2815 return IC_RESULT (ic);
2818 /*-----------------------------------------------------------------*/
2819 /* geniCodeRightShift - gen i code for right shift */
2820 /*-----------------------------------------------------------------*/
2822 geniCodeRightShift (operand * left, operand * right)
2826 ic = newiCode (RIGHT_OP, left, right);
2827 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2829 return IC_RESULT (ic);
2832 /*-----------------------------------------------------------------*/
2833 /* geniCodeLogic- logic code */
2834 /*-----------------------------------------------------------------*/
2836 geniCodeLogic (operand * left, operand * right, int op)
2840 sym_link *rtype = operandType (right);
2841 sym_link *ltype = operandType (left);
2843 /* left is integral type and right is literal then
2844 check if the literal value is within bounds */
2845 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2847 checkConstantRange(ltype,
2848 OP_VALUE(right), "compare operation", 1);
2851 /* if one operand is a pointer and the other is a literal generic void pointer,
2852 change the type of the literal generic void pointer to match the other pointer */
2853 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2854 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2856 /* find left's definition */
2857 ic = (iCode *) setFirstItem (iCodeChain);
2860 if (((ic->op == CAST) || (ic->op == '='))
2861 && isOperandEqual(left, IC_RESULT (ic)))
2864 ic = setNextItem (iCodeChain);
2866 /* if casting literal to generic pointer, then cast to rtype instead */
2867 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2869 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2870 ltype = operandType(left);
2873 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2874 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2876 /* find right's definition */
2877 ic = (iCode *) setFirstItem (iCodeChain);
2880 if (((ic->op == CAST) || (ic->op == '='))
2881 && isOperandEqual(right, IC_RESULT (ic)))
2884 ic = setNextItem (iCodeChain);
2886 /* if casting literal to generic pointer, then cast to rtype instead */
2887 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2889 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2890 rtype = operandType(right);
2894 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
2896 ic = newiCode (op, left, right);
2897 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2899 /* if comparing float
2900 and not a '==' || '!=' || '&&' || '||' (these
2902 if (IS_FLOAT(ctype) &&
2910 return IC_RESULT (ic);
2913 /*-----------------------------------------------------------------*/
2914 /* geniCodeLogicAndOr - && || operations */
2915 /*-----------------------------------------------------------------*/
2917 geniCodeLogicAndOr (ast *tree, int lvl)
2920 symbol *falseLabel = newiTempLabel (NULL);
2921 symbol *trueLabel = newiTempLabel (NULL);
2922 symbol *exitLabel = newiTempLabel (NULL);
2923 operand *op, *result, *condition;
2925 /* AND_OP and OR_OP are no longer generated because of bug-905492.
2926 They can be reenabled by executing the following block. If you find
2927 a decent optimization you could start right here:
2932 operand *leftOp, *rightOp;
2934 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
2935 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
2937 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
2941 /* generate two IFX for the '&&' or '||' op */
2943 /* evaluate left operand */
2944 condition = ast2iCode (tree->left, lvl + 1);
2945 op = geniCodeRValue (condition, FALSE);
2947 /* test left operand */
2948 if (tree->opval.op == AND_OP)
2949 ic = newiCodeCondition (op, NULL, falseLabel);
2951 ic = newiCodeCondition (op, trueLabel, NULL);
2954 /* evaluate right operand */
2955 condition = ast2iCode (tree->right, lvl + 1);
2956 op = geniCodeRValue (condition, FALSE);
2958 /* test right operand */
2959 ic = newiCodeCondition (op, trueLabel, NULL);
2962 /* store 0 or 1 in result */
2963 result = newiTempOperand (newCharLink(), 1);
2965 geniCodeLabel (falseLabel);
2966 geniCodeAssign (result, operandFromLit (0), 0, 0);
2967 /* generate an unconditional goto */
2968 geniCodeGoto (exitLabel);
2970 geniCodeLabel (trueLabel);
2971 geniCodeAssign (result, operandFromLit (1), 0, 0);
2973 geniCodeLabel (exitLabel);
2978 /*-----------------------------------------------------------------*/
2979 /* geniCodeUnary - for a a generic unary operation */
2980 /*-----------------------------------------------------------------*/
2982 geniCodeUnary (operand * op, int oper)
2984 iCode *ic = newiCode (oper, op, NULL);
2986 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2988 return IC_RESULT (ic);
2991 /*-----------------------------------------------------------------*/
2992 /* geniCodeConditional - geniCode for '?' ':' operation */
2993 /*-----------------------------------------------------------------*/
2995 geniCodeConditional (ast * tree,int lvl)
2998 symbol *falseLabel = newiTempLabel (NULL);
2999 symbol *exitLabel = newiTempLabel (NULL);
3000 operand *cond = ast2iCode (tree->left,lvl+1);
3001 operand *true, *false, *result;
3003 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3007 true = ast2iCode (tree->right->left,lvl+1);
3009 /* move the value to a new Operand */
3010 result = newiTempOperand (tree->right->ftype, 0);
3011 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3013 /* generate an unconditional goto */
3014 geniCodeGoto (exitLabel);
3016 /* now for the right side */
3017 geniCodeLabel (falseLabel);
3019 false = ast2iCode (tree->right->right,lvl+1);
3020 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3022 /* create the exit label */
3023 geniCodeLabel (exitLabel);
3028 /*-----------------------------------------------------------------*/
3029 /* geniCodeAssign - generate code for assignment */
3030 /*-----------------------------------------------------------------*/
3032 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3035 sym_link *ltype = operandType (left);
3036 sym_link *rtype = operandType (right);
3038 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3040 werror (E_LVALUE_REQUIRED, "assignment");
3044 /* left is integral type and right is literal then
3045 check if the literal value is within bounds */
3046 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3048 checkConstantRange(ltype,
3049 OP_VALUE(right), "= operation", 0);
3052 /* if the left & right type don't exactly match */
3053 /* if pointer set then make sure the check is
3054 done with the type & not the pointer */
3055 /* then cast rights type to left */
3057 /* first check the type for pointer assignement */
3058 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3059 compareType (ltype, rtype) <= 0)
3061 if (compareType (ltype->next, rtype) < 0)
3062 right = geniCodeCast (ltype->next, right, TRUE);
3064 else if (compareType (ltype, rtype) < 0)
3065 right = geniCodeCast (ltype, right, TRUE);
3067 /* If left is a true symbol & ! volatile
3068 create an assignment to temporary for
3069 the right & then assign this temporary
3070 to the symbol. This is SSA (static single
3071 assignment). Isn't it simple and folks have
3072 published mountains of paper on it */
3073 if (IS_TRUE_SYMOP (left) &&
3074 !isOperandVolatile (left, FALSE) &&
3075 isOperandGlobal (left))
3079 if (IS_TRUE_SYMOP (right))
3080 sym = OP_SYMBOL (right);
3081 ic = newiCode ('=', NULL, right);
3082 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3083 SPIL_LOC (right) = sym;
3087 ic = newiCode ('=', NULL, right);
3088 IC_RESULT (ic) = left;
3091 /* if left isgptr flag is set then support
3092 routine will be required */
3096 ic->nosupdate = nosupdate;
3100 /*-----------------------------------------------------------------*/
3101 /* geniCodeDummyRead - generate code for dummy read */
3102 /*-----------------------------------------------------------------*/
3104 geniCodeDummyRead (operand * op)
3107 sym_link *type = operandType (op);
3109 if (!IS_VOLATILE(type))
3112 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3118 /*-----------------------------------------------------------------*/
3119 /* geniCodeSEParms - generate code for side effecting fcalls */
3120 /*-----------------------------------------------------------------*/
3122 geniCodeSEParms (ast * parms,int lvl)
3127 if (parms->type == EX_OP && parms->opval.op == PARAM)
3129 geniCodeSEParms (parms->left,lvl);
3130 geniCodeSEParms (parms->right,lvl);
3134 /* hack don't like this but too lazy to think of
3136 if (IS_ADDRESS_OF_OP (parms))
3137 parms->left->lvalue = 1;
3139 if (IS_CAST_OP (parms) &&
3140 IS_PTR (parms->ftype) &&
3141 IS_ADDRESS_OF_OP (parms->right))
3142 parms->right->left->lvalue = 1;
3144 parms->opval.oprnd =
3145 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3147 parms->type = EX_OPERAND;
3148 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3149 SPEC_ARGREG(parms->ftype);
3152 /*-----------------------------------------------------------------*/
3153 /* geniCodeParms - generates parameters */
3154 /*-----------------------------------------------------------------*/
3156 geniCodeParms (ast * parms, value *argVals, int *stack,
3157 sym_link * ftype, int lvl)
3165 if (argVals==NULL) {
3167 argVals = FUNC_ARGS (ftype);
3170 /* if this is a param node then do the left & right */
3171 if (parms->type == EX_OP && parms->opval.op == PARAM)
3173 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3174 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3178 /* get the parameter value */
3179 if (parms->type == EX_OPERAND)
3180 pval = parms->opval.oprnd;
3183 /* maybe this else should go away ?? */
3184 /* hack don't like this but too lazy to think of
3186 if (IS_ADDRESS_OF_OP (parms))
3187 parms->left->lvalue = 1;
3189 if (IS_CAST_OP (parms) &&
3190 IS_PTR (parms->ftype) &&
3191 IS_ADDRESS_OF_OP (parms->right))
3192 parms->right->left->lvalue = 1;
3194 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3197 /* if register parm then make it a send */
3198 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3199 IFFUNC_ISBUILTIN(ftype))
3201 ic = newiCode (SEND, pval, NULL);
3202 ic->argreg = SPEC_ARGREG(parms->etype);
3203 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3208 /* now decide whether to push or assign */
3209 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3213 operand *top = operandFromSymbol (argVals->sym);
3214 /* clear useDef and other bitVectors */
3215 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3216 geniCodeAssign (top, pval, 1, 0);
3220 sym_link *p = operandType (pval);
3222 ic = newiCode (IPUSH, pval, NULL);
3224 /* update the stack adjustment */
3225 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3230 argVals=argVals->next;
3234 /*-----------------------------------------------------------------*/
3235 /* geniCodeCall - generates temp code for calling */
3236 /*-----------------------------------------------------------------*/
3238 geniCodeCall (operand * left, ast * parms,int lvl)
3242 sym_link *type, *etype;
3246 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3247 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3248 werror (E_FUNCTION_EXPECTED);
3249 return operandFromValue(valueFromLit(0));
3252 /* take care of parameters with side-effecting
3253 function calls in them, this is required to take care
3254 of overlaying function parameters */
3255 geniCodeSEParms (parms,lvl);
3257 ftype = operandType (left);
3258 if (IS_CODEPTR (ftype))
3259 ftype = ftype->next;
3261 /* first the parameters */
3262 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3264 /* now call : if symbol then pcall */
3265 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3266 ic = newiCode (PCALL, left, NULL);
3268 ic = newiCode (CALL, left, NULL);
3271 type = copyLinkChain (ftype->next);
3272 etype = getSpec (type);
3273 SPEC_EXTR (etype) = 0;
3274 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3278 /* stack adjustment after call */
3279 ic->parmBytes = stack;
3284 /*-----------------------------------------------------------------*/
3285 /* geniCodeReceive - generate intermediate code for "receive" */
3286 /*-----------------------------------------------------------------*/
3288 geniCodeReceive (value * args)
3290 /* for all arguments that are passed in registers */
3294 if (IS_REGPARM (args->etype))
3296 operand *opr = operandFromValue (args);
3298 symbol *sym = OP_SYMBOL (opr);
3301 /* we will use it after all optimizations
3302 and before liveRange calculation */
3303 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3306 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3307 options.stackAuto == 0 &&
3308 (!(options.model == MODEL_FLAT24)) )
3313 opl = newiTempOperand (args->type, 0);
3315 sym->reqv->key = sym->key;
3316 OP_SYMBOL (sym->reqv)->key = sym->key;
3317 OP_SYMBOL (sym->reqv)->isreqv = 1;
3318 OP_SYMBOL (sym->reqv)->islocal = 0;
3319 SPIL_LOC (sym->reqv) = sym;
3323 ic = newiCode (RECEIVE, NULL, NULL);
3324 ic->argreg = SPEC_ARGREG(args->etype);
3326 currFunc->recvSize = getSize (sym->type);
3329 IC_RESULT (ic) = opr;
3337 /*-----------------------------------------------------------------*/
3338 /* geniCodeFunctionBody - create the function body */
3339 /*-----------------------------------------------------------------*/
3341 geniCodeFunctionBody (ast * tree,int lvl)
3348 /* reset the auto generation */
3354 func = ast2iCode (tree->left,lvl+1);
3355 fetype = getSpec (operandType (func));
3357 savelineno = lineno;
3358 lineno = OP_SYMBOL (func)->lineDef;
3359 /* create an entry label */
3360 geniCodeLabel (entryLabel);
3361 lineno = savelineno;
3363 /* create a proc icode */
3364 ic = newiCode (FUNCTION, func, NULL);
3365 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3369 /* for all parameters that are passed
3370 on registers add a "receive" */
3371 geniCodeReceive (tree->values.args);
3373 /* generate code for the body */
3374 ast2iCode (tree->right,lvl+1);
3376 /* create a label for return */
3377 geniCodeLabel (returnLabel);
3379 /* now generate the end proc */
3380 ic = newiCode (ENDFUNCTION, func, NULL);
3385 /*-----------------------------------------------------------------*/
3386 /* geniCodeReturn - gen icode for 'return' statement */
3387 /*-----------------------------------------------------------------*/
3389 geniCodeReturn (operand * op)
3393 /* if the operand is present force an rvalue */
3395 op = geniCodeRValue (op, FALSE);
3397 ic = newiCode (RETURN, op, NULL);
3401 /*-----------------------------------------------------------------*/
3402 /* geniCodeIfx - generates code for extended if statement */
3403 /*-----------------------------------------------------------------*/
3405 geniCodeIfx (ast * tree,int lvl)
3408 operand *condition = ast2iCode (tree->left,lvl+1);
3411 /* if condition is null then exit */
3415 condition = geniCodeRValue (condition, FALSE);
3417 cetype = getSpec (operandType (condition));
3418 /* if the condition is a literal */
3419 if (IS_LITERAL (cetype))
3421 if (floatFromVal (condition->operand.valOperand))
3423 if (tree->trueLabel)
3424 geniCodeGoto (tree->trueLabel);
3430 if (tree->falseLabel)
3431 geniCodeGoto (tree->falseLabel);
3438 if (tree->trueLabel)
3440 ic = newiCodeCondition (condition,
3445 if (tree->falseLabel)
3446 geniCodeGoto (tree->falseLabel);
3450 ic = newiCodeCondition (condition,
3457 ast2iCode (tree->right,lvl+1);
3460 /*-----------------------------------------------------------------*/
3461 /* geniCodeJumpTable - tries to create a jump table for switch */
3462 /*-----------------------------------------------------------------*/
3464 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3466 int min = 0, max = 0, t, cnt = 0;
3472 int needRangeCheck = !optimize.noJTabBoundary
3473 || tree->values.switchVals.swDefault;
3475 if (!tree || !caseVals)
3478 /* the criteria for creating a jump table is */
3479 /* all integer numbers between the maximum & minimum must */
3480 /* be present , the maximum value should not exceed 255 */
3481 min = max = (int) floatFromVal (vch = caseVals);
3482 SNPRINTF (buffer, sizeof(buffer),
3484 tree->values.switchVals.swNum,
3486 addSet (&labels, newiTempLabel (buffer));
3488 /* if there is only one case value then no need */
3489 if (!(vch = vch->next))
3494 if (((t = (int) floatFromVal (vch)) - max) != 1)
3496 SNPRINTF (buffer, sizeof(buffer),
3498 tree->values.switchVals.swNum,
3500 addSet (&labels, newiTempLabel (buffer));
3506 /* if the number of case statements <= 2 then */
3507 /* it is not economical to create the jump table */
3508 /* since two compares are needed for boundary conditions */
3509 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3512 if (tree->values.switchVals.swDefault)
3514 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3518 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3522 falseLabel = newiTempLabel (buffer);
3524 /* so we can create a jumptable */
3525 /* first we rule out the boundary conditions */
3526 /* if only optimization says so */
3529 sym_link *cetype = getSpec (operandType (cond));
3530 /* no need to check the lower bound if
3531 the condition is unsigned & minimum value is zero */
3532 if (!(min == 0 && IS_UNSIGNED (cetype)))
3534 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3535 ic = newiCodeCondition (boundary, falseLabel, NULL);
3539 /* now for upper bounds */
3540 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3541 ic = newiCodeCondition (boundary, falseLabel, NULL);
3545 /* if the min is not zero then we no make it zero */
3548 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3549 if (!IS_LITERAL(getSpec(operandType(cond))))
3550 setOperandType (cond, UCHARTYPE);
3553 /* now create the jumptable */
3554 ic = newiCode (JUMPTABLE, NULL, NULL);
3555 IC_JTCOND (ic) = cond;
3556 IC_JTLABELS (ic) = labels;
3561 /*-----------------------------------------------------------------*/
3562 /* geniCodeSwitch - changes a switch to a if statement */
3563 /*-----------------------------------------------------------------*/
3565 geniCodeSwitch (ast * tree,int lvl)
3568 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3569 value *caseVals = tree->values.switchVals.swVals;
3570 symbol *trueLabel, *falseLabel;
3572 /* If the condition is a literal, then just jump to the */
3573 /* appropriate case label. */
3574 if (IS_LITERAL(getSpec(operandType(cond))))
3576 int switchVal, caseVal;
3578 switchVal = (int) floatFromVal (cond->operand.valOperand);
3581 caseVal = (int) floatFromVal (caseVals);
3582 if (caseVal == switchVal)
3584 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3585 tree->values.switchVals.swNum, caseVal);
3586 trueLabel = newiTempLabel (buffer);
3587 geniCodeGoto (trueLabel);
3590 caseVals = caseVals->next;
3592 goto defaultOrBreak;
3595 /* if we can make this a jump table */
3596 if (geniCodeJumpTable (cond, caseVals, tree))
3597 goto jumpTable; /* no need for the comparison */
3599 /* for the cases defined do */
3603 operand *compare = geniCodeLogic (cond,
3604 operandFromValue (caseVals),
3607 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3608 tree->values.switchVals.swNum,
3609 (int) floatFromVal (caseVals));
3610 trueLabel = newiTempLabel (buffer);
3612 ic = newiCodeCondition (compare, trueLabel, NULL);
3614 caseVals = caseVals->next;
3619 /* if default is present then goto break else break */
3620 if (tree->values.switchVals.swDefault)
3622 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3626 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3629 falseLabel = newiTempLabel (buffer);
3630 geniCodeGoto (falseLabel);
3633 ast2iCode (tree->right,lvl+1);
3636 /*-----------------------------------------------------------------*/
3637 /* geniCodeInline - intermediate code for inline assembler */
3638 /*-----------------------------------------------------------------*/
3640 geniCodeInline (ast * tree)
3644 ic = newiCode (INLINEASM, NULL, NULL);
3645 IC_INLINE (ic) = tree->values.inlineasm;
3649 /*-----------------------------------------------------------------*/
3650 /* geniCodeArrayInit - intermediate code for array initializer */
3651 /*-----------------------------------------------------------------*/
3653 geniCodeArrayInit (ast * tree, operand *array)
3657 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3658 ic = newiCode (ARRAYINIT, array, NULL);
3659 IC_ARRAYILIST (ic) = tree->values.constlist;
3661 operand *left=newOperand(), *right=newOperand();
3662 left->type=right->type=SYMBOL;
3663 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3664 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3665 ic = newiCode (ARRAYINIT, left, right);
3670 /*-----------------------------------------------------------------*/
3671 /* geniCodeCritical - intermediate code for a critical statement */
3672 /*-----------------------------------------------------------------*/
3674 geniCodeCritical (ast *tree, int lvl)
3679 /* If op is NULL, the original interrupt state will saved on */
3680 /* the stack. Otherwise, it will be saved in op. */
3682 /* Generate a save of the current interrupt state & disabled */
3683 ic = newiCode (CRITICAL, NULL, NULL);
3684 IC_RESULT (ic) = op;
3687 /* Generate the critical code sequence */
3688 if (tree->left && tree->left->type == EX_VALUE)
3689 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3691 ast2iCode (tree->left,lvl+1);
3693 /* Generate a restore of the original interrupt state */
3694 ic = newiCode (ENDCRITICAL, NULL, op);
3698 /*-----------------------------------------------------------------*/
3699 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3700 /* particular case. Ie : assigning or dereferencing array or ptr */
3701 /*-----------------------------------------------------------------*/
3702 set * lvaluereqSet = NULL;
3703 typedef struct lvalItem
3710 /*-----------------------------------------------------------------*/
3711 /* addLvaluereq - add a flag for lvalreq for current ast level */
3712 /*-----------------------------------------------------------------*/
3713 void addLvaluereq(int lvl)
3715 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3718 addSetHead(&lvaluereqSet,lpItem);
3721 /*-----------------------------------------------------------------*/
3722 /* delLvaluereq - del a flag for lvalreq for current ast level */
3723 /*-----------------------------------------------------------------*/
3727 lpItem = getSet(&lvaluereqSet);
3728 if(lpItem) Safe_free(lpItem);
3730 /*-----------------------------------------------------------------*/
3731 /* clearLvaluereq - clear lvalreq flag */
3732 /*-----------------------------------------------------------------*/
3733 void clearLvaluereq()
3736 lpItem = peekSet(lvaluereqSet);
3737 if(lpItem) lpItem->req = 0;
3739 /*-----------------------------------------------------------------*/
3740 /* getLvaluereq - get the last lvalreq level */
3741 /*-----------------------------------------------------------------*/
3742 int getLvaluereqLvl()
3745 lpItem = peekSet(lvaluereqSet);
3746 if(lpItem) return lpItem->lvl;
3749 /*-----------------------------------------------------------------*/
3750 /* isLvaluereq - is lvalreq valid for this level ? */
3751 /*-----------------------------------------------------------------*/
3752 int isLvaluereq(int lvl)
3755 lpItem = peekSet(lvaluereqSet);
3756 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3760 /*-----------------------------------------------------------------*/
3761 /* ast2iCode - creates an icodeList from an ast */
3762 /*-----------------------------------------------------------------*/
3764 ast2iCode (ast * tree,int lvl)
3766 operand *left = NULL;
3767 operand *right = NULL;
3771 /* set the global variables for filename & line number */
3773 filename = tree->filename;
3775 lineno = tree->lineno;
3777 block = tree->block;
3779 scopeLevel = tree->level;
3781 seqPoint = tree->seqPoint;
3783 if (tree->type == EX_VALUE)
3784 return operandFromValue (tree->opval.val);
3786 if (tree->type == EX_LINK)
3787 return operandFromLink (tree->opval.lnk);
3789 /* if we find a nullop */
3790 if (tree->type == EX_OP &&
3791 (tree->opval.op == NULLOP ||
3792 tree->opval.op == BLOCK))
3794 if (tree->left && tree->left->type == EX_VALUE)
3795 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3797 ast2iCode (tree->left,lvl+1);
3798 if (tree->right && tree->right->type == EX_VALUE)
3799 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3801 ast2iCode (tree->right,lvl+1);
3805 /* special cases for not evaluating */
3806 if (tree->opval.op != ':' &&
3807 tree->opval.op != '?' &&
3808 tree->opval.op != CALL &&
3809 tree->opval.op != IFX &&
3810 tree->opval.op != AND_OP &&
3811 tree->opval.op != OR_OP &&
3812 tree->opval.op != LABEL &&
3813 tree->opval.op != GOTO &&
3814 tree->opval.op != SWITCH &&
3815 tree->opval.op != FUNCTION &&
3816 tree->opval.op != INLINEASM &&
3817 tree->opval.op != CRITICAL)
3820 if (IS_ASSIGN_OP (tree->opval.op) ||
3821 IS_DEREF_OP (tree) ||
3822 (tree->opval.op == '&' && !tree->right) ||
3823 tree->opval.op == PTR_OP)
3826 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3827 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3830 left = operandFromAst (tree->left,lvl);
3832 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3833 left = geniCodeRValue (left, TRUE);
3837 left = operandFromAst (tree->left,lvl);
3839 if (tree->opval.op == INC_OP ||
3840 tree->opval.op == DEC_OP)
3843 right = operandFromAst (tree->right,lvl);
3848 right = operandFromAst (tree->right,lvl);
3852 /* now depending on the type of operand */
3853 /* this will be a biggy */
3854 switch (tree->opval.op)
3857 case '[': /* array operation */
3859 //sym_link *ltype = operandType (left);
3860 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3861 left = geniCodeRValue (left, FALSE);
3862 right = geniCodeRValue (right, TRUE);
3865 return geniCodeArray (left, right,lvl);
3867 case '.': /* structure dereference */
3868 if (IS_PTR (operandType (left)))
3869 left = geniCodeRValue (left, TRUE);
3871 left = geniCodeRValue (left, FALSE);
3873 return geniCodeStruct (left, right, tree->lvalue);
3875 case PTR_OP: /* structure pointer dereference */
3878 pType = operandType (left);
3879 left = geniCodeRValue (left, TRUE);
3881 setOClass (pType, getSpec (operandType (left)));
3884 return geniCodeStruct (left, right, tree->lvalue);
3886 case INC_OP: /* increment operator */
3888 return geniCodePostInc (left);
3890 return geniCodePreInc (right, tree->lvalue);
3892 case DEC_OP: /* decrement operator */
3894 return geniCodePostDec (left);
3896 return geniCodePreDec (right, tree->lvalue);
3898 case '&': /* bitwise and or address of operator */
3900 { /* this is a bitwise operator */
3901 left = geniCodeRValue (left, FALSE);
3902 right = geniCodeRValue (right, FALSE);
3903 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3906 return geniCodeAddressOf (left);
3908 case '|': /* bitwise or & xor */
3910 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3911 geniCodeRValue (right, FALSE),
3916 return geniCodeDivision (geniCodeRValue (left, FALSE),
3917 geniCodeRValue (right, FALSE),
3918 getResultTypeFromType (tree->ftype));
3921 return geniCodeModulus (geniCodeRValue (left, FALSE),
3922 geniCodeRValue (right, FALSE),
3923 getResultTypeFromType (tree->ftype));
3926 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3927 geniCodeRValue (right, FALSE),
3928 getResultTypeFromType (tree->ftype));
3930 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3934 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3935 geniCodeRValue (right, FALSE),
3936 getResultTypeFromType (tree->ftype));
3938 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3942 return geniCodeAdd (geniCodeRValue (left, FALSE),
3943 geniCodeRValue (right, FALSE),
3944 getResultTypeFromType (tree->ftype),
3947 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3950 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3951 geniCodeRValue (right, FALSE),
3952 getResultTypeFromType (tree->ftype));
3955 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3956 geniCodeRValue (right, FALSE));
3958 #if 0 // this indeed needs a second thought
3962 // let's keep this simple: get the rvalue we need
3963 op=geniCodeRValue (right, FALSE);
3964 // now cast it to whatever we want
3965 op=geniCodeCast (operandType(left), op, FALSE);
3966 // if this is going to be used as an lvalue, make it so
3972 #else // bug #604575, is it a bug ????
3973 return geniCodeCast (operandType (left),
3974 geniCodeRValue (right, FALSE), FALSE);
3981 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3986 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3987 setOperandType (op, UCHARTYPE);
3992 return geniCodeLogicAndOr (tree, lvl);
3999 /* different compilers (even different gccs) evaluate
4000 the two calls in a different order. to get the same
4001 result on all machines we've to specify a clear sequence.
4002 return geniCodeLogic (geniCodeRValue (left, FALSE),
4003 geniCodeRValue (right, FALSE),
4007 operand *leftOp, *rightOp;
4009 leftOp = geniCodeRValue (left , FALSE);
4010 rightOp = geniCodeRValue (right, FALSE);
4012 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4015 return geniCodeConditional (tree,lvl);
4018 return operandFromLit (getSize (tree->right->ftype));
4022 sym_link *rtype = operandType (right);
4023 sym_link *ltype = operandType (left);
4024 if (IS_PTR (rtype) && IS_ITEMP (right)
4025 && right->isaddr && compareType (rtype->next, ltype) == 1)
4026 right = geniCodeRValue (right, TRUE);
4028 right = geniCodeRValue (right, FALSE);
4030 geniCodeAssign (left, right, 0, 1);
4035 geniCodeAssign (left,
4036 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4038 geniCodeRValue (right, FALSE),
4039 getResultTypeFromType (tree->ftype)),
4044 geniCodeAssign (left,
4045 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4047 geniCodeRValue (right, FALSE),
4048 getResultTypeFromType (tree->ftype)),
4052 geniCodeAssign (left,
4053 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4055 geniCodeRValue (right, FALSE),
4056 getResultTypeFromType (tree->ftype)),
4060 sym_link *rtype = operandType (right);
4061 sym_link *ltype = operandType (left);
4062 if (IS_PTR (rtype) && IS_ITEMP (right)
4063 && right->isaddr && compareType (rtype->next, ltype) == 1)
4064 right = geniCodeRValue (right, TRUE);
4066 right = geniCodeRValue (right, FALSE);
4069 return geniCodeAssign (left,
4070 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4073 getResultTypeFromType (tree->ftype),
4079 sym_link *rtype = operandType (right);
4080 sym_link *ltype = operandType (left);
4081 if (IS_PTR (rtype) && IS_ITEMP (right)
4082 && right->isaddr && compareType (rtype->next, ltype) == 1)
4084 right = geniCodeRValue (right, TRUE);
4088 right = geniCodeRValue (right, FALSE);
4091 geniCodeAssign (left,
4092 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4095 getResultTypeFromType (tree->ftype)),
4100 geniCodeAssign (left,
4101 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4103 geniCodeRValue (right, FALSE),
4104 getResultTypeFromType (tree->ftype)),
4108 geniCodeAssign (left,
4109 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4111 geniCodeRValue (right, FALSE)), 0, 1);
4114 geniCodeAssign (left,
4115 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4117 geniCodeRValue (right, FALSE),
4119 operandType (left)), 0, 1);
4122 geniCodeAssign (left,
4123 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4125 geniCodeRValue (right, FALSE),
4127 operandType (left)), 0, 1);
4130 geniCodeAssign (left,
4131 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4133 geniCodeRValue (right, FALSE),
4135 operandType (left)), 0, 1);
4137 return geniCodeRValue (right, FALSE);
4140 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4143 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4144 return ast2iCode (tree->right,lvl+1);
4147 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4148 return ast2iCode (tree->right,lvl+1);
4151 geniCodeFunctionBody (tree,lvl);
4155 geniCodeReturn (right);
4159 geniCodeIfx (tree,lvl);
4163 geniCodeSwitch (tree,lvl);
4167 geniCodeInline (tree);
4171 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4175 geniCodeCritical (tree, lvl);
4181 /*-----------------------------------------------------------------*/
4182 /* reverseICChain - gets from the list and creates a linkedlist */
4183 /*-----------------------------------------------------------------*/
4190 while ((loop = getSet (&iCodeChain)))
4202 /*-----------------------------------------------------------------*/
4203 /* iCodeFromAst - given an ast will convert it to iCode */
4204 /*-----------------------------------------------------------------*/
4206 iCodeFromAst (ast * tree)
4208 returnLabel = newiTempLabel ("_return");
4209 entryLabel = newiTempLabel ("_entry");
4211 return reverseiCChain ();
4214 static const char *opTypeToStr(OPTYPE op)
4218 case SYMBOL: return "symbol";
4219 case VALUE: return "value";
4220 case TYPE: return "type";
4222 return "undefined type";
4226 operand *validateOpType(operand *op,
4233 if (op && op->type == type)
4238 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4239 " expected %s, got %s\n",
4240 macro, args, file, line,
4241 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4243 return op; // never reached, makes compiler happy.