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 operand *geniCodeArray (operand *, operand *,int);
51 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 /*-----------------------------------------------------------------*/
1737 usualUnaryConversions (operand * op)
1739 if (IS_INTEGRAL (operandType (op)))
1741 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1744 return geniCodeCast (INTTYPE, op, TRUE);
1750 /*-----------------------------------------------------------------*/
1751 /* perform "usual binary conversions" */
1752 /*-----------------------------------------------------------------*/
1754 usualBinaryConversions (operand ** op1, operand ** op2,
1755 bool promoteCharToInt, bool isMul)
1758 sym_link *rtype = operandType (*op2);
1759 sym_link *ltype = operandType (*op1);
1761 ctype = computeType (ltype, rtype, promoteCharToInt);
1763 /* special for multiplication:
1764 This if for 'mul a,b', which takes two chars and returns an int */
1766 /* && promoteCharToInt superfluous, already handled by computeType() */
1767 && IS_INT (getSpec (ctype)))
1769 sym_link *retype = getSpec (rtype);
1770 sym_link *letype = getSpec (ltype);
1772 if ( IS_CHAR (letype)
1774 && IS_UNSIGNED (letype)
1775 && IS_UNSIGNED (retype))
1780 *op1 = geniCodeCast (ctype, *op1, TRUE);
1781 *op2 = geniCodeCast (ctype, *op2, TRUE);
1786 /*-----------------------------------------------------------------*/
1787 /* geniCodeValueAtAddress - generate intermeditate code for value */
1789 /*-----------------------------------------------------------------*/
1791 geniCodeRValue (operand * op, bool force)
1794 sym_link *type = operandType (op);
1795 sym_link *etype = getSpec (type);
1797 /* if this is an array & already */
1798 /* an address then return this */
1799 if (IS_AGGREGATE (type) ||
1800 (IS_PTR (type) && !force && !op->isaddr))
1801 return operandFromOperand (op);
1803 /* if this is not an address then must be */
1804 /* rvalue already so return this one */
1808 /* if this is not a temp symbol then */
1809 if (!IS_ITEMP (op) &&
1811 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1813 op = operandFromOperand (op);
1818 if (IS_SPEC (type) &&
1819 IS_TRUE_SYMOP (op) &&
1820 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1821 (options.model == MODEL_FLAT24) ))
1823 op = operandFromOperand (op);
1828 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1829 if (IS_PTR (type) && op->isaddr && force)
1832 type = copyLinkChain (type);
1834 IC_RESULT (ic) = newiTempOperand (type, 1);
1835 IC_RESULT (ic)->isaddr = 0;
1837 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1841 return IC_RESULT (ic);
1844 /*-----------------------------------------------------------------*/
1845 /* geniCodeCast - changes the value from one type to another */
1846 /*-----------------------------------------------------------------*/
1848 geniCodeCast (sym_link * type, operand * op, bool implicit)
1852 sym_link *opetype = getSpec (optype = operandType (op));
1856 /* one of them has size zero then error */
1857 if (IS_VOID (optype))
1859 werror (E_CAST_ZERO);
1863 /* if the operand is already the desired type then do nothing */
1864 if (compareType (type, optype) == 1)
1867 /* if this is a literal then just change the type & return */
1868 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1870 return operandFromValue (valCastLiteral (type,
1871 operandLitValue (op)));
1874 /* if casting to/from pointers, do some checking */
1875 if (IS_PTR(type)) { // to a pointer
1876 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1877 if (IS_INTEGRAL(optype)) {
1878 // maybe this is NULL, than it's ok.
1879 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1880 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1881 // no way to set the storage
1882 if (IS_LITERAL(optype)) {
1883 werror(E_LITERAL_GENERIC);
1886 werror(E_NONPTR2_GENPTR);
1889 } else if (implicit) {
1890 werror(W_INTEGRAL2PTR_NOCAST);
1895 // shouldn't do that with float, array or structure unless to void
1896 if (!IS_VOID(getSpec(type)) &&
1897 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1898 werror(E_INCOMPAT_TYPES);
1902 } else { // from a pointer to a pointer
1903 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1904 // if not a pointer to a function
1905 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1906 if (implicit) { // if not to generic, they have to match
1907 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1908 werror(E_INCOMPAT_PTYPES);
1915 } else { // to a non pointer
1916 if (IS_PTR(optype)) { // from a pointer
1917 if (implicit) { // sneaky
1918 if (IS_INTEGRAL(type)) {
1919 werror(W_PTR2INTEGRAL_NOCAST);
1921 } else { // shouldn't do that with float, array or structure
1922 werror(E_INCOMPAT_TYPES);
1929 printFromToType (optype, type);
1932 /* if they are the same size create an assignment */
1933 if (getSize (type) == getSize (optype) &&
1934 !IS_BITFIELD (type) &&
1936 !IS_FLOAT (optype) &&
1937 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1938 (!IS_SPEC (type) && !IS_SPEC (optype))))
1940 ic = newiCode ('=', NULL, op);
1941 IC_RESULT (ic) = newiTempOperand (type, 0);
1942 SPIL_LOC (IC_RESULT (ic)) =
1943 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1944 IC_RESULT (ic)->isaddr = 0;
1948 ic = newiCode (CAST, operandFromLink (type),
1949 geniCodeRValue (op, FALSE));
1951 IC_RESULT (ic) = newiTempOperand (type, 0);
1954 /* preserve the storage class & output class */
1955 /* of the original variable */
1956 restype = getSpec (operandType (IC_RESULT (ic)));
1957 if (!IS_LITERAL(opetype))
1958 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1959 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1962 return IC_RESULT (ic);
1965 /*-----------------------------------------------------------------*/
1966 /* geniCodeLabel - will create a Label */
1967 /*-----------------------------------------------------------------*/
1969 geniCodeLabel (symbol * label)
1973 ic = newiCodeLabelGoto (LABEL, label);
1977 /*-----------------------------------------------------------------*/
1978 /* geniCodeGoto - will create a Goto */
1979 /*-----------------------------------------------------------------*/
1981 geniCodeGoto (symbol * label)
1985 ic = newiCodeLabelGoto (GOTO, label);
1989 /*-----------------------------------------------------------------*/
1990 /* geniCodeMultiply - gen intermediate code for multiplication */
1991 /*-----------------------------------------------------------------*/
1993 geniCodeMultiply (operand * left, operand * right, int resultIsInt)
2000 /* if they are both literal then we know the result */
2001 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2002 return operandFromValue (valMult (left->operand.valOperand,
2003 right->operand.valOperand));
2005 if (IS_LITERAL(retype)) {
2006 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2009 resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE);
2011 rtype = operandType (right);
2012 retype = getSpec (rtype);
2013 ltype = operandType (left);
2014 letype = getSpec (ltype);
2017 /* if the right is a literal & power of 2 */
2018 /* then make it a left shift */
2019 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2020 efficient in most cases than 2 bytes result = 2 bytes << literal
2021 if port has 1 byte muldiv */
2022 if (p2 && !IS_FLOAT (letype) &&
2023 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
2024 (port->support.muldiv == 1)))
2026 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2028 /* LEFT_OP need same size for left and result, */
2029 left = geniCodeCast (resType, left, TRUE);
2030 ltype = operandType (left);
2032 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2036 ic = newiCode ('*', left, right); /* normal multiplication */
2037 /* if the size left or right > 1 then support routine */
2038 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2042 IC_RESULT (ic) = newiTempOperand (resType, 1);
2045 return IC_RESULT (ic);
2048 /*-----------------------------------------------------------------*/
2049 /* geniCodeDivision - gen intermediate code for division */
2050 /*-----------------------------------------------------------------*/
2052 geniCodeDivision (operand * left, operand * right)
2057 sym_link *rtype = operandType (right);
2058 sym_link *retype = getSpec (rtype);
2059 sym_link *ltype = operandType (left);
2060 sym_link *letype = getSpec (ltype);
2062 resType = usualBinaryConversions (&left, &right,
2063 (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2066 /* if the right is a literal & power of 2
2067 and left is unsigned then make it a
2069 if (IS_LITERAL (retype) &&
2070 !IS_FLOAT (letype) &&
2071 IS_UNSIGNED(letype) &&
2072 (p2 = powof2 ((TYPE_UDWORD)
2073 floatFromVal (right->operand.valOperand)))) {
2074 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2078 ic = newiCode ('/', left, right); /* normal division */
2079 /* if the size left or right > 1 then support routine */
2080 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2083 IC_RESULT (ic) = newiTempOperand (resType, 0);
2086 return IC_RESULT (ic);
2088 /*-----------------------------------------------------------------*/
2089 /* geniCodeModulus - gen intermediate code for modulus */
2090 /*-----------------------------------------------------------------*/
2092 geniCodeModulus (operand * left, operand * right)
2098 /* if they are both literal then we know the result */
2099 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2100 return operandFromValue (valMod (left->operand.valOperand,
2101 right->operand.valOperand));
2103 resType = usualBinaryConversions (&left, &right,
2104 (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2107 /* now they are the same size */
2108 ic = newiCode ('%', left, right);
2110 /* if the size left or right > 1 then support routine */
2111 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2113 IC_RESULT (ic) = newiTempOperand (resType, 0);
2116 return IC_RESULT (ic);
2119 /*-----------------------------------------------------------------*/
2120 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2121 /*-----------------------------------------------------------------*/
2123 geniCodePtrPtrSubtract (operand * left, operand * right)
2129 /* if they are both literals then */
2130 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2132 result = operandFromValue (valMinus (left->operand.valOperand,
2133 right->operand.valOperand));
2137 ic = newiCode ('-', left, right);
2139 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2143 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2147 // should we really do this? is this ANSI?
2148 return geniCodeDivision (result,
2149 operandFromLit (getSize (ltype->next)));
2152 /*-----------------------------------------------------------------*/
2153 /* geniCodeSubtract - generates code for subtraction */
2154 /*-----------------------------------------------------------------*/
2156 geniCodeSubtract (operand * left, operand * right)
2163 /* if they both pointers then */
2164 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2165 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2166 return geniCodePtrPtrSubtract (left, right);
2168 /* if they are both literal then we know the result */
2169 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2170 && left->isLiteral && right->isLiteral)
2171 return operandFromValue (valMinus (left->operand.valOperand,
2172 right->operand.valOperand));
2174 /* if left is an array or pointer */
2175 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2177 isarray = left->isaddr;
2178 right = geniCodeMultiply (right,
2179 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2180 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2183 { /* make them the same size */
2184 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2187 ic = newiCode ('-', left, right);
2189 IC_RESULT (ic) = newiTempOperand (resType, 1);
2190 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2192 /* if left or right is a float */
2193 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2197 return IC_RESULT (ic);
2200 /*-----------------------------------------------------------------*/
2201 /* geniCodeAdd - generates iCode for addition */
2202 /*-----------------------------------------------------------------*/
2204 geniCodeAdd (operand * left, operand * right, int lvl)
2213 /* if the right side is LITERAL zero */
2214 /* return the left side */
2215 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2218 /* if left is literal zero return right */
2219 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2222 /* if left is a pointer then size */
2223 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2225 isarray = left->isaddr;
2226 // there is no need to multiply with 1
2227 if (getSize (ltype->next) != 1)
2229 size = operandFromLit (getSize (ltype->next));
2230 SPEC_USIGN (getSpec (operandType (size))) = 1;
2231 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2232 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2233 /* Even if right is a 'unsigned char',
2234 the result will be a 'signed int' due to the promotion rules.
2235 It doesn't make sense when accessing arrays, so let's fix it here: */
2237 SPEC_USIGN (getSpec (operandType (right))) = 1;
2239 resType = copyLinkChain (ltype);
2242 { // make them the same size
2243 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2246 /* if they are both literals then we know */
2247 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2248 && left->isLiteral && right->isLiteral)
2249 return operandFromValue (valPlus (valFromType (ltype),
2250 valFromType (rtype)));
2252 ic = newiCode ('+', left, right);
2254 IC_RESULT (ic) = newiTempOperand (resType, 1);
2255 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2257 /* if left or right is a float then support
2259 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2264 return IC_RESULT (ic);
2268 /*-----------------------------------------------------------------*/
2269 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2270 /*-----------------------------------------------------------------*/
2272 aggrToPtr (sym_link * type, bool force)
2277 if (IS_PTR (type) && !force)
2280 etype = getSpec (type);
2281 ptype = newLink (DECLARATOR);
2285 /* set the pointer depending on the storage class */
2286 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2290 /*-----------------------------------------------------------------*/
2291 /* geniCodeArray2Ptr - array to pointer */
2292 /*-----------------------------------------------------------------*/
2294 geniCodeArray2Ptr (operand * op)
2296 sym_link *optype = operandType (op);
2297 sym_link *opetype = getSpec (optype);
2299 /* set the pointer depending on the storage class */
2300 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2307 /*-----------------------------------------------------------------*/
2308 /* geniCodeArray - array access */
2309 /*-----------------------------------------------------------------*/
2311 geniCodeArray (operand * left, operand * right,int lvl)
2315 sym_link *ltype = operandType (left);
2320 if (IS_PTR (ltype->next) && left->isaddr)
2322 left = geniCodeRValue (left, FALSE);
2325 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2327 size = operandFromLit (getSize (ltype->next));
2328 SPEC_USIGN (getSpec (operandType (size))) = 1;
2329 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2330 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2331 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2332 It doesn't make sense when accessing arrays, so let's fix it here: */
2334 SPEC_USIGN (getSpec (operandType (right))) = 1;
2335 /* we can check for limits here */
2336 if (isOperandLiteral (right) &&
2339 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2341 werror (E_ARRAY_BOUND);
2342 right = operandFromLit (0);
2345 ic = newiCode ('+', left, right);
2347 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2348 !IS_AGGREGATE (ltype->next) &&
2349 !IS_PTR (ltype->next))
2350 ? ltype : ltype->next), 0);
2352 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2355 return IC_RESULT (ic);
2358 /*-----------------------------------------------------------------*/
2359 /* geniCodeStruct - generates intermediate code for structures */
2360 /*-----------------------------------------------------------------*/
2362 geniCodeStruct (operand * left, operand * right, bool islval)
2365 sym_link *type = operandType (left);
2366 sym_link *etype = getSpec (type);
2368 symbol *element = getStructElement (SPEC_STRUCT (etype),
2369 right->operand.symOperand);
2371 wassert(IS_SYMOP(right));
2373 /* add the offset */
2374 ic = newiCode ('+', left, operandFromLit (element->offset));
2376 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2378 /* preserve the storage & output class of the struct */
2379 /* as well as the volatile attribute */
2380 retype = getSpec (operandType (IC_RESULT (ic)));
2381 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2382 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2383 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2384 SPEC_CONST (retype) |= SPEC_CONST (etype);
2386 if (IS_PTR (element->type))
2387 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2389 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2392 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2395 /*-----------------------------------------------------------------*/
2396 /* geniCodePostInc - generate int code for Post increment */
2397 /*-----------------------------------------------------------------*/
2399 geniCodePostInc (operand * op)
2403 sym_link *optype = operandType (op);
2405 operand *rv = (IS_ITEMP (op) ?
2406 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2408 sym_link *rvtype = operandType (rv);
2411 /* if this is not an address we have trouble */
2414 werror (E_LVALUE_REQUIRED, "++");
2418 rOp = newiTempOperand (rvtype, 0);
2419 OP_SYMBOL(rOp)->noSpilLoc = 1;
2422 OP_SYMBOL(rv)->noSpilLoc = 1;
2424 geniCodeAssign (rOp, rv, 0);
2426 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2427 if (IS_FLOAT (rvtype))
2428 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2430 ic = newiCode ('+', rv, operandFromLit (size));
2432 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2435 geniCodeAssign (op, result, 0);
2441 /*-----------------------------------------------------------------*/
2442 /* geniCodePreInc - generate code for preIncrement */
2443 /*-----------------------------------------------------------------*/
2445 geniCodePreInc (operand * op, bool lvalue)
2448 sym_link *optype = operandType (op);
2449 operand *rop = (IS_ITEMP (op) ?
2450 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2452 sym_link *roptype = operandType (rop);
2458 werror (E_LVALUE_REQUIRED, "++");
2463 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2464 if (IS_FLOAT (roptype))
2465 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2467 ic = newiCode ('+', rop, operandFromLit (size));
2468 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2471 (void) geniCodeAssign (op, result, 0);
2472 if (lvalue || IS_TRUE_SYMOP (op))
2478 /*-----------------------------------------------------------------*/
2479 /* geniCodePostDec - generates code for Post decrement */
2480 /*-----------------------------------------------------------------*/
2482 geniCodePostDec (operand * op)
2486 sym_link *optype = operandType (op);
2488 operand *rv = (IS_ITEMP (op) ?
2489 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2491 sym_link *rvtype = operandType (rv);
2494 /* if this is not an address we have trouble */
2497 werror (E_LVALUE_REQUIRED, "--");
2501 rOp = newiTempOperand (rvtype, 0);
2502 OP_SYMBOL(rOp)->noSpilLoc = 1;
2505 OP_SYMBOL(rv)->noSpilLoc = 1;
2507 geniCodeAssign (rOp, rv, 0);
2509 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2510 if (IS_FLOAT (rvtype))
2511 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2513 ic = newiCode ('-', rv, operandFromLit (size));
2515 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2518 geniCodeAssign (op, result, 0);
2524 /*-----------------------------------------------------------------*/
2525 /* geniCodePreDec - generate code for pre decrement */
2526 /*-----------------------------------------------------------------*/
2528 geniCodePreDec (operand * op, bool lvalue)
2531 sym_link *optype = operandType (op);
2532 operand *rop = (IS_ITEMP (op) ?
2533 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2535 sym_link *roptype = operandType (rop);
2541 werror (E_LVALUE_REQUIRED, "--");
2546 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2547 if (IS_FLOAT (roptype))
2548 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2550 ic = newiCode ('-', rop, operandFromLit (size));
2551 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2554 (void) geniCodeAssign (op, result, 0);
2555 if (lvalue || IS_TRUE_SYMOP (op))
2562 /*-----------------------------------------------------------------*/
2563 /* geniCodeBitwise - gen int code for bitWise operators */
2564 /*-----------------------------------------------------------------*/
2566 geniCodeBitwise (operand * left, operand * right,
2567 int oper, sym_link * resType)
2571 left = geniCodeCast (resType, left, TRUE);
2572 right = geniCodeCast (resType, right, TRUE);
2574 ic = newiCode (oper, left, right);
2575 IC_RESULT (ic) = newiTempOperand (resType, 0);
2578 return IC_RESULT (ic);
2581 /*-----------------------------------------------------------------*/
2582 /* geniCodeAddressOf - gens icode for '&' address of operator */
2583 /*-----------------------------------------------------------------*/
2585 geniCodeAddressOf (operand * op)
2589 sym_link *optype = operandType (op);
2590 sym_link *opetype = getSpec (optype);
2592 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2594 op = operandFromOperand (op);
2599 /* lvalue check already done in decorateType */
2600 /* this must be a lvalue */
2601 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2602 /* werror (E_LVALUE_REQUIRED,"&"); */
2606 p = newLink (DECLARATOR);
2608 /* set the pointer depending on the storage class */
2609 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2611 p->next = copyLinkChain (optype);
2613 /* if already a temp */
2616 setOperandType (op, p);
2621 /* other wise make this of the type coming in */
2622 ic = newiCode (ADDRESS_OF, op, NULL);
2623 IC_RESULT (ic) = newiTempOperand (p, 1);
2624 IC_RESULT (ic)->isaddr = 0;
2626 return IC_RESULT (ic);
2628 /*-----------------------------------------------------------------*/
2629 /* setOClass - sets the output class depending on the pointer type */
2630 /*-----------------------------------------------------------------*/
2632 setOClass (sym_link * ptr, sym_link * spec)
2634 switch (DCL_TYPE (ptr))
2637 SPEC_OCLS (spec) = data;
2641 SPEC_OCLS (spec) = generic;
2645 SPEC_OCLS (spec) = xdata;
2649 SPEC_OCLS (spec) = code;
2653 SPEC_OCLS (spec) = idata;
2657 SPEC_OCLS (spec) = xstack;
2661 SPEC_OCLS (spec) = eeprom;
2670 /*-----------------------------------------------------------------*/
2671 /* geniCodeDerefPtr - dereference pointer with '*' */
2672 /*-----------------------------------------------------------------*/
2674 geniCodeDerefPtr (operand * op,int lvl)
2676 sym_link *rtype, *retype;
2677 sym_link *optype = operandType (op);
2679 // if this is an array then array access
2680 if (IS_ARRAY (optype)) {
2681 // don't worry, this will be optimized out later
2682 return geniCodeArray (op, operandFromLit (0), lvl);
2685 // just in case someone screws up
2686 wassert (IS_PTR (optype));
2688 if (IS_TRUE_SYMOP (op))
2691 op = geniCodeRValue (op, TRUE);
2694 /* now get rid of the pointer part */
2695 if (isLvaluereq(lvl) && IS_ITEMP (op))
2697 retype = getSpec (rtype = copyLinkChain (optype));
2701 retype = getSpec (rtype = copyLinkChain (optype->next));
2702 /* outputclass needs 2b updated */
2703 setOClass (optype, retype);
2706 op->isGptr = IS_GENPTR (optype);
2708 op->isaddr = (IS_PTR (rtype) ||
2709 IS_STRUCT (rtype) ||
2714 if (!isLvaluereq(lvl))
2715 op = geniCodeRValue (op, TRUE);
2717 setOperandType (op, rtype);
2722 /*-----------------------------------------------------------------*/
2723 /* geniCodeUnaryMinus - does a unary minus of the operand */
2724 /*-----------------------------------------------------------------*/
2726 geniCodeUnaryMinus (operand * op)
2729 sym_link *optype = operandType (op);
2731 if (IS_LITERAL (optype))
2732 return operandFromLit (-floatFromVal (op->operand.valOperand));
2734 ic = newiCode (UNARYMINUS, op, NULL);
2735 IC_RESULT (ic) = newiTempOperand (optype, 0);
2737 return IC_RESULT (ic);
2740 /*-----------------------------------------------------------------*/
2741 /* geniCodeLeftShift - gen i code for left shift */
2742 /*-----------------------------------------------------------------*/
2744 geniCodeLeftShift (operand * left, operand * right)
2748 left = usualUnaryConversions (left);
2749 ic = newiCode (LEFT_OP, left, right);
2750 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2752 return IC_RESULT (ic);
2755 /*-----------------------------------------------------------------*/
2756 /* geniCodeRightShift - gen i code for right shift */
2757 /*-----------------------------------------------------------------*/
2759 geniCodeRightShift (operand * left, operand * right)
2763 ic = newiCode (RIGHT_OP, left, right);
2764 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2766 return IC_RESULT (ic);
2769 /*-----------------------------------------------------------------*/
2770 /* geniCodeLogic- logic code */
2771 /*-----------------------------------------------------------------*/
2773 geniCodeLogic (operand * left, operand * right, int op)
2777 sym_link *rtype = operandType (right);
2778 sym_link *ltype = operandType (left);
2780 /* left is integral type and right is literal then
2781 check if the literal value is within bounds */
2782 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2784 checkConstantRange(ltype,
2785 OP_VALUE(right), "compare operation", 1);
2788 /* if one operand is a pointer and the other is a literal generic void pointer,
2789 change the type of the literal generic void pointer to match the other pointer */
2790 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2791 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2793 /* find left's definition */
2794 ic = (iCode *) setFirstItem (iCodeChain);
2797 if (((ic->op == CAST) || (ic->op == '='))
2798 && isOperandEqual(left, IC_RESULT (ic)))
2801 ic = setNextItem (iCodeChain);
2803 /* if casting literal to generic pointer, then cast to rtype instead */
2804 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2806 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2807 ltype = operandType(left);
2810 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2811 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2813 /* find right's definition */
2814 ic = (iCode *) setFirstItem (iCodeChain);
2817 if (((ic->op == CAST) || (ic->op == '='))
2818 && isOperandEqual(right, IC_RESULT (ic)))
2821 ic = setNextItem (iCodeChain);
2823 /* if casting literal to generic pointer, then cast to rtype instead */
2824 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2826 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2827 rtype = operandType(right);
2831 ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
2833 ic = newiCode (op, left, right);
2834 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2836 /* if comparing float
2837 and not a '==' || '!=' || '&&' || '||' (these
2839 if (IS_FLOAT(ctype) &&
2847 return IC_RESULT (ic);
2850 /*-----------------------------------------------------------------*/
2851 /* geniCodeUnary - for a a generic unary operation */
2852 /*-----------------------------------------------------------------*/
2854 geniCodeUnary (operand * op, int oper)
2856 iCode *ic = newiCode (oper, op, NULL);
2858 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2860 return IC_RESULT (ic);
2863 /*-----------------------------------------------------------------*/
2864 /* geniCodeConditional - geniCode for '?' ':' operation */
2865 /*-----------------------------------------------------------------*/
2867 geniCodeConditional (ast * tree,int lvl)
2870 symbol *falseLabel = newiTempLabel (NULL);
2871 symbol *exitLabel = newiTempLabel (NULL);
2872 operand *cond = ast2iCode (tree->left,lvl+1);
2873 operand *true, *false, *result;
2875 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2879 true = ast2iCode (tree->right->left,lvl+1);
2881 /* move the value to a new Operand */
2882 result = newiTempOperand (tree->right->ftype, 0);
2883 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2885 /* generate an unconditional goto */
2886 geniCodeGoto (exitLabel);
2888 /* now for the right side */
2889 geniCodeLabel (falseLabel);
2891 false = ast2iCode (tree->right->right,lvl+1);
2892 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2894 /* create the exit label */
2895 geniCodeLabel (exitLabel);
2900 /*-----------------------------------------------------------------*/
2901 /* geniCodeAssign - generate code for assignment */
2902 /*-----------------------------------------------------------------*/
2904 geniCodeAssign (operand * left, operand * right, int nosupdate)
2907 sym_link *ltype = operandType (left);
2908 sym_link *rtype = operandType (right);
2910 if (!left->isaddr && !IS_ITEMP (left))
2912 werror (E_LVALUE_REQUIRED, "assignment");
2916 /* left is integral type and right is literal then
2917 check if the literal value is within bounds */
2918 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2920 checkConstantRange(ltype,
2921 OP_VALUE(right), "= operation", 0);
2924 /* if the left & right type don't exactly match */
2925 /* if pointer set then make sure the check is
2926 done with the type & not the pointer */
2927 /* then cast rights type to left */
2929 /* first check the type for pointer assignement */
2930 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2931 compareType (ltype, rtype) <= 0)
2933 if (compareType (ltype->next, rtype) < 0)
2934 right = geniCodeCast (ltype->next, right, TRUE);
2936 else if (compareType (ltype, rtype) < 0)
2937 right = geniCodeCast (ltype, right, TRUE);
2939 /* If left is a true symbol & ! volatile
2940 create an assignment to temporary for
2941 the right & then assign this temporary
2942 to the symbol. This is SSA (static single
2943 assignment). Isn't it simple and folks have
2944 published mountains of paper on it */
2945 if (IS_TRUE_SYMOP (left) &&
2946 !isOperandVolatile (left, FALSE) &&
2947 isOperandGlobal (left))
2951 if (IS_TRUE_SYMOP (right))
2952 sym = OP_SYMBOL (right);
2953 ic = newiCode ('=', NULL, right);
2954 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2955 SPIL_LOC (right) = sym;
2959 ic = newiCode ('=', NULL, right);
2960 IC_RESULT (ic) = left;
2963 /* if left isgptr flag is set then support
2964 routine will be required */
2968 ic->nosupdate = nosupdate;
2972 /*-----------------------------------------------------------------*/
2973 /* geniCodeDummyRead - generate code for dummy read */
2974 /*-----------------------------------------------------------------*/
2976 geniCodeDummyRead (operand * op)
2979 sym_link *type = operandType (op);
2981 if (!IS_VOLATILE(type))
2984 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2990 /*-----------------------------------------------------------------*/
2991 /* geniCodeSEParms - generate code for side effecting fcalls */
2992 /*-----------------------------------------------------------------*/
2994 geniCodeSEParms (ast * parms,int lvl)
2999 if (parms->type == EX_OP && parms->opval.op == PARAM)
3001 geniCodeSEParms (parms->left,lvl);
3002 geniCodeSEParms (parms->right,lvl);
3006 /* hack don't like this but too lazy to think of
3008 if (IS_ADDRESS_OF_OP (parms))
3009 parms->left->lvalue = 1;
3011 if (IS_CAST_OP (parms) &&
3012 IS_PTR (parms->ftype) &&
3013 IS_ADDRESS_OF_OP (parms->right))
3014 parms->right->left->lvalue = 1;
3016 parms->opval.oprnd =
3017 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3019 parms->type = EX_OPERAND;
3020 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3021 SPEC_ARGREG(parms->ftype);
3024 /*-----------------------------------------------------------------*/
3025 /* geniCodeParms - generates parameters */
3026 /*-----------------------------------------------------------------*/
3028 geniCodeParms (ast * parms, value *argVals, int *stack,
3029 sym_link * fetype, symbol * func,int lvl)
3037 if (argVals==NULL) {
3039 argVals=FUNC_ARGS(func->type);
3042 /* if this is a param node then do the left & right */
3043 if (parms->type == EX_OP && parms->opval.op == PARAM)
3045 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
3046 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
3050 /* get the parameter value */
3051 if (parms->type == EX_OPERAND)
3052 pval = parms->opval.oprnd;
3055 /* maybe this else should go away ?? */
3056 /* hack don't like this but too lazy to think of
3058 if (IS_ADDRESS_OF_OP (parms))
3059 parms->left->lvalue = 1;
3061 if (IS_CAST_OP (parms) &&
3062 IS_PTR (parms->ftype) &&
3063 IS_ADDRESS_OF_OP (parms->right))
3064 parms->right->left->lvalue = 1;
3066 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3069 /* if register parm then make it a send */
3070 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
3071 IFFUNC_ISBUILTIN(func->type))
3073 ic = newiCode (SEND, pval, NULL);
3074 ic->argreg = SPEC_ARGREG(parms->etype);
3075 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
3080 /* now decide whether to push or assign */
3081 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
3085 operand *top = operandFromSymbol (argVals->sym);
3086 /* clear useDef and other bitVectors */
3087 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3088 geniCodeAssign (top, pval, 1);
3092 sym_link *p = operandType (pval);
3094 ic = newiCode (IPUSH, pval, NULL);
3096 /* update the stack adjustment */
3097 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3102 argVals=argVals->next;
3106 /*-----------------------------------------------------------------*/
3107 /* geniCodeCall - generates temp code for calling */
3108 /*-----------------------------------------------------------------*/
3110 geniCodeCall (operand * left, ast * parms,int lvl)
3114 sym_link *type, *etype;
3117 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3118 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3119 werror (E_FUNCTION_EXPECTED);
3120 return operandFromValue(valueFromLit(0));
3123 /* take care of parameters with side-effecting
3124 function calls in them, this is required to take care
3125 of overlaying function parameters */
3126 geniCodeSEParms (parms,lvl);
3128 /* first the parameters */
3129 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3131 /* now call : if symbol then pcall */
3132 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3133 ic = newiCode (PCALL, left, NULL);
3135 ic = newiCode (CALL, left, NULL);
3138 type = copyLinkChain (operandType (left)->next);
3139 etype = getSpec (type);
3140 SPEC_EXTR (etype) = 0;
3141 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3145 /* stack adjustment after call */
3146 ic->parmBytes = stack;
3151 /*-----------------------------------------------------------------*/
3152 /* geniCodeReceive - generate intermediate code for "receive" */
3153 /*-----------------------------------------------------------------*/
3155 geniCodeReceive (value * args)
3157 /* for all arguments that are passed in registers */
3161 if (IS_REGPARM (args->etype))
3163 operand *opr = operandFromValue (args);
3165 symbol *sym = OP_SYMBOL (opr);
3168 /* we will use it after all optimizations
3169 and before liveRange calculation */
3170 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3173 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3174 options.stackAuto == 0 &&
3175 (!(options.model == MODEL_FLAT24)) )
3180 opl = newiTempOperand (args->type, 0);
3182 sym->reqv->key = sym->key;
3183 OP_SYMBOL (sym->reqv)->key = sym->key;
3184 OP_SYMBOL (sym->reqv)->isreqv = 1;
3185 OP_SYMBOL (sym->reqv)->islocal = 0;
3186 SPIL_LOC (sym->reqv) = sym;
3190 ic = newiCode (RECEIVE, NULL, NULL);
3191 ic->argreg = SPEC_ARGREG(args->etype);
3193 currFunc->recvSize = getSize (sym->type);
3196 IC_RESULT (ic) = opr;
3204 /*-----------------------------------------------------------------*/
3205 /* geniCodeFunctionBody - create the function body */
3206 /*-----------------------------------------------------------------*/
3208 geniCodeFunctionBody (ast * tree,int lvl)
3215 /* reset the auto generation */
3221 func = ast2iCode (tree->left,lvl+1);
3222 fetype = getSpec (operandType (func));
3224 savelineno = lineno;
3225 lineno = OP_SYMBOL (func)->lineDef;
3226 /* create an entry label */
3227 geniCodeLabel (entryLabel);
3228 lineno = savelineno;
3230 /* create a proc icode */
3231 ic = newiCode (FUNCTION, func, NULL);
3232 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3236 /* for all parameters that are passed
3237 on registers add a "receive" */
3238 geniCodeReceive (tree->values.args);
3240 /* generate code for the body */
3241 ast2iCode (tree->right,lvl+1);
3243 /* create a label for return */
3244 geniCodeLabel (returnLabel);
3246 /* now generate the end proc */
3247 ic = newiCode (ENDFUNCTION, func, NULL);
3252 /*-----------------------------------------------------------------*/
3253 /* geniCodeReturn - gen icode for 'return' statement */
3254 /*-----------------------------------------------------------------*/
3256 geniCodeReturn (operand * op)
3260 /* if the operand is present force an rvalue */
3262 op = geniCodeRValue (op, FALSE);
3264 ic = newiCode (RETURN, op, NULL);
3268 /*-----------------------------------------------------------------*/
3269 /* geniCodeIfx - generates code for extended if statement */
3270 /*-----------------------------------------------------------------*/
3272 geniCodeIfx (ast * tree,int lvl)
3275 operand *condition = ast2iCode (tree->left,lvl+1);
3278 /* if condition is null then exit */
3282 condition = geniCodeRValue (condition, FALSE);
3284 cetype = getSpec (operandType (condition));
3285 /* if the condition is a literal */
3286 if (IS_LITERAL (cetype))
3288 if (floatFromVal (condition->operand.valOperand))
3290 if (tree->trueLabel)
3291 geniCodeGoto (tree->trueLabel);
3297 if (tree->falseLabel)
3298 geniCodeGoto (tree->falseLabel);
3305 if (tree->trueLabel)
3307 ic = newiCodeCondition (condition,
3312 if (tree->falseLabel)
3313 geniCodeGoto (tree->falseLabel);
3317 ic = newiCodeCondition (condition,
3324 ast2iCode (tree->right,lvl+1);
3327 /*-----------------------------------------------------------------*/
3328 /* geniCodeJumpTable - tries to create a jump table for switch */
3329 /*-----------------------------------------------------------------*/
3331 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3333 int min = 0, max = 0, t, cnt = 0;
3339 int needRangeCheck = !optimize.noJTabBoundary
3340 || tree->values.switchVals.swDefault;
3342 if (!tree || !caseVals)
3345 /* the criteria for creating a jump table is */
3346 /* all integer numbers between the maximum & minimum must */
3347 /* be present , the maximum value should not exceed 255 */
3348 min = max = (int) floatFromVal (vch = caseVals);
3349 SNPRINTF (buffer, sizeof(buffer),
3351 tree->values.switchVals.swNum,
3353 addSet (&labels, newiTempLabel (buffer));
3355 /* if there is only one case value then no need */
3356 if (!(vch = vch->next))
3361 if (((t = (int) floatFromVal (vch)) - max) != 1)
3363 SNPRINTF (buffer, sizeof(buffer),
3365 tree->values.switchVals.swNum,
3367 addSet (&labels, newiTempLabel (buffer));
3373 /* if the number of case statements <= 2 then */
3374 /* it is not economical to create the jump table */
3375 /* since two compares are needed for boundary conditions */
3376 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3379 if (tree->values.switchVals.swDefault)
3381 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3385 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3389 falseLabel = newiTempLabel (buffer);
3391 /* so we can create a jumptable */
3392 /* first we rule out the boundary conditions */
3393 /* if only optimization says so */
3396 sym_link *cetype = getSpec (operandType (cond));
3397 /* no need to check the lower bound if
3398 the condition is unsigned & minimum value is zero */
3399 if (!(min == 0 && IS_UNSIGNED (cetype)))
3401 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3402 ic = newiCodeCondition (boundary, falseLabel, NULL);
3406 /* now for upper bounds */
3407 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3408 ic = newiCodeCondition (boundary, falseLabel, NULL);
3412 /* if the min is not zero then we no make it zero */
3415 cond = geniCodeSubtract (cond, operandFromLit (min));
3416 if (!IS_LITERAL(getSpec(operandType(cond))))
3417 setOperandType (cond, UCHARTYPE);
3420 /* now create the jumptable */
3421 ic = newiCode (JUMPTABLE, NULL, NULL);
3422 IC_JTCOND (ic) = cond;
3423 IC_JTLABELS (ic) = labels;
3428 /*-----------------------------------------------------------------*/
3429 /* geniCodeSwitch - changes a switch to a if statement */
3430 /*-----------------------------------------------------------------*/
3432 geniCodeSwitch (ast * tree,int lvl)
3435 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3436 value *caseVals = tree->values.switchVals.swVals;
3437 symbol *trueLabel, *falseLabel;
3439 /* If the condition is a literal, then just jump to the */
3440 /* appropriate case label. */
3441 if (IS_LITERAL(getSpec(operandType(cond))))
3443 int switchVal, caseVal;
3445 switchVal = (int) floatFromVal (cond->operand.valOperand);
3448 caseVal = (int) floatFromVal (caseVals);
3449 if (caseVal == switchVal)
3451 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3452 tree->values.switchVals.swNum, caseVal);
3453 trueLabel = newiTempLabel (buffer);
3454 geniCodeGoto (trueLabel);
3457 caseVals = caseVals->next;
3459 goto defaultOrBreak;
3462 /* if we can make this a jump table */
3463 if (geniCodeJumpTable (cond, caseVals, tree))
3464 goto jumpTable; /* no need for the comparison */
3466 /* for the cases defined do */
3470 operand *compare = geniCodeLogic (cond,
3471 operandFromValue (caseVals),
3474 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3475 tree->values.switchVals.swNum,
3476 (int) floatFromVal (caseVals));
3477 trueLabel = newiTempLabel (buffer);
3479 ic = newiCodeCondition (compare, trueLabel, NULL);
3481 caseVals = caseVals->next;
3486 /* if default is present then goto break else break */
3487 if (tree->values.switchVals.swDefault)
3489 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3493 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3496 falseLabel = newiTempLabel (buffer);
3497 geniCodeGoto (falseLabel);
3500 ast2iCode (tree->right,lvl+1);
3503 /*-----------------------------------------------------------------*/
3504 /* geniCodeInline - intermediate code for inline assembler */
3505 /*-----------------------------------------------------------------*/
3507 geniCodeInline (ast * tree)
3511 ic = newiCode (INLINEASM, NULL, NULL);
3512 IC_INLINE (ic) = tree->values.inlineasm;
3516 /*-----------------------------------------------------------------*/
3517 /* geniCodeArrayInit - intermediate code for array initializer */
3518 /*-----------------------------------------------------------------*/
3520 geniCodeArrayInit (ast * tree, operand *array)
3524 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3525 ic = newiCode (ARRAYINIT, array, NULL);
3526 IC_ARRAYILIST (ic) = tree->values.constlist;
3528 operand *left=newOperand(), *right=newOperand();
3529 left->type=right->type=SYMBOL;
3530 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3531 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3532 ic = newiCode (ARRAYINIT, left, right);
3537 /*-----------------------------------------------------------------*/
3538 /* geniCodeCritical - intermediate code for a critical statement */
3539 /*-----------------------------------------------------------------*/
3541 geniCodeCritical (ast *tree, int lvl)
3546 /* If op is NULL, the original interrupt state will saved on */
3547 /* the stack. Otherwise, it will be saved in op. */
3549 /* Generate a save of the current interrupt state & disabled */
3550 ic = newiCode (CRITICAL, NULL, NULL);
3551 IC_RESULT (ic) = op;
3554 /* Generate the critical code sequence */
3555 if (tree->left && tree->left->type == EX_VALUE)
3556 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3558 ast2iCode (tree->left,lvl+1);
3560 /* Generate a restore of the original interrupt state */
3561 ic = newiCode (ENDCRITICAL, NULL, op);
3565 /*-----------------------------------------------------------------*/
3566 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3567 /* particular case. Ie : assigning or dereferencing array or ptr */
3568 /*-----------------------------------------------------------------*/
3569 set * lvaluereqSet = NULL;
3570 typedef struct lvalItem
3577 /*-----------------------------------------------------------------*/
3578 /* addLvaluereq - add a flag for lvalreq for current ast level */
3579 /*-----------------------------------------------------------------*/
3580 void addLvaluereq(int lvl)
3582 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3585 addSetHead(&lvaluereqSet,lpItem);
3588 /*-----------------------------------------------------------------*/
3589 /* delLvaluereq - del a flag for lvalreq for current ast level */
3590 /*-----------------------------------------------------------------*/
3594 lpItem = getSet(&lvaluereqSet);
3595 if(lpItem) Safe_free(lpItem);
3597 /*-----------------------------------------------------------------*/
3598 /* clearLvaluereq - clear lvalreq flag */
3599 /*-----------------------------------------------------------------*/
3600 void clearLvaluereq()
3603 lpItem = peekSet(lvaluereqSet);
3604 if(lpItem) lpItem->req = 0;
3606 /*-----------------------------------------------------------------*/
3607 /* getLvaluereq - get the last lvalreq level */
3608 /*-----------------------------------------------------------------*/
3609 int getLvaluereqLvl()
3612 lpItem = peekSet(lvaluereqSet);
3613 if(lpItem) return lpItem->lvl;
3616 /*-----------------------------------------------------------------*/
3617 /* isLvaluereq - is lvalreq valid for this level ? */
3618 /*-----------------------------------------------------------------*/
3619 int isLvaluereq(int lvl)
3622 lpItem = peekSet(lvaluereqSet);
3623 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3627 /*-----------------------------------------------------------------*/
3628 /* ast2iCode - creates an icodeList from an ast */
3629 /*-----------------------------------------------------------------*/
3631 ast2iCode (ast * tree,int lvl)
3633 operand *left = NULL;
3634 operand *right = NULL;
3638 /* set the global variables for filename & line number */
3640 filename = tree->filename;
3642 lineno = tree->lineno;
3644 block = tree->block;
3646 scopeLevel = tree->level;
3648 seqPoint = tree->seqPoint;
3650 if (tree->type == EX_VALUE)
3651 return operandFromValue (tree->opval.val);
3653 if (tree->type == EX_LINK)
3654 return operandFromLink (tree->opval.lnk);
3656 /* if we find a nullop */
3657 if (tree->type == EX_OP &&
3658 (tree->opval.op == NULLOP ||
3659 tree->opval.op == BLOCK))
3661 if (tree->left && tree->left->type == EX_VALUE)
3662 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3664 ast2iCode (tree->left,lvl+1);
3665 if (tree->right && tree->right->type == EX_VALUE)
3666 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3668 ast2iCode (tree->right,lvl+1);
3672 /* special cases for not evaluating */
3673 if (tree->opval.op != ':' &&
3674 tree->opval.op != '?' &&
3675 tree->opval.op != CALL &&
3676 tree->opval.op != IFX &&
3677 tree->opval.op != LABEL &&
3678 tree->opval.op != GOTO &&
3679 tree->opval.op != SWITCH &&
3680 tree->opval.op != FUNCTION &&
3681 tree->opval.op != INLINEASM &&
3682 tree->opval.op != CRITICAL)
3685 if (IS_ASSIGN_OP (tree->opval.op) ||
3686 IS_DEREF_OP (tree) ||
3687 (tree->opval.op == '&' && !tree->right) ||
3688 tree->opval.op == PTR_OP)
3691 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3692 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3695 left = operandFromAst (tree->left,lvl);
3697 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3698 left = geniCodeRValue (left, TRUE);
3702 left = operandFromAst (tree->left,lvl);
3704 if (tree->opval.op == INC_OP ||
3705 tree->opval.op == DEC_OP)
3708 right = operandFromAst (tree->right,lvl);
3713 right = operandFromAst (tree->right,lvl);
3717 /* now depending on the type of operand */
3718 /* this will be a biggy */
3719 switch (tree->opval.op)
3722 case '[': /* array operation */
3724 //sym_link *ltype = operandType (left);
3725 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3726 left = geniCodeRValue (left, FALSE);
3727 right = geniCodeRValue (right, TRUE);
3730 return geniCodeArray (left, right,lvl);
3732 case '.': /* structure dereference */
3733 if (IS_PTR (operandType (left)))
3734 left = geniCodeRValue (left, TRUE);
3736 left = geniCodeRValue (left, FALSE);
3738 return geniCodeStruct (left, right, tree->lvalue);
3740 case PTR_OP: /* structure pointer dereference */
3743 pType = operandType (left);
3744 left = geniCodeRValue (left, TRUE);
3746 setOClass (pType, getSpec (operandType (left)));
3749 return geniCodeStruct (left, right, tree->lvalue);
3751 case INC_OP: /* increment operator */
3753 return geniCodePostInc (left);
3755 return geniCodePreInc (right, tree->lvalue);
3757 case DEC_OP: /* decrement operator */
3759 return geniCodePostDec (left);
3761 return geniCodePreDec (right, tree->lvalue);
3763 case '&': /* bitwise and or address of operator */
3765 { /* this is a bitwise operator */
3766 left = geniCodeRValue (left, FALSE);
3767 right = geniCodeRValue (right, FALSE);
3768 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3771 return geniCodeAddressOf (left);
3773 case '|': /* bitwise or & xor */
3775 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3776 geniCodeRValue (right, FALSE),
3781 return geniCodeDivision (geniCodeRValue (left, FALSE),
3782 geniCodeRValue (right, FALSE));
3785 return geniCodeModulus (geniCodeRValue (left, FALSE),
3786 geniCodeRValue (right, FALSE));
3789 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3790 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3792 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3796 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3797 geniCodeRValue (right, FALSE));
3799 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3803 return geniCodeAdd (geniCodeRValue (left, FALSE),
3804 geniCodeRValue (right, FALSE),lvl);
3806 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3809 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3810 geniCodeRValue (right, FALSE));
3813 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3814 geniCodeRValue (right, FALSE));
3816 #if 0 // this indeed needs a second thought
3820 // let's keep this simple: get the rvalue we need
3821 op=geniCodeRValue (right, FALSE);
3822 // now cast it to whatever we want
3823 op=geniCodeCast (operandType(left), op, FALSE);
3824 // if this is going to be used as an lvalue, make it so
3830 #else // bug #604575, is it a bug ????
3831 return geniCodeCast (operandType (left),
3832 geniCodeRValue (right, FALSE), FALSE);
3839 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3844 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3845 setOperandType (op, UCHARTYPE);
3856 /* different compilers (even different gccs) evaluate
3857 the two calls in a different order. to get the same
3858 result on all machines we've to specify a clear sequence.
3859 return geniCodeLogic (geniCodeRValue (left, FALSE),
3860 geniCodeRValue (right, FALSE),
3864 operand *leftOp, *rightOp;
3866 rightOp = geniCodeRValue (right, FALSE);
3867 leftOp = geniCodeRValue (left , FALSE);
3869 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3872 return geniCodeConditional (tree,lvl);
3875 return operandFromLit (getSize (tree->right->ftype));
3879 sym_link *rtype = operandType (right);
3880 sym_link *ltype = operandType (left);
3881 if (IS_PTR (rtype) && IS_ITEMP (right)
3882 && right->isaddr && compareType (rtype->next, ltype) == 1)
3883 right = geniCodeRValue (right, TRUE);
3885 right = geniCodeRValue (right, FALSE);
3887 geniCodeAssign (left, right, 0);
3892 geniCodeAssign (left,
3893 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3895 geniCodeRValue (right, FALSE),FALSE), 0);
3899 geniCodeAssign (left,
3900 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3902 geniCodeRValue (right, FALSE)), 0);
3905 geniCodeAssign (left,
3906 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3908 geniCodeRValue (right, FALSE)), 0);
3911 sym_link *rtype = operandType (right);
3912 sym_link *ltype = operandType (left);
3913 if (IS_PTR (rtype) && IS_ITEMP (right)
3914 && right->isaddr && compareType (rtype->next, ltype) == 1)
3915 right = geniCodeRValue (right, TRUE);
3917 right = geniCodeRValue (right, FALSE);
3920 return geniCodeAssign (left,
3921 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3927 sym_link *rtype = operandType (right);
3928 sym_link *ltype = operandType (left);
3929 if (IS_PTR (rtype) && IS_ITEMP (right)
3930 && right->isaddr && compareType (rtype->next, ltype) == 1)
3932 right = geniCodeRValue (right, TRUE);
3936 right = geniCodeRValue (right, FALSE);
3939 geniCodeAssign (left,
3940 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3946 geniCodeAssign (left,
3947 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3949 geniCodeRValue (right, FALSE)), 0);
3952 geniCodeAssign (left,
3953 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3955 geniCodeRValue (right, FALSE)), 0);
3958 geniCodeAssign (left,
3959 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3961 geniCodeRValue (right, FALSE),
3963 operandType (left)), 0);
3966 geniCodeAssign (left,
3967 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3969 geniCodeRValue (right, FALSE),
3971 operandType (left)), 0);
3974 geniCodeAssign (left,
3975 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3977 geniCodeRValue (right, FALSE),
3979 operandType (left)), 0);
3981 return geniCodeRValue (right, FALSE);
3984 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3987 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3988 return ast2iCode (tree->right,lvl+1);
3991 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3992 return ast2iCode (tree->right,lvl+1);
3995 geniCodeFunctionBody (tree,lvl);
3999 geniCodeReturn (right);
4003 geniCodeIfx (tree,lvl);
4007 geniCodeSwitch (tree,lvl);
4011 geniCodeInline (tree);
4015 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4019 geniCodeCritical (tree, lvl);
4025 /*-----------------------------------------------------------------*/
4026 /* reverseICChain - gets from the list and creates a linkedlist */
4027 /*-----------------------------------------------------------------*/
4034 while ((loop = getSet (&iCodeChain)))
4046 /*-----------------------------------------------------------------*/
4047 /* iCodeFromAst - given an ast will convert it to iCode */
4048 /*-----------------------------------------------------------------*/
4050 iCodeFromAst (ast * tree)
4052 returnLabel = newiTempLabel ("_return");
4053 entryLabel = newiTempLabel ("_entry");
4055 return reverseiCChain ();
4058 static const char *opTypeToStr(OPTYPE op)
4062 case SYMBOL: return "symbol";
4063 case VALUE: return "value";
4064 case TYPE: return "type";
4066 return "undefined type";
4070 operand *validateOpType(operand *op,
4077 if (op && op->type == type)
4082 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4083 " expected %s, got %s\n",
4084 macro, args, file, line,
4085 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4087 return op; // never reached, makes compiler happy.