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)->key = sym->key;
1537 OP_SYMBOL (sym->reqv)->isreqv = 1;
1538 OP_SYMBOL (sym->reqv)->islocal = 1;
1539 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1540 SPIL_LOC (sym->reqv) = sym;
1543 if (!IS_AGGREGATE (sym->type))
1547 op->operand.symOperand = sym;
1550 op->isvolatile = isOperandVolatile (op, TRUE);
1551 op->isGlobal = isOperandGlobal (op);
1552 op->isPtr = IS_PTR (operandType (op));
1553 op->isParm = sym->_isparm;
1558 /* itemp = &[_symbol] */
1560 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1561 IC_LEFT (ic)->type = SYMBOL;
1562 IC_LEFT (ic)->operand.symOperand = sym;
1563 IC_LEFT (ic)->key = sym->key;
1564 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1565 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1566 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1569 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1570 if (IS_ARRAY (sym->type))
1572 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1573 IC_RESULT (ic)->isaddr = 0;
1576 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1580 return IC_RESULT (ic);
1583 /*-----------------------------------------------------------------*/
1584 /* operandFromValue - creates an operand from value */
1585 /*-----------------------------------------------------------------*/
1587 operandFromValue (value * val)
1591 /* if this is a symbol then do the symbol thing */
1593 return operandFromSymbol (val->sym);
1595 /* this is not a symbol */
1598 op->operand.valOperand = val;
1599 op->isLiteral = isOperandLiteral (op);
1603 /*-----------------------------------------------------------------*/
1604 /* operandFromLink - operand from typeChain */
1605 /*-----------------------------------------------------------------*/
1607 operandFromLink (sym_link * type)
1611 /* operand from sym_link */
1617 op->operand.typeOperand = copyLinkChain (type);
1621 /*-----------------------------------------------------------------*/
1622 /* operandFromLit - makes an operand from a literal value */
1623 /*-----------------------------------------------------------------*/
1625 operandFromLit (double i)
1627 return operandFromValue (valueFromLit (i));
1630 /*-----------------------------------------------------------------*/
1631 /* operandFromAst - creates an operand from an ast */
1632 /*-----------------------------------------------------------------*/
1634 operandFromAst (ast * tree,int lvl)
1640 /* depending on type do */
1644 return ast2iCode (tree,lvl+1);
1648 return operandFromValue (tree->opval.val);
1652 return operandFromLink (tree->opval.lnk);
1659 /* Just to keep the compiler happy */
1660 return (operand *) 0;
1663 /*-----------------------------------------------------------------*/
1664 /* setOperandType - sets the operand's type to the given type */
1665 /*-----------------------------------------------------------------*/
1667 setOperandType (operand * op, sym_link * type)
1669 /* depending on the type of operand */
1674 op->operand.valOperand->etype =
1675 getSpec (op->operand.valOperand->type =
1676 copyLinkChain (type));
1680 if (op->operand.symOperand->isitmp)
1681 op->operand.symOperand->etype =
1682 getSpec (op->operand.symOperand->type =
1683 copyLinkChain (type));
1685 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1686 "attempt to modify type of source");
1690 op->operand.typeOperand = copyLinkChain (type);
1695 /*-----------------------------------------------------------------*/
1696 /* Get size in byte of ptr need to access an array */
1697 /*-----------------------------------------------------------------*/
1699 getArraySizePtr (operand * op)
1701 sym_link *ltype = operandType(op);
1705 int size = getSize(ltype);
1706 return(IS_GENPTR(ltype)?(size-1):size);
1711 sym_link *letype = getSpec(ltype);
1712 switch (PTR_TYPE (SPEC_OCLS (letype)))
1724 return (GPTRSIZE-1);
1733 /*-----------------------------------------------------------------*/
1734 /* perform "usual unary conversions" */
1735 /*-----------------------------------------------------------------*/
1738 usualUnaryConversions (operand * op)
1740 if (IS_INTEGRAL (operandType (op)))
1742 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1745 return geniCodeCast (INTTYPE, op, TRUE);
1752 /*-----------------------------------------------------------------*/
1753 /* perform "usual binary conversions" */
1754 /*-----------------------------------------------------------------*/
1756 usualBinaryConversions (operand ** op1, operand ** op2,
1757 bool promoteCharToInt, bool isMul)
1760 sym_link *rtype = operandType (*op2);
1761 sym_link *ltype = operandType (*op1);
1763 ctype = computeType (ltype, rtype, promoteCharToInt);
1765 /* special for multiplication:
1766 This if for 'mul a,b', which takes two chars and returns an int */
1768 /* && promoteCharToInt superfluous, already handled by computeType() */
1769 && IS_INT (getSpec (ctype)))
1771 sym_link *retype = getSpec (rtype);
1772 sym_link *letype = getSpec (ltype);
1774 if ( IS_CHAR (letype)
1776 && IS_UNSIGNED (letype)
1777 && IS_UNSIGNED (retype))
1782 *op1 = geniCodeCast (ctype, *op1, TRUE);
1783 *op2 = geniCodeCast (ctype, *op2, TRUE);
1788 /*-----------------------------------------------------------------*/
1789 /* geniCodeValueAtAddress - generate intermeditate code for value */
1791 /*-----------------------------------------------------------------*/
1793 geniCodeRValue (operand * op, bool force)
1796 sym_link *type = operandType (op);
1797 sym_link *etype = getSpec (type);
1799 /* if this is an array & already */
1800 /* an address then return this */
1801 if (IS_AGGREGATE (type) ||
1802 (IS_PTR (type) && !force && !op->isaddr))
1803 return operandFromOperand (op);
1805 /* if this is not an address then must be */
1806 /* rvalue already so return this one */
1810 /* if this is not a temp symbol then */
1811 if (!IS_ITEMP (op) &&
1813 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1815 op = operandFromOperand (op);
1820 if (IS_SPEC (type) &&
1821 IS_TRUE_SYMOP (op) &&
1822 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1823 (options.model == MODEL_FLAT24) ))
1825 op = operandFromOperand (op);
1830 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1831 if (IS_PTR (type) && op->isaddr && force)
1834 type = copyLinkChain (type);
1836 IC_RESULT (ic) = newiTempOperand (type, 1);
1837 IC_RESULT (ic)->isaddr = 0;
1839 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1843 return IC_RESULT (ic);
1846 /*-----------------------------------------------------------------*/
1847 /* geniCodeCast - changes the value from one type to another */
1848 /*-----------------------------------------------------------------*/
1850 geniCodeCast (sym_link * type, operand * op, bool implicit)
1854 sym_link *opetype = getSpec (optype = operandType (op));
1858 /* one of them has size zero then error */
1859 if (IS_VOID (optype))
1861 werror (E_CAST_ZERO);
1865 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1867 geniCodeArray2Ptr (op);
1871 /* if the operand is already the desired type then do nothing */
1872 if (compareType (type, optype) == 1)
1875 /* if this is a literal then just change the type & return */
1876 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1878 return operandFromValue (valCastLiteral (type,
1879 operandLitValue (op)));
1882 /* if casting to/from pointers, do some checking */
1883 if (IS_PTR(type)) { // to a pointer
1884 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1885 if (IS_INTEGRAL(optype)) {
1886 // maybe this is NULL, than it's ok.
1887 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1888 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1889 // no way to set the storage
1890 if (IS_LITERAL(optype)) {
1891 werror(E_LITERAL_GENERIC);
1894 werror(E_NONPTR2_GENPTR);
1897 } else if (implicit) {
1898 werror(W_INTEGRAL2PTR_NOCAST);
1903 // shouldn't do that with float, array or structure unless to void
1904 if (!IS_VOID(getSpec(type)) &&
1905 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1906 werror(E_INCOMPAT_TYPES);
1910 } else { // from a pointer to a pointer
1911 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1912 // if not a pointer to a function
1913 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1914 if (implicit) { // if not to generic, they have to match
1915 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1916 werror(E_INCOMPAT_PTYPES);
1923 } else { // to a non pointer
1924 if (IS_PTR(optype)) { // from a pointer
1925 if (implicit) { // sneaky
1926 if (IS_INTEGRAL(type)) {
1927 werror(W_PTR2INTEGRAL_NOCAST);
1929 } else { // shouldn't do that with float, array or structure
1930 werror(E_INCOMPAT_TYPES);
1937 printFromToType (optype, type);
1940 /* if they are the same size create an assignment */
1942 /* This seems very dangerous to me, since there are several */
1943 /* optimizations (for example, gcse) that don't notice the */
1944 /* cast hidden in this assignement and may simplify an */
1945 /* iCode to use the original (uncasted) operand. */
1946 /* Unfortunately, other things break when this cast is */
1947 /* made explicit. Need to fix this someday. */
1948 /* -- EEP, 2004/01/21 */
1949 if (getSize (type) == getSize (optype) &&
1950 !IS_BITFIELD (type) &&
1952 !IS_FLOAT (optype) &&
1953 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1954 (!IS_SPEC (type) && !IS_SPEC (optype))))
1956 ic = newiCode ('=', NULL, op);
1957 IC_RESULT (ic) = newiTempOperand (type, 0);
1958 SPIL_LOC (IC_RESULT (ic)) =
1959 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1960 IC_RESULT (ic)->isaddr = 0;
1964 ic = newiCode (CAST, operandFromLink (type),
1965 geniCodeRValue (op, FALSE));
1967 IC_RESULT (ic) = newiTempOperand (type, 0);
1970 /* preserve the storage class & output class */
1971 /* of the original variable */
1972 restype = getSpec (operandType (IC_RESULT (ic)));
1973 if (!IS_LITERAL(opetype))
1974 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1975 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1978 return IC_RESULT (ic);
1981 /*-----------------------------------------------------------------*/
1982 /* geniCodeLabel - will create a Label */
1983 /*-----------------------------------------------------------------*/
1985 geniCodeLabel (symbol * label)
1989 ic = newiCodeLabelGoto (LABEL, label);
1993 /*-----------------------------------------------------------------*/
1994 /* geniCodeGoto - will create a Goto */
1995 /*-----------------------------------------------------------------*/
1997 geniCodeGoto (symbol * label)
2001 ic = newiCodeLabelGoto (GOTO, label);
2005 /*-----------------------------------------------------------------*/
2006 /* geniCodeMultiply - gen intermediate code for multiplication */
2007 /*-----------------------------------------------------------------*/
2009 geniCodeMultiply (operand * left, operand * right, int resultIsInt)
2016 /* if they are both literal then we know the result */
2017 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2018 return operandFromValue (valMult (left->operand.valOperand,
2019 right->operand.valOperand));
2021 if (IS_LITERAL(retype)) {
2022 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2025 resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE);
2027 rtype = operandType (right);
2028 retype = getSpec (rtype);
2029 ltype = operandType (left);
2030 letype = getSpec (ltype);
2033 /* if the right is a literal & power of 2 */
2034 /* then make it a left shift */
2035 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2036 efficient in most cases than 2 bytes result = 2 bytes << literal
2037 if port has 1 byte muldiv */
2038 if (p2 && !IS_FLOAT (letype) &&
2039 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
2040 (port->support.muldiv == 1)))
2042 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2044 /* LEFT_OP need same size for left and result, */
2045 left = geniCodeCast (resType, left, TRUE);
2046 ltype = operandType (left);
2048 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2052 ic = newiCode ('*', left, right); /* normal multiplication */
2053 /* if the size left or right > 1 then support routine */
2054 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2058 IC_RESULT (ic) = newiTempOperand (resType, 1);
2061 return IC_RESULT (ic);
2064 /*-----------------------------------------------------------------*/
2065 /* geniCodeDivision - gen intermediate code for division */
2066 /*-----------------------------------------------------------------*/
2068 geniCodeDivision (operand * left, operand * right)
2073 sym_link *rtype = operandType (right);
2074 sym_link *retype = getSpec (rtype);
2075 sym_link *ltype = operandType (left);
2076 sym_link *letype = getSpec (ltype);
2078 resType = usualBinaryConversions (&left, &right,
2079 (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2082 /* if the right is a literal & power of 2
2083 and left is unsigned then make it a
2085 if (IS_LITERAL (retype) &&
2086 !IS_FLOAT (letype) &&
2087 IS_UNSIGNED(letype) &&
2088 (p2 = powof2 ((TYPE_UDWORD)
2089 floatFromVal (right->operand.valOperand)))) {
2090 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2094 ic = newiCode ('/', left, right); /* normal division */
2095 /* if the size left or right > 1 then support routine */
2096 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2099 IC_RESULT (ic) = newiTempOperand (resType, 0);
2102 return IC_RESULT (ic);
2104 /*-----------------------------------------------------------------*/
2105 /* geniCodeModulus - gen intermediate code for modulus */
2106 /*-----------------------------------------------------------------*/
2108 geniCodeModulus (operand * left, operand * right)
2114 /* if they are both literal then we know the result */
2115 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2116 return operandFromValue (valMod (left->operand.valOperand,
2117 right->operand.valOperand));
2119 resType = usualBinaryConversions (&left, &right,
2120 (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2123 /* now they are the same size */
2124 ic = newiCode ('%', left, right);
2126 /* if the size left or right > 1 then support routine */
2127 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2129 IC_RESULT (ic) = newiTempOperand (resType, 0);
2132 return IC_RESULT (ic);
2135 /*-----------------------------------------------------------------*/
2136 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2137 /*-----------------------------------------------------------------*/
2139 geniCodePtrPtrSubtract (operand * left, operand * right)
2145 /* if they are both literals then */
2146 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2148 result = operandFromValue (valMinus (left->operand.valOperand,
2149 right->operand.valOperand));
2153 ic = newiCode ('-', left, right);
2155 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2159 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2163 // should we really do this? is this ANSI?
2164 return geniCodeDivision (result,
2165 operandFromLit (getSize (ltype->next)));
2168 /*-----------------------------------------------------------------*/
2169 /* geniCodeSubtract - generates code for subtraction */
2170 /*-----------------------------------------------------------------*/
2172 geniCodeSubtract (operand * left, operand * right)
2179 /* if they both pointers then */
2180 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2181 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2182 return geniCodePtrPtrSubtract (left, right);
2184 /* if they are both literal then we know the result */
2185 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2186 && left->isLiteral && right->isLiteral)
2187 return operandFromValue (valMinus (left->operand.valOperand,
2188 right->operand.valOperand));
2190 /* if left is an array or pointer */
2191 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2193 isarray = left->isaddr;
2194 right = geniCodeMultiply (right,
2195 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2196 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2199 { /* make them the same size */
2200 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2203 ic = newiCode ('-', left, right);
2205 IC_RESULT (ic) = newiTempOperand (resType, 1);
2206 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2208 /* if left or right is a float */
2209 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2213 return IC_RESULT (ic);
2216 /*-----------------------------------------------------------------*/
2217 /* geniCodeAdd - generates iCode for addition */
2218 /*-----------------------------------------------------------------*/
2220 geniCodeAdd (operand * left, operand * right, int lvl)
2229 /* if the right side is LITERAL zero */
2230 /* return the left side */
2231 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2234 /* if left is literal zero return right */
2235 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2238 /* if left is a pointer then size */
2239 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2241 isarray = left->isaddr;
2242 // there is no need to multiply with 1
2243 if (getSize (ltype->next) != 1)
2245 size = operandFromLit (getSize (ltype->next));
2246 SPEC_USIGN (getSpec (operandType (size))) = 1;
2247 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2248 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2249 /* Even if right is a 'unsigned char',
2250 the result will be a 'signed int' due to the promotion rules.
2251 It doesn't make sense when accessing arrays, so let's fix it here: */
2253 SPEC_USIGN (getSpec (operandType (right))) = 1;
2255 resType = copyLinkChain (ltype);
2258 { // make them the same size
2259 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2262 /* if they are both literals then we know */
2263 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2264 && left->isLiteral && right->isLiteral)
2265 return operandFromValue (valPlus (valFromType (ltype),
2266 valFromType (rtype)));
2268 ic = newiCode ('+', left, right);
2270 IC_RESULT (ic) = newiTempOperand (resType, 1);
2271 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2273 /* if left or right is a float then support
2275 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2280 return IC_RESULT (ic);
2284 /*-----------------------------------------------------------------*/
2285 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2286 /*-----------------------------------------------------------------*/
2288 aggrToPtr (sym_link * type, bool force)
2293 if (IS_PTR (type) && !force)
2296 etype = getSpec (type);
2297 ptype = newLink (DECLARATOR);
2301 /* set the pointer depending on the storage class */
2302 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2306 /*-----------------------------------------------------------------*/
2307 /* geniCodeArray2Ptr - array to pointer */
2308 /*-----------------------------------------------------------------*/
2310 geniCodeArray2Ptr (operand * op)
2312 sym_link *optype = operandType (op);
2313 sym_link *opetype = getSpec (optype);
2315 /* set the pointer depending on the storage class */
2316 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2323 /*-----------------------------------------------------------------*/
2324 /* geniCodeArray - array access */
2325 /*-----------------------------------------------------------------*/
2327 geniCodeArray (operand * left, operand * right, int lvl)
2331 sym_link *ltype = operandType (left);
2336 if (IS_PTR (ltype->next) && left->isaddr)
2338 left = geniCodeRValue (left, FALSE);
2341 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2343 size = operandFromLit (getSize (ltype->next));
2344 SPEC_USIGN (getSpec (operandType (size))) = 1;
2345 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2346 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2347 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2348 It doesn't make sense when accessing arrays, so let's fix it here: */
2350 SPEC_USIGN (getSpec (operandType (right))) = 1;
2351 /* we can check for limits here */
2352 /* already done in SDCCast.c
2353 if (isOperandLiteral (right) &&
2356 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2358 werror (W_IDX_OUT_OF_BOUNDS,
2359 (int) operandLitValue (right) / getSize (ltype->next),
2364 ic = newiCode ('+', left, right);
2366 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2367 !IS_AGGREGATE (ltype->next) &&
2368 !IS_PTR (ltype->next))
2369 ? ltype : ltype->next), 0);
2371 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2374 return IC_RESULT (ic);
2377 /*-----------------------------------------------------------------*/
2378 /* geniCodeStruct - generates intermediate code for structures */
2379 /*-----------------------------------------------------------------*/
2381 geniCodeStruct (operand * left, operand * right, bool islval)
2384 sym_link *type = operandType (left);
2385 sym_link *etype = getSpec (type);
2387 symbol *element = getStructElement (SPEC_STRUCT (etype),
2388 right->operand.symOperand);
2390 wassert(IS_SYMOP(right));
2392 /* add the offset */
2393 ic = newiCode ('+', left, operandFromLit (element->offset));
2395 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2397 /* preserve the storage & output class of the struct */
2398 /* as well as the volatile attribute */
2399 retype = getSpec (operandType (IC_RESULT (ic)));
2400 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2401 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2402 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2403 SPEC_CONST (retype) |= SPEC_CONST (etype);
2405 if (IS_PTR (element->type))
2406 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2408 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2411 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2414 /*-----------------------------------------------------------------*/
2415 /* geniCodePostInc - generate int code for Post increment */
2416 /*-----------------------------------------------------------------*/
2418 geniCodePostInc (operand * op)
2422 sym_link *optype = operandType (op);
2424 operand *rv = (IS_ITEMP (op) ?
2425 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2427 sym_link *rvtype = operandType (rv);
2430 /* if this is not an address we have trouble */
2433 werror (E_LVALUE_REQUIRED, "++");
2437 rOp = newiTempOperand (rvtype, 0);
2438 OP_SYMBOL(rOp)->noSpilLoc = 1;
2441 OP_SYMBOL(rv)->noSpilLoc = 1;
2443 geniCodeAssign (rOp, rv, 0);
2445 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2446 if (IS_FLOAT (rvtype))
2447 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2449 ic = newiCode ('+', rv, operandFromLit (size));
2451 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2454 geniCodeAssign (op, result, 0);
2460 /*-----------------------------------------------------------------*/
2461 /* geniCodePreInc - generate code for preIncrement */
2462 /*-----------------------------------------------------------------*/
2464 geniCodePreInc (operand * op, bool lvalue)
2467 sym_link *optype = operandType (op);
2468 operand *rop = (IS_ITEMP (op) ?
2469 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2471 sym_link *roptype = operandType (rop);
2477 werror (E_LVALUE_REQUIRED, "++");
2482 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2483 if (IS_FLOAT (roptype))
2484 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2486 ic = newiCode ('+', rop, operandFromLit (size));
2487 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2490 (void) geniCodeAssign (op, result, 0);
2491 if (lvalue || IS_TRUE_SYMOP (op))
2497 /*-----------------------------------------------------------------*/
2498 /* geniCodePostDec - generates code for Post decrement */
2499 /*-----------------------------------------------------------------*/
2501 geniCodePostDec (operand * op)
2505 sym_link *optype = operandType (op);
2507 operand *rv = (IS_ITEMP (op) ?
2508 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2510 sym_link *rvtype = operandType (rv);
2513 /* if this is not an address we have trouble */
2516 werror (E_LVALUE_REQUIRED, "--");
2520 rOp = newiTempOperand (rvtype, 0);
2521 OP_SYMBOL(rOp)->noSpilLoc = 1;
2524 OP_SYMBOL(rv)->noSpilLoc = 1;
2526 geniCodeAssign (rOp, rv, 0);
2528 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2529 if (IS_FLOAT (rvtype))
2530 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2532 ic = newiCode ('-', rv, operandFromLit (size));
2534 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2537 geniCodeAssign (op, result, 0);
2543 /*-----------------------------------------------------------------*/
2544 /* geniCodePreDec - generate code for pre decrement */
2545 /*-----------------------------------------------------------------*/
2547 geniCodePreDec (operand * op, bool lvalue)
2550 sym_link *optype = operandType (op);
2551 operand *rop = (IS_ITEMP (op) ?
2552 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2554 sym_link *roptype = operandType (rop);
2560 werror (E_LVALUE_REQUIRED, "--");
2565 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2566 if (IS_FLOAT (roptype))
2567 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2569 ic = newiCode ('-', rop, operandFromLit (size));
2570 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2573 (void) geniCodeAssign (op, result, 0);
2574 if (lvalue || IS_TRUE_SYMOP (op))
2581 /*-----------------------------------------------------------------*/
2582 /* geniCodeBitwise - gen int code for bitWise operators */
2583 /*-----------------------------------------------------------------*/
2585 geniCodeBitwise (operand * left, operand * right,
2586 int oper, sym_link * resType)
2590 left = geniCodeCast (resType, left, TRUE);
2591 right = geniCodeCast (resType, right, TRUE);
2593 ic = newiCode (oper, left, right);
2594 IC_RESULT (ic) = newiTempOperand (resType, 0);
2597 return IC_RESULT (ic);
2600 /*-----------------------------------------------------------------*/
2601 /* geniCodeAddressOf - gens icode for '&' address of operator */
2602 /*-----------------------------------------------------------------*/
2604 geniCodeAddressOf (operand * op)
2608 sym_link *optype = operandType (op);
2609 sym_link *opetype = getSpec (optype);
2611 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2613 op = operandFromOperand (op);
2618 /* lvalue check already done in decorateType */
2619 /* this must be a lvalue */
2620 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2621 /* werror (E_LVALUE_REQUIRED,"&"); */
2625 p = newLink (DECLARATOR);
2627 /* set the pointer depending on the storage class */
2628 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2630 p->next = copyLinkChain (optype);
2632 /* if already a temp */
2635 setOperandType (op, p);
2640 /* other wise make this of the type coming in */
2641 ic = newiCode (ADDRESS_OF, op, NULL);
2642 IC_RESULT (ic) = newiTempOperand (p, 1);
2643 IC_RESULT (ic)->isaddr = 0;
2645 return IC_RESULT (ic);
2647 /*-----------------------------------------------------------------*/
2648 /* setOClass - sets the output class depending on the pointer type */
2649 /*-----------------------------------------------------------------*/
2651 setOClass (sym_link * ptr, sym_link * spec)
2653 switch (DCL_TYPE (ptr))
2656 SPEC_OCLS (spec) = data;
2660 SPEC_OCLS (spec) = generic;
2664 SPEC_OCLS (spec) = xdata;
2668 SPEC_OCLS (spec) = code;
2672 SPEC_OCLS (spec) = idata;
2676 SPEC_OCLS (spec) = xstack;
2680 SPEC_OCLS (spec) = eeprom;
2689 /*-----------------------------------------------------------------*/
2690 /* geniCodeDerefPtr - dereference pointer with '*' */
2691 /*-----------------------------------------------------------------*/
2693 geniCodeDerefPtr (operand * op,int lvl)
2695 sym_link *rtype, *retype;
2696 sym_link *optype = operandType (op);
2698 // if this is an array then array access
2699 if (IS_ARRAY (optype)) {
2700 // don't worry, this will be optimized out later
2701 return geniCodeArray (op, operandFromLit (0), lvl);
2704 // just in case someone screws up
2705 wassert (IS_PTR (optype));
2707 if (IS_TRUE_SYMOP (op))
2710 op = geniCodeRValue (op, TRUE);
2713 /* now get rid of the pointer part */
2714 if (isLvaluereq(lvl) && IS_ITEMP (op))
2716 retype = getSpec (rtype = copyLinkChain (optype));
2720 retype = getSpec (rtype = copyLinkChain (optype->next));
2721 /* outputclass needs 2b updated */
2722 setOClass (optype, retype);
2725 op->isGptr = IS_GENPTR (optype);
2727 op->isaddr = (IS_PTR (rtype) ||
2728 IS_STRUCT (rtype) ||
2733 if (!isLvaluereq(lvl))
2734 op = geniCodeRValue (op, TRUE);
2736 setOperandType (op, rtype);
2741 /*-----------------------------------------------------------------*/
2742 /* geniCodeUnaryMinus - does a unary minus of the operand */
2743 /*-----------------------------------------------------------------*/
2745 geniCodeUnaryMinus (operand * op)
2748 sym_link *optype = operandType (op);
2750 if (IS_LITERAL (optype))
2751 return operandFromLit (-floatFromVal (op->operand.valOperand));
2753 ic = newiCode (UNARYMINUS, op, NULL);
2754 IC_RESULT (ic) = newiTempOperand (optype, 0);
2756 return IC_RESULT (ic);
2759 /*-----------------------------------------------------------------*/
2760 /* geniCodeLeftShift - gen i code for left shift */
2761 /*-----------------------------------------------------------------*/
2763 geniCodeLeftShift (operand * left, operand * right)
2767 ic = newiCode (LEFT_OP, left, right);
2768 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2770 return IC_RESULT (ic);
2773 /*-----------------------------------------------------------------*/
2774 /* geniCodeRightShift - gen i code for right shift */
2775 /*-----------------------------------------------------------------*/
2777 geniCodeRightShift (operand * left, operand * right)
2781 ic = newiCode (RIGHT_OP, left, right);
2782 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2784 return IC_RESULT (ic);
2787 /*-----------------------------------------------------------------*/
2788 /* geniCodeLogic- logic code */
2789 /*-----------------------------------------------------------------*/
2791 geniCodeLogic (operand * left, operand * right, int op)
2795 sym_link *rtype = operandType (right);
2796 sym_link *ltype = operandType (left);
2798 /* left is integral type and right is literal then
2799 check if the literal value is within bounds */
2800 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2802 checkConstantRange(ltype,
2803 OP_VALUE(right), "compare operation", 1);
2806 /* if one operand is a pointer and the other is a literal generic void pointer,
2807 change the type of the literal generic void pointer to match the other pointer */
2808 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2809 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2811 /* find left's definition */
2812 ic = (iCode *) setFirstItem (iCodeChain);
2815 if (((ic->op == CAST) || (ic->op == '='))
2816 && isOperandEqual(left, IC_RESULT (ic)))
2819 ic = setNextItem (iCodeChain);
2821 /* if casting literal to generic pointer, then cast to rtype instead */
2822 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2824 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2825 ltype = operandType(left);
2828 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2829 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2831 /* find right's definition */
2832 ic = (iCode *) setFirstItem (iCodeChain);
2835 if (((ic->op == CAST) || (ic->op == '='))
2836 && isOperandEqual(right, IC_RESULT (ic)))
2839 ic = setNextItem (iCodeChain);
2841 /* if casting literal to generic pointer, then cast to rtype instead */
2842 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2844 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2845 rtype = operandType(right);
2849 ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
2851 ic = newiCode (op, left, right);
2852 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2854 /* if comparing float
2855 and not a '==' || '!=' || '&&' || '||' (these
2857 if (IS_FLOAT(ctype) &&
2865 return IC_RESULT (ic);
2868 /*-----------------------------------------------------------------*/
2869 /* geniCodeUnary - for a a generic unary operation */
2870 /*-----------------------------------------------------------------*/
2872 geniCodeUnary (operand * op, int oper)
2874 iCode *ic = newiCode (oper, op, NULL);
2876 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2878 return IC_RESULT (ic);
2881 /*-----------------------------------------------------------------*/
2882 /* geniCodeConditional - geniCode for '?' ':' operation */
2883 /*-----------------------------------------------------------------*/
2885 geniCodeConditional (ast * tree,int lvl)
2888 symbol *falseLabel = newiTempLabel (NULL);
2889 symbol *exitLabel = newiTempLabel (NULL);
2890 operand *cond = ast2iCode (tree->left,lvl+1);
2891 operand *true, *false, *result;
2893 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2897 true = ast2iCode (tree->right->left,lvl+1);
2899 /* move the value to a new Operand */
2900 result = newiTempOperand (tree->right->ftype, 0);
2901 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2903 /* generate an unconditional goto */
2904 geniCodeGoto (exitLabel);
2906 /* now for the right side */
2907 geniCodeLabel (falseLabel);
2909 false = ast2iCode (tree->right->right,lvl+1);
2910 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2912 /* create the exit label */
2913 geniCodeLabel (exitLabel);
2918 /*-----------------------------------------------------------------*/
2919 /* geniCodeAssign - generate code for assignment */
2920 /*-----------------------------------------------------------------*/
2922 geniCodeAssign (operand * left, operand * right, int nosupdate)
2925 sym_link *ltype = operandType (left);
2926 sym_link *rtype = operandType (right);
2928 if (!left->isaddr && !IS_ITEMP (left))
2930 werror (E_LVALUE_REQUIRED, "assignment");
2934 /* left is integral type and right is literal then
2935 check if the literal value is within bounds */
2936 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2938 checkConstantRange(ltype,
2939 OP_VALUE(right), "= operation", 0);
2942 /* if the left & right type don't exactly match */
2943 /* if pointer set then make sure the check is
2944 done with the type & not the pointer */
2945 /* then cast rights type to left */
2947 /* first check the type for pointer assignement */
2948 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2949 compareType (ltype, rtype) <= 0)
2951 if (compareType (ltype->next, rtype) < 0)
2952 right = geniCodeCast (ltype->next, right, TRUE);
2954 else if (compareType (ltype, rtype) < 0)
2955 right = geniCodeCast (ltype, right, TRUE);
2957 /* If left is a true symbol & ! volatile
2958 create an assignment to temporary for
2959 the right & then assign this temporary
2960 to the symbol. This is SSA (static single
2961 assignment). Isn't it simple and folks have
2962 published mountains of paper on it */
2963 if (IS_TRUE_SYMOP (left) &&
2964 !isOperandVolatile (left, FALSE) &&
2965 isOperandGlobal (left))
2969 if (IS_TRUE_SYMOP (right))
2970 sym = OP_SYMBOL (right);
2971 ic = newiCode ('=', NULL, right);
2972 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2973 SPIL_LOC (right) = sym;
2977 ic = newiCode ('=', NULL, right);
2978 IC_RESULT (ic) = left;
2981 /* if left isgptr flag is set then support
2982 routine will be required */
2986 ic->nosupdate = nosupdate;
2990 /*-----------------------------------------------------------------*/
2991 /* geniCodeDummyRead - generate code for dummy read */
2992 /*-----------------------------------------------------------------*/
2994 geniCodeDummyRead (operand * op)
2997 sym_link *type = operandType (op);
2999 if (!IS_VOLATILE(type))
3002 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3008 /*-----------------------------------------------------------------*/
3009 /* geniCodeSEParms - generate code for side effecting fcalls */
3010 /*-----------------------------------------------------------------*/
3012 geniCodeSEParms (ast * parms,int lvl)
3017 if (parms->type == EX_OP && parms->opval.op == PARAM)
3019 geniCodeSEParms (parms->left,lvl);
3020 geniCodeSEParms (parms->right,lvl);
3024 /* hack don't like this but too lazy to think of
3026 if (IS_ADDRESS_OF_OP (parms))
3027 parms->left->lvalue = 1;
3029 if (IS_CAST_OP (parms) &&
3030 IS_PTR (parms->ftype) &&
3031 IS_ADDRESS_OF_OP (parms->right))
3032 parms->right->left->lvalue = 1;
3034 parms->opval.oprnd =
3035 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3037 parms->type = EX_OPERAND;
3038 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3039 SPEC_ARGREG(parms->ftype);
3042 /*-----------------------------------------------------------------*/
3043 /* geniCodeParms - generates parameters */
3044 /*-----------------------------------------------------------------*/
3046 geniCodeParms (ast * parms, value *argVals, int *stack,
3047 sym_link * ftype, int lvl)
3055 if (argVals==NULL) {
3057 argVals = FUNC_ARGS (ftype);
3060 /* if this is a param node then do the left & right */
3061 if (parms->type == EX_OP && parms->opval.op == PARAM)
3063 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3064 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3068 /* get the parameter value */
3069 if (parms->type == EX_OPERAND)
3070 pval = parms->opval.oprnd;
3073 /* maybe this else should go away ?? */
3074 /* hack don't like this but too lazy to think of
3076 if (IS_ADDRESS_OF_OP (parms))
3077 parms->left->lvalue = 1;
3079 if (IS_CAST_OP (parms) &&
3080 IS_PTR (parms->ftype) &&
3081 IS_ADDRESS_OF_OP (parms->right))
3082 parms->right->left->lvalue = 1;
3084 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3087 /* if register parm then make it a send */
3088 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3089 IFFUNC_ISBUILTIN(ftype))
3091 ic = newiCode (SEND, pval, NULL);
3092 ic->argreg = SPEC_ARGREG(parms->etype);
3093 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3098 /* now decide whether to push or assign */
3099 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3103 operand *top = operandFromSymbol (argVals->sym);
3104 /* clear useDef and other bitVectors */
3105 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3106 geniCodeAssign (top, pval, 1);
3110 sym_link *p = operandType (pval);
3112 ic = newiCode (IPUSH, pval, NULL);
3114 /* update the stack adjustment */
3115 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3120 argVals=argVals->next;
3124 /*-----------------------------------------------------------------*/
3125 /* geniCodeCall - generates temp code for calling */
3126 /*-----------------------------------------------------------------*/
3128 geniCodeCall (operand * left, ast * parms,int lvl)
3132 sym_link *type, *etype;
3136 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3137 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3138 werror (E_FUNCTION_EXPECTED);
3139 return operandFromValue(valueFromLit(0));
3142 /* take care of parameters with side-effecting
3143 function calls in them, this is required to take care
3144 of overlaying function parameters */
3145 geniCodeSEParms (parms,lvl);
3147 ftype = operandType (left);
3148 if (IS_CODEPTR (ftype))
3149 ftype = ftype->next;
3151 /* first the parameters */
3152 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3154 /* now call : if symbol then pcall */
3155 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3156 ic = newiCode (PCALL, left, NULL);
3158 ic = newiCode (CALL, left, NULL);
3161 type = copyLinkChain (ftype->next);
3162 etype = getSpec (type);
3163 SPEC_EXTR (etype) = 0;
3164 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3168 /* stack adjustment after call */
3169 ic->parmBytes = stack;
3174 /*-----------------------------------------------------------------*/
3175 /* geniCodeReceive - generate intermediate code for "receive" */
3176 /*-----------------------------------------------------------------*/
3178 geniCodeReceive (value * args)
3180 /* for all arguments that are passed in registers */
3184 if (IS_REGPARM (args->etype))
3186 operand *opr = operandFromValue (args);
3188 symbol *sym = OP_SYMBOL (opr);
3191 /* we will use it after all optimizations
3192 and before liveRange calculation */
3193 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3196 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3197 options.stackAuto == 0 &&
3198 (!(options.model == MODEL_FLAT24)) )
3203 opl = newiTempOperand (args->type, 0);
3205 sym->reqv->key = sym->key;
3206 OP_SYMBOL (sym->reqv)->key = sym->key;
3207 OP_SYMBOL (sym->reqv)->isreqv = 1;
3208 OP_SYMBOL (sym->reqv)->islocal = 0;
3209 SPIL_LOC (sym->reqv) = sym;
3213 ic = newiCode (RECEIVE, NULL, NULL);
3214 ic->argreg = SPEC_ARGREG(args->etype);
3216 currFunc->recvSize = getSize (sym->type);
3219 IC_RESULT (ic) = opr;
3227 /*-----------------------------------------------------------------*/
3228 /* geniCodeFunctionBody - create the function body */
3229 /*-----------------------------------------------------------------*/
3231 geniCodeFunctionBody (ast * tree,int lvl)
3238 /* reset the auto generation */
3244 func = ast2iCode (tree->left,lvl+1);
3245 fetype = getSpec (operandType (func));
3247 savelineno = lineno;
3248 lineno = OP_SYMBOL (func)->lineDef;
3249 /* create an entry label */
3250 geniCodeLabel (entryLabel);
3251 lineno = savelineno;
3253 /* create a proc icode */
3254 ic = newiCode (FUNCTION, func, NULL);
3255 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3259 /* for all parameters that are passed
3260 on registers add a "receive" */
3261 geniCodeReceive (tree->values.args);
3263 /* generate code for the body */
3264 ast2iCode (tree->right,lvl+1);
3266 /* create a label for return */
3267 geniCodeLabel (returnLabel);
3269 /* now generate the end proc */
3270 ic = newiCode (ENDFUNCTION, func, NULL);
3275 /*-----------------------------------------------------------------*/
3276 /* geniCodeReturn - gen icode for 'return' statement */
3277 /*-----------------------------------------------------------------*/
3279 geniCodeReturn (operand * op)
3283 /* if the operand is present force an rvalue */
3285 op = geniCodeRValue (op, FALSE);
3287 ic = newiCode (RETURN, op, NULL);
3291 /*-----------------------------------------------------------------*/
3292 /* geniCodeIfx - generates code for extended if statement */
3293 /*-----------------------------------------------------------------*/
3295 geniCodeIfx (ast * tree,int lvl)
3298 operand *condition = ast2iCode (tree->left,lvl+1);
3301 /* if condition is null then exit */
3305 condition = geniCodeRValue (condition, FALSE);
3307 cetype = getSpec (operandType (condition));
3308 /* if the condition is a literal */
3309 if (IS_LITERAL (cetype))
3311 if (floatFromVal (condition->operand.valOperand))
3313 if (tree->trueLabel)
3314 geniCodeGoto (tree->trueLabel);
3320 if (tree->falseLabel)
3321 geniCodeGoto (tree->falseLabel);
3328 if (tree->trueLabel)
3330 ic = newiCodeCondition (condition,
3335 if (tree->falseLabel)
3336 geniCodeGoto (tree->falseLabel);
3340 ic = newiCodeCondition (condition,
3347 ast2iCode (tree->right,lvl+1);
3350 /*-----------------------------------------------------------------*/
3351 /* geniCodeJumpTable - tries to create a jump table for switch */
3352 /*-----------------------------------------------------------------*/
3354 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3356 int min = 0, max = 0, t, cnt = 0;
3362 int needRangeCheck = !optimize.noJTabBoundary
3363 || tree->values.switchVals.swDefault;
3365 if (!tree || !caseVals)
3368 /* the criteria for creating a jump table is */
3369 /* all integer numbers between the maximum & minimum must */
3370 /* be present , the maximum value should not exceed 255 */
3371 min = max = (int) floatFromVal (vch = caseVals);
3372 SNPRINTF (buffer, sizeof(buffer),
3374 tree->values.switchVals.swNum,
3376 addSet (&labels, newiTempLabel (buffer));
3378 /* if there is only one case value then no need */
3379 if (!(vch = vch->next))
3384 if (((t = (int) floatFromVal (vch)) - max) != 1)
3386 SNPRINTF (buffer, sizeof(buffer),
3388 tree->values.switchVals.swNum,
3390 addSet (&labels, newiTempLabel (buffer));
3396 /* if the number of case statements <= 2 then */
3397 /* it is not economical to create the jump table */
3398 /* since two compares are needed for boundary conditions */
3399 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3402 if (tree->values.switchVals.swDefault)
3404 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3408 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3412 falseLabel = newiTempLabel (buffer);
3414 /* so we can create a jumptable */
3415 /* first we rule out the boundary conditions */
3416 /* if only optimization says so */
3419 sym_link *cetype = getSpec (operandType (cond));
3420 /* no need to check the lower bound if
3421 the condition is unsigned & minimum value is zero */
3422 if (!(min == 0 && IS_UNSIGNED (cetype)))
3424 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3425 ic = newiCodeCondition (boundary, falseLabel, NULL);
3429 /* now for upper bounds */
3430 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3431 ic = newiCodeCondition (boundary, falseLabel, NULL);
3435 /* if the min is not zero then we no make it zero */
3438 cond = geniCodeSubtract (cond, operandFromLit (min));
3439 if (!IS_LITERAL(getSpec(operandType(cond))))
3440 setOperandType (cond, UCHARTYPE);
3443 /* now create the jumptable */
3444 ic = newiCode (JUMPTABLE, NULL, NULL);
3445 IC_JTCOND (ic) = cond;
3446 IC_JTLABELS (ic) = labels;
3451 /*-----------------------------------------------------------------*/
3452 /* geniCodeSwitch - changes a switch to a if statement */
3453 /*-----------------------------------------------------------------*/
3455 geniCodeSwitch (ast * tree,int lvl)
3458 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3459 value *caseVals = tree->values.switchVals.swVals;
3460 symbol *trueLabel, *falseLabel;
3462 /* If the condition is a literal, then just jump to the */
3463 /* appropriate case label. */
3464 if (IS_LITERAL(getSpec(operandType(cond))))
3466 int switchVal, caseVal;
3468 switchVal = (int) floatFromVal (cond->operand.valOperand);
3471 caseVal = (int) floatFromVal (caseVals);
3472 if (caseVal == switchVal)
3474 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3475 tree->values.switchVals.swNum, caseVal);
3476 trueLabel = newiTempLabel (buffer);
3477 geniCodeGoto (trueLabel);
3480 caseVals = caseVals->next;
3482 goto defaultOrBreak;
3485 /* if we can make this a jump table */
3486 if (geniCodeJumpTable (cond, caseVals, tree))
3487 goto jumpTable; /* no need for the comparison */
3489 /* for the cases defined do */
3493 operand *compare = geniCodeLogic (cond,
3494 operandFromValue (caseVals),
3497 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3498 tree->values.switchVals.swNum,
3499 (int) floatFromVal (caseVals));
3500 trueLabel = newiTempLabel (buffer);
3502 ic = newiCodeCondition (compare, trueLabel, NULL);
3504 caseVals = caseVals->next;
3509 /* if default is present then goto break else break */
3510 if (tree->values.switchVals.swDefault)
3512 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3516 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3519 falseLabel = newiTempLabel (buffer);
3520 geniCodeGoto (falseLabel);
3523 ast2iCode (tree->right,lvl+1);
3526 /*-----------------------------------------------------------------*/
3527 /* geniCodeInline - intermediate code for inline assembler */
3528 /*-----------------------------------------------------------------*/
3530 geniCodeInline (ast * tree)
3534 ic = newiCode (INLINEASM, NULL, NULL);
3535 IC_INLINE (ic) = tree->values.inlineasm;
3539 /*-----------------------------------------------------------------*/
3540 /* geniCodeArrayInit - intermediate code for array initializer */
3541 /*-----------------------------------------------------------------*/
3543 geniCodeArrayInit (ast * tree, operand *array)
3547 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3548 ic = newiCode (ARRAYINIT, array, NULL);
3549 IC_ARRAYILIST (ic) = tree->values.constlist;
3551 operand *left=newOperand(), *right=newOperand();
3552 left->type=right->type=SYMBOL;
3553 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3554 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3555 ic = newiCode (ARRAYINIT, left, right);
3560 /*-----------------------------------------------------------------*/
3561 /* geniCodeCritical - intermediate code for a critical statement */
3562 /*-----------------------------------------------------------------*/
3564 geniCodeCritical (ast *tree, int lvl)
3569 /* If op is NULL, the original interrupt state will saved on */
3570 /* the stack. Otherwise, it will be saved in op. */
3572 /* Generate a save of the current interrupt state & disabled */
3573 ic = newiCode (CRITICAL, NULL, NULL);
3574 IC_RESULT (ic) = op;
3577 /* Generate the critical code sequence */
3578 if (tree->left && tree->left->type == EX_VALUE)
3579 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3581 ast2iCode (tree->left,lvl+1);
3583 /* Generate a restore of the original interrupt state */
3584 ic = newiCode (ENDCRITICAL, NULL, op);
3588 /*-----------------------------------------------------------------*/
3589 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3590 /* particular case. Ie : assigning or dereferencing array or ptr */
3591 /*-----------------------------------------------------------------*/
3592 set * lvaluereqSet = NULL;
3593 typedef struct lvalItem
3600 /*-----------------------------------------------------------------*/
3601 /* addLvaluereq - add a flag for lvalreq for current ast level */
3602 /*-----------------------------------------------------------------*/
3603 void addLvaluereq(int lvl)
3605 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3608 addSetHead(&lvaluereqSet,lpItem);
3611 /*-----------------------------------------------------------------*/
3612 /* delLvaluereq - del a flag for lvalreq for current ast level */
3613 /*-----------------------------------------------------------------*/
3617 lpItem = getSet(&lvaluereqSet);
3618 if(lpItem) Safe_free(lpItem);
3620 /*-----------------------------------------------------------------*/
3621 /* clearLvaluereq - clear lvalreq flag */
3622 /*-----------------------------------------------------------------*/
3623 void clearLvaluereq()
3626 lpItem = peekSet(lvaluereqSet);
3627 if(lpItem) lpItem->req = 0;
3629 /*-----------------------------------------------------------------*/
3630 /* getLvaluereq - get the last lvalreq level */
3631 /*-----------------------------------------------------------------*/
3632 int getLvaluereqLvl()
3635 lpItem = peekSet(lvaluereqSet);
3636 if(lpItem) return lpItem->lvl;
3639 /*-----------------------------------------------------------------*/
3640 /* isLvaluereq - is lvalreq valid for this level ? */
3641 /*-----------------------------------------------------------------*/
3642 int isLvaluereq(int lvl)
3645 lpItem = peekSet(lvaluereqSet);
3646 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3650 /*-----------------------------------------------------------------*/
3651 /* ast2iCode - creates an icodeList from an ast */
3652 /*-----------------------------------------------------------------*/
3654 ast2iCode (ast * tree,int lvl)
3656 operand *left = NULL;
3657 operand *right = NULL;
3661 /* set the global variables for filename & line number */
3663 filename = tree->filename;
3665 lineno = tree->lineno;
3667 block = tree->block;
3669 scopeLevel = tree->level;
3671 seqPoint = tree->seqPoint;
3673 if (tree->type == EX_VALUE)
3674 return operandFromValue (tree->opval.val);
3676 if (tree->type == EX_LINK)
3677 return operandFromLink (tree->opval.lnk);
3679 /* if we find a nullop */
3680 if (tree->type == EX_OP &&
3681 (tree->opval.op == NULLOP ||
3682 tree->opval.op == BLOCK))
3684 if (tree->left && tree->left->type == EX_VALUE)
3685 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3687 ast2iCode (tree->left,lvl+1);
3688 if (tree->right && tree->right->type == EX_VALUE)
3689 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3691 ast2iCode (tree->right,lvl+1);
3695 /* special cases for not evaluating */
3696 if (tree->opval.op != ':' &&
3697 tree->opval.op != '?' &&
3698 tree->opval.op != CALL &&
3699 tree->opval.op != IFX &&
3700 tree->opval.op != LABEL &&
3701 tree->opval.op != GOTO &&
3702 tree->opval.op != SWITCH &&
3703 tree->opval.op != FUNCTION &&
3704 tree->opval.op != INLINEASM &&
3705 tree->opval.op != CRITICAL)
3708 if (IS_ASSIGN_OP (tree->opval.op) ||
3709 IS_DEREF_OP (tree) ||
3710 (tree->opval.op == '&' && !tree->right) ||
3711 tree->opval.op == PTR_OP)
3714 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3715 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3718 left = operandFromAst (tree->left,lvl);
3720 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3721 left = geniCodeRValue (left, TRUE);
3725 left = operandFromAst (tree->left,lvl);
3727 if (tree->opval.op == INC_OP ||
3728 tree->opval.op == DEC_OP)
3731 right = operandFromAst (tree->right,lvl);
3736 right = operandFromAst (tree->right,lvl);
3740 /* now depending on the type of operand */
3741 /* this will be a biggy */
3742 switch (tree->opval.op)
3745 case '[': /* array operation */
3747 //sym_link *ltype = operandType (left);
3748 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3749 left = geniCodeRValue (left, FALSE);
3750 right = geniCodeRValue (right, TRUE);
3753 return geniCodeArray (left, right,lvl);
3755 case '.': /* structure dereference */
3756 if (IS_PTR (operandType (left)))
3757 left = geniCodeRValue (left, TRUE);
3759 left = geniCodeRValue (left, FALSE);
3761 return geniCodeStruct (left, right, tree->lvalue);
3763 case PTR_OP: /* structure pointer dereference */
3766 pType = operandType (left);
3767 left = geniCodeRValue (left, TRUE);
3769 setOClass (pType, getSpec (operandType (left)));
3772 return geniCodeStruct (left, right, tree->lvalue);
3774 case INC_OP: /* increment operator */
3776 return geniCodePostInc (left);
3778 return geniCodePreInc (right, tree->lvalue);
3780 case DEC_OP: /* decrement operator */
3782 return geniCodePostDec (left);
3784 return geniCodePreDec (right, tree->lvalue);
3786 case '&': /* bitwise and or address of operator */
3788 { /* this is a bitwise operator */
3789 left = geniCodeRValue (left, FALSE);
3790 right = geniCodeRValue (right, FALSE);
3791 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3794 return geniCodeAddressOf (left);
3796 case '|': /* bitwise or & xor */
3798 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3799 geniCodeRValue (right, FALSE),
3804 return geniCodeDivision (geniCodeRValue (left, FALSE),
3805 geniCodeRValue (right, FALSE));
3808 return geniCodeModulus (geniCodeRValue (left, FALSE),
3809 geniCodeRValue (right, FALSE));
3812 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3813 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3815 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3819 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3820 geniCodeRValue (right, FALSE));
3822 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3826 return geniCodeAdd (geniCodeRValue (left, FALSE),
3827 geniCodeRValue (right, FALSE),lvl);
3829 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3832 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3833 geniCodeRValue (right, FALSE));
3836 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3837 geniCodeRValue (right, FALSE));
3839 #if 0 // this indeed needs a second thought
3843 // let's keep this simple: get the rvalue we need
3844 op=geniCodeRValue (right, FALSE);
3845 // now cast it to whatever we want
3846 op=geniCodeCast (operandType(left), op, FALSE);
3847 // if this is going to be used as an lvalue, make it so
3853 #else // bug #604575, is it a bug ????
3854 return geniCodeCast (operandType (left),
3855 geniCodeRValue (right, FALSE), FALSE);
3862 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3867 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3868 setOperandType (op, UCHARTYPE);
3879 /* different compilers (even different gccs) evaluate
3880 the two calls in a different order. to get the same
3881 result on all machines we've to specify a clear sequence.
3882 return geniCodeLogic (geniCodeRValue (left, FALSE),
3883 geniCodeRValue (right, FALSE),
3887 operand *leftOp, *rightOp;
3889 rightOp = geniCodeRValue (right, FALSE);
3890 leftOp = geniCodeRValue (left , FALSE);
3892 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3895 return geniCodeConditional (tree,lvl);
3898 return operandFromLit (getSize (tree->right->ftype));
3902 sym_link *rtype = operandType (right);
3903 sym_link *ltype = operandType (left);
3904 if (IS_PTR (rtype) && IS_ITEMP (right)
3905 && right->isaddr && compareType (rtype->next, ltype) == 1)
3906 right = geniCodeRValue (right, TRUE);
3908 right = geniCodeRValue (right, FALSE);
3910 geniCodeAssign (left, right, 0);
3915 geniCodeAssign (left,
3916 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3918 geniCodeRValue (right, FALSE),FALSE), 0);
3922 geniCodeAssign (left,
3923 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3925 geniCodeRValue (right, FALSE)), 0);
3928 geniCodeAssign (left,
3929 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3931 geniCodeRValue (right, FALSE)), 0);
3934 sym_link *rtype = operandType (right);
3935 sym_link *ltype = operandType (left);
3936 if (IS_PTR (rtype) && IS_ITEMP (right)
3937 && right->isaddr && compareType (rtype->next, ltype) == 1)
3938 right = geniCodeRValue (right, TRUE);
3940 right = geniCodeRValue (right, FALSE);
3943 return geniCodeAssign (left,
3944 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3950 sym_link *rtype = operandType (right);
3951 sym_link *ltype = operandType (left);
3952 if (IS_PTR (rtype) && IS_ITEMP (right)
3953 && right->isaddr && compareType (rtype->next, ltype) == 1)
3955 right = geniCodeRValue (right, TRUE);
3959 right = geniCodeRValue (right, FALSE);
3962 geniCodeAssign (left,
3963 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3969 geniCodeAssign (left,
3970 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3972 geniCodeRValue (right, FALSE)), 0);
3975 geniCodeAssign (left,
3976 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3978 geniCodeRValue (right, FALSE)), 0);
3981 geniCodeAssign (left,
3982 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3984 geniCodeRValue (right, FALSE),
3986 operandType (left)), 0);
3989 geniCodeAssign (left,
3990 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3992 geniCodeRValue (right, FALSE),
3994 operandType (left)), 0);
3997 geniCodeAssign (left,
3998 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4000 geniCodeRValue (right, FALSE),
4002 operandType (left)), 0);
4004 return geniCodeRValue (right, FALSE);
4007 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4010 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4011 return ast2iCode (tree->right,lvl+1);
4014 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4015 return ast2iCode (tree->right,lvl+1);
4018 geniCodeFunctionBody (tree,lvl);
4022 geniCodeReturn (right);
4026 geniCodeIfx (tree,lvl);
4030 geniCodeSwitch (tree,lvl);
4034 geniCodeInline (tree);
4038 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4042 geniCodeCritical (tree, lvl);
4048 /*-----------------------------------------------------------------*/
4049 /* reverseICChain - gets from the list and creates a linkedlist */
4050 /*-----------------------------------------------------------------*/
4057 while ((loop = getSet (&iCodeChain)))
4069 /*-----------------------------------------------------------------*/
4070 /* iCodeFromAst - given an ast will convert it to iCode */
4071 /*-----------------------------------------------------------------*/
4073 iCodeFromAst (ast * tree)
4075 returnLabel = newiTempLabel ("_return");
4076 entryLabel = newiTempLabel ("_entry");
4078 return reverseiCChain ();
4081 static const char *opTypeToStr(OPTYPE op)
4085 case SYMBOL: return "symbol";
4086 case VALUE: return "value";
4087 case TYPE: return "type";
4089 return "undefined type";
4093 operand *validateOpType(operand *op,
4100 if (op && op->type == type)
4105 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4106 " expected %s, got %s\n",
4107 macro, args, file, line,
4108 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4110 return op; // never reached, makes compiler happy.