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 *geniCodeDivision (operand *, operand *);
49 operand *geniCodeAssign (operand *, operand *, int);
50 static operand *geniCodeArray (operand *, operand *,int);
51 static operand *geniCodeArray2Ptr (operand *);
52 operand *geniCodeRValue (operand *, bool);
53 operand *geniCodeDerefPtr (operand *,int);
54 int isLvaluereq(int lvl);
55 void setOClass (sym_link * ptr, sym_link * spec);
56 static operand *geniCodeCast (sym_link *, operand *, bool);
58 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
59 /* forward definition of ic print functions */
60 PRINTFUNC (picGetValueAtAddr);
61 PRINTFUNC (picSetValueAtAddr);
62 PRINTFUNC (picAddrOf);
63 PRINTFUNC (picGeneric);
64 PRINTFUNC (picGenericOne);
66 PRINTFUNC (picAssign);
70 PRINTFUNC (picJumpTable);
71 PRINTFUNC (picInline);
72 PRINTFUNC (picReceive);
73 PRINTFUNC (picDummyRead);
74 PRINTFUNC (picCritical);
75 PRINTFUNC (picEndCritical);
77 iCodeTable codeTable[] =
79 {'!', "not", picGenericOne, NULL},
80 {'~', "~", picGenericOne, NULL},
81 {RRC, "rrc", picGenericOne, NULL},
82 {RLC, "rlc", picGenericOne, NULL},
83 {GETHBIT, "ghbit", picGenericOne, NULL},
84 {UNARYMINUS, "-", picGenericOne, NULL},
85 {IPUSH, "push", picGenericOne, NULL},
86 {IPOP, "pop", picGenericOne, NULL},
87 {CALL, "call", picGenericOne, NULL},
88 {PCALL, "pcall", picGenericOne, NULL},
89 {FUNCTION, "proc", picGenericOne, NULL},
90 {ENDFUNCTION, "eproc", picGenericOne, NULL},
91 {RETURN, "ret", picGenericOne, NULL},
92 {'+', "+", picGeneric, NULL},
93 {'-', "-", picGeneric, NULL},
94 {'*', "*", picGeneric, NULL},
95 {'/', "/", picGeneric, NULL},
96 {'%', "%", picGeneric, NULL},
97 {'>', ">", picGeneric, NULL},
98 {'<', "<", picGeneric, NULL},
99 {LE_OP, "<=", picGeneric, NULL},
100 {GE_OP, ">=", picGeneric, NULL},
101 {EQ_OP, "==", picGeneric, NULL},
102 {NE_OP, "!=", picGeneric, NULL},
103 {AND_OP, "&&", picGeneric, NULL},
104 {OR_OP, "||", picGeneric, NULL},
105 {'^', "^", picGeneric, NULL},
106 {'|', "|", picGeneric, NULL},
107 {BITWISEAND, "&", picGeneric, NULL},
108 {LEFT_OP, "<<", picGeneric, NULL},
109 {RIGHT_OP, ">>", picGeneric, NULL},
110 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
111 {ADDRESS_OF, "&", picAddrOf, NULL},
112 {CAST, "<>", picCast, NULL},
113 {'=', ":=", picAssign, NULL},
114 {LABEL, "", picLabel, NULL},
115 {GOTO, "", picGoto, NULL},
116 {JUMPTABLE, "jtab", picJumpTable, NULL},
117 {IFX, "if", picIfx, NULL},
118 {INLINEASM, "", picInline, NULL},
119 {RECEIVE, "recv", picReceive, NULL},
120 {SEND, "send", picGenericOne, NULL},
121 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
122 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
123 {CRITICAL, "critical_start", picCritical, NULL},
124 {ENDCRITICAL, "critical_end", picEndCritical, NULL}
127 /*-----------------------------------------------------------------*/
128 /* checkConstantRange: check a constant against the type */
129 /*-----------------------------------------------------------------*/
132 /* pedantic=0: allmost anything is allowed as long as the absolute
133 value is within the bit range of the type, and -1 is treated as
134 0xf..f for unsigned types (e.g. in assign)
135 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
136 pedantic>1: "char c=200" is not allowed (evaluates to -56)
139 void checkConstantRange(sym_link *ltype, value *val, char *msg,
146 max = pow ((double)2.0, (double)bitsForType(ltype));
148 if (IS_LONG(val->type)) {
149 if (IS_UNSIGNED(val->type)) {
150 v=SPEC_CVAL(val->type).v_ulong;
152 v=SPEC_CVAL(val->type).v_long;
155 if (IS_UNSIGNED(val->type)) {
156 v=SPEC_CVAL(val->type).v_uint;
158 v=SPEC_CVAL(val->type).v_int;
164 // this could be a good idea
165 if (options.pedantic)
169 if (IS_FLOAT(ltype)) {
174 if (!IS_UNSIGNED(val->type) && v<0) {
176 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
182 // if very pedantic: "char c=200" is not allowed
183 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
184 max = max/2 + negative;
191 #if 0 // temporary disabled, leaving the warning as a reminder
193 SNPRINTF (message, sizeof(message), "for %s %s in %s",
194 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
195 nounName(ltype), msg);
196 werror (W_CONST_RANGE, message);
204 /*-----------------------------------------------------------------*/
205 /* operandName - returns the name of the operand */
206 /*-----------------------------------------------------------------*/
208 printOperand (operand * op, FILE * file)
225 opetype = getSpec (operandType (op));
226 if (IS_FLOAT (opetype))
227 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
229 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
230 printTypeChain (operandType (op), file);
237 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
238 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
240 OP_LIVEFROM (op), OP_LIVETO (op),
241 OP_SYMBOL (op)->stack,
242 op->isaddr, OP_SYMBOL (op)->isreqv,
243 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
244 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
248 printTypeChain (operandType (op), file);
249 if (SPIL_LOC (op) && IS_ITEMP (op))
250 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
255 /* if assigned to registers */
256 if (OP_SYMBOL (op)->nRegs)
258 if (OP_SYMBOL (op)->isspilt)
260 if (!OP_SYMBOL (op)->remat)
261 if (OP_SYMBOL (op)->usl.spillLoc)
262 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
263 OP_SYMBOL (op)->usl.spillLoc->rname :
264 OP_SYMBOL (op)->usl.spillLoc->name));
266 fprintf (file, "[err]");
268 fprintf (file, "[remat]");
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
280 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
281 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
282 /* if assigned to registers */
283 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
287 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
288 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
289 OP_SYMBOL (op)->regs[i]->name :
298 printTypeChain (op->operand.typeOperand, file);
304 fprintf (file, "\n");
309 /*-----------------------------------------------------------------*/
310 /* print functions */
311 /*-----------------------------------------------------------------*/
312 PRINTFUNC (picGetValueAtAddr)
315 printOperand (IC_RESULT (ic), of);
318 printOperand (IC_LEFT (ic), of);
324 PRINTFUNC (picSetValueAtAddr)
328 printOperand (IC_LEFT (ic), of);
329 fprintf (of, "] = ");
330 printOperand (IC_RIGHT (ic), of);
334 PRINTFUNC (picAddrOf)
337 printOperand (IC_RESULT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
341 fprintf (of, " = &[");
342 printOperand (IC_LEFT (ic), of);
345 if (IS_ITEMP (IC_LEFT (ic)))
346 fprintf (of, " offsetAdd ");
349 printOperand (IC_RIGHT (ic), of);
351 if (IS_ITEMP (IC_LEFT (ic)))
357 PRINTFUNC (picJumpTable)
362 fprintf (of, "%s\t", s);
363 printOperand (IC_JTCOND (ic), of);
365 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
366 sym = setNextItem (IC_JTLABELS (ic)))
367 fprintf (of, "\t\t\t%s\n", sym->name);
370 PRINTFUNC (picGeneric)
373 printOperand (IC_RESULT (ic), of);
375 printOperand (IC_LEFT (ic), of);
376 fprintf (of, " %s ", s);
377 printOperand (IC_RIGHT (ic), of);
381 PRINTFUNC (picGenericOne)
386 printOperand (IC_RESULT (ic), of);
392 fprintf (of, "%s ", s);
393 printOperand (IC_LEFT (ic), of);
396 if (!IC_RESULT (ic) && !IC_LEFT (ic))
399 if (ic->op == SEND || ic->op == RECEIVE) {
400 fprintf(of,"{argreg = %d}",ic->argreg);
408 printOperand (IC_RESULT (ic), of);
410 printOperand (IC_LEFT (ic), of);
411 printOperand (IC_RIGHT (ic), of);
416 PRINTFUNC (picAssign)
420 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
423 printOperand (IC_RESULT (ic), of);
425 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
428 fprintf (of, " %s ", s);
429 printOperand (IC_RIGHT (ic), of);
436 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
442 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
449 printOperand (IC_COND (ic), of);
452 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
455 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
457 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
461 PRINTFUNC (picInline)
463 fprintf (of, "%s", IC_INLINE (ic));
466 PRINTFUNC (picReceive)
468 printOperand (IC_RESULT (ic), of);
469 fprintf (of, " = %s ", s);
470 printOperand (IC_LEFT (ic), of);
474 PRINTFUNC (picDummyRead)
477 fprintf (of, "%s ", s);
478 printOperand (IC_RIGHT (ic), of);
482 PRINTFUNC (picCritical)
486 printOperand (IC_RESULT (ic), of);
488 fprintf (of, "(stack)");
489 fprintf (of, " = %s ", s);
493 PRINTFUNC (picEndCritical)
496 fprintf (of, "%s = ", s);
498 printOperand (IC_RIGHT (ic), of);
500 fprintf (of, "(stack)");
504 /*-----------------------------------------------------------------*/
505 /* piCode - prints one iCode */
506 /*-----------------------------------------------------------------*/
508 piCode (void *item, FILE * of)
516 icTab = getTableEntry (ic->op);
517 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
518 ic->filename, ic->lineno,
519 ic->seq, ic->key, ic->depth, ic->supportRtn);
520 icTab->iCodePrint (of, ic, icTab->printName);
526 printiCChain(ic,stdout);
528 /*-----------------------------------------------------------------*/
529 /* printiCChain - prints intermediate code for humans */
530 /*-----------------------------------------------------------------*/
532 printiCChain (iCode * icChain, FILE * of)
539 for (loop = icChain; loop; loop = loop->next)
541 if ((icTab = getTableEntry (loop->op)))
543 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
544 loop->filename, loop->lineno,
545 loop->seq, loop->key, loop->depth, loop->supportRtn);
547 icTab->iCodePrint (of, loop, icTab->printName);
553 /*-----------------------------------------------------------------*/
554 /* newOperand - allocate, init & return a new iCode */
555 /*-----------------------------------------------------------------*/
561 op = Safe_alloc ( sizeof (operand));
567 /*-----------------------------------------------------------------*/
568 /* newiCode - create and return a new iCode entry initialised */
569 /*-----------------------------------------------------------------*/
571 newiCode (int op, operand * left, operand * right)
575 ic = Safe_alloc ( sizeof (iCode));
577 ic->seqPoint = seqPoint;
579 ic->filename = filename;
581 ic->level = scopeLevel;
583 ic->key = iCodeKey++;
585 IC_RIGHT (ic) = right;
590 /*-----------------------------------------------------------------*/
591 /* newiCode for conditional statements */
592 /*-----------------------------------------------------------------*/
594 newiCodeCondition (operand * condition,
600 if (IS_VOID(operandType(condition))) {
601 werror(E_VOID_VALUE_USED);
604 ic = newiCode (IFX, NULL, NULL);
605 IC_COND (ic) = condition;
606 IC_TRUE (ic) = trueLabel;
607 IC_FALSE (ic) = falseLabel;
611 /*-----------------------------------------------------------------*/
612 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
613 /*-----------------------------------------------------------------*/
615 newiCodeLabelGoto (int op, symbol * label)
619 ic = newiCode (op, NULL, NULL);
623 IC_RIGHT (ic) = NULL;
624 IC_RESULT (ic) = NULL;
628 /*-----------------------------------------------------------------*/
629 /* newiTemp - allocate & return a newItemp Variable */
630 /*-----------------------------------------------------------------*/
638 SNPRINTF (buffer, sizeof(buffer), "%s", s);
642 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
645 itmp = newSymbol (buffer, 1);
646 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
652 /*-----------------------------------------------------------------*/
653 /* newiTempLabel - creates a temp variable label */
654 /*-----------------------------------------------------------------*/
656 newiTempLabel (char *s)
660 /* check if this alredy exists */
661 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
666 itmplbl = newSymbol (s, 1);
670 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
671 itmplbl = newSymbol (buffer, 1);
676 itmplbl->key = labelKey++;
677 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
681 /*-----------------------------------------------------------------*/
682 /* newiTempPreheaderLabel - creates a new preheader label */
683 /*-----------------------------------------------------------------*/
685 newiTempPreheaderLabel ()
689 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
690 itmplbl = newSymbol (buffer, 1);
694 itmplbl->key = labelKey++;
695 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
700 /*-----------------------------------------------------------------*/
701 /* initiCode - initialises some iCode related stuff */
702 /*-----------------------------------------------------------------*/
709 /*-----------------------------------------------------------------*/
710 /* copyiCode - make a copy of the iCode given */
711 /*-----------------------------------------------------------------*/
713 copyiCode (iCode * ic)
715 iCode *nic = newiCode (ic->op, NULL, NULL);
717 nic->lineno = ic->lineno;
718 nic->filename = ic->filename;
719 nic->block = ic->block;
720 nic->level = ic->level;
721 nic->parmBytes = ic->parmBytes;
723 /* deal with the special cases first */
727 IC_COND (nic) = operandFromOperand (IC_COND (ic));
728 IC_TRUE (nic) = IC_TRUE (ic);
729 IC_FALSE (nic) = IC_FALSE (ic);
733 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
734 IC_JTLABELS (nic) = IC_JTLABELS (ic);
739 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
740 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
744 IC_INLINE (nic) = IC_INLINE (ic);
748 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
752 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
753 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
754 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
760 /*-----------------------------------------------------------------*/
761 /* getTableEntry - gets the table entry for the given operator */
762 /*-----------------------------------------------------------------*/
764 getTableEntry (int oper)
768 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
769 if (oper == codeTable[i].icode)
770 return &codeTable[i];
775 /*-----------------------------------------------------------------*/
776 /* newiTempOperand - new intermediate temp operand */
777 /*-----------------------------------------------------------------*/
779 newiTempOperand (sym_link * type, char throwType)
782 operand *op = newOperand ();
786 itmp = newiTemp (NULL);
788 etype = getSpec (type);
790 if (IS_LITERAL (etype))
793 /* copy the type information */
795 itmp->etype = getSpec (itmp->type = (throwType ? type :
796 copyLinkChain (type)));
797 if (IS_LITERAL (itmp->etype))
799 SPEC_SCLS (itmp->etype) = S_REGISTER;
800 SPEC_OCLS (itmp->etype) = reg;
803 op->operand.symOperand = itmp;
804 op->key = itmp->key = ++operandKey;
808 /*-----------------------------------------------------------------*/
809 /* operandType - returns the type chain for an operand */
810 /*-----------------------------------------------------------------*/
812 operandType (operand * op)
814 /* depending on type of operand */
819 return op->operand.valOperand->type;
822 return op->operand.symOperand->type;
825 return op->operand.typeOperand;
827 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
828 " operand type not known ");
829 assert (0); /* should never come here */
830 /* Just to keep the compiler happy */
831 return (sym_link *) 0;
835 /*-----------------------------------------------------------------*/
836 /* isParamterToCall - will return 1 if op is a parameter to args */
837 /*-----------------------------------------------------------------*/
839 isParameterToCall (value * args, operand * op)
843 wassert (IS_SYMOP(op));
848 isSymbolEqual (op->operand.symOperand, tval->sym))
855 /*-----------------------------------------------------------------*/
856 /* isOperandGlobal - return 1 if operand is a global variable */
857 /*-----------------------------------------------------------------*/
859 isOperandGlobal (operand * op)
868 (op->operand.symOperand->level == 0 ||
869 IS_STATIC (op->operand.symOperand->etype) ||
870 IS_EXTERN (op->operand.symOperand->etype))
877 /*-----------------------------------------------------------------*/
878 /* isOperandVolatile - return 1 if the operand is volatile */
879 /*-----------------------------------------------------------------*/
881 isOperandVolatile (operand * op, bool chkTemp)
886 if (IS_ITEMP (op) && !chkTemp)
889 opetype = getSpec (optype = operandType (op));
891 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
894 if (IS_VOLATILE (opetype))
899 /*-----------------------------------------------------------------*/
900 /* isOperandLiteral - returns 1 if an operand contains a literal */
901 /*-----------------------------------------------------------------*/
903 isOperandLiteral (operand * op)
910 opetype = getSpec (operandType (op));
912 if (IS_LITERAL (opetype))
918 /*-----------------------------------------------------------------*/
919 /* isOperandInFarSpace - will return true if operand is in farSpace */
920 /*-----------------------------------------------------------------*/
922 isOperandInFarSpace (operand * op)
932 if (!IS_TRUE_SYMOP (op))
935 etype = SPIL_LOC (op)->etype;
941 etype = getSpec (operandType (op));
943 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
946 /*------------------------------------------------------------------*/
947 /* isOperandInDirSpace - will return true if operand is in dirSpace */
948 /*------------------------------------------------------------------*/
950 isOperandInDirSpace (operand * op)
960 if (!IS_TRUE_SYMOP (op))
963 etype = SPIL_LOC (op)->etype;
969 etype = getSpec (operandType (op));
971 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
974 /*--------------------------------------------------------------------*/
975 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
976 /*--------------------------------------------------------------------*/
978 isOperandInCodeSpace (operand * op)
988 etype = getSpec (operandType (op));
990 if (!IS_TRUE_SYMOP (op))
993 etype = SPIL_LOC (op)->etype;
999 etype = getSpec (operandType (op));
1001 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1004 /*-----------------------------------------------------------------*/
1005 /* isOperandOnStack - will return true if operand is on stack */
1006 /*-----------------------------------------------------------------*/
1008 isOperandOnStack (operand * op)
1018 etype = getSpec (operandType (op));
1019 if (IN_STACK (etype) ||
1020 OP_SYMBOL(op)->onStack ||
1021 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1027 /*-----------------------------------------------------------------*/
1028 /* isOclsExpensive - will return true if accesses to an output */
1029 /* storage class are expensive */
1030 /*-----------------------------------------------------------------*/
1032 isOclsExpensive (struct memmap *oclass)
1034 if (port->oclsExpense)
1035 return port->oclsExpense (oclass) > 0;
1037 /* In the absence of port specific guidance, assume only */
1038 /* farspace is expensive. */
1039 return IN_FARSPACE (oclass);
1042 /*-----------------------------------------------------------------*/
1043 /* operandLitValue - literal value of an operand */
1044 /*-----------------------------------------------------------------*/
1046 operandLitValue (operand * op)
1048 assert (isOperandLiteral (op));
1050 return floatFromVal (op->operand.valOperand);
1053 /*-----------------------------------------------------------------*/
1054 /* getBuiltInParms - returns parameters to a builtin functions */
1055 /*-----------------------------------------------------------------*/
1056 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1061 /* builtin functions uses only SEND for parameters */
1062 while (ic->op != CALL) {
1063 assert(ic->op == SEND && ic->builtinSEND);
1064 ic->generated = 1; /* mark the icode as generated */
1065 parms[*pcount] = IC_LEFT(ic);
1071 /* make sure this is a builtin function call */
1072 assert(IS_SYMOP(IC_LEFT(ic)));
1073 ftype = operandType(IC_LEFT(ic));
1074 assert(IFFUNC_ISBUILTIN(ftype));
1078 /*-----------------------------------------------------------------*/
1079 /* operandOperation - performs operations on operands */
1080 /*-----------------------------------------------------------------*/
1082 operandOperation (operand * left, operand * right,
1083 int op, sym_link * type)
1085 sym_link *let , *ret=NULL;
1086 operand *retval = (operand *) 0;
1088 assert (isOperandLiteral (left));
1089 let = getSpec(operandType(left));
1091 assert (isOperandLiteral (right));
1092 ret = getSpec(operandType(right));
1098 retval = operandFromValue (valCastLiteral (type,
1099 operandLitValue (left) +
1100 operandLitValue (right)));
1103 retval = operandFromValue (valCastLiteral (type,
1104 operandLitValue (left) -
1105 operandLitValue (right)));
1109 retval = operandFromValue (valCastLiteral (type,
1110 operandLitValue (left) *
1111 operandLitValue (right)));
1112 This could be all we've to do, but with gcc we've to take care about
1113 overflows. Two examples:
1114 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1115 significant bits are lost (52 in fraction, 63 bits would be
1116 necessary to keep full precision).
1117 If the resulting double value is greater than ULONG_MAX (resp.
1118 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1121 /* if it is not a specifier then we can assume that */
1122 /* it will be an unsigned long */
1123 if (IS_INT (type) ||
1126 /* long is handled here, because it can overflow with double */
1127 if (IS_LONG (type) ||
1129 /* signed and unsigned mul are the same, as long as the precision
1130 of the result isn't bigger than the precision of the operands. */
1131 retval = operandFromValue (valCastLiteral (type,
1132 (TYPE_UDWORD) operandLitValue (left) *
1133 (TYPE_UDWORD) operandLitValue (right)));
1134 else if (IS_UNSIGNED (type)) /* unsigned int */
1136 /* unsigned int is handled here in order to detect overflow */
1137 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1138 (TYPE_UWORD) operandLitValue (right);
1140 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1141 if (ul != (TYPE_UWORD) ul)
1144 else /* signed int */
1146 /* signed int is handled here in order to detect overflow */
1147 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1148 (TYPE_WORD) operandLitValue (right);
1150 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1151 if (l != (TYPE_WORD) l)
1156 /* all others go here: */
1157 retval = operandFromValue (valCastLiteral (type,
1158 operandLitValue (left) *
1159 operandLitValue (right)));
1162 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1164 werror (E_DIVIDE_BY_ZERO);
1170 if (IS_UNSIGNED (type))
1172 SPEC_USIGN (let) = 1;
1173 SPEC_USIGN (ret) = 1;
1174 retval = operandFromValue (valCastLiteral (type,
1175 (TYPE_UDWORD) operandLitValue (left) /
1176 (TYPE_UDWORD) operandLitValue (right)));
1180 retval = operandFromValue (valCastLiteral (type,
1181 operandLitValue (left) /
1182 operandLitValue (right)));
1187 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1189 werror (E_DIVIDE_BY_ZERO);
1194 if (IS_UNSIGNED (type))
1195 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1196 (TYPE_UDWORD) operandLitValue (right));
1198 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1199 (TYPE_DWORD) operandLitValue (right));
1203 /* The number of left shifts is always unsigned. Signed doesn't make
1204 sense here. Shifting by a negative number is impossible. */
1205 retval = operandFromValue (valCastLiteral (type,
1206 ((TYPE_UDWORD) operandLitValue (left) <<
1207 (TYPE_UDWORD) operandLitValue (right))));
1210 /* The number of right shifts is always unsigned. Signed doesn't make
1211 sense here. Shifting by a negative number is impossible. */
1212 if (IS_UNSIGNED(let))
1213 /* unsigned: logic shift right */
1214 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1215 (TYPE_UDWORD) operandLitValue (right));
1217 /* signed: arithmetic shift right */
1218 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1219 (TYPE_UDWORD) operandLitValue (right));
1222 /* this op doesn't care about signedness */
1226 l = (TYPE_UDWORD) operandLitValue (left);
1227 if (IS_CHAR(OP_VALUE(left)->type))
1229 else if (!IS_LONG (OP_VALUE(left)->type))
1231 r = (TYPE_UDWORD) operandLitValue (right);
1232 if (IS_CHAR(OP_VALUE(right)->type))
1234 else if (!IS_LONG (OP_VALUE(right)->type))
1236 retval = operandFromLit (l == r);
1240 retval = operandFromLit (operandLitValue (left) <
1241 operandLitValue (right));
1244 retval = operandFromLit (operandLitValue (left) <=
1245 operandLitValue (right));
1248 retval = operandFromLit (operandLitValue (left) !=
1249 operandLitValue (right));
1252 retval = operandFromLit (operandLitValue (left) >
1253 operandLitValue (right));
1256 retval = operandFromLit (operandLitValue (left) >=
1257 operandLitValue (right));
1260 retval = operandFromValue (valCastLiteral (type,
1261 (TYPE_UDWORD)operandLitValue(left) &
1262 (TYPE_UDWORD)operandLitValue(right)));
1265 retval = operandFromValue (valCastLiteral (type,
1266 (TYPE_UDWORD)operandLitValue(left) |
1267 (TYPE_UDWORD)operandLitValue(right)));
1270 retval = operandFromValue (valCastLiteral (type,
1271 (TYPE_UDWORD)operandLitValue(left) ^
1272 (TYPE_UDWORD)operandLitValue(right)));
1275 retval = operandFromLit (operandLitValue (left) &&
1276 operandLitValue (right));
1279 retval = operandFromLit (operandLitValue (left) ||
1280 operandLitValue (right));
1284 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1286 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1292 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1294 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1300 retval = operandFromValue (valCastLiteral (type,
1301 -1 * operandLitValue (left)));
1305 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1309 retval = operandFromLit (!operandLitValue (left));
1313 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1314 " operandOperation invalid operator ");
1322 /*-----------------------------------------------------------------*/
1323 /* isOperandEqual - compares two operand & return 1 if they r = */
1324 /*-----------------------------------------------------------------*/
1326 isOperandEqual (operand * left, operand * right)
1328 /* if the pointers are equal then they are equal */
1332 /* if either of them null then false */
1333 if (!left || !right)
1336 if (left->type != right->type)
1339 if (IS_SYMOP (left) && IS_SYMOP (right))
1340 return left->key == right->key;
1342 /* if types are the same */
1346 return isSymbolEqual (left->operand.symOperand,
1347 right->operand.symOperand);
1349 return (floatFromVal (left->operand.valOperand) ==
1350 floatFromVal (right->operand.valOperand));
1352 if (compareType (left->operand.typeOperand,
1353 right->operand.typeOperand) == 1)
1360 /*-------------------------------------------------------------------*/
1361 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1362 /*-------------------------------------------------------------------*/
1364 isiCodeEqual (iCode * left, iCode * right)
1366 /* if the same pointer */
1370 /* if either of them null */
1371 if (!left || !right)
1374 /* if operand are the same */
1375 if (left->op == right->op)
1378 /* compare all the elements depending on type */
1379 if (left->op != IFX)
1381 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1383 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1389 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1391 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1393 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1402 /*-----------------------------------------------------------------*/
1403 /* newiTempFromOp - create a temp Operand with same attributes */
1404 /*-----------------------------------------------------------------*/
1406 newiTempFromOp (operand * op)
1416 nop = newiTempOperand (operandType (op), TRUE);
1417 nop->isaddr = op->isaddr;
1418 nop->isvolatile = op->isvolatile;
1419 nop->isGlobal = op->isGlobal;
1420 nop->isLiteral = op->isLiteral;
1421 nop->usesDefs = op->usesDefs;
1422 nop->isParm = op->isParm;
1426 /*-----------------------------------------------------------------*/
1427 /* operand from operand - creates an operand holder for the type */
1428 /*-----------------------------------------------------------------*/
1430 operandFromOperand (operand * op)
1436 nop = newOperand ();
1437 nop->type = op->type;
1438 nop->isaddr = op->isaddr;
1440 nop->isvolatile = op->isvolatile;
1441 nop->isGlobal = op->isGlobal;
1442 nop->isLiteral = op->isLiteral;
1443 nop->usesDefs = op->usesDefs;
1444 nop->isParm = op->isParm;
1449 nop->operand.symOperand = op->operand.symOperand;
1452 nop->operand.valOperand = op->operand.valOperand;
1455 nop->operand.typeOperand = op->operand.typeOperand;
1462 /*-----------------------------------------------------------------*/
1463 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1464 /*-----------------------------------------------------------------*/
1466 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1468 operand *nop = operandFromOperand (op);
1470 if (nop->type == SYMBOL)
1472 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1473 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1479 /*-----------------------------------------------------------------*/
1480 /* operandFromSymbol - creates an operand from a symbol */
1481 /*-----------------------------------------------------------------*/
1483 operandFromSymbol (symbol * sym)
1488 /* if the symbol's type is a literal */
1489 /* then it is an enumerator type */
1490 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1491 return operandFromValue (valFromType (sym->etype));
1494 sym->key = ++operandKey;
1496 /* if this an implicit variable, means struct/union */
1497 /* member so just return it */
1498 if (sym->implicit || IS_FUNC (sym->type))
1502 op->operand.symOperand = sym;
1504 op->isvolatile = isOperandVolatile (op, TRUE);
1505 op->isGlobal = isOperandGlobal (op);
1509 /* under the following conditions create a
1510 register equivalent for a local symbol */
1511 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1512 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1514 (!(options.model == MODEL_FLAT24)) ) &&
1515 options.stackAuto == 0)
1518 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1519 !IS_FUNC (sym->type) && /* not a function */
1520 !sym->_isparm && /* not a parameter */
1521 sym->level && /* is a local variable */
1522 !sym->addrtaken && /* whose address has not been taken */
1523 !sym->reqv && /* does not already have a reg equivalence */
1524 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1525 !IS_STATIC (sym->etype) && /* and not declared static */
1526 !sym->islbl && /* not a label */
1527 ok && /* farspace check */
1528 !IS_BITVAR (sym->etype) /* not a bit variable */
1532 /* we will use it after all optimizations
1533 and before liveRange calculation */
1534 sym->reqv = newiTempOperand (sym->type, 0);
1535 sym->reqv->key = sym->key;
1536 OP_SYMBOL (sym->reqv)->prereqv = sym;
1537 OP_SYMBOL (sym->reqv)->key = sym->key;
1538 OP_SYMBOL (sym->reqv)->isreqv = 1;
1539 OP_SYMBOL (sym->reqv)->islocal = 1;
1540 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1541 SPIL_LOC (sym->reqv) = sym;
1544 if (!IS_AGGREGATE (sym->type))
1548 op->operand.symOperand = sym;
1551 op->isvolatile = isOperandVolatile (op, TRUE);
1552 op->isGlobal = isOperandGlobal (op);
1553 op->isPtr = IS_PTR (operandType (op));
1554 op->isParm = sym->_isparm;
1559 /* itemp = &[_symbol] */
1561 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1562 IC_LEFT (ic)->type = SYMBOL;
1563 IC_LEFT (ic)->operand.symOperand = sym;
1564 IC_LEFT (ic)->key = sym->key;
1565 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1566 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1567 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1570 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1571 if (IS_ARRAY (sym->type))
1573 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1574 IC_RESULT (ic)->isaddr = 0;
1577 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1581 return IC_RESULT (ic);
1584 /*-----------------------------------------------------------------*/
1585 /* operandFromValue - creates an operand from value */
1586 /*-----------------------------------------------------------------*/
1588 operandFromValue (value * val)
1592 /* if this is a symbol then do the symbol thing */
1594 return operandFromSymbol (val->sym);
1596 /* this is not a symbol */
1599 op->operand.valOperand = val;
1600 op->isLiteral = isOperandLiteral (op);
1604 /*-----------------------------------------------------------------*/
1605 /* operandFromLink - operand from typeChain */
1606 /*-----------------------------------------------------------------*/
1608 operandFromLink (sym_link * type)
1612 /* operand from sym_link */
1618 op->operand.typeOperand = copyLinkChain (type);
1622 /*-----------------------------------------------------------------*/
1623 /* operandFromLit - makes an operand from a literal value */
1624 /*-----------------------------------------------------------------*/
1626 operandFromLit (double i)
1628 return operandFromValue (valueFromLit (i));
1631 /*-----------------------------------------------------------------*/
1632 /* operandFromAst - creates an operand from an ast */
1633 /*-----------------------------------------------------------------*/
1635 operandFromAst (ast * tree,int lvl)
1641 /* depending on type do */
1645 return ast2iCode (tree,lvl+1);
1649 return operandFromValue (tree->opval.val);
1653 return operandFromLink (tree->opval.lnk);
1660 /* Just to keep the compiler happy */
1661 return (operand *) 0;
1664 /*-----------------------------------------------------------------*/
1665 /* setOperandType - sets the operand's type to the given type */
1666 /*-----------------------------------------------------------------*/
1668 setOperandType (operand * op, sym_link * type)
1670 /* depending on the type of operand */
1675 op->operand.valOperand->etype =
1676 getSpec (op->operand.valOperand->type =
1677 copyLinkChain (type));
1681 if (op->operand.symOperand->isitmp)
1682 op->operand.symOperand->etype =
1683 getSpec (op->operand.symOperand->type =
1684 copyLinkChain (type));
1686 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1687 "attempt to modify type of source");
1691 op->operand.typeOperand = copyLinkChain (type);
1696 /*-----------------------------------------------------------------*/
1697 /* Get size in byte of ptr need to access an array */
1698 /*-----------------------------------------------------------------*/
1700 getArraySizePtr (operand * op)
1702 sym_link *ltype = operandType(op);
1706 int size = getSize(ltype);
1707 return(IS_GENPTR(ltype)?(size-1):size);
1712 sym_link *letype = getSpec(ltype);
1713 switch (PTR_TYPE (SPEC_OCLS (letype)))
1725 return (GPTRSIZE-1);
1734 /*-----------------------------------------------------------------*/
1735 /* perform "usual unary conversions" */
1736 /*-----------------------------------------------------------------*/
1739 usualUnaryConversions (operand * op)
1741 if (IS_INTEGRAL (operandType (op)))
1743 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1746 return geniCodeCast (INTTYPE, op, TRUE);
1753 /*-----------------------------------------------------------------*/
1754 /* perform "usual binary conversions" */
1755 /*-----------------------------------------------------------------*/
1757 usualBinaryConversions (operand ** op1, operand ** op2,
1758 bool promoteCharToInt, bool isMul)
1761 sym_link *rtype = operandType (*op2);
1762 sym_link *ltype = operandType (*op1);
1764 ctype = computeType (ltype, rtype, promoteCharToInt);
1766 /* special for multiplication:
1767 This if for 'mul a,b', which takes two chars and returns an int */
1769 /* && promoteCharToInt superfluous, already handled by computeType() */
1770 && IS_INT (getSpec (ctype)))
1772 sym_link *retype = getSpec (rtype);
1773 sym_link *letype = getSpec (ltype);
1775 if ( IS_CHAR (letype)
1777 && IS_UNSIGNED (letype)
1778 && IS_UNSIGNED (retype))
1783 *op1 = geniCodeCast (ctype, *op1, TRUE);
1784 *op2 = geniCodeCast (ctype, *op2, TRUE);
1789 /*-----------------------------------------------------------------*/
1790 /* geniCodeValueAtAddress - generate intermeditate code for value */
1792 /*-----------------------------------------------------------------*/
1794 geniCodeRValue (operand * op, bool force)
1797 sym_link *type = operandType (op);
1798 sym_link *etype = getSpec (type);
1800 /* if this is an array & already */
1801 /* an address then return this */
1802 if (IS_AGGREGATE (type) ||
1803 (IS_PTR (type) && !force && !op->isaddr))
1804 return operandFromOperand (op);
1806 /* if this is not an address then must be */
1807 /* rvalue already so return this one */
1811 /* if this is not a temp symbol then */
1812 if (!IS_ITEMP (op) &&
1814 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1816 op = operandFromOperand (op);
1821 if (IS_SPEC (type) &&
1822 IS_TRUE_SYMOP (op) &&
1823 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1824 (options.model == MODEL_FLAT24) ))
1826 op = operandFromOperand (op);
1831 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1832 if (IS_PTR (type) && op->isaddr && force)
1835 type = copyLinkChain (type);
1837 IC_RESULT (ic) = newiTempOperand (type, 1);
1838 IC_RESULT (ic)->isaddr = 0;
1840 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1844 return IC_RESULT (ic);
1847 /*-----------------------------------------------------------------*/
1848 /* geniCodeCast - changes the value from one type to another */
1849 /*-----------------------------------------------------------------*/
1851 geniCodeCast (sym_link * type, operand * op, bool implicit)
1855 sym_link *opetype = getSpec (optype = operandType (op));
1859 /* one of them has size zero then error */
1860 if (IS_VOID (optype))
1862 werror (E_CAST_ZERO);
1866 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1868 geniCodeArray2Ptr (op);
1872 /* if the operand is already the desired type then do nothing */
1873 if (compareType (type, optype) == 1)
1876 /* if this is a literal then just change the type & return */
1877 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1879 return operandFromValue (valCastLiteral (type,
1880 operandLitValue (op)));
1883 /* if casting to/from pointers, do some checking */
1884 if (IS_PTR(type)) { // to a pointer
1885 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1886 if (IS_INTEGRAL(optype)) {
1887 // maybe this is NULL, than it's ok.
1888 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1889 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1890 // no way to set the storage
1891 if (IS_LITERAL(optype)) {
1892 werror(E_LITERAL_GENERIC);
1895 werror(E_NONPTR2_GENPTR);
1898 } else if (implicit) {
1899 werror(W_INTEGRAL2PTR_NOCAST);
1904 // shouldn't do that with float, array or structure unless to void
1905 if (!IS_VOID(getSpec(type)) &&
1906 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1907 werror(E_INCOMPAT_TYPES);
1911 } else { // from a pointer to a pointer
1912 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1913 // if not a pointer to a function
1914 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1915 if (implicit) { // if not to generic, they have to match
1916 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1917 werror(E_INCOMPAT_PTYPES);
1924 } else { // to a non pointer
1925 if (IS_PTR(optype)) { // from a pointer
1926 if (implicit) { // sneaky
1927 if (IS_INTEGRAL(type)) {
1928 werror(W_PTR2INTEGRAL_NOCAST);
1930 } else { // shouldn't do that with float, array or structure
1931 werror(E_INCOMPAT_TYPES);
1938 printFromToType (optype, type);
1941 /* if they are the same size create an assignment */
1943 /* This seems very dangerous to me, since there are several */
1944 /* optimizations (for example, gcse) that don't notice the */
1945 /* cast hidden in this assignement and may simplify an */
1946 /* iCode to use the original (uncasted) operand. */
1947 /* Unfortunately, other things break when this cast is */
1948 /* made explicit. Need to fix this someday. */
1949 /* -- EEP, 2004/01/21 */
1950 if (getSize (type) == getSize (optype) &&
1951 !IS_BITFIELD (type) &&
1953 !IS_FLOAT (optype) &&
1954 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1955 (!IS_SPEC (type) && !IS_SPEC (optype))))
1957 ic = newiCode ('=', NULL, op);
1958 IC_RESULT (ic) = newiTempOperand (type, 0);
1959 SPIL_LOC (IC_RESULT (ic)) =
1960 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1961 IC_RESULT (ic)->isaddr = 0;
1965 ic = newiCode (CAST, operandFromLink (type),
1966 geniCodeRValue (op, FALSE));
1968 IC_RESULT (ic) = newiTempOperand (type, 0);
1971 /* preserve the storage class & output class */
1972 /* of the original variable */
1973 restype = getSpec (operandType (IC_RESULT (ic)));
1974 if (!IS_LITERAL(opetype))
1975 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1976 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1979 return IC_RESULT (ic);
1982 /*-----------------------------------------------------------------*/
1983 /* geniCodeLabel - will create a Label */
1984 /*-----------------------------------------------------------------*/
1986 geniCodeLabel (symbol * label)
1990 ic = newiCodeLabelGoto (LABEL, label);
1994 /*-----------------------------------------------------------------*/
1995 /* geniCodeGoto - will create a Goto */
1996 /*-----------------------------------------------------------------*/
1998 geniCodeGoto (symbol * label)
2002 ic = newiCodeLabelGoto (GOTO, label);
2006 /*-----------------------------------------------------------------*/
2007 /* geniCodeMultiply - gen intermediate code for multiplication */
2008 /*-----------------------------------------------------------------*/
2010 geniCodeMultiply (operand * left, operand * right, int resultIsInt)
2017 /* if they are both literal then we know the result */
2018 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2019 return operandFromValue (valMult (left->operand.valOperand,
2020 right->operand.valOperand));
2022 if (IS_LITERAL(retype)) {
2023 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2026 resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE);
2028 rtype = operandType (right);
2029 retype = getSpec (rtype);
2030 ltype = operandType (left);
2031 letype = getSpec (ltype);
2034 /* if the right is a literal & power of 2 */
2035 /* then make it a left shift */
2036 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2037 efficient in most cases than 2 bytes result = 2 bytes << literal
2038 if port has 1 byte muldiv */
2039 if (p2 && !IS_FLOAT (letype) &&
2040 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
2041 (port->support.muldiv == 1)))
2043 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2045 /* LEFT_OP need same size for left and result, */
2046 left = geniCodeCast (resType, left, TRUE);
2047 ltype = operandType (left);
2049 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2053 ic = newiCode ('*', left, right); /* normal multiplication */
2054 /* if the size left or right > 1 then support routine */
2055 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2059 IC_RESULT (ic) = newiTempOperand (resType, 1);
2062 return IC_RESULT (ic);
2065 /*-----------------------------------------------------------------*/
2066 /* geniCodeDivision - gen intermediate code for division */
2067 /*-----------------------------------------------------------------*/
2069 geniCodeDivision (operand * left, operand * right)
2074 sym_link *rtype = operandType (right);
2075 sym_link *retype = getSpec (rtype);
2076 sym_link *ltype = operandType (left);
2077 sym_link *letype = getSpec (ltype);
2079 resType = usualBinaryConversions (&left, &right,
2080 (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2083 /* if the right is a literal & power of 2
2084 and left is unsigned then make it a
2086 if (IS_LITERAL (retype) &&
2087 !IS_FLOAT (letype) &&
2088 IS_UNSIGNED(letype) &&
2089 (p2 = powof2 ((TYPE_UDWORD)
2090 floatFromVal (right->operand.valOperand)))) {
2091 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2095 ic = newiCode ('/', left, right); /* normal division */
2096 /* if the size left or right > 1 then support routine */
2097 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2100 IC_RESULT (ic) = newiTempOperand (resType, 0);
2103 return IC_RESULT (ic);
2105 /*-----------------------------------------------------------------*/
2106 /* geniCodeModulus - gen intermediate code for modulus */
2107 /*-----------------------------------------------------------------*/
2109 geniCodeModulus (operand * left, operand * right)
2115 /* if they are both literal then we know the result */
2116 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2117 return operandFromValue (valMod (left->operand.valOperand,
2118 right->operand.valOperand));
2120 resType = usualBinaryConversions (&left, &right,
2121 (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2124 /* now they are the same size */
2125 ic = newiCode ('%', left, right);
2127 /* if the size left or right > 1 then support routine */
2128 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2130 IC_RESULT (ic) = newiTempOperand (resType, 0);
2133 return IC_RESULT (ic);
2136 /*-----------------------------------------------------------------*/
2137 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2138 /*-----------------------------------------------------------------*/
2140 geniCodePtrPtrSubtract (operand * left, operand * right)
2146 /* if they are both literals then */
2147 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2149 result = operandFromValue (valMinus (left->operand.valOperand,
2150 right->operand.valOperand));
2154 ic = newiCode ('-', left, right);
2156 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2160 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2164 // should we really do this? is this ANSI?
2165 return geniCodeDivision (result,
2166 operandFromLit (getSize (ltype->next)));
2169 /*-----------------------------------------------------------------*/
2170 /* geniCodeSubtract - generates code for subtraction */
2171 /*-----------------------------------------------------------------*/
2173 geniCodeSubtract (operand * left, operand * right)
2180 /* if they both pointers then */
2181 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2182 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2183 return geniCodePtrPtrSubtract (left, right);
2185 /* if they are both literal then we know the result */
2186 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2187 && left->isLiteral && right->isLiteral)
2188 return operandFromValue (valMinus (left->operand.valOperand,
2189 right->operand.valOperand));
2191 /* if left is an array or pointer */
2192 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2194 isarray = left->isaddr;
2195 right = geniCodeMultiply (right,
2196 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2197 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2200 { /* make them the same size */
2201 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2204 ic = newiCode ('-', left, right);
2206 IC_RESULT (ic) = newiTempOperand (resType, 1);
2207 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2209 /* if left or right is a float */
2210 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2214 return IC_RESULT (ic);
2217 /*-----------------------------------------------------------------*/
2218 /* geniCodeAdd - generates iCode for addition */
2219 /*-----------------------------------------------------------------*/
2221 geniCodeAdd (operand * left, operand * right, int lvl)
2230 /* if the right side is LITERAL zero */
2231 /* return the left side */
2232 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2235 /* if left is literal zero return right */
2236 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2239 /* if left is a pointer then size */
2240 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2242 isarray = left->isaddr;
2243 // there is no need to multiply with 1
2244 if (getSize (ltype->next) != 1)
2246 size = operandFromLit (getSize (ltype->next));
2247 SPEC_USIGN (getSpec (operandType (size))) = 1;
2248 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2249 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2250 /* Even if right is a 'unsigned char',
2251 the result will be a 'signed int' due to the promotion rules.
2252 It doesn't make sense when accessing arrays, so let's fix it here: */
2254 SPEC_USIGN (getSpec (operandType (right))) = 1;
2256 resType = copyLinkChain (ltype);
2259 { // make them the same size
2260 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2263 /* if they are both literals then we know */
2264 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2265 && left->isLiteral && right->isLiteral)
2266 return operandFromValue (valPlus (valFromType (ltype),
2267 valFromType (rtype)));
2269 ic = newiCode ('+', left, right);
2271 IC_RESULT (ic) = newiTempOperand (resType, 1);
2272 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2274 /* if left or right is a float then support
2276 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2281 return IC_RESULT (ic);
2285 /*-----------------------------------------------------------------*/
2286 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2287 /*-----------------------------------------------------------------*/
2289 aggrToPtr (sym_link * type, bool force)
2294 if (IS_PTR (type) && !force)
2297 etype = getSpec (type);
2298 ptype = newLink (DECLARATOR);
2302 /* set the pointer depending on the storage class */
2303 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2307 /*-----------------------------------------------------------------*/
2308 /* geniCodeArray2Ptr - array to pointer */
2309 /*-----------------------------------------------------------------*/
2311 geniCodeArray2Ptr (operand * op)
2313 sym_link *optype = operandType (op);
2314 sym_link *opetype = getSpec (optype);
2316 /* set the pointer depending on the storage class */
2317 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2324 /*-----------------------------------------------------------------*/
2325 /* geniCodeArray - array access */
2326 /*-----------------------------------------------------------------*/
2328 geniCodeArray (operand * left, operand * right, int lvl)
2332 sym_link *ltype = operandType (left);
2337 if (IS_PTR (ltype->next) && left->isaddr)
2339 left = geniCodeRValue (left, FALSE);
2342 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2344 size = operandFromLit (getSize (ltype->next));
2345 SPEC_USIGN (getSpec (operandType (size))) = 1;
2346 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2347 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2348 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2349 It doesn't make sense when accessing arrays, so let's fix it here: */
2351 SPEC_USIGN (getSpec (operandType (right))) = 1;
2352 /* we can check for limits here */
2353 /* already done in SDCCast.c
2354 if (isOperandLiteral (right) &&
2357 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2359 werror (W_IDX_OUT_OF_BOUNDS,
2360 (int) operandLitValue (right) / getSize (ltype->next),
2365 ic = newiCode ('+', left, right);
2367 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2368 !IS_AGGREGATE (ltype->next) &&
2369 !IS_PTR (ltype->next))
2370 ? ltype : ltype->next), 0);
2372 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2375 return IC_RESULT (ic);
2378 /*-----------------------------------------------------------------*/
2379 /* geniCodeStruct - generates intermediate code for structures */
2380 /*-----------------------------------------------------------------*/
2382 geniCodeStruct (operand * left, operand * right, bool islval)
2385 sym_link *type = operandType (left);
2386 sym_link *etype = getSpec (type);
2388 symbol *element = getStructElement (SPEC_STRUCT (etype),
2389 right->operand.symOperand);
2391 wassert(IS_SYMOP(right));
2393 /* add the offset */
2394 ic = newiCode ('+', left, operandFromLit (element->offset));
2396 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2398 /* preserve the storage & output class of the struct */
2399 /* as well as the volatile attribute */
2400 retype = getSpec (operandType (IC_RESULT (ic)));
2401 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2402 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2403 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2404 SPEC_CONST (retype) |= SPEC_CONST (etype);
2406 if (IS_PTR (element->type))
2407 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2409 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2412 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2415 /*-----------------------------------------------------------------*/
2416 /* geniCodePostInc - generate int code for Post increment */
2417 /*-----------------------------------------------------------------*/
2419 geniCodePostInc (operand * op)
2423 sym_link *optype = operandType (op);
2425 operand *rv = (IS_ITEMP (op) ?
2426 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2428 sym_link *rvtype = operandType (rv);
2431 /* if this is not an address we have trouble */
2434 werror (E_LVALUE_REQUIRED, "++");
2438 rOp = newiTempOperand (rvtype, 0);
2439 OP_SYMBOL(rOp)->noSpilLoc = 1;
2442 OP_SYMBOL(rv)->noSpilLoc = 1;
2444 geniCodeAssign (rOp, rv, 0);
2446 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2447 if (IS_FLOAT (rvtype))
2448 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2450 ic = newiCode ('+', rv, operandFromLit (size));
2452 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2455 geniCodeAssign (op, result, 0);
2461 /*-----------------------------------------------------------------*/
2462 /* geniCodePreInc - generate code for preIncrement */
2463 /*-----------------------------------------------------------------*/
2465 geniCodePreInc (operand * op, bool lvalue)
2468 sym_link *optype = operandType (op);
2469 operand *rop = (IS_ITEMP (op) ?
2470 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2472 sym_link *roptype = operandType (rop);
2478 werror (E_LVALUE_REQUIRED, "++");
2483 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2484 if (IS_FLOAT (roptype))
2485 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2487 ic = newiCode ('+', rop, operandFromLit (size));
2488 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2491 (void) geniCodeAssign (op, result, 0);
2492 if (lvalue || IS_TRUE_SYMOP (op))
2498 /*-----------------------------------------------------------------*/
2499 /* geniCodePostDec - generates code for Post decrement */
2500 /*-----------------------------------------------------------------*/
2502 geniCodePostDec (operand * op)
2506 sym_link *optype = operandType (op);
2508 operand *rv = (IS_ITEMP (op) ?
2509 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2511 sym_link *rvtype = operandType (rv);
2514 /* if this is not an address we have trouble */
2517 werror (E_LVALUE_REQUIRED, "--");
2521 rOp = newiTempOperand (rvtype, 0);
2522 OP_SYMBOL(rOp)->noSpilLoc = 1;
2525 OP_SYMBOL(rv)->noSpilLoc = 1;
2527 geniCodeAssign (rOp, rv, 0);
2529 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2530 if (IS_FLOAT (rvtype))
2531 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2533 ic = newiCode ('-', rv, operandFromLit (size));
2535 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2538 geniCodeAssign (op, result, 0);
2544 /*-----------------------------------------------------------------*/
2545 /* geniCodePreDec - generate code for pre decrement */
2546 /*-----------------------------------------------------------------*/
2548 geniCodePreDec (operand * op, bool lvalue)
2551 sym_link *optype = operandType (op);
2552 operand *rop = (IS_ITEMP (op) ?
2553 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2555 sym_link *roptype = operandType (rop);
2561 werror (E_LVALUE_REQUIRED, "--");
2566 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2567 if (IS_FLOAT (roptype))
2568 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2570 ic = newiCode ('-', rop, operandFromLit (size));
2571 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2574 (void) geniCodeAssign (op, result, 0);
2575 if (lvalue || IS_TRUE_SYMOP (op))
2582 /*-----------------------------------------------------------------*/
2583 /* geniCodeBitwise - gen int code for bitWise operators */
2584 /*-----------------------------------------------------------------*/
2586 geniCodeBitwise (operand * left, operand * right,
2587 int oper, sym_link * resType)
2591 left = geniCodeCast (resType, left, TRUE);
2592 right = geniCodeCast (resType, right, TRUE);
2594 ic = newiCode (oper, left, right);
2595 IC_RESULT (ic) = newiTempOperand (resType, 0);
2598 return IC_RESULT (ic);
2601 /*-----------------------------------------------------------------*/
2602 /* geniCodeAddressOf - gens icode for '&' address of operator */
2603 /*-----------------------------------------------------------------*/
2605 geniCodeAddressOf (operand * op)
2609 sym_link *optype = operandType (op);
2610 sym_link *opetype = getSpec (optype);
2612 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2614 op = operandFromOperand (op);
2619 /* lvalue check already done in decorateType */
2620 /* this must be a lvalue */
2621 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2622 /* werror (E_LVALUE_REQUIRED,"&"); */
2626 p = newLink (DECLARATOR);
2628 /* set the pointer depending on the storage class */
2629 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2631 p->next = copyLinkChain (optype);
2633 /* if already a temp */
2636 setOperandType (op, p);
2641 /* other wise make this of the type coming in */
2642 ic = newiCode (ADDRESS_OF, op, NULL);
2643 IC_RESULT (ic) = newiTempOperand (p, 1);
2644 IC_RESULT (ic)->isaddr = 0;
2646 return IC_RESULT (ic);
2648 /*-----------------------------------------------------------------*/
2649 /* setOClass - sets the output class depending on the pointer type */
2650 /*-----------------------------------------------------------------*/
2652 setOClass (sym_link * ptr, sym_link * spec)
2654 switch (DCL_TYPE (ptr))
2657 SPEC_OCLS (spec) = data;
2661 SPEC_OCLS (spec) = generic;
2665 SPEC_OCLS (spec) = xdata;
2669 SPEC_OCLS (spec) = code;
2673 SPEC_OCLS (spec) = idata;
2677 SPEC_OCLS (spec) = xstack;
2681 SPEC_OCLS (spec) = eeprom;
2690 /*-----------------------------------------------------------------*/
2691 /* geniCodeDerefPtr - dereference pointer with '*' */
2692 /*-----------------------------------------------------------------*/
2694 geniCodeDerefPtr (operand * op,int lvl)
2696 sym_link *rtype, *retype;
2697 sym_link *optype = operandType (op);
2699 // if this is an array then array access
2700 if (IS_ARRAY (optype)) {
2701 // don't worry, this will be optimized out later
2702 return geniCodeArray (op, operandFromLit (0), lvl);
2705 // just in case someone screws up
2706 wassert (IS_PTR (optype));
2708 if (IS_TRUE_SYMOP (op))
2711 op = geniCodeRValue (op, TRUE);
2714 /* now get rid of the pointer part */
2715 if (isLvaluereq(lvl) && IS_ITEMP (op))
2717 retype = getSpec (rtype = copyLinkChain (optype));
2721 retype = getSpec (rtype = copyLinkChain (optype->next));
2722 /* outputclass needs 2b updated */
2723 setOClass (optype, retype);
2726 op->isGptr = IS_GENPTR (optype);
2728 op->isaddr = (IS_PTR (rtype) ||
2729 IS_STRUCT (rtype) ||
2734 if (!isLvaluereq(lvl))
2735 op = geniCodeRValue (op, TRUE);
2737 setOperandType (op, rtype);
2742 /*-----------------------------------------------------------------*/
2743 /* geniCodeUnaryMinus - does a unary minus of the operand */
2744 /*-----------------------------------------------------------------*/
2746 geniCodeUnaryMinus (operand * op)
2749 sym_link *optype = operandType (op);
2751 if (IS_LITERAL (optype))
2752 return operandFromLit (-floatFromVal (op->operand.valOperand));
2754 ic = newiCode (UNARYMINUS, op, NULL);
2755 IC_RESULT (ic) = newiTempOperand (optype, 0);
2757 return IC_RESULT (ic);
2760 /*-----------------------------------------------------------------*/
2761 /* geniCodeLeftShift - gen i code for left shift */
2762 /*-----------------------------------------------------------------*/
2764 geniCodeLeftShift (operand * left, operand * right)
2768 ic = newiCode (LEFT_OP, left, right);
2769 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2771 return IC_RESULT (ic);
2774 /*-----------------------------------------------------------------*/
2775 /* geniCodeRightShift - gen i code for right shift */
2776 /*-----------------------------------------------------------------*/
2778 geniCodeRightShift (operand * left, operand * right)
2782 ic = newiCode (RIGHT_OP, left, right);
2783 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2785 return IC_RESULT (ic);
2788 /*-----------------------------------------------------------------*/
2789 /* geniCodeLogic- logic code */
2790 /*-----------------------------------------------------------------*/
2792 geniCodeLogic (operand * left, operand * right, int op)
2796 sym_link *rtype = operandType (right);
2797 sym_link *ltype = operandType (left);
2799 /* left is integral type and right is literal then
2800 check if the literal value is within bounds */
2801 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2803 checkConstantRange(ltype,
2804 OP_VALUE(right), "compare operation", 1);
2807 /* if one operand is a pointer and the other is a literal generic void pointer,
2808 change the type of the literal generic void pointer to match the other pointer */
2809 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2810 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2812 /* find left's definition */
2813 ic = (iCode *) setFirstItem (iCodeChain);
2816 if (((ic->op == CAST) || (ic->op == '='))
2817 && isOperandEqual(left, IC_RESULT (ic)))
2820 ic = setNextItem (iCodeChain);
2822 /* if casting literal to generic pointer, then cast to rtype instead */
2823 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2825 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2826 ltype = operandType(left);
2829 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2830 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2832 /* find right's definition */
2833 ic = (iCode *) setFirstItem (iCodeChain);
2836 if (((ic->op == CAST) || (ic->op == '='))
2837 && isOperandEqual(right, IC_RESULT (ic)))
2840 ic = setNextItem (iCodeChain);
2842 /* if casting literal to generic pointer, then cast to rtype instead */
2843 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2845 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2846 rtype = operandType(right);
2850 ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
2852 ic = newiCode (op, left, right);
2853 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2855 /* if comparing float
2856 and not a '==' || '!=' || '&&' || '||' (these
2858 if (IS_FLOAT(ctype) &&
2866 return IC_RESULT (ic);
2869 /*-----------------------------------------------------------------*/
2870 /* geniCodeUnary - for a a generic unary operation */
2871 /*-----------------------------------------------------------------*/
2873 geniCodeUnary (operand * op, int oper)
2875 iCode *ic = newiCode (oper, op, NULL);
2877 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2879 return IC_RESULT (ic);
2882 /*-----------------------------------------------------------------*/
2883 /* geniCodeConditional - geniCode for '?' ':' operation */
2884 /*-----------------------------------------------------------------*/
2886 geniCodeConditional (ast * tree,int lvl)
2889 symbol *falseLabel = newiTempLabel (NULL);
2890 symbol *exitLabel = newiTempLabel (NULL);
2891 operand *cond = ast2iCode (tree->left,lvl+1);
2892 operand *true, *false, *result;
2894 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2898 true = ast2iCode (tree->right->left,lvl+1);
2900 /* move the value to a new Operand */
2901 result = newiTempOperand (tree->right->ftype, 0);
2902 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2904 /* generate an unconditional goto */
2905 geniCodeGoto (exitLabel);
2907 /* now for the right side */
2908 geniCodeLabel (falseLabel);
2910 false = ast2iCode (tree->right->right,lvl+1);
2911 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2913 /* create the exit label */
2914 geniCodeLabel (exitLabel);
2919 /*-----------------------------------------------------------------*/
2920 /* geniCodeAssign - generate code for assignment */
2921 /*-----------------------------------------------------------------*/
2923 geniCodeAssign (operand * left, operand * right, int nosupdate)
2926 sym_link *ltype = operandType (left);
2927 sym_link *rtype = operandType (right);
2929 if (!left->isaddr && !IS_ITEMP (left))
2931 werror (E_LVALUE_REQUIRED, "assignment");
2935 /* left is integral type and right is literal then
2936 check if the literal value is within bounds */
2937 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2939 checkConstantRange(ltype,
2940 OP_VALUE(right), "= operation", 0);
2943 /* if the left & right type don't exactly match */
2944 /* if pointer set then make sure the check is
2945 done with the type & not the pointer */
2946 /* then cast rights type to left */
2948 /* first check the type for pointer assignement */
2949 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2950 compareType (ltype, rtype) <= 0)
2952 if (compareType (ltype->next, rtype) < 0)
2953 right = geniCodeCast (ltype->next, right, TRUE);
2955 else if (compareType (ltype, rtype) < 0)
2956 right = geniCodeCast (ltype, right, TRUE);
2958 /* If left is a true symbol & ! volatile
2959 create an assignment to temporary for
2960 the right & then assign this temporary
2961 to the symbol. This is SSA (static single
2962 assignment). Isn't it simple and folks have
2963 published mountains of paper on it */
2964 if (IS_TRUE_SYMOP (left) &&
2965 !isOperandVolatile (left, FALSE) &&
2966 isOperandGlobal (left))
2970 if (IS_TRUE_SYMOP (right))
2971 sym = OP_SYMBOL (right);
2972 ic = newiCode ('=', NULL, right);
2973 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2974 SPIL_LOC (right) = sym;
2978 ic = newiCode ('=', NULL, right);
2979 IC_RESULT (ic) = left;
2982 /* if left isgptr flag is set then support
2983 routine will be required */
2987 ic->nosupdate = nosupdate;
2991 /*-----------------------------------------------------------------*/
2992 /* geniCodeDummyRead - generate code for dummy read */
2993 /*-----------------------------------------------------------------*/
2995 geniCodeDummyRead (operand * op)
2998 sym_link *type = operandType (op);
3000 if (!IS_VOLATILE(type))
3003 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3009 /*-----------------------------------------------------------------*/
3010 /* geniCodeSEParms - generate code for side effecting fcalls */
3011 /*-----------------------------------------------------------------*/
3013 geniCodeSEParms (ast * parms,int lvl)
3018 if (parms->type == EX_OP && parms->opval.op == PARAM)
3020 geniCodeSEParms (parms->left,lvl);
3021 geniCodeSEParms (parms->right,lvl);
3025 /* hack don't like this but too lazy to think of
3027 if (IS_ADDRESS_OF_OP (parms))
3028 parms->left->lvalue = 1;
3030 if (IS_CAST_OP (parms) &&
3031 IS_PTR (parms->ftype) &&
3032 IS_ADDRESS_OF_OP (parms->right))
3033 parms->right->left->lvalue = 1;
3035 parms->opval.oprnd =
3036 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3038 parms->type = EX_OPERAND;
3039 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3040 SPEC_ARGREG(parms->ftype);
3043 /*-----------------------------------------------------------------*/
3044 /* geniCodeParms - generates parameters */
3045 /*-----------------------------------------------------------------*/
3047 geniCodeParms (ast * parms, value *argVals, int *stack,
3048 sym_link * ftype, int lvl)
3056 if (argVals==NULL) {
3058 argVals = FUNC_ARGS (ftype);
3061 /* if this is a param node then do the left & right */
3062 if (parms->type == EX_OP && parms->opval.op == PARAM)
3064 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3065 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3069 /* get the parameter value */
3070 if (parms->type == EX_OPERAND)
3071 pval = parms->opval.oprnd;
3074 /* maybe this else should go away ?? */
3075 /* hack don't like this but too lazy to think of
3077 if (IS_ADDRESS_OF_OP (parms))
3078 parms->left->lvalue = 1;
3080 if (IS_CAST_OP (parms) &&
3081 IS_PTR (parms->ftype) &&
3082 IS_ADDRESS_OF_OP (parms->right))
3083 parms->right->left->lvalue = 1;
3085 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3088 /* if register parm then make it a send */
3089 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3090 IFFUNC_ISBUILTIN(ftype))
3092 ic = newiCode (SEND, pval, NULL);
3093 ic->argreg = SPEC_ARGREG(parms->etype);
3094 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3099 /* now decide whether to push or assign */
3100 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3104 operand *top = operandFromSymbol (argVals->sym);
3105 /* clear useDef and other bitVectors */
3106 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3107 geniCodeAssign (top, pval, 1);
3111 sym_link *p = operandType (pval);
3113 ic = newiCode (IPUSH, pval, NULL);
3115 /* update the stack adjustment */
3116 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3121 argVals=argVals->next;
3125 /*-----------------------------------------------------------------*/
3126 /* geniCodeCall - generates temp code for calling */
3127 /*-----------------------------------------------------------------*/
3129 geniCodeCall (operand * left, ast * parms,int lvl)
3133 sym_link *type, *etype;
3137 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3138 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3139 werror (E_FUNCTION_EXPECTED);
3140 return operandFromValue(valueFromLit(0));
3143 /* take care of parameters with side-effecting
3144 function calls in them, this is required to take care
3145 of overlaying function parameters */
3146 geniCodeSEParms (parms,lvl);
3148 ftype = operandType (left);
3149 if (IS_CODEPTR (ftype))
3150 ftype = ftype->next;
3152 /* first the parameters */
3153 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3155 /* now call : if symbol then pcall */
3156 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3157 ic = newiCode (PCALL, left, NULL);
3159 ic = newiCode (CALL, left, NULL);
3162 type = copyLinkChain (ftype->next);
3163 etype = getSpec (type);
3164 SPEC_EXTR (etype) = 0;
3165 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3169 /* stack adjustment after call */
3170 ic->parmBytes = stack;
3175 /*-----------------------------------------------------------------*/
3176 /* geniCodeReceive - generate intermediate code for "receive" */
3177 /*-----------------------------------------------------------------*/
3179 geniCodeReceive (value * args)
3181 /* for all arguments that are passed in registers */
3185 if (IS_REGPARM (args->etype))
3187 operand *opr = operandFromValue (args);
3189 symbol *sym = OP_SYMBOL (opr);
3192 /* we will use it after all optimizations
3193 and before liveRange calculation */
3194 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3197 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3198 options.stackAuto == 0 &&
3199 (!(options.model == MODEL_FLAT24)) )
3204 opl = newiTempOperand (args->type, 0);
3206 sym->reqv->key = sym->key;
3207 OP_SYMBOL (sym->reqv)->key = sym->key;
3208 OP_SYMBOL (sym->reqv)->isreqv = 1;
3209 OP_SYMBOL (sym->reqv)->islocal = 0;
3210 SPIL_LOC (sym->reqv) = sym;
3214 ic = newiCode (RECEIVE, NULL, NULL);
3215 ic->argreg = SPEC_ARGREG(args->etype);
3217 currFunc->recvSize = getSize (sym->type);
3220 IC_RESULT (ic) = opr;
3228 /*-----------------------------------------------------------------*/
3229 /* geniCodeFunctionBody - create the function body */
3230 /*-----------------------------------------------------------------*/
3232 geniCodeFunctionBody (ast * tree,int lvl)
3239 /* reset the auto generation */
3245 func = ast2iCode (tree->left,lvl+1);
3246 fetype = getSpec (operandType (func));
3248 savelineno = lineno;
3249 lineno = OP_SYMBOL (func)->lineDef;
3250 /* create an entry label */
3251 geniCodeLabel (entryLabel);
3252 lineno = savelineno;
3254 /* create a proc icode */
3255 ic = newiCode (FUNCTION, func, NULL);
3256 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3260 /* for all parameters that are passed
3261 on registers add a "receive" */
3262 geniCodeReceive (tree->values.args);
3264 /* generate code for the body */
3265 ast2iCode (tree->right,lvl+1);
3267 /* create a label for return */
3268 geniCodeLabel (returnLabel);
3270 /* now generate the end proc */
3271 ic = newiCode (ENDFUNCTION, func, NULL);
3276 /*-----------------------------------------------------------------*/
3277 /* geniCodeReturn - gen icode for 'return' statement */
3278 /*-----------------------------------------------------------------*/
3280 geniCodeReturn (operand * op)
3284 /* if the operand is present force an rvalue */
3286 op = geniCodeRValue (op, FALSE);
3288 ic = newiCode (RETURN, op, NULL);
3292 /*-----------------------------------------------------------------*/
3293 /* geniCodeIfx - generates code for extended if statement */
3294 /*-----------------------------------------------------------------*/
3296 geniCodeIfx (ast * tree,int lvl)
3299 operand *condition = ast2iCode (tree->left,lvl+1);
3302 /* if condition is null then exit */
3306 condition = geniCodeRValue (condition, FALSE);
3308 cetype = getSpec (operandType (condition));
3309 /* if the condition is a literal */
3310 if (IS_LITERAL (cetype))
3312 if (floatFromVal (condition->operand.valOperand))
3314 if (tree->trueLabel)
3315 geniCodeGoto (tree->trueLabel);
3321 if (tree->falseLabel)
3322 geniCodeGoto (tree->falseLabel);
3329 if (tree->trueLabel)
3331 ic = newiCodeCondition (condition,
3336 if (tree->falseLabel)
3337 geniCodeGoto (tree->falseLabel);
3341 ic = newiCodeCondition (condition,
3348 ast2iCode (tree->right,lvl+1);
3351 /*-----------------------------------------------------------------*/
3352 /* geniCodeJumpTable - tries to create a jump table for switch */
3353 /*-----------------------------------------------------------------*/
3355 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3357 int min = 0, max = 0, t, cnt = 0;
3363 int needRangeCheck = !optimize.noJTabBoundary
3364 || tree->values.switchVals.swDefault;
3366 if (!tree || !caseVals)
3369 /* the criteria for creating a jump table is */
3370 /* all integer numbers between the maximum & minimum must */
3371 /* be present , the maximum value should not exceed 255 */
3372 min = max = (int) floatFromVal (vch = caseVals);
3373 SNPRINTF (buffer, sizeof(buffer),
3375 tree->values.switchVals.swNum,
3377 addSet (&labels, newiTempLabel (buffer));
3379 /* if there is only one case value then no need */
3380 if (!(vch = vch->next))
3385 if (((t = (int) floatFromVal (vch)) - max) != 1)
3387 SNPRINTF (buffer, sizeof(buffer),
3389 tree->values.switchVals.swNum,
3391 addSet (&labels, newiTempLabel (buffer));
3397 /* if the number of case statements <= 2 then */
3398 /* it is not economical to create the jump table */
3399 /* since two compares are needed for boundary conditions */
3400 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3403 if (tree->values.switchVals.swDefault)
3405 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3409 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3413 falseLabel = newiTempLabel (buffer);
3415 /* so we can create a jumptable */
3416 /* first we rule out the boundary conditions */
3417 /* if only optimization says so */
3420 sym_link *cetype = getSpec (operandType (cond));
3421 /* no need to check the lower bound if
3422 the condition is unsigned & minimum value is zero */
3423 if (!(min == 0 && IS_UNSIGNED (cetype)))
3425 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3426 ic = newiCodeCondition (boundary, falseLabel, NULL);
3430 /* now for upper bounds */
3431 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3432 ic = newiCodeCondition (boundary, falseLabel, NULL);
3436 /* if the min is not zero then we no make it zero */
3439 cond = geniCodeSubtract (cond, operandFromLit (min));
3440 if (!IS_LITERAL(getSpec(operandType(cond))))
3441 setOperandType (cond, UCHARTYPE);
3444 /* now create the jumptable */
3445 ic = newiCode (JUMPTABLE, NULL, NULL);
3446 IC_JTCOND (ic) = cond;
3447 IC_JTLABELS (ic) = labels;
3452 /*-----------------------------------------------------------------*/
3453 /* geniCodeSwitch - changes a switch to a if statement */
3454 /*-----------------------------------------------------------------*/
3456 geniCodeSwitch (ast * tree,int lvl)
3459 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3460 value *caseVals = tree->values.switchVals.swVals;
3461 symbol *trueLabel, *falseLabel;
3463 /* If the condition is a literal, then just jump to the */
3464 /* appropriate case label. */
3465 if (IS_LITERAL(getSpec(operandType(cond))))
3467 int switchVal, caseVal;
3469 switchVal = (int) floatFromVal (cond->operand.valOperand);
3472 caseVal = (int) floatFromVal (caseVals);
3473 if (caseVal == switchVal)
3475 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3476 tree->values.switchVals.swNum, caseVal);
3477 trueLabel = newiTempLabel (buffer);
3478 geniCodeGoto (trueLabel);
3481 caseVals = caseVals->next;
3483 goto defaultOrBreak;
3486 /* if we can make this a jump table */
3487 if (geniCodeJumpTable (cond, caseVals, tree))
3488 goto jumpTable; /* no need for the comparison */
3490 /* for the cases defined do */
3494 operand *compare = geniCodeLogic (cond,
3495 operandFromValue (caseVals),
3498 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3499 tree->values.switchVals.swNum,
3500 (int) floatFromVal (caseVals));
3501 trueLabel = newiTempLabel (buffer);
3503 ic = newiCodeCondition (compare, trueLabel, NULL);
3505 caseVals = caseVals->next;
3510 /* if default is present then goto break else break */
3511 if (tree->values.switchVals.swDefault)
3513 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3517 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3520 falseLabel = newiTempLabel (buffer);
3521 geniCodeGoto (falseLabel);
3524 ast2iCode (tree->right,lvl+1);
3527 /*-----------------------------------------------------------------*/
3528 /* geniCodeInline - intermediate code for inline assembler */
3529 /*-----------------------------------------------------------------*/
3531 geniCodeInline (ast * tree)
3535 ic = newiCode (INLINEASM, NULL, NULL);
3536 IC_INLINE (ic) = tree->values.inlineasm;
3540 /*-----------------------------------------------------------------*/
3541 /* geniCodeArrayInit - intermediate code for array initializer */
3542 /*-----------------------------------------------------------------*/
3544 geniCodeArrayInit (ast * tree, operand *array)
3548 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3549 ic = newiCode (ARRAYINIT, array, NULL);
3550 IC_ARRAYILIST (ic) = tree->values.constlist;
3552 operand *left=newOperand(), *right=newOperand();
3553 left->type=right->type=SYMBOL;
3554 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3555 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3556 ic = newiCode (ARRAYINIT, left, right);
3561 /*-----------------------------------------------------------------*/
3562 /* geniCodeCritical - intermediate code for a critical statement */
3563 /*-----------------------------------------------------------------*/
3565 geniCodeCritical (ast *tree, int lvl)
3570 /* If op is NULL, the original interrupt state will saved on */
3571 /* the stack. Otherwise, it will be saved in op. */
3573 /* Generate a save of the current interrupt state & disabled */
3574 ic = newiCode (CRITICAL, NULL, NULL);
3575 IC_RESULT (ic) = op;
3578 /* Generate the critical code sequence */
3579 if (tree->left && tree->left->type == EX_VALUE)
3580 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3582 ast2iCode (tree->left,lvl+1);
3584 /* Generate a restore of the original interrupt state */
3585 ic = newiCode (ENDCRITICAL, NULL, op);
3589 /*-----------------------------------------------------------------*/
3590 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3591 /* particular case. Ie : assigning or dereferencing array or ptr */
3592 /*-----------------------------------------------------------------*/
3593 set * lvaluereqSet = NULL;
3594 typedef struct lvalItem
3601 /*-----------------------------------------------------------------*/
3602 /* addLvaluereq - add a flag for lvalreq for current ast level */
3603 /*-----------------------------------------------------------------*/
3604 void addLvaluereq(int lvl)
3606 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3609 addSetHead(&lvaluereqSet,lpItem);
3612 /*-----------------------------------------------------------------*/
3613 /* delLvaluereq - del a flag for lvalreq for current ast level */
3614 /*-----------------------------------------------------------------*/
3618 lpItem = getSet(&lvaluereqSet);
3619 if(lpItem) Safe_free(lpItem);
3621 /*-----------------------------------------------------------------*/
3622 /* clearLvaluereq - clear lvalreq flag */
3623 /*-----------------------------------------------------------------*/
3624 void clearLvaluereq()
3627 lpItem = peekSet(lvaluereqSet);
3628 if(lpItem) lpItem->req = 0;
3630 /*-----------------------------------------------------------------*/
3631 /* getLvaluereq - get the last lvalreq level */
3632 /*-----------------------------------------------------------------*/
3633 int getLvaluereqLvl()
3636 lpItem = peekSet(lvaluereqSet);
3637 if(lpItem) return lpItem->lvl;
3640 /*-----------------------------------------------------------------*/
3641 /* isLvaluereq - is lvalreq valid for this level ? */
3642 /*-----------------------------------------------------------------*/
3643 int isLvaluereq(int lvl)
3646 lpItem = peekSet(lvaluereqSet);
3647 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3651 /*-----------------------------------------------------------------*/
3652 /* ast2iCode - creates an icodeList from an ast */
3653 /*-----------------------------------------------------------------*/
3655 ast2iCode (ast * tree,int lvl)
3657 operand *left = NULL;
3658 operand *right = NULL;
3662 /* set the global variables for filename & line number */
3664 filename = tree->filename;
3666 lineno = tree->lineno;
3668 block = tree->block;
3670 scopeLevel = tree->level;
3672 seqPoint = tree->seqPoint;
3674 if (tree->type == EX_VALUE)
3675 return operandFromValue (tree->opval.val);
3677 if (tree->type == EX_LINK)
3678 return operandFromLink (tree->opval.lnk);
3680 /* if we find a nullop */
3681 if (tree->type == EX_OP &&
3682 (tree->opval.op == NULLOP ||
3683 tree->opval.op == BLOCK))
3685 if (tree->left && tree->left->type == EX_VALUE)
3686 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3688 ast2iCode (tree->left,lvl+1);
3689 if (tree->right && tree->right->type == EX_VALUE)
3690 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3692 ast2iCode (tree->right,lvl+1);
3696 /* special cases for not evaluating */
3697 if (tree->opval.op != ':' &&
3698 tree->opval.op != '?' &&
3699 tree->opval.op != CALL &&
3700 tree->opval.op != IFX &&
3701 tree->opval.op != LABEL &&
3702 tree->opval.op != GOTO &&
3703 tree->opval.op != SWITCH &&
3704 tree->opval.op != FUNCTION &&
3705 tree->opval.op != INLINEASM &&
3706 tree->opval.op != CRITICAL)
3709 if (IS_ASSIGN_OP (tree->opval.op) ||
3710 IS_DEREF_OP (tree) ||
3711 (tree->opval.op == '&' && !tree->right) ||
3712 tree->opval.op == PTR_OP)
3715 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3716 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3719 left = operandFromAst (tree->left,lvl);
3721 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3722 left = geniCodeRValue (left, TRUE);
3726 left = operandFromAst (tree->left,lvl);
3728 if (tree->opval.op == INC_OP ||
3729 tree->opval.op == DEC_OP)
3732 right = operandFromAst (tree->right,lvl);
3737 right = operandFromAst (tree->right,lvl);
3741 /* now depending on the type of operand */
3742 /* this will be a biggy */
3743 switch (tree->opval.op)
3746 case '[': /* array operation */
3748 //sym_link *ltype = operandType (left);
3749 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3750 left = geniCodeRValue (left, FALSE);
3751 right = geniCodeRValue (right, TRUE);
3754 return geniCodeArray (left, right,lvl);
3756 case '.': /* structure dereference */
3757 if (IS_PTR (operandType (left)))
3758 left = geniCodeRValue (left, TRUE);
3760 left = geniCodeRValue (left, FALSE);
3762 return geniCodeStruct (left, right, tree->lvalue);
3764 case PTR_OP: /* structure pointer dereference */
3767 pType = operandType (left);
3768 left = geniCodeRValue (left, TRUE);
3770 setOClass (pType, getSpec (operandType (left)));
3773 return geniCodeStruct (left, right, tree->lvalue);
3775 case INC_OP: /* increment operator */
3777 return geniCodePostInc (left);
3779 return geniCodePreInc (right, tree->lvalue);
3781 case DEC_OP: /* decrement operator */
3783 return geniCodePostDec (left);
3785 return geniCodePreDec (right, tree->lvalue);
3787 case '&': /* bitwise and or address of operator */
3789 { /* this is a bitwise operator */
3790 left = geniCodeRValue (left, FALSE);
3791 right = geniCodeRValue (right, FALSE);
3792 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3795 return geniCodeAddressOf (left);
3797 case '|': /* bitwise or & xor */
3799 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3800 geniCodeRValue (right, FALSE),
3805 return geniCodeDivision (geniCodeRValue (left, FALSE),
3806 geniCodeRValue (right, FALSE));
3809 return geniCodeModulus (geniCodeRValue (left, FALSE),
3810 geniCodeRValue (right, FALSE));
3813 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3814 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3816 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3820 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3821 geniCodeRValue (right, FALSE));
3823 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3827 return geniCodeAdd (geniCodeRValue (left, FALSE),
3828 geniCodeRValue (right, FALSE),lvl);
3830 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3833 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3834 geniCodeRValue (right, FALSE));
3837 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3838 geniCodeRValue (right, FALSE));
3840 #if 0 // this indeed needs a second thought
3844 // let's keep this simple: get the rvalue we need
3845 op=geniCodeRValue (right, FALSE);
3846 // now cast it to whatever we want
3847 op=geniCodeCast (operandType(left), op, FALSE);
3848 // if this is going to be used as an lvalue, make it so
3854 #else // bug #604575, is it a bug ????
3855 return geniCodeCast (operandType (left),
3856 geniCodeRValue (right, FALSE), FALSE);
3863 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3868 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3869 setOperandType (op, UCHARTYPE);
3880 /* different compilers (even different gccs) evaluate
3881 the two calls in a different order. to get the same
3882 result on all machines we've to specify a clear sequence.
3883 return geniCodeLogic (geniCodeRValue (left, FALSE),
3884 geniCodeRValue (right, FALSE),
3888 operand *leftOp, *rightOp;
3890 rightOp = geniCodeRValue (right, FALSE);
3891 leftOp = geniCodeRValue (left , FALSE);
3893 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3896 return geniCodeConditional (tree,lvl);
3899 return operandFromLit (getSize (tree->right->ftype));
3903 sym_link *rtype = operandType (right);
3904 sym_link *ltype = operandType (left);
3905 if (IS_PTR (rtype) && IS_ITEMP (right)
3906 && right->isaddr && compareType (rtype->next, ltype) == 1)
3907 right = geniCodeRValue (right, TRUE);
3909 right = geniCodeRValue (right, FALSE);
3911 geniCodeAssign (left, right, 0);
3916 geniCodeAssign (left,
3917 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3919 geniCodeRValue (right, FALSE),FALSE), 0);
3923 geniCodeAssign (left,
3924 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3926 geniCodeRValue (right, FALSE)), 0);
3929 geniCodeAssign (left,
3930 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3932 geniCodeRValue (right, FALSE)), 0);
3935 sym_link *rtype = operandType (right);
3936 sym_link *ltype = operandType (left);
3937 if (IS_PTR (rtype) && IS_ITEMP (right)
3938 && right->isaddr && compareType (rtype->next, ltype) == 1)
3939 right = geniCodeRValue (right, TRUE);
3941 right = geniCodeRValue (right, FALSE);
3944 return geniCodeAssign (left,
3945 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3951 sym_link *rtype = operandType (right);
3952 sym_link *ltype = operandType (left);
3953 if (IS_PTR (rtype) && IS_ITEMP (right)
3954 && right->isaddr && compareType (rtype->next, ltype) == 1)
3956 right = geniCodeRValue (right, TRUE);
3960 right = geniCodeRValue (right, FALSE);
3963 geniCodeAssign (left,
3964 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3970 geniCodeAssign (left,
3971 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3973 geniCodeRValue (right, FALSE)), 0);
3976 geniCodeAssign (left,
3977 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3979 geniCodeRValue (right, FALSE)), 0);
3982 geniCodeAssign (left,
3983 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3985 geniCodeRValue (right, FALSE),
3987 operandType (left)), 0);
3990 geniCodeAssign (left,
3991 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3993 geniCodeRValue (right, FALSE),
3995 operandType (left)), 0);
3998 geniCodeAssign (left,
3999 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4001 geniCodeRValue (right, FALSE),
4003 operandType (left)), 0);
4005 return geniCodeRValue (right, FALSE);
4008 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4011 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4012 return ast2iCode (tree->right,lvl+1);
4015 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4016 return ast2iCode (tree->right,lvl+1);
4019 geniCodeFunctionBody (tree,lvl);
4023 geniCodeReturn (right);
4027 geniCodeIfx (tree,lvl);
4031 geniCodeSwitch (tree,lvl);
4035 geniCodeInline (tree);
4039 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4043 geniCodeCritical (tree, lvl);
4049 /*-----------------------------------------------------------------*/
4050 /* reverseICChain - gets from the list and creates a linkedlist */
4051 /*-----------------------------------------------------------------*/
4058 while ((loop = getSet (&iCodeChain)))
4070 /*-----------------------------------------------------------------*/
4071 /* iCodeFromAst - given an ast will convert it to iCode */
4072 /*-----------------------------------------------------------------*/
4074 iCodeFromAst (ast * tree)
4076 returnLabel = newiTempLabel ("_return");
4077 entryLabel = newiTempLabel ("_entry");
4079 return reverseiCChain ();
4082 static const char *opTypeToStr(OPTYPE op)
4086 case SYMBOL: return "symbol";
4087 case VALUE: return "value";
4088 case TYPE: return "type";
4090 return "undefined type";
4094 operand *validateOpType(operand *op,
4101 if (op && op->type == type)
4106 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4107 " expected %s, got %s\n",
4108 macro, args, file, line,
4109 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4111 return op; // never reached, makes compiler happy.