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 the operand is already the desired type then do nothing */
1866 if (compareType (type, optype) == 1)
1869 /* if this is a literal then just change the type & return */
1870 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1872 return operandFromValue (valCastLiteral (type,
1873 operandLitValue (op)));
1876 /* if casting to/from pointers, do some checking */
1877 if (IS_PTR(type)) { // to a pointer
1878 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1879 if (IS_INTEGRAL(optype)) {
1880 // maybe this is NULL, than it's ok.
1881 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1882 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1883 // no way to set the storage
1884 if (IS_LITERAL(optype)) {
1885 werror(E_LITERAL_GENERIC);
1888 werror(E_NONPTR2_GENPTR);
1891 } else if (implicit) {
1892 werror(W_INTEGRAL2PTR_NOCAST);
1897 // shouldn't do that with float, array or structure unless to void
1898 if (!IS_VOID(getSpec(type)) &&
1899 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1900 werror(E_INCOMPAT_TYPES);
1904 } else { // from a pointer to a pointer
1905 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1906 // if not a pointer to a function
1907 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1908 if (implicit) { // if not to generic, they have to match
1909 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1910 werror(E_INCOMPAT_PTYPES);
1917 } else { // to a non pointer
1918 if (IS_PTR(optype)) { // from a pointer
1919 if (implicit) { // sneaky
1920 if (IS_INTEGRAL(type)) {
1921 werror(W_PTR2INTEGRAL_NOCAST);
1923 } else { // shouldn't do that with float, array or structure
1924 werror(E_INCOMPAT_TYPES);
1931 printFromToType (optype, type);
1934 /* if they are the same size create an assignment */
1936 /* This seems very dangerous to me, since there are several */
1937 /* optimizations (for example, gcse) that don't notice the */
1938 /* cast hidden in this assignement and may simplify an */
1939 /* iCode to use the original (uncasted) operand. */
1940 /* Unfortunately, other things break when this cast is */
1941 /* made explicit. Need to fix this someday. */
1942 /* -- EEP, 2004/01/21 */
1943 if (getSize (type) == getSize (optype) &&
1944 !IS_BITFIELD (type) &&
1946 !IS_FLOAT (optype) &&
1947 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1948 (!IS_SPEC (type) && !IS_SPEC (optype))))
1950 ic = newiCode ('=', NULL, op);
1951 IC_RESULT (ic) = newiTempOperand (type, 0);
1952 SPIL_LOC (IC_RESULT (ic)) =
1953 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1954 IC_RESULT (ic)->isaddr = 0;
1958 ic = newiCode (CAST, operandFromLink (type),
1959 geniCodeRValue (op, FALSE));
1961 IC_RESULT (ic) = newiTempOperand (type, 0);
1964 /* preserve the storage class & output class */
1965 /* of the original variable */
1966 restype = getSpec (operandType (IC_RESULT (ic)));
1967 if (!IS_LITERAL(opetype))
1968 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1969 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1972 return IC_RESULT (ic);
1975 /*-----------------------------------------------------------------*/
1976 /* geniCodeLabel - will create a Label */
1977 /*-----------------------------------------------------------------*/
1979 geniCodeLabel (symbol * label)
1983 ic = newiCodeLabelGoto (LABEL, label);
1987 /*-----------------------------------------------------------------*/
1988 /* geniCodeGoto - will create a Goto */
1989 /*-----------------------------------------------------------------*/
1991 geniCodeGoto (symbol * label)
1995 ic = newiCodeLabelGoto (GOTO, label);
1999 /*-----------------------------------------------------------------*/
2000 /* geniCodeMultiply - gen intermediate code for multiplication */
2001 /*-----------------------------------------------------------------*/
2003 geniCodeMultiply (operand * left, operand * right, int resultIsInt)
2010 /* if they are both literal then we know the result */
2011 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2012 return operandFromValue (valMult (left->operand.valOperand,
2013 right->operand.valOperand));
2015 if (IS_LITERAL(retype)) {
2016 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2019 resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE);
2021 rtype = operandType (right);
2022 retype = getSpec (rtype);
2023 ltype = operandType (left);
2024 letype = getSpec (ltype);
2027 /* if the right is a literal & power of 2 */
2028 /* then make it a left shift */
2029 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2030 efficient in most cases than 2 bytes result = 2 bytes << literal
2031 if port has 1 byte muldiv */
2032 if (p2 && !IS_FLOAT (letype) &&
2033 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
2034 (port->support.muldiv == 1)))
2036 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2038 /* LEFT_OP need same size for left and result, */
2039 left = geniCodeCast (resType, left, TRUE);
2040 ltype = operandType (left);
2042 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2046 ic = newiCode ('*', left, right); /* normal multiplication */
2047 /* if the size left or right > 1 then support routine */
2048 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2052 IC_RESULT (ic) = newiTempOperand (resType, 1);
2055 return IC_RESULT (ic);
2058 /*-----------------------------------------------------------------*/
2059 /* geniCodeDivision - gen intermediate code for division */
2060 /*-----------------------------------------------------------------*/
2062 geniCodeDivision (operand * left, operand * right)
2067 sym_link *rtype = operandType (right);
2068 sym_link *retype = getSpec (rtype);
2069 sym_link *ltype = operandType (left);
2070 sym_link *letype = getSpec (ltype);
2072 resType = usualBinaryConversions (&left, &right,
2073 (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2076 /* if the right is a literal & power of 2
2077 and left is unsigned then make it a
2079 if (IS_LITERAL (retype) &&
2080 !IS_FLOAT (letype) &&
2081 IS_UNSIGNED(letype) &&
2082 (p2 = powof2 ((TYPE_UDWORD)
2083 floatFromVal (right->operand.valOperand)))) {
2084 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2088 ic = newiCode ('/', left, right); /* normal division */
2089 /* if the size left or right > 1 then support routine */
2090 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2093 IC_RESULT (ic) = newiTempOperand (resType, 0);
2096 return IC_RESULT (ic);
2098 /*-----------------------------------------------------------------*/
2099 /* geniCodeModulus - gen intermediate code for modulus */
2100 /*-----------------------------------------------------------------*/
2102 geniCodeModulus (operand * left, operand * right)
2108 /* if they are both literal then we know the result */
2109 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2110 return operandFromValue (valMod (left->operand.valOperand,
2111 right->operand.valOperand));
2113 resType = usualBinaryConversions (&left, &right,
2114 (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2117 /* now they are the same size */
2118 ic = newiCode ('%', left, right);
2120 /* if the size left or right > 1 then support routine */
2121 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2123 IC_RESULT (ic) = newiTempOperand (resType, 0);
2126 return IC_RESULT (ic);
2129 /*-----------------------------------------------------------------*/
2130 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2131 /*-----------------------------------------------------------------*/
2133 geniCodePtrPtrSubtract (operand * left, operand * right)
2139 /* if they are both literals then */
2140 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2142 result = operandFromValue (valMinus (left->operand.valOperand,
2143 right->operand.valOperand));
2147 ic = newiCode ('-', left, right);
2149 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2153 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2157 // should we really do this? is this ANSI?
2158 return geniCodeDivision (result,
2159 operandFromLit (getSize (ltype->next)));
2162 /*-----------------------------------------------------------------*/
2163 /* geniCodeSubtract - generates code for subtraction */
2164 /*-----------------------------------------------------------------*/
2166 geniCodeSubtract (operand * left, operand * right)
2173 /* if they both pointers then */
2174 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2175 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2176 return geniCodePtrPtrSubtract (left, right);
2178 /* if they are both literal then we know the result */
2179 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2180 && left->isLiteral && right->isLiteral)
2181 return operandFromValue (valMinus (left->operand.valOperand,
2182 right->operand.valOperand));
2184 /* if left is an array or pointer */
2185 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2187 isarray = left->isaddr;
2188 right = geniCodeMultiply (right,
2189 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2190 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2193 { /* make them the same size */
2194 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2197 ic = newiCode ('-', left, right);
2199 IC_RESULT (ic) = newiTempOperand (resType, 1);
2200 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2202 /* if left or right is a float */
2203 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2207 return IC_RESULT (ic);
2210 /*-----------------------------------------------------------------*/
2211 /* geniCodeAdd - generates iCode for addition */
2212 /*-----------------------------------------------------------------*/
2214 geniCodeAdd (operand * left, operand * right, int lvl)
2223 /* if the right side is LITERAL zero */
2224 /* return the left side */
2225 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2228 /* if left is literal zero return right */
2229 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2232 /* if left is a pointer then size */
2233 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2235 isarray = left->isaddr;
2236 // there is no need to multiply with 1
2237 if (getSize (ltype->next) != 1)
2239 size = operandFromLit (getSize (ltype->next));
2240 SPEC_USIGN (getSpec (operandType (size))) = 1;
2241 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2242 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2243 /* Even if right is a 'unsigned char',
2244 the result will be a 'signed int' due to the promotion rules.
2245 It doesn't make sense when accessing arrays, so let's fix it here: */
2247 SPEC_USIGN (getSpec (operandType (right))) = 1;
2249 resType = copyLinkChain (ltype);
2252 { // make them the same size
2253 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2256 /* if they are both literals then we know */
2257 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2258 && left->isLiteral && right->isLiteral)
2259 return operandFromValue (valPlus (valFromType (ltype),
2260 valFromType (rtype)));
2262 ic = newiCode ('+', left, right);
2264 IC_RESULT (ic) = newiTempOperand (resType, 1);
2265 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2267 /* if left or right is a float then support
2269 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2274 return IC_RESULT (ic);
2278 /*-----------------------------------------------------------------*/
2279 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2280 /*-----------------------------------------------------------------*/
2282 aggrToPtr (sym_link * type, bool force)
2287 if (IS_PTR (type) && !force)
2290 etype = getSpec (type);
2291 ptype = newLink (DECLARATOR);
2295 /* set the pointer depending on the storage class */
2296 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2300 /*-----------------------------------------------------------------*/
2301 /* geniCodeArray2Ptr - array to pointer */
2302 /*-----------------------------------------------------------------*/
2304 geniCodeArray2Ptr (operand * op)
2306 sym_link *optype = operandType (op);
2307 sym_link *opetype = getSpec (optype);
2309 /* set the pointer depending on the storage class */
2310 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2317 /*-----------------------------------------------------------------*/
2318 /* geniCodeArray - array access */
2319 /*-----------------------------------------------------------------*/
2321 geniCodeArray (operand * left, operand * right, int lvl)
2325 sym_link *ltype = operandType (left);
2330 if (IS_PTR (ltype->next) && left->isaddr)
2332 left = geniCodeRValue (left, FALSE);
2335 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2337 size = operandFromLit (getSize (ltype->next));
2338 SPEC_USIGN (getSpec (operandType (size))) = 1;
2339 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2340 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2341 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2342 It doesn't make sense when accessing arrays, so let's fix it here: */
2344 SPEC_USIGN (getSpec (operandType (right))) = 1;
2345 /* we can check for limits here */
2346 /* already done in SDCCast.c
2347 if (isOperandLiteral (right) &&
2350 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2352 werror (W_IDX_OUT_OF_BOUNDS,
2353 (int) operandLitValue (right) / getSize (ltype->next),
2358 ic = newiCode ('+', left, right);
2360 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2361 !IS_AGGREGATE (ltype->next) &&
2362 !IS_PTR (ltype->next))
2363 ? ltype : ltype->next), 0);
2365 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2368 return IC_RESULT (ic);
2371 /*-----------------------------------------------------------------*/
2372 /* geniCodeStruct - generates intermediate code for structures */
2373 /*-----------------------------------------------------------------*/
2375 geniCodeStruct (operand * left, operand * right, bool islval)
2378 sym_link *type = operandType (left);
2379 sym_link *etype = getSpec (type);
2381 symbol *element = getStructElement (SPEC_STRUCT (etype),
2382 right->operand.symOperand);
2384 wassert(IS_SYMOP(right));
2386 /* add the offset */
2387 ic = newiCode ('+', left, operandFromLit (element->offset));
2389 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2391 /* preserve the storage & output class of the struct */
2392 /* as well as the volatile attribute */
2393 retype = getSpec (operandType (IC_RESULT (ic)));
2394 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2395 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2396 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2397 SPEC_CONST (retype) |= SPEC_CONST (etype);
2399 if (IS_PTR (element->type))
2400 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2402 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2405 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2408 /*-----------------------------------------------------------------*/
2409 /* geniCodePostInc - generate int code for Post increment */
2410 /*-----------------------------------------------------------------*/
2412 geniCodePostInc (operand * op)
2416 sym_link *optype = operandType (op);
2418 operand *rv = (IS_ITEMP (op) ?
2419 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2421 sym_link *rvtype = operandType (rv);
2424 /* if this is not an address we have trouble */
2427 werror (E_LVALUE_REQUIRED, "++");
2431 rOp = newiTempOperand (rvtype, 0);
2432 OP_SYMBOL(rOp)->noSpilLoc = 1;
2435 OP_SYMBOL(rv)->noSpilLoc = 1;
2437 geniCodeAssign (rOp, rv, 0);
2439 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2440 if (IS_FLOAT (rvtype))
2441 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2443 ic = newiCode ('+', rv, operandFromLit (size));
2445 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2448 geniCodeAssign (op, result, 0);
2454 /*-----------------------------------------------------------------*/
2455 /* geniCodePreInc - generate code for preIncrement */
2456 /*-----------------------------------------------------------------*/
2458 geniCodePreInc (operand * op, bool lvalue)
2461 sym_link *optype = operandType (op);
2462 operand *rop = (IS_ITEMP (op) ?
2463 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2465 sym_link *roptype = operandType (rop);
2471 werror (E_LVALUE_REQUIRED, "++");
2476 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2477 if (IS_FLOAT (roptype))
2478 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2480 ic = newiCode ('+', rop, operandFromLit (size));
2481 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2484 (void) geniCodeAssign (op, result, 0);
2485 if (lvalue || IS_TRUE_SYMOP (op))
2491 /*-----------------------------------------------------------------*/
2492 /* geniCodePostDec - generates code for Post decrement */
2493 /*-----------------------------------------------------------------*/
2495 geniCodePostDec (operand * op)
2499 sym_link *optype = operandType (op);
2501 operand *rv = (IS_ITEMP (op) ?
2502 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2504 sym_link *rvtype = operandType (rv);
2507 /* if this is not an address we have trouble */
2510 werror (E_LVALUE_REQUIRED, "--");
2514 rOp = newiTempOperand (rvtype, 0);
2515 OP_SYMBOL(rOp)->noSpilLoc = 1;
2518 OP_SYMBOL(rv)->noSpilLoc = 1;
2520 geniCodeAssign (rOp, rv, 0);
2522 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2523 if (IS_FLOAT (rvtype))
2524 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2526 ic = newiCode ('-', rv, operandFromLit (size));
2528 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2531 geniCodeAssign (op, result, 0);
2537 /*-----------------------------------------------------------------*/
2538 /* geniCodePreDec - generate code for pre decrement */
2539 /*-----------------------------------------------------------------*/
2541 geniCodePreDec (operand * op, bool lvalue)
2544 sym_link *optype = operandType (op);
2545 operand *rop = (IS_ITEMP (op) ?
2546 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2548 sym_link *roptype = operandType (rop);
2554 werror (E_LVALUE_REQUIRED, "--");
2559 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2560 if (IS_FLOAT (roptype))
2561 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2563 ic = newiCode ('-', rop, operandFromLit (size));
2564 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2567 (void) geniCodeAssign (op, result, 0);
2568 if (lvalue || IS_TRUE_SYMOP (op))
2575 /*-----------------------------------------------------------------*/
2576 /* geniCodeBitwise - gen int code for bitWise operators */
2577 /*-----------------------------------------------------------------*/
2579 geniCodeBitwise (operand * left, operand * right,
2580 int oper, sym_link * resType)
2584 left = geniCodeCast (resType, left, TRUE);
2585 right = geniCodeCast (resType, right, TRUE);
2587 ic = newiCode (oper, left, right);
2588 IC_RESULT (ic) = newiTempOperand (resType, 0);
2591 return IC_RESULT (ic);
2594 /*-----------------------------------------------------------------*/
2595 /* geniCodeAddressOf - gens icode for '&' address of operator */
2596 /*-----------------------------------------------------------------*/
2598 geniCodeAddressOf (operand * op)
2602 sym_link *optype = operandType (op);
2603 sym_link *opetype = getSpec (optype);
2605 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2607 op = operandFromOperand (op);
2612 /* lvalue check already done in decorateType */
2613 /* this must be a lvalue */
2614 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2615 /* werror (E_LVALUE_REQUIRED,"&"); */
2619 p = newLink (DECLARATOR);
2621 /* set the pointer depending on the storage class */
2622 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2624 p->next = copyLinkChain (optype);
2626 /* if already a temp */
2629 setOperandType (op, p);
2634 /* other wise make this of the type coming in */
2635 ic = newiCode (ADDRESS_OF, op, NULL);
2636 IC_RESULT (ic) = newiTempOperand (p, 1);
2637 IC_RESULT (ic)->isaddr = 0;
2639 return IC_RESULT (ic);
2641 /*-----------------------------------------------------------------*/
2642 /* setOClass - sets the output class depending on the pointer type */
2643 /*-----------------------------------------------------------------*/
2645 setOClass (sym_link * ptr, sym_link * spec)
2647 switch (DCL_TYPE (ptr))
2650 SPEC_OCLS (spec) = data;
2654 SPEC_OCLS (spec) = generic;
2658 SPEC_OCLS (spec) = xdata;
2662 SPEC_OCLS (spec) = code;
2666 SPEC_OCLS (spec) = idata;
2670 SPEC_OCLS (spec) = xstack;
2674 SPEC_OCLS (spec) = eeprom;
2683 /*-----------------------------------------------------------------*/
2684 /* geniCodeDerefPtr - dereference pointer with '*' */
2685 /*-----------------------------------------------------------------*/
2687 geniCodeDerefPtr (operand * op,int lvl)
2689 sym_link *rtype, *retype;
2690 sym_link *optype = operandType (op);
2692 // if this is an array then array access
2693 if (IS_ARRAY (optype)) {
2694 // don't worry, this will be optimized out later
2695 return geniCodeArray (op, operandFromLit (0), lvl);
2698 // just in case someone screws up
2699 wassert (IS_PTR (optype));
2701 if (IS_TRUE_SYMOP (op))
2704 op = geniCodeRValue (op, TRUE);
2707 /* now get rid of the pointer part */
2708 if (isLvaluereq(lvl) && IS_ITEMP (op))
2710 retype = getSpec (rtype = copyLinkChain (optype));
2714 retype = getSpec (rtype = copyLinkChain (optype->next));
2715 /* outputclass needs 2b updated */
2716 setOClass (optype, retype);
2719 op->isGptr = IS_GENPTR (optype);
2721 op->isaddr = (IS_PTR (rtype) ||
2722 IS_STRUCT (rtype) ||
2727 if (!isLvaluereq(lvl))
2728 op = geniCodeRValue (op, TRUE);
2730 setOperandType (op, rtype);
2735 /*-----------------------------------------------------------------*/
2736 /* geniCodeUnaryMinus - does a unary minus of the operand */
2737 /*-----------------------------------------------------------------*/
2739 geniCodeUnaryMinus (operand * op)
2742 sym_link *optype = operandType (op);
2744 if (IS_LITERAL (optype))
2745 return operandFromLit (-floatFromVal (op->operand.valOperand));
2747 ic = newiCode (UNARYMINUS, op, NULL);
2748 IC_RESULT (ic) = newiTempOperand (optype, 0);
2750 return IC_RESULT (ic);
2753 /*-----------------------------------------------------------------*/
2754 /* geniCodeLeftShift - gen i code for left shift */
2755 /*-----------------------------------------------------------------*/
2757 geniCodeLeftShift (operand * left, operand * right)
2761 ic = newiCode (LEFT_OP, left, right);
2762 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2764 return IC_RESULT (ic);
2767 /*-----------------------------------------------------------------*/
2768 /* geniCodeRightShift - gen i code for right shift */
2769 /*-----------------------------------------------------------------*/
2771 geniCodeRightShift (operand * left, operand * right)
2775 ic = newiCode (RIGHT_OP, left, right);
2776 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2778 return IC_RESULT (ic);
2781 /*-----------------------------------------------------------------*/
2782 /* geniCodeLogic- logic code */
2783 /*-----------------------------------------------------------------*/
2785 geniCodeLogic (operand * left, operand * right, int op)
2789 sym_link *rtype = operandType (right);
2790 sym_link *ltype = operandType (left);
2792 /* left is integral type and right is literal then
2793 check if the literal value is within bounds */
2794 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2796 checkConstantRange(ltype,
2797 OP_VALUE(right), "compare operation", 1);
2800 /* if one operand is a pointer and the other is a literal generic void pointer,
2801 change the type of the literal generic void pointer to match the other pointer */
2802 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2803 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2805 /* find left's definition */
2806 ic = (iCode *) setFirstItem (iCodeChain);
2809 if (((ic->op == CAST) || (ic->op == '='))
2810 && isOperandEqual(left, IC_RESULT (ic)))
2813 ic = setNextItem (iCodeChain);
2815 /* if casting literal to generic pointer, then cast to rtype instead */
2816 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2818 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2819 ltype = operandType(left);
2822 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2823 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2825 /* find right's definition */
2826 ic = (iCode *) setFirstItem (iCodeChain);
2829 if (((ic->op == CAST) || (ic->op == '='))
2830 && isOperandEqual(right, IC_RESULT (ic)))
2833 ic = setNextItem (iCodeChain);
2835 /* if casting literal to generic pointer, then cast to rtype instead */
2836 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2838 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2839 rtype = operandType(right);
2843 ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
2845 ic = newiCode (op, left, right);
2846 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2848 /* if comparing float
2849 and not a '==' || '!=' || '&&' || '||' (these
2851 if (IS_FLOAT(ctype) &&
2859 return IC_RESULT (ic);
2862 /*-----------------------------------------------------------------*/
2863 /* geniCodeUnary - for a a generic unary operation */
2864 /*-----------------------------------------------------------------*/
2866 geniCodeUnary (operand * op, int oper)
2868 iCode *ic = newiCode (oper, op, NULL);
2870 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2872 return IC_RESULT (ic);
2875 /*-----------------------------------------------------------------*/
2876 /* geniCodeConditional - geniCode for '?' ':' operation */
2877 /*-----------------------------------------------------------------*/
2879 geniCodeConditional (ast * tree,int lvl)
2882 symbol *falseLabel = newiTempLabel (NULL);
2883 symbol *exitLabel = newiTempLabel (NULL);
2884 operand *cond = ast2iCode (tree->left,lvl+1);
2885 operand *true, *false, *result;
2887 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2891 true = ast2iCode (tree->right->left,lvl+1);
2893 /* move the value to a new Operand */
2894 result = newiTempOperand (tree->right->ftype, 0);
2895 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2897 /* generate an unconditional goto */
2898 geniCodeGoto (exitLabel);
2900 /* now for the right side */
2901 geniCodeLabel (falseLabel);
2903 false = ast2iCode (tree->right->right,lvl+1);
2904 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2906 /* create the exit label */
2907 geniCodeLabel (exitLabel);
2912 /*-----------------------------------------------------------------*/
2913 /* geniCodeAssign - generate code for assignment */
2914 /*-----------------------------------------------------------------*/
2916 geniCodeAssign (operand * left, operand * right, int nosupdate)
2919 sym_link *ltype = operandType (left);
2920 sym_link *rtype = operandType (right);
2922 if (!left->isaddr && !IS_ITEMP (left))
2924 werror (E_LVALUE_REQUIRED, "assignment");
2928 /* left is integral type and right is literal then
2929 check if the literal value is within bounds */
2930 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2932 checkConstantRange(ltype,
2933 OP_VALUE(right), "= operation", 0);
2936 /* if the left & right type don't exactly match */
2937 /* if pointer set then make sure the check is
2938 done with the type & not the pointer */
2939 /* then cast rights type to left */
2941 /* first check the type for pointer assignement */
2942 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2943 compareType (ltype, rtype) <= 0)
2945 if (compareType (ltype->next, rtype) < 0)
2946 right = geniCodeCast (ltype->next, right, TRUE);
2948 else if (compareType (ltype, rtype) < 0)
2949 right = geniCodeCast (ltype, right, TRUE);
2951 /* If left is a true symbol & ! volatile
2952 create an assignment to temporary for
2953 the right & then assign this temporary
2954 to the symbol. This is SSA (static single
2955 assignment). Isn't it simple and folks have
2956 published mountains of paper on it */
2957 if (IS_TRUE_SYMOP (left) &&
2958 !isOperandVolatile (left, FALSE) &&
2959 isOperandGlobal (left))
2963 if (IS_TRUE_SYMOP (right))
2964 sym = OP_SYMBOL (right);
2965 ic = newiCode ('=', NULL, right);
2966 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2967 SPIL_LOC (right) = sym;
2971 ic = newiCode ('=', NULL, right);
2972 IC_RESULT (ic) = left;
2975 /* if left isgptr flag is set then support
2976 routine will be required */
2980 ic->nosupdate = nosupdate;
2984 /*-----------------------------------------------------------------*/
2985 /* geniCodeDummyRead - generate code for dummy read */
2986 /*-----------------------------------------------------------------*/
2988 geniCodeDummyRead (operand * op)
2991 sym_link *type = operandType (op);
2993 if (!IS_VOLATILE(type))
2996 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3002 /*-----------------------------------------------------------------*/
3003 /* geniCodeSEParms - generate code for side effecting fcalls */
3004 /*-----------------------------------------------------------------*/
3006 geniCodeSEParms (ast * parms,int lvl)
3011 if (parms->type == EX_OP && parms->opval.op == PARAM)
3013 geniCodeSEParms (parms->left,lvl);
3014 geniCodeSEParms (parms->right,lvl);
3018 /* hack don't like this but too lazy to think of
3020 if (IS_ADDRESS_OF_OP (parms))
3021 parms->left->lvalue = 1;
3023 if (IS_CAST_OP (parms) &&
3024 IS_PTR (parms->ftype) &&
3025 IS_ADDRESS_OF_OP (parms->right))
3026 parms->right->left->lvalue = 1;
3028 parms->opval.oprnd =
3029 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3031 parms->type = EX_OPERAND;
3032 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3033 SPEC_ARGREG(parms->ftype);
3036 /*-----------------------------------------------------------------*/
3037 /* geniCodeParms - generates parameters */
3038 /*-----------------------------------------------------------------*/
3040 geniCodeParms (ast * parms, value *argVals, int *stack,
3041 sym_link * fetype, symbol * func,int lvl)
3049 if (argVals==NULL) {
3051 if (IS_CODEPTR(func->type))
3052 argVals = FUNC_ARGS (func->type->next);
3054 argVals = FUNC_ARGS (func->type);
3057 /* if this is a param node then do the left & right */
3058 if (parms->type == EX_OP && parms->opval.op == PARAM)
3060 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
3061 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
3065 /* get the parameter value */
3066 if (parms->type == EX_OPERAND)
3067 pval = parms->opval.oprnd;
3070 /* maybe this else should go away ?? */
3071 /* hack don't like this but too lazy to think of
3073 if (IS_ADDRESS_OF_OP (parms))
3074 parms->left->lvalue = 1;
3076 if (IS_CAST_OP (parms) &&
3077 IS_PTR (parms->ftype) &&
3078 IS_ADDRESS_OF_OP (parms->right))
3079 parms->right->left->lvalue = 1;
3081 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3084 /* if register parm then make it a send */
3085 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
3086 IFFUNC_ISBUILTIN(func->type))
3088 ic = newiCode (SEND, pval, NULL);
3089 ic->argreg = SPEC_ARGREG(parms->etype);
3090 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
3095 /* now decide whether to push or assign */
3096 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
3100 operand *top = operandFromSymbol (argVals->sym);
3101 /* clear useDef and other bitVectors */
3102 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3103 geniCodeAssign (top, pval, 1);
3107 sym_link *p = operandType (pval);
3109 ic = newiCode (IPUSH, pval, NULL);
3111 /* update the stack adjustment */
3112 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3117 argVals=argVals->next;
3121 /*-----------------------------------------------------------------*/
3122 /* geniCodeCall - generates temp code for calling */
3123 /*-----------------------------------------------------------------*/
3125 geniCodeCall (operand * left, ast * parms,int lvl)
3129 sym_link *type, *etype;
3132 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3133 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3134 werror (E_FUNCTION_EXPECTED);
3135 return operandFromValue(valueFromLit(0));
3138 /* take care of parameters with side-effecting
3139 function calls in them, this is required to take care
3140 of overlaying function parameters */
3141 geniCodeSEParms (parms,lvl);
3143 /* first the parameters */
3144 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3146 /* now call : if symbol then pcall */
3147 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3148 ic = newiCode (PCALL, left, NULL);
3150 ic = newiCode (CALL, left, NULL);
3153 type = copyLinkChain (operandType (left)->next);
3154 etype = getSpec (type);
3155 SPEC_EXTR (etype) = 0;
3156 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3160 /* stack adjustment after call */
3161 ic->parmBytes = stack;
3166 /*-----------------------------------------------------------------*/
3167 /* geniCodeReceive - generate intermediate code for "receive" */
3168 /*-----------------------------------------------------------------*/
3170 geniCodeReceive (value * args)
3172 /* for all arguments that are passed in registers */
3176 if (IS_REGPARM (args->etype))
3178 operand *opr = operandFromValue (args);
3180 symbol *sym = OP_SYMBOL (opr);
3183 /* we will use it after all optimizations
3184 and before liveRange calculation */
3185 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3188 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3189 options.stackAuto == 0 &&
3190 (!(options.model == MODEL_FLAT24)) )
3195 opl = newiTempOperand (args->type, 0);
3197 sym->reqv->key = sym->key;
3198 OP_SYMBOL (sym->reqv)->key = sym->key;
3199 OP_SYMBOL (sym->reqv)->isreqv = 1;
3200 OP_SYMBOL (sym->reqv)->islocal = 0;
3201 SPIL_LOC (sym->reqv) = sym;
3205 ic = newiCode (RECEIVE, NULL, NULL);
3206 ic->argreg = SPEC_ARGREG(args->etype);
3208 currFunc->recvSize = getSize (sym->type);
3211 IC_RESULT (ic) = opr;
3219 /*-----------------------------------------------------------------*/
3220 /* geniCodeFunctionBody - create the function body */
3221 /*-----------------------------------------------------------------*/
3223 geniCodeFunctionBody (ast * tree,int lvl)
3230 /* reset the auto generation */
3236 func = ast2iCode (tree->left,lvl+1);
3237 fetype = getSpec (operandType (func));
3239 savelineno = lineno;
3240 lineno = OP_SYMBOL (func)->lineDef;
3241 /* create an entry label */
3242 geniCodeLabel (entryLabel);
3243 lineno = savelineno;
3245 /* create a proc icode */
3246 ic = newiCode (FUNCTION, func, NULL);
3247 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3251 /* for all parameters that are passed
3252 on registers add a "receive" */
3253 geniCodeReceive (tree->values.args);
3255 /* generate code for the body */
3256 ast2iCode (tree->right,lvl+1);
3258 /* create a label for return */
3259 geniCodeLabel (returnLabel);
3261 /* now generate the end proc */
3262 ic = newiCode (ENDFUNCTION, func, NULL);
3267 /*-----------------------------------------------------------------*/
3268 /* geniCodeReturn - gen icode for 'return' statement */
3269 /*-----------------------------------------------------------------*/
3271 geniCodeReturn (operand * op)
3275 /* if the operand is present force an rvalue */
3277 op = geniCodeRValue (op, FALSE);
3279 ic = newiCode (RETURN, op, NULL);
3283 /*-----------------------------------------------------------------*/
3284 /* geniCodeIfx - generates code for extended if statement */
3285 /*-----------------------------------------------------------------*/
3287 geniCodeIfx (ast * tree,int lvl)
3290 operand *condition = ast2iCode (tree->left,lvl+1);
3293 /* if condition is null then exit */
3297 condition = geniCodeRValue (condition, FALSE);
3299 cetype = getSpec (operandType (condition));
3300 /* if the condition is a literal */
3301 if (IS_LITERAL (cetype))
3303 if (floatFromVal (condition->operand.valOperand))
3305 if (tree->trueLabel)
3306 geniCodeGoto (tree->trueLabel);
3312 if (tree->falseLabel)
3313 geniCodeGoto (tree->falseLabel);
3320 if (tree->trueLabel)
3322 ic = newiCodeCondition (condition,
3327 if (tree->falseLabel)
3328 geniCodeGoto (tree->falseLabel);
3332 ic = newiCodeCondition (condition,
3339 ast2iCode (tree->right,lvl+1);
3342 /*-----------------------------------------------------------------*/
3343 /* geniCodeJumpTable - tries to create a jump table for switch */
3344 /*-----------------------------------------------------------------*/
3346 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3348 int min = 0, max = 0, t, cnt = 0;
3354 int needRangeCheck = !optimize.noJTabBoundary
3355 || tree->values.switchVals.swDefault;
3357 if (!tree || !caseVals)
3360 /* the criteria for creating a jump table is */
3361 /* all integer numbers between the maximum & minimum must */
3362 /* be present , the maximum value should not exceed 255 */
3363 min = max = (int) floatFromVal (vch = caseVals);
3364 SNPRINTF (buffer, sizeof(buffer),
3366 tree->values.switchVals.swNum,
3368 addSet (&labels, newiTempLabel (buffer));
3370 /* if there is only one case value then no need */
3371 if (!(vch = vch->next))
3376 if (((t = (int) floatFromVal (vch)) - max) != 1)
3378 SNPRINTF (buffer, sizeof(buffer),
3380 tree->values.switchVals.swNum,
3382 addSet (&labels, newiTempLabel (buffer));
3388 /* if the number of case statements <= 2 then */
3389 /* it is not economical to create the jump table */
3390 /* since two compares are needed for boundary conditions */
3391 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3394 if (tree->values.switchVals.swDefault)
3396 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3400 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3404 falseLabel = newiTempLabel (buffer);
3406 /* so we can create a jumptable */
3407 /* first we rule out the boundary conditions */
3408 /* if only optimization says so */
3411 sym_link *cetype = getSpec (operandType (cond));
3412 /* no need to check the lower bound if
3413 the condition is unsigned & minimum value is zero */
3414 if (!(min == 0 && IS_UNSIGNED (cetype)))
3416 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3417 ic = newiCodeCondition (boundary, falseLabel, NULL);
3421 /* now for upper bounds */
3422 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3423 ic = newiCodeCondition (boundary, falseLabel, NULL);
3427 /* if the min is not zero then we no make it zero */
3430 cond = geniCodeSubtract (cond, operandFromLit (min));
3431 if (!IS_LITERAL(getSpec(operandType(cond))))
3432 setOperandType (cond, UCHARTYPE);
3435 /* now create the jumptable */
3436 ic = newiCode (JUMPTABLE, NULL, NULL);
3437 IC_JTCOND (ic) = cond;
3438 IC_JTLABELS (ic) = labels;
3443 /*-----------------------------------------------------------------*/
3444 /* geniCodeSwitch - changes a switch to a if statement */
3445 /*-----------------------------------------------------------------*/
3447 geniCodeSwitch (ast * tree,int lvl)
3450 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3451 value *caseVals = tree->values.switchVals.swVals;
3452 symbol *trueLabel, *falseLabel;
3454 /* If the condition is a literal, then just jump to the */
3455 /* appropriate case label. */
3456 if (IS_LITERAL(getSpec(operandType(cond))))
3458 int switchVal, caseVal;
3460 switchVal = (int) floatFromVal (cond->operand.valOperand);
3463 caseVal = (int) floatFromVal (caseVals);
3464 if (caseVal == switchVal)
3466 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3467 tree->values.switchVals.swNum, caseVal);
3468 trueLabel = newiTempLabel (buffer);
3469 geniCodeGoto (trueLabel);
3472 caseVals = caseVals->next;
3474 goto defaultOrBreak;
3477 /* if we can make this a jump table */
3478 if (geniCodeJumpTable (cond, caseVals, tree))
3479 goto jumpTable; /* no need for the comparison */
3481 /* for the cases defined do */
3485 operand *compare = geniCodeLogic (cond,
3486 operandFromValue (caseVals),
3489 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3490 tree->values.switchVals.swNum,
3491 (int) floatFromVal (caseVals));
3492 trueLabel = newiTempLabel (buffer);
3494 ic = newiCodeCondition (compare, trueLabel, NULL);
3496 caseVals = caseVals->next;
3501 /* if default is present then goto break else break */
3502 if (tree->values.switchVals.swDefault)
3504 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3508 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3511 falseLabel = newiTempLabel (buffer);
3512 geniCodeGoto (falseLabel);
3515 ast2iCode (tree->right,lvl+1);
3518 /*-----------------------------------------------------------------*/
3519 /* geniCodeInline - intermediate code for inline assembler */
3520 /*-----------------------------------------------------------------*/
3522 geniCodeInline (ast * tree)
3526 ic = newiCode (INLINEASM, NULL, NULL);
3527 IC_INLINE (ic) = tree->values.inlineasm;
3531 /*-----------------------------------------------------------------*/
3532 /* geniCodeArrayInit - intermediate code for array initializer */
3533 /*-----------------------------------------------------------------*/
3535 geniCodeArrayInit (ast * tree, operand *array)
3539 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3540 ic = newiCode (ARRAYINIT, array, NULL);
3541 IC_ARRAYILIST (ic) = tree->values.constlist;
3543 operand *left=newOperand(), *right=newOperand();
3544 left->type=right->type=SYMBOL;
3545 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3546 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3547 ic = newiCode (ARRAYINIT, left, right);
3552 /*-----------------------------------------------------------------*/
3553 /* geniCodeCritical - intermediate code for a critical statement */
3554 /*-----------------------------------------------------------------*/
3556 geniCodeCritical (ast *tree, int lvl)
3561 /* If op is NULL, the original interrupt state will saved on */
3562 /* the stack. Otherwise, it will be saved in op. */
3564 /* Generate a save of the current interrupt state & disabled */
3565 ic = newiCode (CRITICAL, NULL, NULL);
3566 IC_RESULT (ic) = op;
3569 /* Generate the critical code sequence */
3570 if (tree->left && tree->left->type == EX_VALUE)
3571 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3573 ast2iCode (tree->left,lvl+1);
3575 /* Generate a restore of the original interrupt state */
3576 ic = newiCode (ENDCRITICAL, NULL, op);
3580 /*-----------------------------------------------------------------*/
3581 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3582 /* particular case. Ie : assigning or dereferencing array or ptr */
3583 /*-----------------------------------------------------------------*/
3584 set * lvaluereqSet = NULL;
3585 typedef struct lvalItem
3592 /*-----------------------------------------------------------------*/
3593 /* addLvaluereq - add a flag for lvalreq for current ast level */
3594 /*-----------------------------------------------------------------*/
3595 void addLvaluereq(int lvl)
3597 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3600 addSetHead(&lvaluereqSet,lpItem);
3603 /*-----------------------------------------------------------------*/
3604 /* delLvaluereq - del a flag for lvalreq for current ast level */
3605 /*-----------------------------------------------------------------*/
3609 lpItem = getSet(&lvaluereqSet);
3610 if(lpItem) Safe_free(lpItem);
3612 /*-----------------------------------------------------------------*/
3613 /* clearLvaluereq - clear lvalreq flag */
3614 /*-----------------------------------------------------------------*/
3615 void clearLvaluereq()
3618 lpItem = peekSet(lvaluereqSet);
3619 if(lpItem) lpItem->req = 0;
3621 /*-----------------------------------------------------------------*/
3622 /* getLvaluereq - get the last lvalreq level */
3623 /*-----------------------------------------------------------------*/
3624 int getLvaluereqLvl()
3627 lpItem = peekSet(lvaluereqSet);
3628 if(lpItem) return lpItem->lvl;
3631 /*-----------------------------------------------------------------*/
3632 /* isLvaluereq - is lvalreq valid for this level ? */
3633 /*-----------------------------------------------------------------*/
3634 int isLvaluereq(int lvl)
3637 lpItem = peekSet(lvaluereqSet);
3638 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3642 /*-----------------------------------------------------------------*/
3643 /* ast2iCode - creates an icodeList from an ast */
3644 /*-----------------------------------------------------------------*/
3646 ast2iCode (ast * tree,int lvl)
3648 operand *left = NULL;
3649 operand *right = NULL;
3653 /* set the global variables for filename & line number */
3655 filename = tree->filename;
3657 lineno = tree->lineno;
3659 block = tree->block;
3661 scopeLevel = tree->level;
3663 seqPoint = tree->seqPoint;
3665 if (tree->type == EX_VALUE)
3666 return operandFromValue (tree->opval.val);
3668 if (tree->type == EX_LINK)
3669 return operandFromLink (tree->opval.lnk);
3671 /* if we find a nullop */
3672 if (tree->type == EX_OP &&
3673 (tree->opval.op == NULLOP ||
3674 tree->opval.op == BLOCK))
3676 if (tree->left && tree->left->type == EX_VALUE)
3677 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3679 ast2iCode (tree->left,lvl+1);
3680 if (tree->right && tree->right->type == EX_VALUE)
3681 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3683 ast2iCode (tree->right,lvl+1);
3687 /* special cases for not evaluating */
3688 if (tree->opval.op != ':' &&
3689 tree->opval.op != '?' &&
3690 tree->opval.op != CALL &&
3691 tree->opval.op != IFX &&
3692 tree->opval.op != LABEL &&
3693 tree->opval.op != GOTO &&
3694 tree->opval.op != SWITCH &&
3695 tree->opval.op != FUNCTION &&
3696 tree->opval.op != INLINEASM &&
3697 tree->opval.op != CRITICAL)
3700 if (IS_ASSIGN_OP (tree->opval.op) ||
3701 IS_DEREF_OP (tree) ||
3702 (tree->opval.op == '&' && !tree->right) ||
3703 tree->opval.op == PTR_OP)
3706 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3707 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3710 left = operandFromAst (tree->left,lvl);
3712 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3713 left = geniCodeRValue (left, TRUE);
3717 left = operandFromAst (tree->left,lvl);
3719 if (tree->opval.op == INC_OP ||
3720 tree->opval.op == DEC_OP)
3723 right = operandFromAst (tree->right,lvl);
3728 right = operandFromAst (tree->right,lvl);
3732 /* now depending on the type of operand */
3733 /* this will be a biggy */
3734 switch (tree->opval.op)
3737 case '[': /* array operation */
3739 //sym_link *ltype = operandType (left);
3740 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3741 left = geniCodeRValue (left, FALSE);
3742 right = geniCodeRValue (right, TRUE);
3745 return geniCodeArray (left, right,lvl);
3747 case '.': /* structure dereference */
3748 if (IS_PTR (operandType (left)))
3749 left = geniCodeRValue (left, TRUE);
3751 left = geniCodeRValue (left, FALSE);
3753 return geniCodeStruct (left, right, tree->lvalue);
3755 case PTR_OP: /* structure pointer dereference */
3758 pType = operandType (left);
3759 left = geniCodeRValue (left, TRUE);
3761 setOClass (pType, getSpec (operandType (left)));
3764 return geniCodeStruct (left, right, tree->lvalue);
3766 case INC_OP: /* increment operator */
3768 return geniCodePostInc (left);
3770 return geniCodePreInc (right, tree->lvalue);
3772 case DEC_OP: /* decrement operator */
3774 return geniCodePostDec (left);
3776 return geniCodePreDec (right, tree->lvalue);
3778 case '&': /* bitwise and or address of operator */
3780 { /* this is a bitwise operator */
3781 left = geniCodeRValue (left, FALSE);
3782 right = geniCodeRValue (right, FALSE);
3783 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3786 return geniCodeAddressOf (left);
3788 case '|': /* bitwise or & xor */
3790 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3791 geniCodeRValue (right, FALSE),
3796 return geniCodeDivision (geniCodeRValue (left, FALSE),
3797 geniCodeRValue (right, FALSE));
3800 return geniCodeModulus (geniCodeRValue (left, FALSE),
3801 geniCodeRValue (right, FALSE));
3804 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3805 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3807 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3811 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3812 geniCodeRValue (right, FALSE));
3814 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3818 return geniCodeAdd (geniCodeRValue (left, FALSE),
3819 geniCodeRValue (right, FALSE),lvl);
3821 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3824 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3825 geniCodeRValue (right, FALSE));
3828 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3829 geniCodeRValue (right, FALSE));
3831 #if 0 // this indeed needs a second thought
3835 // let's keep this simple: get the rvalue we need
3836 op=geniCodeRValue (right, FALSE);
3837 // now cast it to whatever we want
3838 op=geniCodeCast (operandType(left), op, FALSE);
3839 // if this is going to be used as an lvalue, make it so
3845 #else // bug #604575, is it a bug ????
3846 return geniCodeCast (operandType (left),
3847 geniCodeRValue (right, FALSE), FALSE);
3854 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3859 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3860 setOperandType (op, UCHARTYPE);
3871 /* different compilers (even different gccs) evaluate
3872 the two calls in a different order. to get the same
3873 result on all machines we've to specify a clear sequence.
3874 return geniCodeLogic (geniCodeRValue (left, FALSE),
3875 geniCodeRValue (right, FALSE),
3879 operand *leftOp, *rightOp;
3881 rightOp = geniCodeRValue (right, FALSE);
3882 leftOp = geniCodeRValue (left , FALSE);
3884 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3887 return geniCodeConditional (tree,lvl);
3890 return operandFromLit (getSize (tree->right->ftype));
3894 sym_link *rtype = operandType (right);
3895 sym_link *ltype = operandType (left);
3896 if (IS_PTR (rtype) && IS_ITEMP (right)
3897 && right->isaddr && compareType (rtype->next, ltype) == 1)
3898 right = geniCodeRValue (right, TRUE);
3900 right = geniCodeRValue (right, FALSE);
3902 geniCodeAssign (left, right, 0);
3907 geniCodeAssign (left,
3908 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3910 geniCodeRValue (right, FALSE),FALSE), 0);
3914 geniCodeAssign (left,
3915 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3917 geniCodeRValue (right, FALSE)), 0);
3920 geniCodeAssign (left,
3921 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3923 geniCodeRValue (right, FALSE)), 0);
3926 sym_link *rtype = operandType (right);
3927 sym_link *ltype = operandType (left);
3928 if (IS_PTR (rtype) && IS_ITEMP (right)
3929 && right->isaddr && compareType (rtype->next, ltype) == 1)
3930 right = geniCodeRValue (right, TRUE);
3932 right = geniCodeRValue (right, FALSE);
3935 return geniCodeAssign (left,
3936 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3942 sym_link *rtype = operandType (right);
3943 sym_link *ltype = operandType (left);
3944 if (IS_PTR (rtype) && IS_ITEMP (right)
3945 && right->isaddr && compareType (rtype->next, ltype) == 1)
3947 right = geniCodeRValue (right, TRUE);
3951 right = geniCodeRValue (right, FALSE);
3954 geniCodeAssign (left,
3955 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3961 geniCodeAssign (left,
3962 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3964 geniCodeRValue (right, FALSE)), 0);
3967 geniCodeAssign (left,
3968 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3970 geniCodeRValue (right, FALSE)), 0);
3973 geniCodeAssign (left,
3974 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3976 geniCodeRValue (right, FALSE),
3978 operandType (left)), 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);
3996 return geniCodeRValue (right, FALSE);
3999 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4002 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4003 return ast2iCode (tree->right,lvl+1);
4006 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4007 return ast2iCode (tree->right,lvl+1);
4010 geniCodeFunctionBody (tree,lvl);
4014 geniCodeReturn (right);
4018 geniCodeIfx (tree,lvl);
4022 geniCodeSwitch (tree,lvl);
4026 geniCodeInline (tree);
4030 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4034 geniCodeCritical (tree, lvl);
4040 /*-----------------------------------------------------------------*/
4041 /* reverseICChain - gets from the list and creates a linkedlist */
4042 /*-----------------------------------------------------------------*/
4049 while ((loop = getSet (&iCodeChain)))
4061 /*-----------------------------------------------------------------*/
4062 /* iCodeFromAst - given an ast will convert it to iCode */
4063 /*-----------------------------------------------------------------*/
4065 iCodeFromAst (ast * tree)
4067 returnLabel = newiTempLabel ("_return");
4068 entryLabel = newiTempLabel ("_entry");
4070 return reverseiCChain ();
4073 static const char *opTypeToStr(OPTYPE op)
4077 case SYMBOL: return "symbol";
4078 case VALUE: return "value";
4079 case TYPE: return "type";
4081 return "undefined type";
4085 operand *validateOpType(operand *op,
4092 if (op && op->type == type)
4097 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4098 " expected %s, got %s\n",
4099 macro, args, file, line,
4100 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4102 return op; // never reached, makes compiler happy.