1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
43 symbol *returnLabel; /* function return label */
44 symbol *entryLabel; /* function entry label */
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeDivision (operand *, operand *);
49 operand *geniCodeAssign (operand *, operand *, int);
50 static operand *geniCodeArray (operand *, operand *,int);
51 static operand *geniCodeArray2Ptr (operand *);
52 operand *geniCodeRValue (operand *, bool);
53 operand *geniCodeDerefPtr (operand *,int);
54 int isLvaluereq(int lvl);
55 void setOClass (sym_link * ptr, sym_link * spec);
56 static operand *geniCodeCast (sym_link *, operand *, bool);
58 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
59 /* forward definition of ic print functions */
60 PRINTFUNC (picGetValueAtAddr);
61 PRINTFUNC (picSetValueAtAddr);
62 PRINTFUNC (picAddrOf);
63 PRINTFUNC (picGeneric);
64 PRINTFUNC (picGenericOne);
66 PRINTFUNC (picAssign);
70 PRINTFUNC (picJumpTable);
71 PRINTFUNC (picInline);
72 PRINTFUNC (picReceive);
73 PRINTFUNC (picDummyRead);
74 PRINTFUNC (picCritical);
75 PRINTFUNC (picEndCritical);
77 iCodeTable codeTable[] =
79 {'!', "not", picGenericOne, NULL},
80 {'~', "~", picGenericOne, NULL},
81 {RRC, "rrc", picGenericOne, NULL},
82 {RLC, "rlc", picGenericOne, NULL},
83 {GETHBIT, "ghbit", picGenericOne, NULL},
84 {UNARYMINUS, "-", picGenericOne, NULL},
85 {IPUSH, "push", picGenericOne, NULL},
86 {IPOP, "pop", picGenericOne, NULL},
87 {CALL, "call", picGenericOne, NULL},
88 {PCALL, "pcall", picGenericOne, NULL},
89 {FUNCTION, "proc", picGenericOne, NULL},
90 {ENDFUNCTION, "eproc", picGenericOne, NULL},
91 {RETURN, "ret", picGenericOne, NULL},
92 {'+', "+", picGeneric, NULL},
93 {'-', "-", picGeneric, NULL},
94 {'*', "*", picGeneric, NULL},
95 {'/', "/", picGeneric, NULL},
96 {'%', "%", picGeneric, NULL},
97 {'>', ">", picGeneric, NULL},
98 {'<', "<", picGeneric, NULL},
99 {LE_OP, "<=", picGeneric, NULL},
100 {GE_OP, ">=", picGeneric, NULL},
101 {EQ_OP, "==", picGeneric, NULL},
102 {NE_OP, "!=", picGeneric, NULL},
103 {AND_OP, "&&", picGeneric, NULL},
104 {OR_OP, "||", picGeneric, NULL},
105 {'^', "^", picGeneric, NULL},
106 {'|', "|", picGeneric, NULL},
107 {BITWISEAND, "&", picGeneric, NULL},
108 {LEFT_OP, "<<", picGeneric, NULL},
109 {RIGHT_OP, ">>", picGeneric, NULL},
110 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
111 {ADDRESS_OF, "&", picAddrOf, NULL},
112 {CAST, "<>", picCast, NULL},
113 {'=', ":=", picAssign, NULL},
114 {LABEL, "", picLabel, NULL},
115 {GOTO, "", picGoto, NULL},
116 {JUMPTABLE, "jtab", picJumpTable, NULL},
117 {IFX, "if", picIfx, NULL},
118 {INLINEASM, "", picInline, NULL},
119 {RECEIVE, "recv", picReceive, NULL},
120 {SEND, "send", picGenericOne, NULL},
121 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
122 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
123 {CRITICAL, "critical_start", picCritical, NULL},
124 {ENDCRITICAL, "critical_end", picEndCritical, NULL}
127 /*-----------------------------------------------------------------*/
128 /* checkConstantRange: check a constant against the type */
129 /*-----------------------------------------------------------------*/
132 /* pedantic=0: allmost anything is allowed as long as the absolute
133 value is within the bit range of the type, and -1 is treated as
134 0xf..f for unsigned types (e.g. in assign)
135 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
136 pedantic>1: "char c=200" is not allowed (evaluates to -56)
139 void checkConstantRange(sym_link *ltype, value *val, char *msg,
146 max = pow ((double)2.0, (double)bitsForType(ltype));
148 if (IS_LONG(val->type)) {
149 if (IS_UNSIGNED(val->type)) {
150 v=SPEC_CVAL(val->type).v_ulong;
152 v=SPEC_CVAL(val->type).v_long;
155 if (IS_UNSIGNED(val->type)) {
156 v=SPEC_CVAL(val->type).v_uint;
158 v=SPEC_CVAL(val->type).v_int;
164 // this could be a good idea
165 if (options.pedantic)
169 if (IS_FLOAT(ltype)) {
174 if (!IS_UNSIGNED(val->type) && v<0) {
176 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
182 // if very pedantic: "char c=200" is not allowed
183 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
184 max = max/2 + negative;
191 #if 0 // temporary disabled, leaving the warning as a reminder
193 SNPRINTF (message, sizeof(message), "for %s %s in %s",
194 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
195 nounName(ltype), msg);
196 werror (W_CONST_RANGE, message);
204 /*-----------------------------------------------------------------*/
205 /* operandName - returns the name of the operand */
206 /*-----------------------------------------------------------------*/
208 printOperand (operand * op, FILE * file)
225 opetype = getSpec (operandType (op));
226 if (IS_FLOAT (opetype))
227 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
229 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
230 printTypeChain (operandType (op), file);
237 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
238 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
240 OP_LIVEFROM (op), OP_LIVETO (op),
241 OP_SYMBOL (op)->stack,
242 op->isaddr, OP_SYMBOL (op)->isreqv,
243 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
244 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
248 printTypeChain (operandType (op), file);
249 if (SPIL_LOC (op) && IS_ITEMP (op))
250 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
255 /* if assigned to registers */
256 if (OP_SYMBOL (op)->nRegs)
258 if (OP_SYMBOL (op)->isspilt)
260 if (!OP_SYMBOL (op)->remat)
261 if (OP_SYMBOL (op)->usl.spillLoc)
262 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
263 OP_SYMBOL (op)->usl.spillLoc->rname :
264 OP_SYMBOL (op)->usl.spillLoc->name));
266 fprintf (file, "[err]");
268 fprintf (file, "[remat]");
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
280 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
281 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
282 /* if assigned to registers */
283 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
287 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
288 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
289 OP_SYMBOL (op)->regs[i]->name :
298 printTypeChain (op->operand.typeOperand, file);
304 fprintf (file, "\n");
309 /*-----------------------------------------------------------------*/
310 /* print functions */
311 /*-----------------------------------------------------------------*/
312 PRINTFUNC (picGetValueAtAddr)
315 printOperand (IC_RESULT (ic), of);
318 printOperand (IC_LEFT (ic), of);
324 PRINTFUNC (picSetValueAtAddr)
328 printOperand (IC_LEFT (ic), of);
329 fprintf (of, "] = ");
330 printOperand (IC_RIGHT (ic), of);
334 PRINTFUNC (picAddrOf)
337 printOperand (IC_RESULT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
341 fprintf (of, " = &[");
342 printOperand (IC_LEFT (ic), of);
345 if (IS_ITEMP (IC_LEFT (ic)))
346 fprintf (of, " offsetAdd ");
349 printOperand (IC_RIGHT (ic), of);
351 if (IS_ITEMP (IC_LEFT (ic)))
357 PRINTFUNC (picJumpTable)
362 fprintf (of, "%s\t", s);
363 printOperand (IC_JTCOND (ic), of);
365 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
366 sym = setNextItem (IC_JTLABELS (ic)))
367 fprintf (of, "\t\t\t%s\n", sym->name);
370 PRINTFUNC (picGeneric)
373 printOperand (IC_RESULT (ic), of);
375 printOperand (IC_LEFT (ic), of);
376 fprintf (of, " %s ", s);
377 printOperand (IC_RIGHT (ic), of);
381 PRINTFUNC (picGenericOne)
386 printOperand (IC_RESULT (ic), of);
392 fprintf (of, "%s ", s);
393 printOperand (IC_LEFT (ic), of);
396 if (!IC_RESULT (ic) && !IC_LEFT (ic))
399 if (ic->op == SEND || ic->op == RECEIVE) {
400 fprintf(of,"{argreg = %d}",ic->argreg);
408 printOperand (IC_RESULT (ic), of);
410 printOperand (IC_LEFT (ic), of);
411 printOperand (IC_RIGHT (ic), of);
416 PRINTFUNC (picAssign)
420 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
423 printOperand (IC_RESULT (ic), of);
425 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
428 fprintf (of, " %s ", s);
429 printOperand (IC_RIGHT (ic), of);
436 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
442 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
449 printOperand (IC_COND (ic), of);
452 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
455 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
457 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
461 PRINTFUNC (picInline)
463 fprintf (of, "%s", IC_INLINE (ic));
466 PRINTFUNC (picReceive)
468 printOperand (IC_RESULT (ic), of);
469 fprintf (of, " = %s ", s);
470 printOperand (IC_LEFT (ic), of);
474 PRINTFUNC (picDummyRead)
477 fprintf (of, "%s ", s);
478 printOperand (IC_RIGHT (ic), of);
482 PRINTFUNC (picCritical)
486 printOperand (IC_RESULT (ic), of);
488 fprintf (of, "(stack)");
489 fprintf (of, " = %s ", s);
493 PRINTFUNC (picEndCritical)
496 fprintf (of, "%s = ", s);
498 printOperand (IC_RIGHT (ic), of);
500 fprintf (of, "(stack)");
504 /*-----------------------------------------------------------------*/
505 /* piCode - prints one iCode */
506 /*-----------------------------------------------------------------*/
508 piCode (void *item, FILE * of)
516 icTab = getTableEntry (ic->op);
517 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
518 ic->filename, ic->lineno,
519 ic->seq, ic->key, ic->depth, ic->supportRtn);
520 icTab->iCodePrint (of, ic, icTab->printName);
526 printiCChain(ic,stdout);
528 /*-----------------------------------------------------------------*/
529 /* printiCChain - prints intermediate code for humans */
530 /*-----------------------------------------------------------------*/
532 printiCChain (iCode * icChain, FILE * of)
539 for (loop = icChain; loop; loop = loop->next)
541 if ((icTab = getTableEntry (loop->op)))
543 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
544 loop->filename, loop->lineno,
545 loop->seq, loop->key, loop->depth, loop->supportRtn);
547 icTab->iCodePrint (of, loop, icTab->printName);
553 /*-----------------------------------------------------------------*/
554 /* newOperand - allocate, init & return a new iCode */
555 /*-----------------------------------------------------------------*/
561 op = Safe_alloc ( sizeof (operand));
567 /*-----------------------------------------------------------------*/
568 /* newiCode - create and return a new iCode entry initialised */
569 /*-----------------------------------------------------------------*/
571 newiCode (int op, operand * left, operand * right)
575 ic = Safe_alloc ( sizeof (iCode));
577 ic->seqPoint = seqPoint;
579 ic->filename = filename;
581 ic->level = scopeLevel;
583 ic->key = iCodeKey++;
585 IC_RIGHT (ic) = right;
590 /*-----------------------------------------------------------------*/
591 /* newiCode for conditional statements */
592 /*-----------------------------------------------------------------*/
594 newiCodeCondition (operand * condition,
600 if (IS_VOID(operandType(condition))) {
601 werror(E_VOID_VALUE_USED);
604 ic = newiCode (IFX, NULL, NULL);
605 IC_COND (ic) = condition;
606 IC_TRUE (ic) = trueLabel;
607 IC_FALSE (ic) = falseLabel;
611 /*-----------------------------------------------------------------*/
612 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
613 /*-----------------------------------------------------------------*/
615 newiCodeLabelGoto (int op, symbol * label)
619 ic = newiCode (op, NULL, NULL);
623 IC_RIGHT (ic) = NULL;
624 IC_RESULT (ic) = NULL;
628 /*-----------------------------------------------------------------*/
629 /* newiTemp - allocate & return a newItemp Variable */
630 /*-----------------------------------------------------------------*/
638 SNPRINTF (buffer, sizeof(buffer), "%s", s);
642 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
645 itmp = newSymbol (buffer, 1);
646 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
652 /*-----------------------------------------------------------------*/
653 /* newiTempLabel - creates a temp variable label */
654 /*-----------------------------------------------------------------*/
656 newiTempLabel (char *s)
660 /* check if this alredy exists */
661 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
666 itmplbl = newSymbol (s, 1);
670 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
671 itmplbl = newSymbol (buffer, 1);
676 itmplbl->key = labelKey++;
677 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
681 /*-----------------------------------------------------------------*/
682 /* newiTempPreheaderLabel - creates a new preheader label */
683 /*-----------------------------------------------------------------*/
685 newiTempPreheaderLabel ()
689 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
690 itmplbl = newSymbol (buffer, 1);
694 itmplbl->key = labelKey++;
695 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
700 /*-----------------------------------------------------------------*/
701 /* initiCode - initialises some iCode related stuff */
702 /*-----------------------------------------------------------------*/
709 /*-----------------------------------------------------------------*/
710 /* copyiCode - make a copy of the iCode given */
711 /*-----------------------------------------------------------------*/
713 copyiCode (iCode * ic)
715 iCode *nic = newiCode (ic->op, NULL, NULL);
717 nic->lineno = ic->lineno;
718 nic->filename = ic->filename;
719 nic->block = ic->block;
720 nic->level = ic->level;
721 nic->parmBytes = ic->parmBytes;
723 /* deal with the special cases first */
727 IC_COND (nic) = operandFromOperand (IC_COND (ic));
728 IC_TRUE (nic) = IC_TRUE (ic);
729 IC_FALSE (nic) = IC_FALSE (ic);
733 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
734 IC_JTLABELS (nic) = IC_JTLABELS (ic);
739 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
740 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
744 IC_INLINE (nic) = IC_INLINE (ic);
748 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
752 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
753 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
754 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
760 /*-----------------------------------------------------------------*/
761 /* getTableEntry - gets the table entry for the given operator */
762 /*-----------------------------------------------------------------*/
764 getTableEntry (int oper)
768 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
769 if (oper == codeTable[i].icode)
770 return &codeTable[i];
775 /*-----------------------------------------------------------------*/
776 /* newiTempOperand - new intermediate temp operand */
777 /*-----------------------------------------------------------------*/
779 newiTempOperand (sym_link * type, char throwType)
782 operand *op = newOperand ();
786 itmp = newiTemp (NULL);
788 etype = getSpec (type);
790 if (IS_LITERAL (etype))
793 /* copy the type information */
795 itmp->etype = getSpec (itmp->type = (throwType ? type :
796 copyLinkChain (type)));
797 if (IS_LITERAL (itmp->etype))
799 SPEC_SCLS (itmp->etype) = S_REGISTER;
800 SPEC_OCLS (itmp->etype) = reg;
803 op->operand.symOperand = itmp;
804 op->key = itmp->key = ++operandKey;
808 /*-----------------------------------------------------------------*/
809 /* operandType - returns the type chain for an operand */
810 /*-----------------------------------------------------------------*/
812 operandType (operand * op)
814 /* depending on type of operand */
819 return op->operand.valOperand->type;
822 return op->operand.symOperand->type;
825 return op->operand.typeOperand;
827 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
828 " operand type not known ");
829 assert (0); /* should never come here */
830 /* Just to keep the compiler happy */
831 return (sym_link *) 0;
835 /*-----------------------------------------------------------------*/
836 /* isParamterToCall - will return 1 if op is a parameter to args */
837 /*-----------------------------------------------------------------*/
839 isParameterToCall (value * args, operand * op)
843 wassert (IS_SYMOP(op));
848 isSymbolEqual (op->operand.symOperand, tval->sym))
855 /*-----------------------------------------------------------------*/
856 /* isOperandGlobal - return 1 if operand is a global variable */
857 /*-----------------------------------------------------------------*/
859 isOperandGlobal (operand * op)
868 (op->operand.symOperand->level == 0 ||
869 IS_STATIC (op->operand.symOperand->etype) ||
870 IS_EXTERN (op->operand.symOperand->etype))
877 /*-----------------------------------------------------------------*/
878 /* isOperandVolatile - return 1 if the operand is volatile */
879 /*-----------------------------------------------------------------*/
881 isOperandVolatile (operand * op, bool chkTemp)
886 if (IS_ITEMP (op) && !chkTemp)
889 opetype = getSpec (optype = operandType (op));
891 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
894 if (IS_VOLATILE (opetype))
899 /*-----------------------------------------------------------------*/
900 /* isOperandLiteral - returns 1 if an operand contains a literal */
901 /*-----------------------------------------------------------------*/
903 isOperandLiteral (operand * op)
910 opetype = getSpec (operandType (op));
912 if (IS_LITERAL (opetype))
918 /*-----------------------------------------------------------------*/
919 /* isOperandInFarSpace - will return true if operand is in farSpace */
920 /*-----------------------------------------------------------------*/
922 isOperandInFarSpace (operand * op)
932 if (!IS_TRUE_SYMOP (op))
935 etype = SPIL_LOC (op)->etype;
941 etype = getSpec (operandType (op));
943 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
946 /*------------------------------------------------------------------*/
947 /* isOperandInDirSpace - will return true if operand is in dirSpace */
948 /*------------------------------------------------------------------*/
950 isOperandInDirSpace (operand * op)
960 if (!IS_TRUE_SYMOP (op))
963 etype = SPIL_LOC (op)->etype;
969 etype = getSpec (operandType (op));
971 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
974 /*--------------------------------------------------------------------*/
975 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
976 /*--------------------------------------------------------------------*/
978 isOperandInCodeSpace (operand * op)
988 etype = getSpec (operandType (op));
990 if (!IS_TRUE_SYMOP (op))
993 etype = SPIL_LOC (op)->etype;
999 etype = getSpec (operandType (op));
1001 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1004 /*-----------------------------------------------------------------*/
1005 /* isOperandOnStack - will return true if operand is on stack */
1006 /*-----------------------------------------------------------------*/
1008 isOperandOnStack (operand * op)
1018 etype = getSpec (operandType (op));
1019 if (IN_STACK (etype) ||
1020 OP_SYMBOL(op)->onStack ||
1021 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1027 /*-----------------------------------------------------------------*/
1028 /* isOclsExpensive - will return true if accesses to an output */
1029 /* storage class are expensive */
1030 /*-----------------------------------------------------------------*/
1032 isOclsExpensive (struct memmap *oclass)
1034 if (port->oclsExpense)
1035 return port->oclsExpense (oclass) > 0;
1037 /* In the absence of port specific guidance, assume only */
1038 /* farspace is expensive. */
1039 return IN_FARSPACE (oclass);
1042 /*-----------------------------------------------------------------*/
1043 /* operandLitValue - literal value of an operand */
1044 /*-----------------------------------------------------------------*/
1046 operandLitValue (operand * op)
1048 assert (isOperandLiteral (op));
1050 return floatFromVal (op->operand.valOperand);
1053 /*-----------------------------------------------------------------*/
1054 /* getBuiltInParms - returns parameters to a builtin functions */
1055 /*-----------------------------------------------------------------*/
1056 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1061 /* builtin functions uses only SEND for parameters */
1062 while (ic->op != CALL) {
1063 assert(ic->op == SEND && ic->builtinSEND);
1064 ic->generated = 1; /* mark the icode as generated */
1065 parms[*pcount] = IC_LEFT(ic);
1071 /* make sure this is a builtin function call */
1072 assert(IS_SYMOP(IC_LEFT(ic)));
1073 ftype = operandType(IC_LEFT(ic));
1074 assert(IFFUNC_ISBUILTIN(ftype));
1078 /*-----------------------------------------------------------------*/
1079 /* operandOperation - performs operations on operands */
1080 /*-----------------------------------------------------------------*/
1082 operandOperation (operand * left, operand * right,
1083 int op, sym_link * type)
1085 sym_link *let , *ret=NULL;
1086 operand *retval = (operand *) 0;
1088 assert (isOperandLiteral (left));
1089 let = getSpec(operandType(left));
1091 assert (isOperandLiteral (right));
1092 ret = getSpec(operandType(right));
1098 retval = operandFromValue (valCastLiteral (type,
1099 operandLitValue (left) +
1100 operandLitValue (right)));
1103 retval = operandFromValue (valCastLiteral (type,
1104 operandLitValue (left) -
1105 operandLitValue (right)));
1109 retval = operandFromValue (valCastLiteral (type,
1110 operandLitValue (left) *
1111 operandLitValue (right)));
1112 This could be all we've to do, but with gcc we've to take care about
1113 overflows. Two examples:
1114 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1115 significant bits are lost (52 in fraction, 63 bits would be
1116 necessary to keep full precision).
1117 If the resulting double value is greater than ULONG_MAX (resp.
1118 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1121 /* if it is not a specifier then we can assume that */
1122 /* it will be an unsigned long */
1123 if (IS_INT (type) ||
1126 /* long is handled here, because it can overflow with double */
1127 if (IS_LONG (type) ||
1129 /* signed and unsigned mul are the same, as long as the precision
1130 of the result isn't bigger than the precision of the operands. */
1131 retval = operandFromValue (valCastLiteral (type,
1132 (TYPE_UDWORD) operandLitValue (left) *
1133 (TYPE_UDWORD) operandLitValue (right)));
1134 else if (IS_UNSIGNED (type)) /* unsigned int */
1136 /* unsigned int is handled here in order to detect overflow */
1137 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1138 (TYPE_UWORD) operandLitValue (right);
1140 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1141 if (ul != (TYPE_UWORD) ul)
1144 else /* signed int */
1146 /* signed int is handled here in order to detect overflow */
1147 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1148 (TYPE_WORD) operandLitValue (right);
1150 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1151 if (l != (TYPE_WORD) l)
1156 /* all others go here: */
1157 retval = operandFromValue (valCastLiteral (type,
1158 operandLitValue (left) *
1159 operandLitValue (right)));
1162 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1164 werror (E_DIVIDE_BY_ZERO);
1170 if (IS_UNSIGNED (type))
1172 SPEC_USIGN (let) = 1;
1173 SPEC_USIGN (ret) = 1;
1174 retval = operandFromValue (valCastLiteral (type,
1175 (TYPE_UDWORD) operandLitValue (left) /
1176 (TYPE_UDWORD) operandLitValue (right)));
1180 retval = operandFromValue (valCastLiteral (type,
1181 operandLitValue (left) /
1182 operandLitValue (right)));
1187 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1189 werror (E_DIVIDE_BY_ZERO);
1194 if (IS_UNSIGNED (type))
1195 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1196 (TYPE_UDWORD) operandLitValue (right));
1198 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1199 (TYPE_DWORD) operandLitValue (right));
1203 /* The number of left shifts is always unsigned. Signed doesn't make
1204 sense here. Shifting by a negative number is impossible. */
1205 retval = operandFromValue (valCastLiteral (type,
1206 ((TYPE_UDWORD) operandLitValue (left) <<
1207 (TYPE_UDWORD) operandLitValue (right))));
1210 /* The number of right shifts is always unsigned. Signed doesn't make
1211 sense here. Shifting by a negative number is impossible. */
1212 if (IS_UNSIGNED(let))
1213 /* unsigned: logic shift right */
1214 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1215 (TYPE_UDWORD) operandLitValue (right));
1217 /* signed: arithmetic shift right */
1218 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1219 (TYPE_UDWORD) operandLitValue (right));
1222 /* this op doesn't care about signedness */
1226 l = (TYPE_UDWORD) operandLitValue (left);
1227 if (IS_CHAR(OP_VALUE(left)->type))
1229 else if (!IS_LONG (OP_VALUE(left)->type))
1231 r = (TYPE_UDWORD) operandLitValue (right);
1232 if (IS_CHAR(OP_VALUE(right)->type))
1234 else if (!IS_LONG (OP_VALUE(right)->type))
1236 retval = operandFromLit (l == r);
1240 retval = operandFromLit (operandLitValue (left) <
1241 operandLitValue (right));
1244 retval = operandFromLit (operandLitValue (left) <=
1245 operandLitValue (right));
1248 retval = operandFromLit (operandLitValue (left) !=
1249 operandLitValue (right));
1252 retval = operandFromLit (operandLitValue (left) >
1253 operandLitValue (right));
1256 retval = operandFromLit (operandLitValue (left) >=
1257 operandLitValue (right));
1260 retval = operandFromValue (valCastLiteral (type,
1261 (TYPE_UDWORD)operandLitValue(left) &
1262 (TYPE_UDWORD)operandLitValue(right)));
1265 retval = operandFromValue (valCastLiteral (type,
1266 (TYPE_UDWORD)operandLitValue(left) |
1267 (TYPE_UDWORD)operandLitValue(right)));
1270 retval = operandFromValue (valCastLiteral (type,
1271 (TYPE_UDWORD)operandLitValue(left) ^
1272 (TYPE_UDWORD)operandLitValue(right)));
1275 retval = operandFromLit (operandLitValue (left) &&
1276 operandLitValue (right));
1279 retval = operandFromLit (operandLitValue (left) ||
1280 operandLitValue (right));
1284 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1286 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1292 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1294 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1300 retval = operandFromValue (valCastLiteral (type,
1301 -1 * operandLitValue (left)));
1305 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1309 retval = operandFromLit (!operandLitValue (left));
1313 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1314 " operandOperation invalid operator ");
1322 /*-----------------------------------------------------------------*/
1323 /* isOperandEqual - compares two operand & return 1 if they r = */
1324 /*-----------------------------------------------------------------*/
1326 isOperandEqual (operand * left, operand * right)
1328 /* if the pointers are equal then they are equal */
1332 /* if either of them null then false */
1333 if (!left || !right)
1336 if (left->type != right->type)
1339 if (IS_SYMOP (left) && IS_SYMOP (right))
1340 return left->key == right->key;
1342 /* if types are the same */
1346 return isSymbolEqual (left->operand.symOperand,
1347 right->operand.symOperand);
1349 return (floatFromVal (left->operand.valOperand) ==
1350 floatFromVal (right->operand.valOperand));
1352 if (compareType (left->operand.typeOperand,
1353 right->operand.typeOperand) == 1)
1360 /*-------------------------------------------------------------------*/
1361 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1362 /*-------------------------------------------------------------------*/
1364 isiCodeEqual (iCode * left, iCode * right)
1366 /* if the same pointer */
1370 /* if either of them null */
1371 if (!left || !right)
1374 /* if operand are the same */
1375 if (left->op == right->op)
1378 /* compare all the elements depending on type */
1379 if (left->op != IFX)
1381 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1383 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1389 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1391 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1393 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1402 /*-----------------------------------------------------------------*/
1403 /* newiTempFromOp - create a temp Operand with same attributes */
1404 /*-----------------------------------------------------------------*/
1406 newiTempFromOp (operand * op)
1416 nop = newiTempOperand (operandType (op), TRUE);
1417 nop->isaddr = op->isaddr;
1418 nop->isvolatile = op->isvolatile;
1419 nop->isGlobal = op->isGlobal;
1420 nop->isLiteral = op->isLiteral;
1421 nop->usesDefs = op->usesDefs;
1422 nop->isParm = op->isParm;
1426 /*-----------------------------------------------------------------*/
1427 /* operand from operand - creates an operand holder for the type */
1428 /*-----------------------------------------------------------------*/
1430 operandFromOperand (operand * op)
1436 nop = newOperand ();
1437 nop->type = op->type;
1438 nop->isaddr = op->isaddr;
1440 nop->isvolatile = op->isvolatile;
1441 nop->isGlobal = op->isGlobal;
1442 nop->isLiteral = op->isLiteral;
1443 nop->usesDefs = op->usesDefs;
1444 nop->isParm = op->isParm;
1449 nop->operand.symOperand = op->operand.symOperand;
1452 nop->operand.valOperand = op->operand.valOperand;
1455 nop->operand.typeOperand = op->operand.typeOperand;
1462 /*-----------------------------------------------------------------*/
1463 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1464 /*-----------------------------------------------------------------*/
1466 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1468 operand *nop = operandFromOperand (op);
1470 if (nop->type == SYMBOL)
1472 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1473 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1479 /*-----------------------------------------------------------------*/
1480 /* operandFromSymbol - creates an operand from a symbol */
1481 /*-----------------------------------------------------------------*/
1483 operandFromSymbol (symbol * sym)
1488 /* if the symbol's type is a literal */
1489 /* then it is an enumerator type */
1490 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1491 return operandFromValue (valFromType (sym->etype));
1494 sym->key = ++operandKey;
1496 /* if this an implicit variable, means struct/union */
1497 /* member so just return it */
1498 if (sym->implicit || IS_FUNC (sym->type))
1502 op->operand.symOperand = sym;
1504 op->isvolatile = isOperandVolatile (op, TRUE);
1505 op->isGlobal = isOperandGlobal (op);
1509 /* under the following conditions create a
1510 register equivalent for a local symbol */
1511 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1512 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1514 (!(options.model == MODEL_FLAT24)) ) &&
1515 options.stackAuto == 0)
1518 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1519 !IS_FUNC (sym->type) && /* not a function */
1520 !sym->_isparm && /* not a parameter */
1521 sym->level && /* is a local variable */
1522 !sym->addrtaken && /* whose address has not been taken */
1523 !sym->reqv && /* does not already have a reg equivalence */
1524 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1525 !IS_STATIC (sym->etype) && /* and not declared static */
1526 !sym->islbl && /* not a label */
1527 ok && /* farspace check */
1528 !IS_BITVAR (sym->etype) /* not a bit variable */
1532 /* we will use it after all optimizations
1533 and before liveRange calculation */
1534 sym->reqv = newiTempOperand (sym->type, 0);
1535 sym->reqv->key = sym->key;
1536 OP_SYMBOL (sym->reqv)->key = sym->key;
1537 OP_SYMBOL (sym->reqv)->isreqv = 1;
1538 OP_SYMBOL (sym->reqv)->islocal = 1;
1539 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1540 SPIL_LOC (sym->reqv) = sym;
1543 if (!IS_AGGREGATE (sym->type))
1547 op->operand.symOperand = sym;
1550 op->isvolatile = isOperandVolatile (op, TRUE);
1551 op->isGlobal = isOperandGlobal (op);
1552 op->isPtr = IS_PTR (operandType (op));
1553 op->isParm = sym->_isparm;
1558 /* itemp = &[_symbol] */
1560 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1561 IC_LEFT (ic)->type = SYMBOL;
1562 IC_LEFT (ic)->operand.symOperand = sym;
1563 IC_LEFT (ic)->key = sym->key;
1564 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1565 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1566 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1569 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1570 if (IS_ARRAY (sym->type))
1572 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1573 IC_RESULT (ic)->isaddr = 0;
1576 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1580 return IC_RESULT (ic);
1583 /*-----------------------------------------------------------------*/
1584 /* operandFromValue - creates an operand from value */
1585 /*-----------------------------------------------------------------*/
1587 operandFromValue (value * val)
1591 /* if this is a symbol then do the symbol thing */
1593 return operandFromSymbol (val->sym);
1595 /* this is not a symbol */
1598 op->operand.valOperand = val;
1599 op->isLiteral = isOperandLiteral (op);
1603 /*-----------------------------------------------------------------*/
1604 /* operandFromLink - operand from typeChain */
1605 /*-----------------------------------------------------------------*/
1607 operandFromLink (sym_link * type)
1611 /* operand from sym_link */
1617 op->operand.typeOperand = copyLinkChain (type);
1621 /*-----------------------------------------------------------------*/
1622 /* operandFromLit - makes an operand from a literal value */
1623 /*-----------------------------------------------------------------*/
1625 operandFromLit (double i)
1627 return operandFromValue (valueFromLit (i));
1630 /*-----------------------------------------------------------------*/
1631 /* operandFromAst - creates an operand from an ast */
1632 /*-----------------------------------------------------------------*/
1634 operandFromAst (ast * tree,int lvl)
1640 /* depending on type do */
1644 return ast2iCode (tree,lvl+1);
1648 return operandFromValue (tree->opval.val);
1652 return operandFromLink (tree->opval.lnk);
1659 /* Just to keep the compiler happy */
1660 return (operand *) 0;
1663 /*-----------------------------------------------------------------*/
1664 /* setOperandType - sets the operand's type to the given type */
1665 /*-----------------------------------------------------------------*/
1667 setOperandType (operand * op, sym_link * type)
1669 /* depending on the type of operand */
1674 op->operand.valOperand->etype =
1675 getSpec (op->operand.valOperand->type =
1676 copyLinkChain (type));
1680 if (op->operand.symOperand->isitmp)
1681 op->operand.symOperand->etype =
1682 getSpec (op->operand.symOperand->type =
1683 copyLinkChain (type));
1685 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1686 "attempt to modify type of source");
1690 op->operand.typeOperand = copyLinkChain (type);
1695 /*-----------------------------------------------------------------*/
1696 /* Get size in byte of ptr need to access an array */
1697 /*-----------------------------------------------------------------*/
1699 getArraySizePtr (operand * op)
1701 sym_link *ltype = operandType(op);
1705 int size = getSize(ltype);
1706 return(IS_GENPTR(ltype)?(size-1):size);
1711 sym_link *letype = getSpec(ltype);
1712 switch (PTR_TYPE (SPEC_OCLS (letype)))
1724 return (GPTRSIZE-1);
1733 /*-----------------------------------------------------------------*/
1734 /* perform "usual unary conversions" */
1735 /*-----------------------------------------------------------------*/
1738 usualUnaryConversions (operand * op)
1740 if (IS_INTEGRAL (operandType (op)))
1742 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1745 return geniCodeCast (INTTYPE, op, TRUE);
1752 /*-----------------------------------------------------------------*/
1753 /* perform "usual binary conversions" */
1754 /*-----------------------------------------------------------------*/
1756 usualBinaryConversions (operand ** op1, operand ** op2,
1757 bool promoteCharToInt, bool isMul)
1760 sym_link *rtype = operandType (*op2);
1761 sym_link *ltype = operandType (*op1);
1763 ctype = computeType (ltype, rtype, promoteCharToInt);
1765 /* special for multiplication:
1766 This if for 'mul a,b', which takes two chars and returns an int */
1768 /* && promoteCharToInt superfluous, already handled by computeType() */
1769 && IS_INT (getSpec (ctype)))
1771 sym_link *retype = getSpec (rtype);
1772 sym_link *letype = getSpec (ltype);
1774 if ( IS_CHAR (letype)
1776 && IS_UNSIGNED (letype)
1777 && IS_UNSIGNED (retype))
1782 *op1 = geniCodeCast (ctype, *op1, TRUE);
1783 *op2 = geniCodeCast (ctype, *op2, TRUE);
1788 /*-----------------------------------------------------------------*/
1789 /* geniCodeValueAtAddress - generate intermeditate code for value */
1791 /*-----------------------------------------------------------------*/
1793 geniCodeRValue (operand * op, bool force)
1796 sym_link *type = operandType (op);
1797 sym_link *etype = getSpec (type);
1799 /* if this is an array & already */
1800 /* an address then return this */
1801 if (IS_AGGREGATE (type) ||
1802 (IS_PTR (type) && !force && !op->isaddr))
1803 return operandFromOperand (op);
1805 /* if this is not an address then must be */
1806 /* rvalue already so return this one */
1810 /* if this is not a temp symbol then */
1811 if (!IS_ITEMP (op) &&
1813 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1815 op = operandFromOperand (op);
1820 if (IS_SPEC (type) &&
1821 IS_TRUE_SYMOP (op) &&
1822 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1823 (options.model == MODEL_FLAT24) ))
1825 op = operandFromOperand (op);
1830 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1831 if (IS_PTR (type) && op->isaddr && force)
1834 type = copyLinkChain (type);
1836 IC_RESULT (ic) = newiTempOperand (type, 1);
1837 IC_RESULT (ic)->isaddr = 0;
1839 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1843 return IC_RESULT (ic);
1846 /*-----------------------------------------------------------------*/
1847 /* geniCodeCast - changes the value from one type to another */
1848 /*-----------------------------------------------------------------*/
1850 geniCodeCast (sym_link * type, operand * op, bool implicit)
1854 sym_link *opetype = getSpec (optype = operandType (op));
1858 /* one of them has size zero then error */
1859 if (IS_VOID (optype))
1861 werror (E_CAST_ZERO);
1865 /* if the operand is already the desired type then do nothing */
1866 if (compareType (type, optype) == 1)
1869 /* if this is a literal then just change the type & return */
1870 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1872 return operandFromValue (valCastLiteral (type,
1873 operandLitValue (op)));
1876 /* if casting to/from pointers, do some checking */
1877 if (IS_PTR(type)) { // to a pointer
1878 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1879 if (IS_INTEGRAL(optype)) {
1880 // maybe this is NULL, than it's ok.
1881 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1882 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1883 // no way to set the storage
1884 if (IS_LITERAL(optype)) {
1885 werror(E_LITERAL_GENERIC);
1888 werror(E_NONPTR2_GENPTR);
1891 } else if (implicit) {
1892 werror(W_INTEGRAL2PTR_NOCAST);
1897 // shouldn't do that with float, array or structure unless to void
1898 if (!IS_VOID(getSpec(type)) &&
1899 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1900 werror(E_INCOMPAT_TYPES);
1904 } else { // from a pointer to a pointer
1905 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1906 // if not a pointer to a function
1907 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1908 if (implicit) { // if not to generic, they have to match
1909 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1910 werror(E_INCOMPAT_PTYPES);
1917 } else { // to a non pointer
1918 if (IS_PTR(optype)) { // from a pointer
1919 if (implicit) { // sneaky
1920 if (IS_INTEGRAL(type)) {
1921 werror(W_PTR2INTEGRAL_NOCAST);
1923 } else { // shouldn't do that with float, array or structure
1924 werror(E_INCOMPAT_TYPES);
1931 printFromToType (optype, type);
1934 /* if they are the same size create an assignment */
1935 if (getSize (type) == getSize (optype) &&
1936 !IS_BITFIELD (type) &&
1938 !IS_FLOAT (optype) &&
1939 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1940 (!IS_SPEC (type) && !IS_SPEC (optype))))
1942 ic = newiCode ('=', NULL, op);
1943 IC_RESULT (ic) = newiTempOperand (type, 0);
1944 SPIL_LOC (IC_RESULT (ic)) =
1945 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1946 IC_RESULT (ic)->isaddr = 0;
1950 ic = newiCode (CAST, operandFromLink (type),
1951 geniCodeRValue (op, FALSE));
1953 IC_RESULT (ic) = newiTempOperand (type, 0);
1956 /* preserve the storage class & output class */
1957 /* of the original variable */
1958 restype = getSpec (operandType (IC_RESULT (ic)));
1959 if (!IS_LITERAL(opetype))
1960 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1961 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1964 return IC_RESULT (ic);
1967 /*-----------------------------------------------------------------*/
1968 /* geniCodeLabel - will create a Label */
1969 /*-----------------------------------------------------------------*/
1971 geniCodeLabel (symbol * label)
1975 ic = newiCodeLabelGoto (LABEL, label);
1979 /*-----------------------------------------------------------------*/
1980 /* geniCodeGoto - will create a Goto */
1981 /*-----------------------------------------------------------------*/
1983 geniCodeGoto (symbol * label)
1987 ic = newiCodeLabelGoto (GOTO, label);
1991 /*-----------------------------------------------------------------*/
1992 /* geniCodeMultiply - gen intermediate code for multiplication */
1993 /*-----------------------------------------------------------------*/
1995 geniCodeMultiply (operand * left, operand * right, int resultIsInt)
2002 /* if they are both literal then we know the result */
2003 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2004 return operandFromValue (valMult (left->operand.valOperand,
2005 right->operand.valOperand));
2007 if (IS_LITERAL(retype)) {
2008 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2011 resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE);
2013 rtype = operandType (right);
2014 retype = getSpec (rtype);
2015 ltype = operandType (left);
2016 letype = getSpec (ltype);
2019 /* if the right is a literal & power of 2 */
2020 /* then make it a left shift */
2021 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2022 efficient in most cases than 2 bytes result = 2 bytes << literal
2023 if port has 1 byte muldiv */
2024 if (p2 && !IS_FLOAT (letype) &&
2025 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
2026 (port->support.muldiv == 1)))
2028 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2030 /* LEFT_OP need same size for left and result, */
2031 left = geniCodeCast (resType, left, TRUE);
2032 ltype = operandType (left);
2034 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2038 ic = newiCode ('*', left, right); /* normal multiplication */
2039 /* if the size left or right > 1 then support routine */
2040 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2044 IC_RESULT (ic) = newiTempOperand (resType, 1);
2047 return IC_RESULT (ic);
2050 /*-----------------------------------------------------------------*/
2051 /* geniCodeDivision - gen intermediate code for division */
2052 /*-----------------------------------------------------------------*/
2054 geniCodeDivision (operand * left, operand * right)
2059 sym_link *rtype = operandType (right);
2060 sym_link *retype = getSpec (rtype);
2061 sym_link *ltype = operandType (left);
2062 sym_link *letype = getSpec (ltype);
2064 resType = usualBinaryConversions (&left, &right,
2065 (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2068 /* if the right is a literal & power of 2
2069 and left is unsigned then make it a
2071 if (IS_LITERAL (retype) &&
2072 !IS_FLOAT (letype) &&
2073 IS_UNSIGNED(letype) &&
2074 (p2 = powof2 ((TYPE_UDWORD)
2075 floatFromVal (right->operand.valOperand)))) {
2076 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2080 ic = newiCode ('/', left, right); /* normal division */
2081 /* if the size left or right > 1 then support routine */
2082 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2085 IC_RESULT (ic) = newiTempOperand (resType, 0);
2088 return IC_RESULT (ic);
2090 /*-----------------------------------------------------------------*/
2091 /* geniCodeModulus - gen intermediate code for modulus */
2092 /*-----------------------------------------------------------------*/
2094 geniCodeModulus (operand * left, operand * right)
2100 /* if they are both literal then we know the result */
2101 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2102 return operandFromValue (valMod (left->operand.valOperand,
2103 right->operand.valOperand));
2105 resType = usualBinaryConversions (&left, &right,
2106 (IS_UNSIGNED (retype) && IS_UNSIGNED (letype)) ? FALSE : TRUE,
2109 /* now they are the same size */
2110 ic = newiCode ('%', left, right);
2112 /* if the size left or right > 1 then support routine */
2113 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2115 IC_RESULT (ic) = newiTempOperand (resType, 0);
2118 return IC_RESULT (ic);
2121 /*-----------------------------------------------------------------*/
2122 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2123 /*-----------------------------------------------------------------*/
2125 geniCodePtrPtrSubtract (operand * left, operand * right)
2131 /* if they are both literals then */
2132 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2134 result = operandFromValue (valMinus (left->operand.valOperand,
2135 right->operand.valOperand));
2139 ic = newiCode ('-', left, right);
2141 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2145 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2149 // should we really do this? is this ANSI?
2150 return geniCodeDivision (result,
2151 operandFromLit (getSize (ltype->next)));
2154 /*-----------------------------------------------------------------*/
2155 /* geniCodeSubtract - generates code for subtraction */
2156 /*-----------------------------------------------------------------*/
2158 geniCodeSubtract (operand * left, operand * right)
2165 /* if they both pointers then */
2166 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2167 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2168 return geniCodePtrPtrSubtract (left, right);
2170 /* if they are both literal then we know the result */
2171 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2172 && left->isLiteral && right->isLiteral)
2173 return operandFromValue (valMinus (left->operand.valOperand,
2174 right->operand.valOperand));
2176 /* if left is an array or pointer */
2177 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2179 isarray = left->isaddr;
2180 right = geniCodeMultiply (right,
2181 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2182 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2185 { /* make them the same size */
2186 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2189 ic = newiCode ('-', left, right);
2191 IC_RESULT (ic) = newiTempOperand (resType, 1);
2192 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2194 /* if left or right is a float */
2195 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2199 return IC_RESULT (ic);
2202 /*-----------------------------------------------------------------*/
2203 /* geniCodeAdd - generates iCode for addition */
2204 /*-----------------------------------------------------------------*/
2206 geniCodeAdd (operand * left, operand * right, int lvl)
2215 /* if the right side is LITERAL zero */
2216 /* return the left side */
2217 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2220 /* if left is literal zero return right */
2221 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2224 /* if left is a pointer then size */
2225 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2227 isarray = left->isaddr;
2228 // there is no need to multiply with 1
2229 if (getSize (ltype->next) != 1)
2231 size = operandFromLit (getSize (ltype->next));
2232 SPEC_USIGN (getSpec (operandType (size))) = 1;
2233 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2234 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2235 /* Even if right is a 'unsigned char',
2236 the result will be a 'signed int' due to the promotion rules.
2237 It doesn't make sense when accessing arrays, so let's fix it here: */
2239 SPEC_USIGN (getSpec (operandType (right))) = 1;
2241 resType = copyLinkChain (ltype);
2244 { // make them the same size
2245 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2248 /* if they are both literals then we know */
2249 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2250 && left->isLiteral && right->isLiteral)
2251 return operandFromValue (valPlus (valFromType (ltype),
2252 valFromType (rtype)));
2254 ic = newiCode ('+', left, right);
2256 IC_RESULT (ic) = newiTempOperand (resType, 1);
2257 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2259 /* if left or right is a float then support
2261 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2266 return IC_RESULT (ic);
2270 /*-----------------------------------------------------------------*/
2271 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2272 /*-----------------------------------------------------------------*/
2274 aggrToPtr (sym_link * type, bool force)
2279 if (IS_PTR (type) && !force)
2282 etype = getSpec (type);
2283 ptype = newLink (DECLARATOR);
2287 /* set the pointer depending on the storage class */
2288 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2292 /*-----------------------------------------------------------------*/
2293 /* geniCodeArray2Ptr - array to pointer */
2294 /*-----------------------------------------------------------------*/
2296 geniCodeArray2Ptr (operand * op)
2298 sym_link *optype = operandType (op);
2299 sym_link *opetype = getSpec (optype);
2301 /* set the pointer depending on the storage class */
2302 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2309 /*-----------------------------------------------------------------*/
2310 /* geniCodeArray - array access */
2311 /*-----------------------------------------------------------------*/
2313 geniCodeArray (operand * left, operand * right, int lvl)
2317 sym_link *ltype = operandType (left);
2322 if (IS_PTR (ltype->next) && left->isaddr)
2324 left = geniCodeRValue (left, FALSE);
2327 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2329 size = operandFromLit (getSize (ltype->next));
2330 SPEC_USIGN (getSpec (operandType (size))) = 1;
2331 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2332 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2333 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2334 It doesn't make sense when accessing arrays, so let's fix it here: */
2336 SPEC_USIGN (getSpec (operandType (right))) = 1;
2337 /* we can check for limits here */
2338 /* already done in SDCCast.c
2339 if (isOperandLiteral (right) &&
2342 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2344 werror (W_IDX_OUT_OF_BOUNDS,
2345 (int) operandLitValue (right) / getSize (ltype->next),
2350 ic = newiCode ('+', left, right);
2352 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2353 !IS_AGGREGATE (ltype->next) &&
2354 !IS_PTR (ltype->next))
2355 ? ltype : ltype->next), 0);
2357 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2360 return IC_RESULT (ic);
2363 /*-----------------------------------------------------------------*/
2364 /* geniCodeStruct - generates intermediate code for structures */
2365 /*-----------------------------------------------------------------*/
2367 geniCodeStruct (operand * left, operand * right, bool islval)
2370 sym_link *type = operandType (left);
2371 sym_link *etype = getSpec (type);
2373 symbol *element = getStructElement (SPEC_STRUCT (etype),
2374 right->operand.symOperand);
2376 wassert(IS_SYMOP(right));
2378 /* add the offset */
2379 ic = newiCode ('+', left, operandFromLit (element->offset));
2381 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2383 /* preserve the storage & output class of the struct */
2384 /* as well as the volatile attribute */
2385 retype = getSpec (operandType (IC_RESULT (ic)));
2386 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2387 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2388 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2389 SPEC_CONST (retype) |= SPEC_CONST (etype);
2391 if (IS_PTR (element->type))
2392 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2394 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2397 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2400 /*-----------------------------------------------------------------*/
2401 /* geniCodePostInc - generate int code for Post increment */
2402 /*-----------------------------------------------------------------*/
2404 geniCodePostInc (operand * op)
2408 sym_link *optype = operandType (op);
2410 operand *rv = (IS_ITEMP (op) ?
2411 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2413 sym_link *rvtype = operandType (rv);
2416 /* if this is not an address we have trouble */
2419 werror (E_LVALUE_REQUIRED, "++");
2423 rOp = newiTempOperand (rvtype, 0);
2424 OP_SYMBOL(rOp)->noSpilLoc = 1;
2427 OP_SYMBOL(rv)->noSpilLoc = 1;
2429 geniCodeAssign (rOp, rv, 0);
2431 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2432 if (IS_FLOAT (rvtype))
2433 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2435 ic = newiCode ('+', rv, operandFromLit (size));
2437 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2440 geniCodeAssign (op, result, 0);
2446 /*-----------------------------------------------------------------*/
2447 /* geniCodePreInc - generate code for preIncrement */
2448 /*-----------------------------------------------------------------*/
2450 geniCodePreInc (operand * op, bool lvalue)
2453 sym_link *optype = operandType (op);
2454 operand *rop = (IS_ITEMP (op) ?
2455 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2457 sym_link *roptype = operandType (rop);
2463 werror (E_LVALUE_REQUIRED, "++");
2468 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2469 if (IS_FLOAT (roptype))
2470 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2472 ic = newiCode ('+', rop, operandFromLit (size));
2473 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2476 (void) geniCodeAssign (op, result, 0);
2477 if (lvalue || IS_TRUE_SYMOP (op))
2483 /*-----------------------------------------------------------------*/
2484 /* geniCodePostDec - generates code for Post decrement */
2485 /*-----------------------------------------------------------------*/
2487 geniCodePostDec (operand * op)
2491 sym_link *optype = operandType (op);
2493 operand *rv = (IS_ITEMP (op) ?
2494 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2496 sym_link *rvtype = operandType (rv);
2499 /* if this is not an address we have trouble */
2502 werror (E_LVALUE_REQUIRED, "--");
2506 rOp = newiTempOperand (rvtype, 0);
2507 OP_SYMBOL(rOp)->noSpilLoc = 1;
2510 OP_SYMBOL(rv)->noSpilLoc = 1;
2512 geniCodeAssign (rOp, rv, 0);
2514 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2515 if (IS_FLOAT (rvtype))
2516 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2518 ic = newiCode ('-', rv, operandFromLit (size));
2520 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2523 geniCodeAssign (op, result, 0);
2529 /*-----------------------------------------------------------------*/
2530 /* geniCodePreDec - generate code for pre decrement */
2531 /*-----------------------------------------------------------------*/
2533 geniCodePreDec (operand * op, bool lvalue)
2536 sym_link *optype = operandType (op);
2537 operand *rop = (IS_ITEMP (op) ?
2538 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2540 sym_link *roptype = operandType (rop);
2546 werror (E_LVALUE_REQUIRED, "--");
2551 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2552 if (IS_FLOAT (roptype))
2553 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2555 ic = newiCode ('-', rop, operandFromLit (size));
2556 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2559 (void) geniCodeAssign (op, result, 0);
2560 if (lvalue || IS_TRUE_SYMOP (op))
2567 /*-----------------------------------------------------------------*/
2568 /* geniCodeBitwise - gen int code for bitWise operators */
2569 /*-----------------------------------------------------------------*/
2571 geniCodeBitwise (operand * left, operand * right,
2572 int oper, sym_link * resType)
2576 left = geniCodeCast (resType, left, TRUE);
2577 right = geniCodeCast (resType, right, TRUE);
2579 ic = newiCode (oper, left, right);
2580 IC_RESULT (ic) = newiTempOperand (resType, 0);
2583 return IC_RESULT (ic);
2586 /*-----------------------------------------------------------------*/
2587 /* geniCodeAddressOf - gens icode for '&' address of operator */
2588 /*-----------------------------------------------------------------*/
2590 geniCodeAddressOf (operand * op)
2594 sym_link *optype = operandType (op);
2595 sym_link *opetype = getSpec (optype);
2597 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2599 op = operandFromOperand (op);
2604 /* lvalue check already done in decorateType */
2605 /* this must be a lvalue */
2606 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2607 /* werror (E_LVALUE_REQUIRED,"&"); */
2611 p = newLink (DECLARATOR);
2613 /* set the pointer depending on the storage class */
2614 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2616 p->next = copyLinkChain (optype);
2618 /* if already a temp */
2621 setOperandType (op, p);
2626 /* other wise make this of the type coming in */
2627 ic = newiCode (ADDRESS_OF, op, NULL);
2628 IC_RESULT (ic) = newiTempOperand (p, 1);
2629 IC_RESULT (ic)->isaddr = 0;
2631 return IC_RESULT (ic);
2633 /*-----------------------------------------------------------------*/
2634 /* setOClass - sets the output class depending on the pointer type */
2635 /*-----------------------------------------------------------------*/
2637 setOClass (sym_link * ptr, sym_link * spec)
2639 switch (DCL_TYPE (ptr))
2642 SPEC_OCLS (spec) = data;
2646 SPEC_OCLS (spec) = generic;
2650 SPEC_OCLS (spec) = xdata;
2654 SPEC_OCLS (spec) = code;
2658 SPEC_OCLS (spec) = idata;
2662 SPEC_OCLS (spec) = xstack;
2666 SPEC_OCLS (spec) = eeprom;
2675 /*-----------------------------------------------------------------*/
2676 /* geniCodeDerefPtr - dereference pointer with '*' */
2677 /*-----------------------------------------------------------------*/
2679 geniCodeDerefPtr (operand * op,int lvl)
2681 sym_link *rtype, *retype;
2682 sym_link *optype = operandType (op);
2684 // if this is an array then array access
2685 if (IS_ARRAY (optype)) {
2686 // don't worry, this will be optimized out later
2687 return geniCodeArray (op, operandFromLit (0), lvl);
2690 // just in case someone screws up
2691 wassert (IS_PTR (optype));
2693 if (IS_TRUE_SYMOP (op))
2696 op = geniCodeRValue (op, TRUE);
2699 /* now get rid of the pointer part */
2700 if (isLvaluereq(lvl) && IS_ITEMP (op))
2702 retype = getSpec (rtype = copyLinkChain (optype));
2706 retype = getSpec (rtype = copyLinkChain (optype->next));
2707 /* outputclass needs 2b updated */
2708 setOClass (optype, retype);
2711 op->isGptr = IS_GENPTR (optype);
2713 op->isaddr = (IS_PTR (rtype) ||
2714 IS_STRUCT (rtype) ||
2719 if (!isLvaluereq(lvl))
2720 op = geniCodeRValue (op, TRUE);
2722 setOperandType (op, rtype);
2727 /*-----------------------------------------------------------------*/
2728 /* geniCodeUnaryMinus - does a unary minus of the operand */
2729 /*-----------------------------------------------------------------*/
2731 geniCodeUnaryMinus (operand * op)
2734 sym_link *optype = operandType (op);
2736 if (IS_LITERAL (optype))
2737 return operandFromLit (-floatFromVal (op->operand.valOperand));
2739 ic = newiCode (UNARYMINUS, op, NULL);
2740 IC_RESULT (ic) = newiTempOperand (optype, 0);
2742 return IC_RESULT (ic);
2745 /*-----------------------------------------------------------------*/
2746 /* geniCodeLeftShift - gen i code for left shift */
2747 /*-----------------------------------------------------------------*/
2749 geniCodeLeftShift (operand * left, operand * right)
2753 ic = newiCode (LEFT_OP, left, right);
2754 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2756 return IC_RESULT (ic);
2759 /*-----------------------------------------------------------------*/
2760 /* geniCodeRightShift - gen i code for right shift */
2761 /*-----------------------------------------------------------------*/
2763 geniCodeRightShift (operand * left, operand * right)
2767 ic = newiCode (RIGHT_OP, left, right);
2768 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2770 return IC_RESULT (ic);
2773 /*-----------------------------------------------------------------*/
2774 /* geniCodeLogic- logic code */
2775 /*-----------------------------------------------------------------*/
2777 geniCodeLogic (operand * left, operand * right, int op)
2781 sym_link *rtype = operandType (right);
2782 sym_link *ltype = operandType (left);
2784 /* left is integral type and right is literal then
2785 check if the literal value is within bounds */
2786 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2788 checkConstantRange(ltype,
2789 OP_VALUE(right), "compare operation", 1);
2792 /* if one operand is a pointer and the other is a literal generic void pointer,
2793 change the type of the literal generic void pointer to match the other pointer */
2794 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2795 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2797 /* find left's definition */
2798 ic = (iCode *) setFirstItem (iCodeChain);
2801 if (((ic->op == CAST) || (ic->op == '='))
2802 && isOperandEqual(left, IC_RESULT (ic)))
2805 ic = setNextItem (iCodeChain);
2807 /* if casting literal to generic pointer, then cast to rtype instead */
2808 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2810 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2811 ltype = operandType(left);
2814 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2815 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2817 /* find right's definition */
2818 ic = (iCode *) setFirstItem (iCodeChain);
2821 if (((ic->op == CAST) || (ic->op == '='))
2822 && isOperandEqual(right, IC_RESULT (ic)))
2825 ic = setNextItem (iCodeChain);
2827 /* if casting literal to generic pointer, then cast to rtype instead */
2828 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2830 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2831 rtype = operandType(right);
2835 ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
2837 ic = newiCode (op, left, right);
2838 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2840 /* if comparing float
2841 and not a '==' || '!=' || '&&' || '||' (these
2843 if (IS_FLOAT(ctype) &&
2851 return IC_RESULT (ic);
2854 /*-----------------------------------------------------------------*/
2855 /* geniCodeUnary - for a a generic unary operation */
2856 /*-----------------------------------------------------------------*/
2858 geniCodeUnary (operand * op, int oper)
2860 iCode *ic = newiCode (oper, op, NULL);
2862 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2864 return IC_RESULT (ic);
2867 /*-----------------------------------------------------------------*/
2868 /* geniCodeConditional - geniCode for '?' ':' operation */
2869 /*-----------------------------------------------------------------*/
2871 geniCodeConditional (ast * tree,int lvl)
2874 symbol *falseLabel = newiTempLabel (NULL);
2875 symbol *exitLabel = newiTempLabel (NULL);
2876 operand *cond = ast2iCode (tree->left,lvl+1);
2877 operand *true, *false, *result;
2879 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2883 true = ast2iCode (tree->right->left,lvl+1);
2885 /* move the value to a new Operand */
2886 result = newiTempOperand (tree->right->ftype, 0);
2887 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2889 /* generate an unconditional goto */
2890 geniCodeGoto (exitLabel);
2892 /* now for the right side */
2893 geniCodeLabel (falseLabel);
2895 false = ast2iCode (tree->right->right,lvl+1);
2896 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2898 /* create the exit label */
2899 geniCodeLabel (exitLabel);
2904 /*-----------------------------------------------------------------*/
2905 /* geniCodeAssign - generate code for assignment */
2906 /*-----------------------------------------------------------------*/
2908 geniCodeAssign (operand * left, operand * right, int nosupdate)
2911 sym_link *ltype = operandType (left);
2912 sym_link *rtype = operandType (right);
2914 if (!left->isaddr && !IS_ITEMP (left))
2916 werror (E_LVALUE_REQUIRED, "assignment");
2920 /* left is integral type and right is literal then
2921 check if the literal value is within bounds */
2922 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2924 checkConstantRange(ltype,
2925 OP_VALUE(right), "= operation", 0);
2928 /* if the left & right type don't exactly match */
2929 /* if pointer set then make sure the check is
2930 done with the type & not the pointer */
2931 /* then cast rights type to left */
2933 /* first check the type for pointer assignement */
2934 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2935 compareType (ltype, rtype) <= 0)
2937 if (compareType (ltype->next, rtype) < 0)
2938 right = geniCodeCast (ltype->next, right, TRUE);
2940 else if (compareType (ltype, rtype) < 0)
2941 right = geniCodeCast (ltype, right, TRUE);
2943 /* If left is a true symbol & ! volatile
2944 create an assignment to temporary for
2945 the right & then assign this temporary
2946 to the symbol. This is SSA (static single
2947 assignment). Isn't it simple and folks have
2948 published mountains of paper on it */
2949 if (IS_TRUE_SYMOP (left) &&
2950 !isOperandVolatile (left, FALSE) &&
2951 isOperandGlobal (left))
2955 if (IS_TRUE_SYMOP (right))
2956 sym = OP_SYMBOL (right);
2957 ic = newiCode ('=', NULL, right);
2958 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2959 SPIL_LOC (right) = sym;
2963 ic = newiCode ('=', NULL, right);
2964 IC_RESULT (ic) = left;
2967 /* if left isgptr flag is set then support
2968 routine will be required */
2972 ic->nosupdate = nosupdate;
2976 /*-----------------------------------------------------------------*/
2977 /* geniCodeDummyRead - generate code for dummy read */
2978 /*-----------------------------------------------------------------*/
2980 geniCodeDummyRead (operand * op)
2983 sym_link *type = operandType (op);
2985 if (!IS_VOLATILE(type))
2988 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2994 /*-----------------------------------------------------------------*/
2995 /* geniCodeSEParms - generate code for side effecting fcalls */
2996 /*-----------------------------------------------------------------*/
2998 geniCodeSEParms (ast * parms,int lvl)
3003 if (parms->type == EX_OP && parms->opval.op == PARAM)
3005 geniCodeSEParms (parms->left,lvl);
3006 geniCodeSEParms (parms->right,lvl);
3010 /* hack don't like this but too lazy to think of
3012 if (IS_ADDRESS_OF_OP (parms))
3013 parms->left->lvalue = 1;
3015 if (IS_CAST_OP (parms) &&
3016 IS_PTR (parms->ftype) &&
3017 IS_ADDRESS_OF_OP (parms->right))
3018 parms->right->left->lvalue = 1;
3020 parms->opval.oprnd =
3021 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3023 parms->type = EX_OPERAND;
3024 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3025 SPEC_ARGREG(parms->ftype);
3028 /*-----------------------------------------------------------------*/
3029 /* geniCodeParms - generates parameters */
3030 /*-----------------------------------------------------------------*/
3032 geniCodeParms (ast * parms, value *argVals, int *stack,
3033 sym_link * fetype, symbol * func,int lvl)
3041 if (argVals==NULL) {
3043 argVals=FUNC_ARGS(func->type);
3046 /* if this is a param node then do the left & right */
3047 if (parms->type == EX_OP && parms->opval.op == PARAM)
3049 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
3050 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
3054 /* get the parameter value */
3055 if (parms->type == EX_OPERAND)
3056 pval = parms->opval.oprnd;
3059 /* maybe this else should go away ?? */
3060 /* hack don't like this but too lazy to think of
3062 if (IS_ADDRESS_OF_OP (parms))
3063 parms->left->lvalue = 1;
3065 if (IS_CAST_OP (parms) &&
3066 IS_PTR (parms->ftype) &&
3067 IS_ADDRESS_OF_OP (parms->right))
3068 parms->right->left->lvalue = 1;
3070 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3073 /* if register parm then make it a send */
3074 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
3075 IFFUNC_ISBUILTIN(func->type))
3077 ic = newiCode (SEND, pval, NULL);
3078 ic->argreg = SPEC_ARGREG(parms->etype);
3079 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
3084 /* now decide whether to push or assign */
3085 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
3089 operand *top = operandFromSymbol (argVals->sym);
3090 /* clear useDef and other bitVectors */
3091 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3092 geniCodeAssign (top, pval, 1);
3096 sym_link *p = operandType (pval);
3098 ic = newiCode (IPUSH, pval, NULL);
3100 /* update the stack adjustment */
3101 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3106 argVals=argVals->next;
3110 /*-----------------------------------------------------------------*/
3111 /* geniCodeCall - generates temp code for calling */
3112 /*-----------------------------------------------------------------*/
3114 geniCodeCall (operand * left, ast * parms,int lvl)
3118 sym_link *type, *etype;
3121 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3122 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3123 werror (E_FUNCTION_EXPECTED);
3124 return operandFromValue(valueFromLit(0));
3127 /* take care of parameters with side-effecting
3128 function calls in them, this is required to take care
3129 of overlaying function parameters */
3130 geniCodeSEParms (parms,lvl);
3132 /* first the parameters */
3133 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3135 /* now call : if symbol then pcall */
3136 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3137 ic = newiCode (PCALL, left, NULL);
3139 ic = newiCode (CALL, left, NULL);
3142 type = copyLinkChain (operandType (left)->next);
3143 etype = getSpec (type);
3144 SPEC_EXTR (etype) = 0;
3145 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3149 /* stack adjustment after call */
3150 ic->parmBytes = stack;
3155 /*-----------------------------------------------------------------*/
3156 /* geniCodeReceive - generate intermediate code for "receive" */
3157 /*-----------------------------------------------------------------*/
3159 geniCodeReceive (value * args)
3161 /* for all arguments that are passed in registers */
3165 if (IS_REGPARM (args->etype))
3167 operand *opr = operandFromValue (args);
3169 symbol *sym = OP_SYMBOL (opr);
3172 /* we will use it after all optimizations
3173 and before liveRange calculation */
3174 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3177 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3178 options.stackAuto == 0 &&
3179 (!(options.model == MODEL_FLAT24)) )
3184 opl = newiTempOperand (args->type, 0);
3186 sym->reqv->key = sym->key;
3187 OP_SYMBOL (sym->reqv)->key = sym->key;
3188 OP_SYMBOL (sym->reqv)->isreqv = 1;
3189 OP_SYMBOL (sym->reqv)->islocal = 0;
3190 SPIL_LOC (sym->reqv) = sym;
3194 ic = newiCode (RECEIVE, NULL, NULL);
3195 ic->argreg = SPEC_ARGREG(args->etype);
3197 currFunc->recvSize = getSize (sym->type);
3200 IC_RESULT (ic) = opr;
3208 /*-----------------------------------------------------------------*/
3209 /* geniCodeFunctionBody - create the function body */
3210 /*-----------------------------------------------------------------*/
3212 geniCodeFunctionBody (ast * tree,int lvl)
3219 /* reset the auto generation */
3225 func = ast2iCode (tree->left,lvl+1);
3226 fetype = getSpec (operandType (func));
3228 savelineno = lineno;
3229 lineno = OP_SYMBOL (func)->lineDef;
3230 /* create an entry label */
3231 geniCodeLabel (entryLabel);
3232 lineno = savelineno;
3234 /* create a proc icode */
3235 ic = newiCode (FUNCTION, func, NULL);
3236 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3240 /* for all parameters that are passed
3241 on registers add a "receive" */
3242 geniCodeReceive (tree->values.args);
3244 /* generate code for the body */
3245 ast2iCode (tree->right,lvl+1);
3247 /* create a label for return */
3248 geniCodeLabel (returnLabel);
3250 /* now generate the end proc */
3251 ic = newiCode (ENDFUNCTION, func, NULL);
3256 /*-----------------------------------------------------------------*/
3257 /* geniCodeReturn - gen icode for 'return' statement */
3258 /*-----------------------------------------------------------------*/
3260 geniCodeReturn (operand * op)
3264 /* if the operand is present force an rvalue */
3266 op = geniCodeRValue (op, FALSE);
3268 ic = newiCode (RETURN, op, NULL);
3272 /*-----------------------------------------------------------------*/
3273 /* geniCodeIfx - generates code for extended if statement */
3274 /*-----------------------------------------------------------------*/
3276 geniCodeIfx (ast * tree,int lvl)
3279 operand *condition = ast2iCode (tree->left,lvl+1);
3282 /* if condition is null then exit */
3286 condition = geniCodeRValue (condition, FALSE);
3288 cetype = getSpec (operandType (condition));
3289 /* if the condition is a literal */
3290 if (IS_LITERAL (cetype))
3292 if (floatFromVal (condition->operand.valOperand))
3294 if (tree->trueLabel)
3295 geniCodeGoto (tree->trueLabel);
3301 if (tree->falseLabel)
3302 geniCodeGoto (tree->falseLabel);
3309 if (tree->trueLabel)
3311 ic = newiCodeCondition (condition,
3316 if (tree->falseLabel)
3317 geniCodeGoto (tree->falseLabel);
3321 ic = newiCodeCondition (condition,
3328 ast2iCode (tree->right,lvl+1);
3331 /*-----------------------------------------------------------------*/
3332 /* geniCodeJumpTable - tries to create a jump table for switch */
3333 /*-----------------------------------------------------------------*/
3335 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3337 int min = 0, max = 0, t, cnt = 0;
3343 int needRangeCheck = !optimize.noJTabBoundary
3344 || tree->values.switchVals.swDefault;
3346 if (!tree || !caseVals)
3349 /* the criteria for creating a jump table is */
3350 /* all integer numbers between the maximum & minimum must */
3351 /* be present , the maximum value should not exceed 255 */
3352 min = max = (int) floatFromVal (vch = caseVals);
3353 SNPRINTF (buffer, sizeof(buffer),
3355 tree->values.switchVals.swNum,
3357 addSet (&labels, newiTempLabel (buffer));
3359 /* if there is only one case value then no need */
3360 if (!(vch = vch->next))
3365 if (((t = (int) floatFromVal (vch)) - max) != 1)
3367 SNPRINTF (buffer, sizeof(buffer),
3369 tree->values.switchVals.swNum,
3371 addSet (&labels, newiTempLabel (buffer));
3377 /* if the number of case statements <= 2 then */
3378 /* it is not economical to create the jump table */
3379 /* since two compares are needed for boundary conditions */
3380 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3383 if (tree->values.switchVals.swDefault)
3385 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3389 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3393 falseLabel = newiTempLabel (buffer);
3395 /* so we can create a jumptable */
3396 /* first we rule out the boundary conditions */
3397 /* if only optimization says so */
3400 sym_link *cetype = getSpec (operandType (cond));
3401 /* no need to check the lower bound if
3402 the condition is unsigned & minimum value is zero */
3403 if (!(min == 0 && IS_UNSIGNED (cetype)))
3405 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3406 ic = newiCodeCondition (boundary, falseLabel, NULL);
3410 /* now for upper bounds */
3411 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3412 ic = newiCodeCondition (boundary, falseLabel, NULL);
3416 /* if the min is not zero then we no make it zero */
3419 cond = geniCodeSubtract (cond, operandFromLit (min));
3420 if (!IS_LITERAL(getSpec(operandType(cond))))
3421 setOperandType (cond, UCHARTYPE);
3424 /* now create the jumptable */
3425 ic = newiCode (JUMPTABLE, NULL, NULL);
3426 IC_JTCOND (ic) = cond;
3427 IC_JTLABELS (ic) = labels;
3432 /*-----------------------------------------------------------------*/
3433 /* geniCodeSwitch - changes a switch to a if statement */
3434 /*-----------------------------------------------------------------*/
3436 geniCodeSwitch (ast * tree,int lvl)
3439 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3440 value *caseVals = tree->values.switchVals.swVals;
3441 symbol *trueLabel, *falseLabel;
3443 /* If the condition is a literal, then just jump to the */
3444 /* appropriate case label. */
3445 if (IS_LITERAL(getSpec(operandType(cond))))
3447 int switchVal, caseVal;
3449 switchVal = (int) floatFromVal (cond->operand.valOperand);
3452 caseVal = (int) floatFromVal (caseVals);
3453 if (caseVal == switchVal)
3455 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3456 tree->values.switchVals.swNum, caseVal);
3457 trueLabel = newiTempLabel (buffer);
3458 geniCodeGoto (trueLabel);
3461 caseVals = caseVals->next;
3463 goto defaultOrBreak;
3466 /* if we can make this a jump table */
3467 if (geniCodeJumpTable (cond, caseVals, tree))
3468 goto jumpTable; /* no need for the comparison */
3470 /* for the cases defined do */
3474 operand *compare = geniCodeLogic (cond,
3475 operandFromValue (caseVals),
3478 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3479 tree->values.switchVals.swNum,
3480 (int) floatFromVal (caseVals));
3481 trueLabel = newiTempLabel (buffer);
3483 ic = newiCodeCondition (compare, trueLabel, NULL);
3485 caseVals = caseVals->next;
3490 /* if default is present then goto break else break */
3491 if (tree->values.switchVals.swDefault)
3493 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3497 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3500 falseLabel = newiTempLabel (buffer);
3501 geniCodeGoto (falseLabel);
3504 ast2iCode (tree->right,lvl+1);
3507 /*-----------------------------------------------------------------*/
3508 /* geniCodeInline - intermediate code for inline assembler */
3509 /*-----------------------------------------------------------------*/
3511 geniCodeInline (ast * tree)
3515 ic = newiCode (INLINEASM, NULL, NULL);
3516 IC_INLINE (ic) = tree->values.inlineasm;
3520 /*-----------------------------------------------------------------*/
3521 /* geniCodeArrayInit - intermediate code for array initializer */
3522 /*-----------------------------------------------------------------*/
3524 geniCodeArrayInit (ast * tree, operand *array)
3528 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3529 ic = newiCode (ARRAYINIT, array, NULL);
3530 IC_ARRAYILIST (ic) = tree->values.constlist;
3532 operand *left=newOperand(), *right=newOperand();
3533 left->type=right->type=SYMBOL;
3534 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3535 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3536 ic = newiCode (ARRAYINIT, left, right);
3541 /*-----------------------------------------------------------------*/
3542 /* geniCodeCritical - intermediate code for a critical statement */
3543 /*-----------------------------------------------------------------*/
3545 geniCodeCritical (ast *tree, int lvl)
3550 /* If op is NULL, the original interrupt state will saved on */
3551 /* the stack. Otherwise, it will be saved in op. */
3553 /* Generate a save of the current interrupt state & disabled */
3554 ic = newiCode (CRITICAL, NULL, NULL);
3555 IC_RESULT (ic) = op;
3558 /* Generate the critical code sequence */
3559 if (tree->left && tree->left->type == EX_VALUE)
3560 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3562 ast2iCode (tree->left,lvl+1);
3564 /* Generate a restore of the original interrupt state */
3565 ic = newiCode (ENDCRITICAL, NULL, op);
3569 /*-----------------------------------------------------------------*/
3570 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3571 /* particular case. Ie : assigning or dereferencing array or ptr */
3572 /*-----------------------------------------------------------------*/
3573 set * lvaluereqSet = NULL;
3574 typedef struct lvalItem
3581 /*-----------------------------------------------------------------*/
3582 /* addLvaluereq - add a flag for lvalreq for current ast level */
3583 /*-----------------------------------------------------------------*/
3584 void addLvaluereq(int lvl)
3586 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3589 addSetHead(&lvaluereqSet,lpItem);
3592 /*-----------------------------------------------------------------*/
3593 /* delLvaluereq - del a flag for lvalreq for current ast level */
3594 /*-----------------------------------------------------------------*/
3598 lpItem = getSet(&lvaluereqSet);
3599 if(lpItem) Safe_free(lpItem);
3601 /*-----------------------------------------------------------------*/
3602 /* clearLvaluereq - clear lvalreq flag */
3603 /*-----------------------------------------------------------------*/
3604 void clearLvaluereq()
3607 lpItem = peekSet(lvaluereqSet);
3608 if(lpItem) lpItem->req = 0;
3610 /*-----------------------------------------------------------------*/
3611 /* getLvaluereq - get the last lvalreq level */
3612 /*-----------------------------------------------------------------*/
3613 int getLvaluereqLvl()
3616 lpItem = peekSet(lvaluereqSet);
3617 if(lpItem) return lpItem->lvl;
3620 /*-----------------------------------------------------------------*/
3621 /* isLvaluereq - is lvalreq valid for this level ? */
3622 /*-----------------------------------------------------------------*/
3623 int isLvaluereq(int lvl)
3626 lpItem = peekSet(lvaluereqSet);
3627 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3631 /*-----------------------------------------------------------------*/
3632 /* ast2iCode - creates an icodeList from an ast */
3633 /*-----------------------------------------------------------------*/
3635 ast2iCode (ast * tree,int lvl)
3637 operand *left = NULL;
3638 operand *right = NULL;
3642 /* set the global variables for filename & line number */
3644 filename = tree->filename;
3646 lineno = tree->lineno;
3648 block = tree->block;
3650 scopeLevel = tree->level;
3652 seqPoint = tree->seqPoint;
3654 if (tree->type == EX_VALUE)
3655 return operandFromValue (tree->opval.val);
3657 if (tree->type == EX_LINK)
3658 return operandFromLink (tree->opval.lnk);
3660 /* if we find a nullop */
3661 if (tree->type == EX_OP &&
3662 (tree->opval.op == NULLOP ||
3663 tree->opval.op == BLOCK))
3665 if (tree->left && tree->left->type == EX_VALUE)
3666 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3668 ast2iCode (tree->left,lvl+1);
3669 if (tree->right && tree->right->type == EX_VALUE)
3670 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3672 ast2iCode (tree->right,lvl+1);
3676 /* special cases for not evaluating */
3677 if (tree->opval.op != ':' &&
3678 tree->opval.op != '?' &&
3679 tree->opval.op != CALL &&
3680 tree->opval.op != IFX &&
3681 tree->opval.op != LABEL &&
3682 tree->opval.op != GOTO &&
3683 tree->opval.op != SWITCH &&
3684 tree->opval.op != FUNCTION &&
3685 tree->opval.op != INLINEASM &&
3686 tree->opval.op != CRITICAL)
3689 if (IS_ASSIGN_OP (tree->opval.op) ||
3690 IS_DEREF_OP (tree) ||
3691 (tree->opval.op == '&' && !tree->right) ||
3692 tree->opval.op == PTR_OP)
3695 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3696 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3699 left = operandFromAst (tree->left,lvl);
3701 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3702 left = geniCodeRValue (left, TRUE);
3706 left = operandFromAst (tree->left,lvl);
3708 if (tree->opval.op == INC_OP ||
3709 tree->opval.op == DEC_OP)
3712 right = operandFromAst (tree->right,lvl);
3717 right = operandFromAst (tree->right,lvl);
3721 /* now depending on the type of operand */
3722 /* this will be a biggy */
3723 switch (tree->opval.op)
3726 case '[': /* array operation */
3728 //sym_link *ltype = operandType (left);
3729 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3730 left = geniCodeRValue (left, FALSE);
3731 right = geniCodeRValue (right, TRUE);
3734 return geniCodeArray (left, right,lvl);
3736 case '.': /* structure dereference */
3737 if (IS_PTR (operandType (left)))
3738 left = geniCodeRValue (left, TRUE);
3740 left = geniCodeRValue (left, FALSE);
3742 return geniCodeStruct (left, right, tree->lvalue);
3744 case PTR_OP: /* structure pointer dereference */
3747 pType = operandType (left);
3748 left = geniCodeRValue (left, TRUE);
3750 setOClass (pType, getSpec (operandType (left)));
3753 return geniCodeStruct (left, right, tree->lvalue);
3755 case INC_OP: /* increment operator */
3757 return geniCodePostInc (left);
3759 return geniCodePreInc (right, tree->lvalue);
3761 case DEC_OP: /* decrement operator */
3763 return geniCodePostDec (left);
3765 return geniCodePreDec (right, tree->lvalue);
3767 case '&': /* bitwise and or address of operator */
3769 { /* this is a bitwise operator */
3770 left = geniCodeRValue (left, FALSE);
3771 right = geniCodeRValue (right, FALSE);
3772 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3775 return geniCodeAddressOf (left);
3777 case '|': /* bitwise or & xor */
3779 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3780 geniCodeRValue (right, FALSE),
3785 return geniCodeDivision (geniCodeRValue (left, FALSE),
3786 geniCodeRValue (right, FALSE));
3789 return geniCodeModulus (geniCodeRValue (left, FALSE),
3790 geniCodeRValue (right, FALSE));
3793 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3794 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3796 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3800 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3801 geniCodeRValue (right, FALSE));
3803 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3807 return geniCodeAdd (geniCodeRValue (left, FALSE),
3808 geniCodeRValue (right, FALSE),lvl);
3810 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3813 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3814 geniCodeRValue (right, FALSE));
3817 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3818 geniCodeRValue (right, FALSE));
3820 #if 0 // this indeed needs a second thought
3824 // let's keep this simple: get the rvalue we need
3825 op=geniCodeRValue (right, FALSE);
3826 // now cast it to whatever we want
3827 op=geniCodeCast (operandType(left), op, FALSE);
3828 // if this is going to be used as an lvalue, make it so
3834 #else // bug #604575, is it a bug ????
3835 return geniCodeCast (operandType (left),
3836 geniCodeRValue (right, FALSE), FALSE);
3843 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3848 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3849 setOperandType (op, UCHARTYPE);
3860 /* different compilers (even different gccs) evaluate
3861 the two calls in a different order. to get the same
3862 result on all machines we've to specify a clear sequence.
3863 return geniCodeLogic (geniCodeRValue (left, FALSE),
3864 geniCodeRValue (right, FALSE),
3868 operand *leftOp, *rightOp;
3870 rightOp = geniCodeRValue (right, FALSE);
3871 leftOp = geniCodeRValue (left , FALSE);
3873 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3876 return geniCodeConditional (tree,lvl);
3879 return operandFromLit (getSize (tree->right->ftype));
3883 sym_link *rtype = operandType (right);
3884 sym_link *ltype = operandType (left);
3885 if (IS_PTR (rtype) && IS_ITEMP (right)
3886 && right->isaddr && compareType (rtype->next, ltype) == 1)
3887 right = geniCodeRValue (right, TRUE);
3889 right = geniCodeRValue (right, FALSE);
3891 geniCodeAssign (left, right, 0);
3896 geniCodeAssign (left,
3897 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3899 geniCodeRValue (right, FALSE),FALSE), 0);
3903 geniCodeAssign (left,
3904 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3906 geniCodeRValue (right, FALSE)), 0);
3909 geniCodeAssign (left,
3910 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3912 geniCodeRValue (right, FALSE)), 0);
3915 sym_link *rtype = operandType (right);
3916 sym_link *ltype = operandType (left);
3917 if (IS_PTR (rtype) && IS_ITEMP (right)
3918 && right->isaddr && compareType (rtype->next, ltype) == 1)
3919 right = geniCodeRValue (right, TRUE);
3921 right = geniCodeRValue (right, FALSE);
3924 return geniCodeAssign (left,
3925 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3931 sym_link *rtype = operandType (right);
3932 sym_link *ltype = operandType (left);
3933 if (IS_PTR (rtype) && IS_ITEMP (right)
3934 && right->isaddr && compareType (rtype->next, ltype) == 1)
3936 right = geniCodeRValue (right, TRUE);
3940 right = geniCodeRValue (right, FALSE);
3943 geniCodeAssign (left,
3944 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3950 geniCodeAssign (left,
3951 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3953 geniCodeRValue (right, FALSE)), 0);
3956 geniCodeAssign (left,
3957 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3959 geniCodeRValue (right, FALSE)), 0);
3962 geniCodeAssign (left,
3963 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3965 geniCodeRValue (right, FALSE),
3967 operandType (left)), 0);
3970 geniCodeAssign (left,
3971 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3973 geniCodeRValue (right, FALSE),
3975 operandType (left)), 0);
3978 geniCodeAssign (left,
3979 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3981 geniCodeRValue (right, FALSE),
3983 operandType (left)), 0);
3985 return geniCodeRValue (right, FALSE);
3988 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3991 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3992 return ast2iCode (tree->right,lvl+1);
3995 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3996 return ast2iCode (tree->right,lvl+1);
3999 geniCodeFunctionBody (tree,lvl);
4003 geniCodeReturn (right);
4007 geniCodeIfx (tree,lvl);
4011 geniCodeSwitch (tree,lvl);
4015 geniCodeInline (tree);
4019 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4023 geniCodeCritical (tree, lvl);
4029 /*-----------------------------------------------------------------*/
4030 /* reverseICChain - gets from the list and creates a linkedlist */
4031 /*-----------------------------------------------------------------*/
4038 while ((loop = getSet (&iCodeChain)))
4050 /*-----------------------------------------------------------------*/
4051 /* iCodeFromAst - given an ast will convert it to iCode */
4052 /*-----------------------------------------------------------------*/
4054 iCodeFromAst (ast * tree)
4056 returnLabel = newiTempLabel ("_return");
4057 entryLabel = newiTempLabel ("_entry");
4059 return reverseiCChain ();
4062 static const char *opTypeToStr(OPTYPE op)
4066 case SYMBOL: return "symbol";
4067 case VALUE: return "value";
4068 case TYPE: return "type";
4070 return "undefined type";
4074 operand *validateOpType(operand *op,
4081 if (op && op->type == type)
4086 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4087 " expected %s, got %s\n",
4088 macro, args, file, line,
4089 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4091 return op; // never reached, makes compiler happy.