1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
43 symbol *returnLabel; /* function return label */
44 symbol *entryLabel; /* function entry label */
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeDivision (operand *, operand *);
49 operand *geniCodeAssign (operand *, operand *, int);
50 operand *geniCodeArray (operand *, operand *,int);
51 operand *geniCodeArray2Ptr (operand *);
52 operand *geniCodeRValue (operand *, bool);
53 operand *geniCodeDerefPtr (operand *,int);
54 int isLvaluereq(int lvl);
55 void setOClass (sym_link * ptr, sym_link * spec);
56 static operand *geniCodeCast (sym_link *, operand *, bool);
58 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
59 /* forward definition of ic print functions */
60 PRINTFUNC (picGetValueAtAddr);
61 PRINTFUNC (picSetValueAtAddr);
62 PRINTFUNC (picAddrOf);
63 PRINTFUNC (picGeneric);
64 PRINTFUNC (picGenericOne);
66 PRINTFUNC (picAssign);
70 PRINTFUNC (picJumpTable);
71 PRINTFUNC (picInline);
72 PRINTFUNC (picReceive);
73 PRINTFUNC (picDummyRead);
74 PRINTFUNC (picCritical);
75 PRINTFUNC (picEndCritical);
77 iCodeTable codeTable[] =
79 {'!', "not", picGenericOne, NULL},
80 {'~', "~", picGenericOne, NULL},
81 {RRC, "rrc", picGenericOne, NULL},
82 {RLC, "rlc", picGenericOne, NULL},
83 {GETHBIT, "ghbit", picGenericOne, NULL},
84 {UNARYMINUS, "-", picGenericOne, NULL},
85 {IPUSH, "push", picGenericOne, NULL},
86 {IPOP, "pop", picGenericOne, NULL},
87 {CALL, "call", picGenericOne, NULL},
88 {PCALL, "pcall", picGenericOne, NULL},
89 {FUNCTION, "proc", picGenericOne, NULL},
90 {ENDFUNCTION, "eproc", picGenericOne, NULL},
91 {RETURN, "ret", picGenericOne, NULL},
92 {'+', "+", picGeneric, NULL},
93 {'-', "-", picGeneric, NULL},
94 {'*', "*", picGeneric, NULL},
95 {'/', "/", picGeneric, NULL},
96 {'%', "%", picGeneric, NULL},
97 {'>', ">", picGeneric, NULL},
98 {'<', "<", picGeneric, NULL},
99 {LE_OP, "<=", picGeneric, NULL},
100 {GE_OP, ">=", picGeneric, NULL},
101 {EQ_OP, "==", picGeneric, NULL},
102 {NE_OP, "!=", picGeneric, NULL},
103 {AND_OP, "&&", picGeneric, NULL},
104 {OR_OP, "||", picGeneric, NULL},
105 {'^', "^", picGeneric, NULL},
106 {'|', "|", picGeneric, NULL},
107 {BITWISEAND, "&", picGeneric, NULL},
108 {LEFT_OP, "<<", picGeneric, NULL},
109 {RIGHT_OP, ">>", picGeneric, NULL},
110 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
111 {ADDRESS_OF, "&", picAddrOf, NULL},
112 {CAST, "<>", picCast, NULL},
113 {'=', ":=", picAssign, NULL},
114 {LABEL, "", picLabel, NULL},
115 {GOTO, "", picGoto, NULL},
116 {JUMPTABLE, "jtab", picJumpTable, NULL},
117 {IFX, "if", picIfx, NULL},
118 {INLINEASM, "", picInline, NULL},
119 {RECEIVE, "recv", picReceive, NULL},
120 {SEND, "send", picGenericOne, NULL},
121 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
122 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
123 {CRITICAL, "critical_start", picCritical, NULL},
124 {ENDCRITICAL, "critical_end", picEndCritical, NULL}
127 /*-----------------------------------------------------------------*/
128 /* checkConstantRange: check a constant against the type */
129 /*-----------------------------------------------------------------*/
132 /* pedantic=0: allmost anything is allowed as long as the absolute
133 value is within the bit range of the type, and -1 is treated as
134 0xf..f for unsigned types (e.g. in assign)
135 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
136 pedantic>1: "char c=200" is not allowed (evaluates to -56)
139 void checkConstantRange(sym_link *ltype, value *val, char *msg,
146 max = pow ((double)2.0, (double)bitsForType(ltype));
148 if (IS_LONG(val->type)) {
149 if (IS_UNSIGNED(val->type)) {
150 v=SPEC_CVAL(val->type).v_ulong;
152 v=SPEC_CVAL(val->type).v_long;
155 if (IS_UNSIGNED(val->type)) {
156 v=SPEC_CVAL(val->type).v_uint;
158 v=SPEC_CVAL(val->type).v_int;
164 // this could be a good idea
165 if (options.pedantic)
169 if (IS_FLOAT(ltype)) {
174 if (!IS_UNSIGNED(val->type) && v<0) {
176 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
182 // if very pedantic: "char c=200" is not allowed
183 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
184 max = max/2 + negative;
191 #if 0 // temporary disabled, leaving the warning as a reminder
193 SNPRINTF (message, sizeof(message), "for %s %s in %s",
194 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
195 nounName(ltype), msg);
196 werror (W_CONST_RANGE, message);
204 /*-----------------------------------------------------------------*/
205 /* operandName - returns the name of the operand */
206 /*-----------------------------------------------------------------*/
208 printOperand (operand * op, FILE * file)
225 opetype = getSpec (operandType (op));
226 if (IS_FLOAT (opetype))
227 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
229 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
230 printTypeChain (operandType (op), file);
237 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
238 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
240 OP_LIVEFROM (op), OP_LIVETO (op),
241 OP_SYMBOL (op)->stack,
242 op->isaddr, OP_SYMBOL (op)->isreqv,
243 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
244 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
248 printTypeChain (operandType (op), file);
249 if (SPIL_LOC (op) && IS_ITEMP (op))
250 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
255 /* if assigned to registers */
256 if (OP_SYMBOL (op)->nRegs)
258 if (OP_SYMBOL (op)->isspilt)
260 if (!OP_SYMBOL (op)->remat)
261 if (OP_SYMBOL (op)->usl.spillLoc)
262 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
263 OP_SYMBOL (op)->usl.spillLoc->rname :
264 OP_SYMBOL (op)->usl.spillLoc->name));
266 fprintf (file, "[err]");
268 fprintf (file, "[remat]");
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
280 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
281 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
282 /* if assigned to registers */
283 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
287 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
288 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
289 OP_SYMBOL (op)->regs[i]->name :
298 printTypeChain (op->operand.typeOperand, file);
304 fprintf (file, "\n");
309 /*-----------------------------------------------------------------*/
310 /* print functions */
311 /*-----------------------------------------------------------------*/
312 PRINTFUNC (picGetValueAtAddr)
315 printOperand (IC_RESULT (ic), of);
318 printOperand (IC_LEFT (ic), of);
324 PRINTFUNC (picSetValueAtAddr)
328 printOperand (IC_LEFT (ic), of);
329 fprintf (of, "] = ");
330 printOperand (IC_RIGHT (ic), of);
334 PRINTFUNC (picAddrOf)
337 printOperand (IC_RESULT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
341 fprintf (of, " = &[");
342 printOperand (IC_LEFT (ic), of);
345 if (IS_ITEMP (IC_LEFT (ic)))
346 fprintf (of, " offsetAdd ");
349 printOperand (IC_RIGHT (ic), of);
351 if (IS_ITEMP (IC_LEFT (ic)))
357 PRINTFUNC (picJumpTable)
362 fprintf (of, "%s\t", s);
363 printOperand (IC_JTCOND (ic), of);
365 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
366 sym = setNextItem (IC_JTLABELS (ic)))
367 fprintf (of, "\t\t\t%s\n", sym->name);
370 PRINTFUNC (picGeneric)
373 printOperand (IC_RESULT (ic), of);
375 printOperand (IC_LEFT (ic), of);
376 fprintf (of, " %s ", s);
377 printOperand (IC_RIGHT (ic), of);
381 PRINTFUNC (picGenericOne)
386 printOperand (IC_RESULT (ic), of);
392 fprintf (of, "%s ", s);
393 printOperand (IC_LEFT (ic), of);
396 if (!IC_RESULT (ic) && !IC_LEFT (ic))
399 if (ic->op == SEND || ic->op == RECEIVE) {
400 fprintf(of,"{argreg = %d}",ic->argreg);
408 printOperand (IC_RESULT (ic), of);
410 printOperand (IC_LEFT (ic), of);
411 printOperand (IC_RIGHT (ic), of);
416 PRINTFUNC (picAssign)
420 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
423 printOperand (IC_RESULT (ic), of);
425 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
428 fprintf (of, " %s ", s);
429 printOperand (IC_RIGHT (ic), of);
436 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
442 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
449 printOperand (IC_COND (ic), of);
452 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
455 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
457 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
461 PRINTFUNC (picInline)
463 fprintf (of, "%s", IC_INLINE (ic));
466 PRINTFUNC (picReceive)
468 printOperand (IC_RESULT (ic), of);
469 fprintf (of, " = %s ", s);
470 printOperand (IC_LEFT (ic), of);
474 PRINTFUNC (picDummyRead)
477 fprintf (of, "%s ", s);
478 printOperand (IC_RIGHT (ic), of);
482 PRINTFUNC (picCritical)
486 printOperand (IC_RESULT (ic), of);
488 fprintf (of, "(stack)");
489 fprintf (of, " = %s ", s);
493 PRINTFUNC (picEndCritical)
496 fprintf (of, "%s = ", s);
498 printOperand (IC_RIGHT (ic), of);
500 fprintf (of, "(stack)");
504 /*-----------------------------------------------------------------*/
505 /* piCode - prints one iCode */
506 /*-----------------------------------------------------------------*/
508 piCode (void *item, FILE * of)
516 icTab = getTableEntry (ic->op);
517 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
518 ic->filename, ic->lineno,
519 ic->seq, ic->key, ic->depth, ic->supportRtn);
520 icTab->iCodePrint (of, ic, icTab->printName);
526 printiCChain(ic,stdout);
528 /*-----------------------------------------------------------------*/
529 /* printiCChain - prints intermediate code for humans */
530 /*-----------------------------------------------------------------*/
532 printiCChain (iCode * icChain, FILE * of)
539 for (loop = icChain; loop; loop = loop->next)
541 if ((icTab = getTableEntry (loop->op)))
543 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
544 loop->filename, loop->lineno,
545 loop->seq, loop->key, loop->depth, loop->supportRtn);
547 icTab->iCodePrint (of, loop, icTab->printName);
553 /*-----------------------------------------------------------------*/
554 /* newOperand - allocate, init & return a new iCode */
555 /*-----------------------------------------------------------------*/
561 op = Safe_alloc ( sizeof (operand));
567 /*-----------------------------------------------------------------*/
568 /* newiCode - create and return a new iCode entry initialised */
569 /*-----------------------------------------------------------------*/
571 newiCode (int op, operand * left, operand * right)
575 ic = Safe_alloc ( sizeof (iCode));
577 ic->seqPoint = seqPoint;
579 ic->filename = filename;
581 ic->level = scopeLevel;
583 ic->key = iCodeKey++;
585 IC_RIGHT (ic) = right;
590 /*-----------------------------------------------------------------*/
591 /* newiCode for conditional statements */
592 /*-----------------------------------------------------------------*/
594 newiCodeCondition (operand * condition,
600 if (IS_VOID(operandType(condition))) {
601 werror(E_VOID_VALUE_USED);
604 ic = newiCode (IFX, NULL, NULL);
605 IC_COND (ic) = condition;
606 IC_TRUE (ic) = trueLabel;
607 IC_FALSE (ic) = falseLabel;
611 /*-----------------------------------------------------------------*/
612 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
613 /*-----------------------------------------------------------------*/
615 newiCodeLabelGoto (int op, symbol * label)
619 ic = newiCode (op, NULL, NULL);
623 IC_RIGHT (ic) = NULL;
624 IC_RESULT (ic) = NULL;
628 /*-----------------------------------------------------------------*/
629 /* newiTemp - allocate & return a newItemp Variable */
630 /*-----------------------------------------------------------------*/
638 SNPRINTF (buffer, sizeof(buffer), "%s", s);
642 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
645 itmp = newSymbol (buffer, 1);
646 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
652 /*-----------------------------------------------------------------*/
653 /* newiTempLabel - creates a temp variable label */
654 /*-----------------------------------------------------------------*/
656 newiTempLabel (char *s)
660 /* check if this alredy exists */
661 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
666 itmplbl = newSymbol (s, 1);
670 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
671 itmplbl = newSymbol (buffer, 1);
676 itmplbl->key = labelKey++;
677 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
681 /*-----------------------------------------------------------------*/
682 /* newiTempPreheaderLabel - creates a new preheader label */
683 /*-----------------------------------------------------------------*/
685 newiTempPreheaderLabel ()
689 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
690 itmplbl = newSymbol (buffer, 1);
694 itmplbl->key = labelKey++;
695 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
700 /*-----------------------------------------------------------------*/
701 /* initiCode - initialises some iCode related stuff */
702 /*-----------------------------------------------------------------*/
709 /*-----------------------------------------------------------------*/
710 /* copyiCode - make a copy of the iCode given */
711 /*-----------------------------------------------------------------*/
713 copyiCode (iCode * ic)
715 iCode *nic = newiCode (ic->op, NULL, NULL);
717 nic->lineno = ic->lineno;
718 nic->filename = ic->filename;
719 nic->block = ic->block;
720 nic->level = ic->level;
721 nic->parmBytes = ic->parmBytes;
723 /* deal with the special cases first */
727 IC_COND (nic) = operandFromOperand (IC_COND (ic));
728 IC_TRUE (nic) = IC_TRUE (ic);
729 IC_FALSE (nic) = IC_FALSE (ic);
733 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
734 IC_JTLABELS (nic) = IC_JTLABELS (ic);
739 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
740 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
744 IC_INLINE (nic) = IC_INLINE (ic);
748 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
752 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
753 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
754 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
760 /*-----------------------------------------------------------------*/
761 /* getTableEntry - gets the table entry for the given operator */
762 /*-----------------------------------------------------------------*/
764 getTableEntry (int oper)
768 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
769 if (oper == codeTable[i].icode)
770 return &codeTable[i];
775 /*-----------------------------------------------------------------*/
776 /* newiTempOperand - new intermediate temp operand */
777 /*-----------------------------------------------------------------*/
779 newiTempOperand (sym_link * type, char throwType)
782 operand *op = newOperand ();
786 itmp = newiTemp (NULL);
788 etype = getSpec (type);
790 if (IS_LITERAL (etype))
793 /* copy the type information */
795 itmp->etype = getSpec (itmp->type = (throwType ? type :
796 copyLinkChain (type)));
797 if (IS_LITERAL (itmp->etype))
799 SPEC_SCLS (itmp->etype) = S_REGISTER;
800 SPEC_OCLS (itmp->etype) = reg;
803 op->operand.symOperand = itmp;
804 op->key = itmp->key = ++operandKey;
808 /*-----------------------------------------------------------------*/
809 /* operandType - returns the type chain for an operand */
810 /*-----------------------------------------------------------------*/
812 operandType (operand * op)
814 /* depending on type of operand */
819 return op->operand.valOperand->type;
822 return op->operand.symOperand->type;
825 return op->operand.typeOperand;
827 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
828 " operand type not known ");
829 assert (0); /* should never come here */
830 /* Just to keep the compiler happy */
831 return (sym_link *) 0;
835 /*-----------------------------------------------------------------*/
836 /* isParamterToCall - will return 1 if op is a parameter to args */
837 /*-----------------------------------------------------------------*/
839 isParameterToCall (value * args, operand * op)
843 wassert (IS_SYMOP(op));
848 isSymbolEqual (op->operand.symOperand, tval->sym))
855 /*-----------------------------------------------------------------*/
856 /* isOperandGlobal - return 1 if operand is a global variable */
857 /*-----------------------------------------------------------------*/
859 isOperandGlobal (operand * op)
868 (op->operand.symOperand->level == 0 ||
869 IS_STATIC (op->operand.symOperand->etype) ||
870 IS_EXTERN (op->operand.symOperand->etype))
877 /*-----------------------------------------------------------------*/
878 /* isOperandVolatile - return 1 if the operand is volatile */
879 /*-----------------------------------------------------------------*/
881 isOperandVolatile (operand * op, bool chkTemp)
886 if (IS_ITEMP (op) && !chkTemp)
889 opetype = getSpec (optype = operandType (op));
891 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
894 if (IS_VOLATILE (opetype))
899 /*-----------------------------------------------------------------*/
900 /* isOperandLiteral - returns 1 if an operand contains a literal */
901 /*-----------------------------------------------------------------*/
903 isOperandLiteral (operand * op)
910 opetype = getSpec (operandType (op));
912 if (IS_LITERAL (opetype))
918 /*-----------------------------------------------------------------*/
919 /* isOperandInFarSpace - will return true if operand is in farSpace */
920 /*-----------------------------------------------------------------*/
922 isOperandInFarSpace (operand * op)
932 if (!IS_TRUE_SYMOP (op))
935 etype = SPIL_LOC (op)->etype;
941 etype = getSpec (operandType (op));
943 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
946 /*------------------------------------------------------------------*/
947 /* isOperandInDirSpace - will return true if operand is in dirSpace */
948 /*------------------------------------------------------------------*/
950 isOperandInDirSpace (operand * op)
960 if (!IS_TRUE_SYMOP (op))
963 etype = SPIL_LOC (op)->etype;
969 etype = getSpec (operandType (op));
971 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
974 /*--------------------------------------------------------------------*/
975 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
976 /*--------------------------------------------------------------------*/
978 isOperandInCodeSpace (operand * op)
988 etype = getSpec (operandType (op));
990 if (!IS_TRUE_SYMOP (op))
993 etype = SPIL_LOC (op)->etype;
999 etype = getSpec (operandType (op));
1001 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1004 /*-----------------------------------------------------------------*/
1005 /* isOperandOnStack - will return true if operand is on stack */
1006 /*-----------------------------------------------------------------*/
1008 isOperandOnStack (operand * op)
1018 etype = getSpec (operandType (op));
1019 if (IN_STACK (etype) ||
1020 OP_SYMBOL(op)->onStack ||
1021 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1027 /*-----------------------------------------------------------------*/
1028 /* isOclsExpensive - will return true if accesses to an output */
1029 /* storage class are expensive */
1030 /*-----------------------------------------------------------------*/
1032 isOclsExpensive (struct memmap *oclass)
1034 if (port->oclsExpense)
1035 return port->oclsExpense (oclass) > 0;
1037 /* In the absence of port specific guidance, assume only */
1038 /* farspace is expensive. */
1039 return IN_FARSPACE (oclass);
1042 /*-----------------------------------------------------------------*/
1043 /* operandLitValue - literal value of an operand */
1044 /*-----------------------------------------------------------------*/
1046 operandLitValue (operand * op)
1048 assert (isOperandLiteral (op));
1050 return floatFromVal (op->operand.valOperand);
1053 /*-----------------------------------------------------------------*/
1054 /* getBuiltInParms - returns parameters to a builtin functions */
1055 /*-----------------------------------------------------------------*/
1056 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1061 /* builtin functions uses only SEND for parameters */
1062 while (ic->op != CALL) {
1063 assert(ic->op == SEND && ic->builtinSEND);
1064 ic->generated = 1; /* mark the icode as generated */
1065 parms[*pcount] = IC_LEFT(ic);
1071 /* make sure this is a builtin function call */
1072 assert(IS_SYMOP(IC_LEFT(ic)));
1073 ftype = operandType(IC_LEFT(ic));
1074 assert(IFFUNC_ISBUILTIN(ftype));
1078 /*-----------------------------------------------------------------*/
1079 /* operandOperation - performs operations on operands */
1080 /*-----------------------------------------------------------------*/
1082 operandOperation (operand * left, operand * right,
1083 int op, sym_link * type)
1085 sym_link *let , *ret=NULL;
1086 operand *retval = (operand *) 0;
1088 assert (isOperandLiteral (left));
1089 let = getSpec(operandType(left));
1091 assert (isOperandLiteral (right));
1092 ret = getSpec(operandType(right));
1098 retval = operandFromValue (valCastLiteral (type,
1099 operandLitValue (left) +
1100 operandLitValue (right)));
1103 retval = operandFromValue (valCastLiteral (type,
1104 operandLitValue (left) -
1105 operandLitValue (right)));
1109 retval = operandFromValue (valCastLiteral (type,
1110 operandLitValue (left) *
1111 operandLitValue (right)));
1112 This could be all we've to do, but with gcc we've to take care about
1113 overflows. Two examples:
1114 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1115 significant bits are lost (52 in fraction, 63 bits would be
1116 necessary to keep full precision).
1117 If the resulting double value is greater than ULONG_MAX (resp.
1118 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1121 /* if it is not a specifier then we can assume that */
1122 /* it will be an unsigned long */
1123 if (IS_INT (type) ||
1126 /* long is handled here, because it can overflow with double */
1127 if (IS_LONG (type) ||
1129 /* signed and unsigned mul are the same, as long as the precision
1130 of the result isn't bigger than the precision of the operands. */
1131 retval = operandFromValue (valCastLiteral (type,
1132 (TYPE_UDWORD) operandLitValue (left) *
1133 (TYPE_UDWORD) operandLitValue (right)));
1134 else if (IS_UNSIGNED (type)) /* unsigned int */
1136 /* unsigned int is handled here in order to detect overflow */
1137 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1138 (TYPE_UWORD) operandLitValue (right);
1140 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1141 if (ul != (TYPE_UWORD) ul)
1144 else /* signed int */
1146 /* signed int is handled here in order to detect overflow */
1147 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1148 (TYPE_WORD) operandLitValue (right);
1150 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1151 if (l != (TYPE_WORD) l)
1156 /* all others go here: */
1157 retval = operandFromValue (valCastLiteral (type,
1158 operandLitValue (left) *
1159 operandLitValue (right)));
1162 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1164 werror (E_DIVIDE_BY_ZERO);
1170 if (IS_UNSIGNED (type))
1172 SPEC_USIGN (let) = 1;
1173 SPEC_USIGN (ret) = 1;
1174 retval = operandFromValue (valCastLiteral (type,
1175 (TYPE_UDWORD) operandLitValue (left) /
1176 (TYPE_UDWORD) operandLitValue (right)));
1180 retval = operandFromValue (valCastLiteral (type,
1181 operandLitValue (left) /
1182 operandLitValue (right)));
1187 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1189 werror (E_DIVIDE_BY_ZERO);
1194 if (IS_UNSIGNED (type))
1195 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1196 (TYPE_UDWORD) operandLitValue (right));
1198 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1199 (TYPE_DWORD) operandLitValue (right));
1203 /* The number of left shifts is always unsigned. Signed doesn't make
1204 sense here. Shifting by a negative number is impossible. */
1205 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
1206 (TYPE_UDWORD) operandLitValue (right));
1209 /* The number of right shifts is always unsigned. Signed doesn't make
1210 sense here. Shifting by a negative number is impossible. */
1211 if (IS_UNSIGNED(let))
1212 /* unsigned: logic shift right */
1213 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1214 (TYPE_UDWORD) operandLitValue (right));
1216 /* signed: arithmetic shift right */
1217 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1218 (TYPE_UDWORD) operandLitValue (right));
1221 /* this op doesn't care about signedness */
1225 l = (TYPE_UDWORD) operandLitValue (left);
1226 if (IS_CHAR(OP_VALUE(left)->type))
1228 else if (!IS_LONG (OP_VALUE(left)->type))
1230 r = (TYPE_UDWORD) operandLitValue (right);
1231 if (IS_CHAR(OP_VALUE(right)->type))
1233 else if (!IS_LONG (OP_VALUE(right)->type))
1235 retval = operandFromLit (l == r);
1239 retval = operandFromLit (operandLitValue (left) <
1240 operandLitValue (right));
1243 retval = operandFromLit (operandLitValue (left) <=
1244 operandLitValue (right));
1247 retval = operandFromLit (operandLitValue (left) !=
1248 operandLitValue (right));
1251 retval = operandFromLit (operandLitValue (left) >
1252 operandLitValue (right));
1255 retval = operandFromLit (operandLitValue (left) >=
1256 operandLitValue (right));
1259 retval = operandFromValue (valCastLiteral (type,
1260 (TYPE_UDWORD)operandLitValue(left) &
1261 (TYPE_UDWORD)operandLitValue(right)));
1264 retval = operandFromValue (valCastLiteral (type,
1265 (TYPE_UDWORD)operandLitValue(left) |
1266 (TYPE_UDWORD)operandLitValue(right)));
1269 retval = operandFromValue (valCastLiteral (type,
1270 (TYPE_UDWORD)operandLitValue(left) ^
1271 (TYPE_UDWORD)operandLitValue(right)));
1274 retval = operandFromLit (operandLitValue (left) &&
1275 operandLitValue (right));
1278 retval = operandFromLit (operandLitValue (left) ||
1279 operandLitValue (right));
1283 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1285 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1291 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1293 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1299 retval = operandFromValue (valCastLiteral (type,
1300 -1 * operandLitValue (left)));
1304 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1308 retval = operandFromLit (!operandLitValue (left));
1312 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1313 " operandOperation invalid operator ");
1321 /*-----------------------------------------------------------------*/
1322 /* isOperandEqual - compares two operand & return 1 if they r = */
1323 /*-----------------------------------------------------------------*/
1325 isOperandEqual (operand * left, operand * right)
1327 /* if the pointers are equal then they are equal */
1331 /* if either of them null then false */
1332 if (!left || !right)
1335 if (left->type != right->type)
1338 if (IS_SYMOP (left) && IS_SYMOP (right))
1339 return left->key == right->key;
1341 /* if types are the same */
1345 return isSymbolEqual (left->operand.symOperand,
1346 right->operand.symOperand);
1348 return (floatFromVal (left->operand.valOperand) ==
1349 floatFromVal (right->operand.valOperand));
1351 if (compareType (left->operand.typeOperand,
1352 right->operand.typeOperand) == 1)
1359 /*-------------------------------------------------------------------*/
1360 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1361 /*-------------------------------------------------------------------*/
1363 isiCodeEqual (iCode * left, iCode * right)
1365 /* if the same pointer */
1369 /* if either of them null */
1370 if (!left || !right)
1373 /* if operand are the same */
1374 if (left->op == right->op)
1377 /* compare all the elements depending on type */
1378 if (left->op != IFX)
1380 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1382 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1388 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1390 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1392 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1401 /*-----------------------------------------------------------------*/
1402 /* newiTempFromOp - create a temp Operand with same attributes */
1403 /*-----------------------------------------------------------------*/
1405 newiTempFromOp (operand * op)
1415 nop = newiTempOperand (operandType (op), TRUE);
1416 nop->isaddr = op->isaddr;
1417 nop->isvolatile = op->isvolatile;
1418 nop->isGlobal = op->isGlobal;
1419 nop->isLiteral = op->isLiteral;
1420 nop->usesDefs = op->usesDefs;
1421 nop->isParm = op->isParm;
1425 /*-----------------------------------------------------------------*/
1426 /* operand from operand - creates an operand holder for the type */
1427 /*-----------------------------------------------------------------*/
1429 operandFromOperand (operand * op)
1435 nop = newOperand ();
1436 nop->type = op->type;
1437 nop->isaddr = op->isaddr;
1439 nop->isvolatile = op->isvolatile;
1440 nop->isGlobal = op->isGlobal;
1441 nop->isLiteral = op->isLiteral;
1442 nop->usesDefs = op->usesDefs;
1443 nop->isParm = op->isParm;
1448 nop->operand.symOperand = op->operand.symOperand;
1451 nop->operand.valOperand = op->operand.valOperand;
1454 nop->operand.typeOperand = op->operand.typeOperand;
1461 /*-----------------------------------------------------------------*/
1462 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1463 /*-----------------------------------------------------------------*/
1465 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1467 operand *nop = operandFromOperand (op);
1469 if (nop->type == SYMBOL)
1471 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1472 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1478 /*-----------------------------------------------------------------*/
1479 /* operandFromSymbol - creates an operand from a symbol */
1480 /*-----------------------------------------------------------------*/
1482 operandFromSymbol (symbol * sym)
1487 /* if the symbol's type is a literal */
1488 /* then it is an enumerator type */
1489 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1490 return operandFromValue (valFromType (sym->etype));
1493 sym->key = ++operandKey;
1495 /* if this an implicit variable, means struct/union */
1496 /* member so just return it */
1497 if (sym->implicit || IS_FUNC (sym->type))
1501 op->operand.symOperand = sym;
1503 op->isvolatile = isOperandVolatile (op, TRUE);
1504 op->isGlobal = isOperandGlobal (op);
1508 /* under the following conditions create a
1509 register equivalent for a local symbol */
1510 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1511 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1513 (!(options.model == MODEL_FLAT24)) ) &&
1514 options.stackAuto == 0)
1517 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1518 !IS_FUNC (sym->type) && /* not a function */
1519 !sym->_isparm && /* not a parameter */
1520 sym->level && /* is a local variable */
1521 !sym->addrtaken && /* whose address has not been taken */
1522 !sym->reqv && /* does not already have a reg equivalence */
1523 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1524 !IS_STATIC (sym->etype) && /* and not declared static */
1525 !sym->islbl && /* not a label */
1526 ok && /* farspace check */
1527 !IS_BITVAR (sym->etype) /* not a bit variable */
1531 /* we will use it after all optimizations
1532 and before liveRange calculation */
1533 sym->reqv = newiTempOperand (sym->type, 0);
1534 sym->reqv->key = sym->key;
1535 OP_SYMBOL (sym->reqv)->key = sym->key;
1536 OP_SYMBOL (sym->reqv)->isreqv = 1;
1537 OP_SYMBOL (sym->reqv)->islocal = 1;
1538 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1539 SPIL_LOC (sym->reqv) = sym;
1542 if (!IS_AGGREGATE (sym->type))
1546 op->operand.symOperand = sym;
1549 op->isvolatile = isOperandVolatile (op, TRUE);
1550 op->isGlobal = isOperandGlobal (op);
1551 op->isPtr = IS_PTR (operandType (op));
1552 op->isParm = sym->_isparm;
1557 /* itemp = &[_symbol] */
1559 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1560 IC_LEFT (ic)->type = SYMBOL;
1561 IC_LEFT (ic)->operand.symOperand = sym;
1562 IC_LEFT (ic)->key = sym->key;
1563 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1564 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1565 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1568 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1569 if (IS_ARRAY (sym->type))
1571 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1572 IC_RESULT (ic)->isaddr = 0;
1575 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1579 return IC_RESULT (ic);
1582 /*-----------------------------------------------------------------*/
1583 /* operandFromValue - creates an operand from value */
1584 /*-----------------------------------------------------------------*/
1586 operandFromValue (value * val)
1590 /* if this is a symbol then do the symbol thing */
1592 return operandFromSymbol (val->sym);
1594 /* this is not a symbol */
1597 op->operand.valOperand = val;
1598 op->isLiteral = isOperandLiteral (op);
1602 /*-----------------------------------------------------------------*/
1603 /* operandFromLink - operand from typeChain */
1604 /*-----------------------------------------------------------------*/
1606 operandFromLink (sym_link * type)
1610 /* operand from sym_link */
1616 op->operand.typeOperand = copyLinkChain (type);
1620 /*-----------------------------------------------------------------*/
1621 /* operandFromLit - makes an operand from a literal value */
1622 /*-----------------------------------------------------------------*/
1624 operandFromLit (double i)
1626 return operandFromValue (valueFromLit (i));
1629 /*-----------------------------------------------------------------*/
1630 /* operandFromAst - creates an operand from an ast */
1631 /*-----------------------------------------------------------------*/
1633 operandFromAst (ast * tree,int lvl)
1639 /* depending on type do */
1643 return ast2iCode (tree,lvl+1);
1647 return operandFromValue (tree->opval.val);
1651 return operandFromLink (tree->opval.lnk);
1658 /* Just to keep the compiler happy */
1659 return (operand *) 0;
1662 /*-----------------------------------------------------------------*/
1663 /* setOperandType - sets the operand's type to the given type */
1664 /*-----------------------------------------------------------------*/
1666 setOperandType (operand * op, sym_link * type)
1668 /* depending on the type of operand */
1673 op->operand.valOperand->etype =
1674 getSpec (op->operand.valOperand->type =
1675 copyLinkChain (type));
1679 if (op->operand.symOperand->isitmp)
1680 op->operand.symOperand->etype =
1681 getSpec (op->operand.symOperand->type =
1682 copyLinkChain (type));
1684 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1685 "attempt to modify type of source");
1689 op->operand.typeOperand = copyLinkChain (type);
1694 /*-----------------------------------------------------------------*/
1695 /* Get size in byte of ptr need to access an array */
1696 /*-----------------------------------------------------------------*/
1698 getArraySizePtr (operand * op)
1700 sym_link *ltype = operandType(op);
1704 int size = getSize(ltype);
1705 return(IS_GENPTR(ltype)?(size-1):size);
1710 sym_link *letype = getSpec(ltype);
1711 switch (PTR_TYPE (SPEC_OCLS (letype)))
1723 return (GPTRSIZE-1);
1732 /*-----------------------------------------------------------------*/
1733 /* perform "usual unary conversions" */
1734 /*-----------------------------------------------------------------*/
1736 usualUnaryConversions (operand * op)
1738 if (IS_INTEGRAL (operandType (op)))
1740 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1743 return geniCodeCast (INTTYPE, op, TRUE);
1749 /*-----------------------------------------------------------------*/
1750 /* perform "usual binary conversions" */
1751 /*-----------------------------------------------------------------*/
1753 usualBinaryConversions (operand ** op1, operand ** op2,
1754 bool promoteCharToInt, bool isMul)
1757 sym_link *rtype = operandType (*op2);
1758 sym_link *ltype = operandType (*op1);
1760 ctype = computeType (ltype, rtype, promoteCharToInt);
1762 /* special for multiplication:
1763 This if for 'mul a,b', which takes two chars and returns an int */
1765 /* && promoteCharToInt superfluous, already handled by computeType() */
1766 && IS_CHAR (getSpec (ltype))
1767 && IS_CHAR (getSpec (rtype))
1768 && !(IS_UNSIGNED (getSpec (rtype)) ^ IS_UNSIGNED (getSpec (ltype)))
1769 && IS_INT (getSpec (ctype)))
1772 *op1 = geniCodeCast (ctype, *op1, TRUE);
1773 *op2 = geniCodeCast (ctype, *op2, TRUE);
1778 /*-----------------------------------------------------------------*/
1779 /* geniCodeValueAtAddress - generate intermeditate code for value */
1781 /*-----------------------------------------------------------------*/
1783 geniCodeRValue (operand * op, bool force)
1786 sym_link *type = operandType (op);
1787 sym_link *etype = getSpec (type);
1789 /* if this is an array & already */
1790 /* an address then return this */
1791 if (IS_AGGREGATE (type) ||
1792 (IS_PTR (type) && !force && !op->isaddr))
1793 return operandFromOperand (op);
1795 /* if this is not an address then must be */
1796 /* rvalue already so return this one */
1800 /* if this is not a temp symbol then */
1801 if (!IS_ITEMP (op) &&
1803 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1805 op = operandFromOperand (op);
1810 if (IS_SPEC (type) &&
1811 IS_TRUE_SYMOP (op) &&
1812 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1813 (options.model == MODEL_FLAT24) ))
1815 op = operandFromOperand (op);
1820 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1821 if (IS_PTR (type) && op->isaddr && force)
1824 type = copyLinkChain (type);
1826 IC_RESULT (ic) = newiTempOperand (type, 1);
1827 IC_RESULT (ic)->isaddr = 0;
1829 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1833 return IC_RESULT (ic);
1836 /*-----------------------------------------------------------------*/
1837 /* geniCodeCast - changes the value from one type to another */
1838 /*-----------------------------------------------------------------*/
1840 geniCodeCast (sym_link * type, operand * op, bool implicit)
1844 sym_link *opetype = getSpec (optype = operandType (op));
1848 /* one of them has size zero then error */
1849 if (IS_VOID (optype))
1851 werror (E_CAST_ZERO);
1855 /* if the operand is already the desired type then do nothing */
1856 if (compareType (type, optype) == 1)
1859 /* if this is a literal then just change the type & return */
1860 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1862 return operandFromValue (valCastLiteral (type,
1863 operandLitValue (op)));
1866 /* if casting to/from pointers, do some checking */
1867 if (IS_PTR(type)) { // to a pointer
1868 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1869 if (IS_INTEGRAL(optype)) {
1870 // maybe this is NULL, than it's ok.
1871 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1872 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1873 // no way to set the storage
1874 if (IS_LITERAL(optype)) {
1875 werror(E_LITERAL_GENERIC);
1878 werror(E_NONPTR2_GENPTR);
1881 } else if (implicit) {
1882 werror(W_INTEGRAL2PTR_NOCAST);
1887 // shouldn't do that with float, array or structure unless to void
1888 if (!IS_VOID(getSpec(type)) &&
1889 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1890 werror(E_INCOMPAT_TYPES);
1894 } else { // from a pointer to a pointer
1895 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1896 // if not a pointer to a function
1897 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1898 if (implicit) { // if not to generic, they have to match
1899 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1900 werror(E_INCOMPAT_PTYPES);
1907 } else { // to a non pointer
1908 if (IS_PTR(optype)) { // from a pointer
1909 if (implicit) { // sneaky
1910 if (IS_INTEGRAL(type)) {
1911 werror(W_PTR2INTEGRAL_NOCAST);
1913 } else { // shouldn't do that with float, array or structure
1914 werror(E_INCOMPAT_TYPES);
1921 printFromToType (optype, type);
1924 /* if they are the same size create an assignment */
1925 if (getSize (type) == getSize (optype) &&
1926 !IS_BITFIELD (type) &&
1928 !IS_FLOAT (optype) &&
1929 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1930 (!IS_SPEC (type) && !IS_SPEC (optype))))
1932 ic = newiCode ('=', NULL, op);
1933 IC_RESULT (ic) = newiTempOperand (type, 0);
1934 SPIL_LOC (IC_RESULT (ic)) =
1935 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1936 IC_RESULT (ic)->isaddr = 0;
1940 ic = newiCode (CAST, operandFromLink (type),
1941 geniCodeRValue (op, FALSE));
1943 IC_RESULT (ic) = newiTempOperand (type, 0);
1946 /* preserve the storage class & output class */
1947 /* of the original variable */
1948 restype = getSpec (operandType (IC_RESULT (ic)));
1949 if (!IS_LITERAL(opetype))
1950 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1951 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1954 return IC_RESULT (ic);
1957 /*-----------------------------------------------------------------*/
1958 /* geniCodeLabel - will create a Label */
1959 /*-----------------------------------------------------------------*/
1961 geniCodeLabel (symbol * label)
1965 ic = newiCodeLabelGoto (LABEL, label);
1969 /*-----------------------------------------------------------------*/
1970 /* geniCodeGoto - will create a Goto */
1971 /*-----------------------------------------------------------------*/
1973 geniCodeGoto (symbol * label)
1977 ic = newiCodeLabelGoto (GOTO, label);
1981 /*-----------------------------------------------------------------*/
1982 /* geniCodeMultiply - gen intermediate code for multiplication */
1983 /*-----------------------------------------------------------------*/
1985 geniCodeMultiply (operand * left, operand * right, int resultIsInt)
1992 /* if they are both literal then we know the result */
1993 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1994 return operandFromValue (valMult (left->operand.valOperand,
1995 right->operand.valOperand));
1997 if (IS_LITERAL(retype)) {
1998 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2001 resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE);
2003 rtype = operandType (right);
2004 retype = getSpec (rtype);
2005 ltype = operandType (left);
2006 letype = getSpec (ltype);
2009 /* if the right is a literal & power of 2 */
2010 /* then make it a left shift */
2011 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2012 efficient in most cases than 2 bytes result = 2 bytes << literal
2013 if port has 1 byte muldiv */
2014 if (p2 && !IS_FLOAT (letype) &&
2015 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
2016 (port->support.muldiv == 1)))
2018 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2020 /* LEFT_OP need same size for left and result, */
2021 left = geniCodeCast (resType, left, TRUE);
2022 ltype = operandType (left);
2024 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2028 ic = newiCode ('*', left, right); /* normal multiplication */
2029 /* if the size left or right > 1 then support routine */
2030 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2034 IC_RESULT (ic) = newiTempOperand (resType, 1);
2037 return IC_RESULT (ic);
2040 /*-----------------------------------------------------------------*/
2041 /* geniCodeDivision - gen intermediate code for division */
2042 /*-----------------------------------------------------------------*/
2044 geniCodeDivision (operand * left, operand * right)
2049 sym_link *rtype = operandType (right);
2050 sym_link *retype = getSpec (rtype);
2051 sym_link *ltype = operandType (left);
2052 sym_link *letype = getSpec (ltype);
2054 resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
2056 /* if the right is a literal & power of 2
2057 and left is unsigned then make it a
2059 if (IS_LITERAL (retype) &&
2060 !IS_FLOAT (letype) &&
2061 IS_UNSIGNED(letype) &&
2062 (p2 = powof2 ((TYPE_UDWORD)
2063 floatFromVal (right->operand.valOperand)))) {
2064 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2068 ic = newiCode ('/', left, right); /* normal division */
2069 /* if the size left or right > 1 then support routine */
2070 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2073 IC_RESULT (ic) = newiTempOperand (resType, 0);
2076 return IC_RESULT (ic);
2078 /*-----------------------------------------------------------------*/
2079 /* geniCodeModulus - gen intermediate code for modulus */
2080 /*-----------------------------------------------------------------*/
2082 geniCodeModulus (operand * left, operand * right)
2088 /* if they are both literal then we know the result */
2089 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2090 return operandFromValue (valMod (left->operand.valOperand,
2091 right->operand.valOperand));
2093 resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
2095 /* now they are the same size */
2096 ic = newiCode ('%', left, right);
2098 /* if the size left or right > 1 then support routine */
2099 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2101 IC_RESULT (ic) = newiTempOperand (resType, 0);
2104 return IC_RESULT (ic);
2107 /*-----------------------------------------------------------------*/
2108 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2109 /*-----------------------------------------------------------------*/
2111 geniCodePtrPtrSubtract (operand * left, operand * right)
2117 /* if they are both literals then */
2118 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2120 result = operandFromValue (valMinus (left->operand.valOperand,
2121 right->operand.valOperand));
2125 ic = newiCode ('-', left, right);
2127 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2131 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2135 // should we really do this? is this ANSI?
2136 return geniCodeDivision (result,
2137 operandFromLit (getSize (ltype->next)));
2140 /*-----------------------------------------------------------------*/
2141 /* geniCodeSubtract - generates code for subtraction */
2142 /*-----------------------------------------------------------------*/
2144 geniCodeSubtract (operand * left, operand * right)
2151 /* if they both pointers then */
2152 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2153 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2154 return geniCodePtrPtrSubtract (left, right);
2156 /* if they are both literal then we know the result */
2157 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2158 && left->isLiteral && right->isLiteral)
2159 return operandFromValue (valMinus (left->operand.valOperand,
2160 right->operand.valOperand));
2162 /* if left is an array or pointer */
2163 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2165 isarray = left->isaddr;
2166 right = geniCodeMultiply (right,
2167 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2168 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2171 { /* make them the same size */
2172 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2175 ic = newiCode ('-', left, right);
2177 IC_RESULT (ic) = newiTempOperand (resType, 1);
2178 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2180 /* if left or right is a float */
2181 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2185 return IC_RESULT (ic);
2188 /*-----------------------------------------------------------------*/
2189 /* geniCodeAdd - generates iCode for addition */
2190 /*-----------------------------------------------------------------*/
2192 geniCodeAdd (operand * left, operand * right, int lvl)
2201 /* if the right side is LITERAL zero */
2202 /* return the left side */
2203 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2206 /* if left is literal zero return right */
2207 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2210 /* if left is a pointer then size */
2211 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2213 isarray = left->isaddr;
2214 // there is no need to multiply with 1
2215 if (getSize (ltype->next) != 1)
2217 size = operandFromLit (getSize (ltype->next));
2218 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2219 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2220 /* Even if right is a 'unsigned char',
2221 the result will be a 'signed int' due to the promotion rules.
2222 It doesn't make sense when accessing arrays, so let's fix it here: */
2224 SPEC_USIGN (getSpec (operandType (right))) = 1;
2226 resType = copyLinkChain (ltype);
2229 { // make them the same size
2230 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2233 /* if they are both literals then we know */
2234 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2235 && left->isLiteral && right->isLiteral)
2236 return operandFromValue (valPlus (valFromType (ltype),
2237 valFromType (rtype)));
2239 ic = newiCode ('+', left, right);
2241 IC_RESULT (ic) = newiTempOperand (resType, 1);
2242 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2244 /* if left or right is a float then support
2246 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2251 return IC_RESULT (ic);
2255 /*-----------------------------------------------------------------*/
2256 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2257 /*-----------------------------------------------------------------*/
2259 aggrToPtr (sym_link * type, bool force)
2264 if (IS_PTR (type) && !force)
2267 etype = getSpec (type);
2268 ptype = newLink (DECLARATOR);
2272 /* set the pointer depending on the storage class */
2273 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2277 /*-----------------------------------------------------------------*/
2278 /* geniCodeArray2Ptr - array to pointer */
2279 /*-----------------------------------------------------------------*/
2281 geniCodeArray2Ptr (operand * op)
2283 sym_link *optype = operandType (op);
2284 sym_link *opetype = getSpec (optype);
2286 /* set the pointer depending on the storage class */
2287 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2294 /*-----------------------------------------------------------------*/
2295 /* geniCodeArray - array access */
2296 /*-----------------------------------------------------------------*/
2298 geniCodeArray (operand * left, operand * right,int lvl)
2301 sym_link *ltype = operandType (left);
2306 if (IS_PTR (ltype->next) && left->isaddr)
2308 left = geniCodeRValue (left, FALSE);
2311 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2313 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2314 right = geniCodeMultiply (right,
2315 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2316 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2317 It doesn't make sense when accessing arrays, so let's fix it here: */
2319 SPEC_USIGN (getSpec (operandType (right))) = 1;
2320 /* we can check for limits here */
2321 if (isOperandLiteral (right) &&
2324 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2326 werror (E_ARRAY_BOUND);
2327 right = operandFromLit (0);
2330 ic = newiCode ('+', left, right);
2332 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2333 !IS_AGGREGATE (ltype->next) &&
2334 !IS_PTR (ltype->next))
2335 ? ltype : ltype->next), 0);
2337 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2340 return IC_RESULT (ic);
2343 /*-----------------------------------------------------------------*/
2344 /* geniCodeStruct - generates intermediate code for structures */
2345 /*-----------------------------------------------------------------*/
2347 geniCodeStruct (operand * left, operand * right, bool islval)
2350 sym_link *type = operandType (left);
2351 sym_link *etype = getSpec (type);
2353 symbol *element = getStructElement (SPEC_STRUCT (etype),
2354 right->operand.symOperand);
2356 wassert(IS_SYMOP(right));
2358 /* add the offset */
2359 ic = newiCode ('+', left, operandFromLit (element->offset));
2361 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2363 /* preserve the storage & output class of the struct */
2364 /* as well as the volatile attribute */
2365 retype = getSpec (operandType (IC_RESULT (ic)));
2366 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2367 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2368 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2369 SPEC_CONST (retype) |= SPEC_CONST (etype);
2371 if (IS_PTR (element->type))
2372 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2374 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2377 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2380 /*-----------------------------------------------------------------*/
2381 /* geniCodePostInc - generate int code for Post increment */
2382 /*-----------------------------------------------------------------*/
2384 geniCodePostInc (operand * op)
2388 sym_link *optype = operandType (op);
2390 operand *rv = (IS_ITEMP (op) ?
2391 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2393 sym_link *rvtype = operandType (rv);
2396 /* if this is not an address we have trouble */
2399 werror (E_LVALUE_REQUIRED, "++");
2403 rOp = newiTempOperand (rvtype, 0);
2404 OP_SYMBOL(rOp)->noSpilLoc = 1;
2407 OP_SYMBOL(rv)->noSpilLoc = 1;
2409 geniCodeAssign (rOp, rv, 0);
2411 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2412 if (IS_FLOAT (rvtype))
2413 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2415 ic = newiCode ('+', rv, operandFromLit (size));
2417 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2420 geniCodeAssign (op, result, 0);
2426 /*-----------------------------------------------------------------*/
2427 /* geniCodePreInc - generate code for preIncrement */
2428 /*-----------------------------------------------------------------*/
2430 geniCodePreInc (operand * op, bool lvalue)
2433 sym_link *optype = operandType (op);
2434 operand *rop = (IS_ITEMP (op) ?
2435 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2437 sym_link *roptype = operandType (rop);
2443 werror (E_LVALUE_REQUIRED, "++");
2448 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2449 if (IS_FLOAT (roptype))
2450 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2452 ic = newiCode ('+', rop, operandFromLit (size));
2453 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2456 (void) geniCodeAssign (op, result, 0);
2457 if (lvalue || IS_TRUE_SYMOP (op))
2463 /*-----------------------------------------------------------------*/
2464 /* geniCodePostDec - generates code for Post decrement */
2465 /*-----------------------------------------------------------------*/
2467 geniCodePostDec (operand * op)
2471 sym_link *optype = operandType (op);
2473 operand *rv = (IS_ITEMP (op) ?
2474 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2476 sym_link *rvtype = operandType (rv);
2479 /* if this is not an address we have trouble */
2482 werror (E_LVALUE_REQUIRED, "--");
2486 rOp = newiTempOperand (rvtype, 0);
2487 OP_SYMBOL(rOp)->noSpilLoc = 1;
2490 OP_SYMBOL(rv)->noSpilLoc = 1;
2492 geniCodeAssign (rOp, rv, 0);
2494 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2495 if (IS_FLOAT (rvtype))
2496 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2498 ic = newiCode ('-', rv, operandFromLit (size));
2500 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2503 geniCodeAssign (op, result, 0);
2509 /*-----------------------------------------------------------------*/
2510 /* geniCodePreDec - generate code for pre decrement */
2511 /*-----------------------------------------------------------------*/
2513 geniCodePreDec (operand * op, bool lvalue)
2516 sym_link *optype = operandType (op);
2517 operand *rop = (IS_ITEMP (op) ?
2518 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2520 sym_link *roptype = operandType (rop);
2526 werror (E_LVALUE_REQUIRED, "--");
2531 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2532 if (IS_FLOAT (roptype))
2533 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2535 ic = newiCode ('-', rop, operandFromLit (size));
2536 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2539 (void) geniCodeAssign (op, result, 0);
2540 if (lvalue || IS_TRUE_SYMOP (op))
2547 /*-----------------------------------------------------------------*/
2548 /* geniCodeBitwise - gen int code for bitWise operators */
2549 /*-----------------------------------------------------------------*/
2551 geniCodeBitwise (operand * left, operand * right,
2552 int oper, sym_link * resType)
2556 left = geniCodeCast (resType, left, TRUE);
2557 right = geniCodeCast (resType, right, TRUE);
2559 ic = newiCode (oper, left, right);
2560 IC_RESULT (ic) = newiTempOperand (resType, 0);
2563 return IC_RESULT (ic);
2566 /*-----------------------------------------------------------------*/
2567 /* geniCodeAddressOf - gens icode for '&' address of operator */
2568 /*-----------------------------------------------------------------*/
2570 geniCodeAddressOf (operand * op)
2574 sym_link *optype = operandType (op);
2575 sym_link *opetype = getSpec (optype);
2577 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2579 op = operandFromOperand (op);
2584 /* lvalue check already done in decorateType */
2585 /* this must be a lvalue */
2586 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2587 /* werror (E_LVALUE_REQUIRED,"&"); */
2591 p = newLink (DECLARATOR);
2593 /* set the pointer depending on the storage class */
2594 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2596 p->next = copyLinkChain (optype);
2598 /* if already a temp */
2601 setOperandType (op, p);
2606 /* other wise make this of the type coming in */
2607 ic = newiCode (ADDRESS_OF, op, NULL);
2608 IC_RESULT (ic) = newiTempOperand (p, 1);
2609 IC_RESULT (ic)->isaddr = 0;
2611 return IC_RESULT (ic);
2613 /*-----------------------------------------------------------------*/
2614 /* setOClass - sets the output class depending on the pointer type */
2615 /*-----------------------------------------------------------------*/
2617 setOClass (sym_link * ptr, sym_link * spec)
2619 switch (DCL_TYPE (ptr))
2622 SPEC_OCLS (spec) = data;
2626 SPEC_OCLS (spec) = generic;
2630 SPEC_OCLS (spec) = xdata;
2634 SPEC_OCLS (spec) = code;
2638 SPEC_OCLS (spec) = idata;
2642 SPEC_OCLS (spec) = xstack;
2646 SPEC_OCLS (spec) = eeprom;
2655 /*-----------------------------------------------------------------*/
2656 /* geniCodeDerefPtr - dereference pointer with '*' */
2657 /*-----------------------------------------------------------------*/
2659 geniCodeDerefPtr (operand * op,int lvl)
2661 sym_link *rtype, *retype;
2662 sym_link *optype = operandType (op);
2664 // if this is an array then array access
2665 if (IS_ARRAY (optype)) {
2666 // don't worry, this will be optimized out later
2667 return geniCodeArray (op, operandFromLit (0), lvl);
2670 // just in case someone screws up
2671 wassert (IS_PTR (optype));
2673 if (IS_TRUE_SYMOP (op))
2676 op = geniCodeRValue (op, TRUE);
2679 /* now get rid of the pointer part */
2680 if (isLvaluereq(lvl) && IS_ITEMP (op))
2682 retype = getSpec (rtype = copyLinkChain (optype));
2686 retype = getSpec (rtype = copyLinkChain (optype->next));
2687 /* outputclass needs 2b updated */
2688 setOClass (optype, retype);
2691 op->isGptr = IS_GENPTR (optype);
2693 op->isaddr = (IS_PTR (rtype) ||
2694 IS_STRUCT (rtype) ||
2699 if (!isLvaluereq(lvl))
2700 op = geniCodeRValue (op, TRUE);
2702 setOperandType (op, rtype);
2707 /*-----------------------------------------------------------------*/
2708 /* geniCodeUnaryMinus - does a unary minus of the operand */
2709 /*-----------------------------------------------------------------*/
2711 geniCodeUnaryMinus (operand * op)
2714 sym_link *optype = operandType (op);
2716 if (IS_LITERAL (optype))
2717 return operandFromLit (-floatFromVal (op->operand.valOperand));
2719 ic = newiCode (UNARYMINUS, op, NULL);
2720 IC_RESULT (ic) = newiTempOperand (optype, 0);
2722 return IC_RESULT (ic);
2725 /*-----------------------------------------------------------------*/
2726 /* geniCodeLeftShift - gen i code for left shift */
2727 /*-----------------------------------------------------------------*/
2729 geniCodeLeftShift (operand * left, operand * right)
2733 left = usualUnaryConversions (left);
2734 ic = newiCode (LEFT_OP, left, right);
2735 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2737 return IC_RESULT (ic);
2740 /*-----------------------------------------------------------------*/
2741 /* geniCodeRightShift - gen i code for right shift */
2742 /*-----------------------------------------------------------------*/
2744 geniCodeRightShift (operand * left, operand * right)
2748 ic = newiCode (RIGHT_OP, left, right);
2749 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2751 return IC_RESULT (ic);
2754 /*-----------------------------------------------------------------*/
2755 /* geniCodeLogic- logic code */
2756 /*-----------------------------------------------------------------*/
2758 geniCodeLogic (operand * left, operand * right, int op)
2762 sym_link *rtype = operandType (right);
2763 sym_link *ltype = operandType (left);
2765 /* left is integral type and right is literal then
2766 check if the literal value is within bounds */
2767 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2769 checkConstantRange(ltype,
2770 OP_VALUE(right), "compare operation", 1);
2773 /* if one operand is a pointer and the other is a literal generic void pointer,
2774 change the type of the literal generic void pointer to match the other pointer */
2775 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2776 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2778 /* find left's definition */
2779 ic = (iCode *) setFirstItem (iCodeChain);
2782 if (((ic->op == CAST) || (ic->op == '='))
2783 && isOperandEqual(left, IC_RESULT (ic)))
2786 ic = setNextItem (iCodeChain);
2788 /* if casting literal to generic pointer, then cast to rtype instead */
2789 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2791 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2792 ltype = operandType(left);
2795 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2796 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2798 /* find right's definition */
2799 ic = (iCode *) setFirstItem (iCodeChain);
2802 if (((ic->op == CAST) || (ic->op == '='))
2803 && isOperandEqual(right, IC_RESULT (ic)))
2806 ic = setNextItem (iCodeChain);
2808 /* if casting literal to generic pointer, then cast to rtype instead */
2809 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2811 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2812 rtype = operandType(right);
2816 ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
2818 ic = newiCode (op, left, right);
2819 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2821 /* if comparing float
2822 and not a '==' || '!=' || '&&' || '||' (these
2824 if (IS_FLOAT(ctype) &&
2832 return IC_RESULT (ic);
2835 /*-----------------------------------------------------------------*/
2836 /* geniCodeUnary - for a a generic unary operation */
2837 /*-----------------------------------------------------------------*/
2839 geniCodeUnary (operand * op, int oper)
2841 iCode *ic = newiCode (oper, op, NULL);
2843 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2845 return IC_RESULT (ic);
2848 /*-----------------------------------------------------------------*/
2849 /* geniCodeConditional - geniCode for '?' ':' operation */
2850 /*-----------------------------------------------------------------*/
2852 geniCodeConditional (ast * tree,int lvl)
2855 symbol *falseLabel = newiTempLabel (NULL);
2856 symbol *exitLabel = newiTempLabel (NULL);
2857 operand *cond = ast2iCode (tree->left,lvl+1);
2858 operand *true, *false, *result;
2860 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2864 true = ast2iCode (tree->right->left,lvl+1);
2866 /* move the value to a new Operand */
2867 result = newiTempOperand (tree->right->ftype, 0);
2868 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2870 /* generate an unconditional goto */
2871 geniCodeGoto (exitLabel);
2873 /* now for the right side */
2874 geniCodeLabel (falseLabel);
2876 false = ast2iCode (tree->right->right,lvl+1);
2877 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2879 /* create the exit label */
2880 geniCodeLabel (exitLabel);
2885 /*-----------------------------------------------------------------*/
2886 /* geniCodeAssign - generate code for assignment */
2887 /*-----------------------------------------------------------------*/
2889 geniCodeAssign (operand * left, operand * right, int nosupdate)
2892 sym_link *ltype = operandType (left);
2893 sym_link *rtype = operandType (right);
2895 if (!left->isaddr && !IS_ITEMP (left))
2897 werror (E_LVALUE_REQUIRED, "assignment");
2901 /* left is integral type and right is literal then
2902 check if the literal value is within bounds */
2903 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2905 checkConstantRange(ltype,
2906 OP_VALUE(right), "= operation", 0);
2909 /* if the left & right type don't exactly match */
2910 /* if pointer set then make sure the check is
2911 done with the type & not the pointer */
2912 /* then cast rights type to left */
2914 /* first check the type for pointer assignement */
2915 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2916 compareType (ltype, rtype) <= 0)
2918 if (compareType (ltype->next, rtype) < 0)
2919 right = geniCodeCast (ltype->next, right, TRUE);
2921 else if (compareType (ltype, rtype) < 0)
2922 right = geniCodeCast (ltype, right, TRUE);
2924 /* If left is a true symbol & ! volatile
2925 create an assignment to temporary for
2926 the right & then assign this temporary
2927 to the symbol. This is SSA (static single
2928 assignment). Isn't it simple and folks have
2929 published mountains of paper on it */
2930 if (IS_TRUE_SYMOP (left) &&
2931 !isOperandVolatile (left, FALSE) &&
2932 isOperandGlobal (left))
2936 if (IS_TRUE_SYMOP (right))
2937 sym = OP_SYMBOL (right);
2938 ic = newiCode ('=', NULL, right);
2939 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2940 SPIL_LOC (right) = sym;
2944 ic = newiCode ('=', NULL, right);
2945 IC_RESULT (ic) = left;
2948 /* if left isgptr flag is set then support
2949 routine will be required */
2953 ic->nosupdate = nosupdate;
2957 /*-----------------------------------------------------------------*/
2958 /* geniCodeDummyRead - generate code for dummy read */
2959 /*-----------------------------------------------------------------*/
2961 geniCodeDummyRead (operand * op)
2964 sym_link *type = operandType (op);
2966 if (!IS_VOLATILE(type))
2969 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2975 /*-----------------------------------------------------------------*/
2976 /* geniCodeSEParms - generate code for side effecting fcalls */
2977 /*-----------------------------------------------------------------*/
2979 geniCodeSEParms (ast * parms,int lvl)
2984 if (parms->type == EX_OP && parms->opval.op == PARAM)
2986 geniCodeSEParms (parms->left,lvl);
2987 geniCodeSEParms (parms->right,lvl);
2991 /* hack don't like this but too lazy to think of
2993 if (IS_ADDRESS_OF_OP (parms))
2994 parms->left->lvalue = 1;
2996 if (IS_CAST_OP (parms) &&
2997 IS_PTR (parms->ftype) &&
2998 IS_ADDRESS_OF_OP (parms->right))
2999 parms->right->left->lvalue = 1;
3001 parms->opval.oprnd =
3002 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3004 parms->type = EX_OPERAND;
3005 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3006 SPEC_ARGREG(parms->ftype);
3009 /*-----------------------------------------------------------------*/
3010 /* geniCodeParms - generates parameters */
3011 /*-----------------------------------------------------------------*/
3013 geniCodeParms (ast * parms, value *argVals, int *stack,
3014 sym_link * fetype, symbol * func,int lvl)
3022 if (argVals==NULL) {
3024 argVals=FUNC_ARGS(func->type);
3027 /* if this is a param node then do the left & right */
3028 if (parms->type == EX_OP && parms->opval.op == PARAM)
3030 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
3031 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
3035 /* get the parameter value */
3036 if (parms->type == EX_OPERAND)
3037 pval = parms->opval.oprnd;
3040 /* maybe this else should go away ?? */
3041 /* hack don't like this but too lazy to think of
3043 if (IS_ADDRESS_OF_OP (parms))
3044 parms->left->lvalue = 1;
3046 if (IS_CAST_OP (parms) &&
3047 IS_PTR (parms->ftype) &&
3048 IS_ADDRESS_OF_OP (parms->right))
3049 parms->right->left->lvalue = 1;
3051 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3054 /* if register parm then make it a send */
3055 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
3056 IFFUNC_ISBUILTIN(func->type))
3058 ic = newiCode (SEND, pval, NULL);
3059 ic->argreg = SPEC_ARGREG(parms->etype);
3060 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
3065 /* now decide whether to push or assign */
3066 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
3070 operand *top = operandFromSymbol (argVals->sym);
3071 /* clear useDef and other bitVectors */
3072 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3073 geniCodeAssign (top, pval, 1);
3077 sym_link *p = operandType (pval);
3079 ic = newiCode (IPUSH, pval, NULL);
3081 /* update the stack adjustment */
3082 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3087 argVals=argVals->next;
3091 /*-----------------------------------------------------------------*/
3092 /* geniCodeCall - generates temp code for calling */
3093 /*-----------------------------------------------------------------*/
3095 geniCodeCall (operand * left, ast * parms,int lvl)
3099 sym_link *type, *etype;
3102 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3103 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3104 werror (E_FUNCTION_EXPECTED);
3105 return operandFromValue(valueFromLit(0));
3108 /* take care of parameters with side-effecting
3109 function calls in them, this is required to take care
3110 of overlaying function parameters */
3111 geniCodeSEParms (parms,lvl);
3113 /* first the parameters */
3114 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3116 /* now call : if symbol then pcall */
3117 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3118 ic = newiCode (PCALL, left, NULL);
3120 ic = newiCode (CALL, left, NULL);
3123 type = copyLinkChain (operandType (left)->next);
3124 etype = getSpec (type);
3125 SPEC_EXTR (etype) = 0;
3126 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3130 /* stack adjustment after call */
3131 ic->parmBytes = stack;
3136 /*-----------------------------------------------------------------*/
3137 /* geniCodeReceive - generate intermediate code for "receive" */
3138 /*-----------------------------------------------------------------*/
3140 geniCodeReceive (value * args)
3142 /* for all arguments that are passed in registers */
3146 if (IS_REGPARM (args->etype))
3148 operand *opr = operandFromValue (args);
3150 symbol *sym = OP_SYMBOL (opr);
3153 /* we will use it after all optimizations
3154 and before liveRange calculation */
3155 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3158 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3159 options.stackAuto == 0 &&
3160 (!(options.model == MODEL_FLAT24)) )
3165 opl = newiTempOperand (args->type, 0);
3167 sym->reqv->key = sym->key;
3168 OP_SYMBOL (sym->reqv)->key = sym->key;
3169 OP_SYMBOL (sym->reqv)->isreqv = 1;
3170 OP_SYMBOL (sym->reqv)->islocal = 0;
3171 SPIL_LOC (sym->reqv) = sym;
3175 ic = newiCode (RECEIVE, NULL, NULL);
3176 ic->argreg = SPEC_ARGREG(args->etype);
3178 currFunc->recvSize = getSize (sym->type);
3181 IC_RESULT (ic) = opr;
3189 /*-----------------------------------------------------------------*/
3190 /* geniCodeFunctionBody - create the function body */
3191 /*-----------------------------------------------------------------*/
3193 geniCodeFunctionBody (ast * tree,int lvl)
3200 /* reset the auto generation */
3206 func = ast2iCode (tree->left,lvl+1);
3207 fetype = getSpec (operandType (func));
3209 savelineno = lineno;
3210 lineno = OP_SYMBOL (func)->lineDef;
3211 /* create an entry label */
3212 geniCodeLabel (entryLabel);
3213 lineno = savelineno;
3215 /* create a proc icode */
3216 ic = newiCode (FUNCTION, func, NULL);
3217 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3221 /* for all parameters that are passed
3222 on registers add a "receive" */
3223 geniCodeReceive (tree->values.args);
3225 /* generate code for the body */
3226 ast2iCode (tree->right,lvl+1);
3228 /* create a label for return */
3229 geniCodeLabel (returnLabel);
3231 /* now generate the end proc */
3232 ic = newiCode (ENDFUNCTION, func, NULL);
3237 /*-----------------------------------------------------------------*/
3238 /* geniCodeReturn - gen icode for 'return' statement */
3239 /*-----------------------------------------------------------------*/
3241 geniCodeReturn (operand * op)
3245 /* if the operand is present force an rvalue */
3247 op = geniCodeRValue (op, FALSE);
3249 ic = newiCode (RETURN, op, NULL);
3253 /*-----------------------------------------------------------------*/
3254 /* geniCodeIfx - generates code for extended if statement */
3255 /*-----------------------------------------------------------------*/
3257 geniCodeIfx (ast * tree,int lvl)
3260 operand *condition = ast2iCode (tree->left,lvl+1);
3263 /* if condition is null then exit */
3267 condition = geniCodeRValue (condition, FALSE);
3269 cetype = getSpec (operandType (condition));
3270 /* if the condition is a literal */
3271 if (IS_LITERAL (cetype))
3273 if (floatFromVal (condition->operand.valOperand))
3275 if (tree->trueLabel)
3276 geniCodeGoto (tree->trueLabel);
3282 if (tree->falseLabel)
3283 geniCodeGoto (tree->falseLabel);
3290 if (tree->trueLabel)
3292 ic = newiCodeCondition (condition,
3297 if (tree->falseLabel)
3298 geniCodeGoto (tree->falseLabel);
3302 ic = newiCodeCondition (condition,
3309 ast2iCode (tree->right,lvl+1);
3312 /*-----------------------------------------------------------------*/
3313 /* geniCodeJumpTable - tries to create a jump table for switch */
3314 /*-----------------------------------------------------------------*/
3316 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3318 int min = 0, max = 0, t, cnt = 0;
3324 int needRangeCheck = !optimize.noJTabBoundary
3325 || tree->values.switchVals.swDefault;
3327 if (!tree || !caseVals)
3330 /* the criteria for creating a jump table is */
3331 /* all integer numbers between the maximum & minimum must */
3332 /* be present , the maximum value should not exceed 255 */
3333 min = max = (int) floatFromVal (vch = caseVals);
3334 SNPRINTF (buffer, sizeof(buffer),
3336 tree->values.switchVals.swNum,
3338 addSet (&labels, newiTempLabel (buffer));
3340 /* if there is only one case value then no need */
3341 if (!(vch = vch->next))
3346 if (((t = (int) floatFromVal (vch)) - max) != 1)
3348 SNPRINTF (buffer, sizeof(buffer),
3350 tree->values.switchVals.swNum,
3352 addSet (&labels, newiTempLabel (buffer));
3358 /* if the number of case statements <= 2 then */
3359 /* it is not economical to create the jump table */
3360 /* since two compares are needed for boundary conditions */
3361 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3364 if (tree->values.switchVals.swDefault)
3366 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3370 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3374 falseLabel = newiTempLabel (buffer);
3376 /* so we can create a jumptable */
3377 /* first we rule out the boundary conditions */
3378 /* if only optimization says so */
3381 sym_link *cetype = getSpec (operandType (cond));
3382 /* no need to check the lower bound if
3383 the condition is unsigned & minimum value is zero */
3384 if (!(min == 0 && IS_UNSIGNED (cetype)))
3386 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3387 ic = newiCodeCondition (boundary, falseLabel, NULL);
3391 /* now for upper bounds */
3392 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3393 ic = newiCodeCondition (boundary, falseLabel, NULL);
3397 /* if the min is not zero then we no make it zero */
3400 cond = geniCodeSubtract (cond, operandFromLit (min));
3401 if (!IS_LITERAL(getSpec(operandType(cond))))
3402 setOperandType (cond, UCHARTYPE);
3405 /* now create the jumptable */
3406 ic = newiCode (JUMPTABLE, NULL, NULL);
3407 IC_JTCOND (ic) = cond;
3408 IC_JTLABELS (ic) = labels;
3413 /*-----------------------------------------------------------------*/
3414 /* geniCodeSwitch - changes a switch to a if statement */
3415 /*-----------------------------------------------------------------*/
3417 geniCodeSwitch (ast * tree,int lvl)
3420 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3421 value *caseVals = tree->values.switchVals.swVals;
3422 symbol *trueLabel, *falseLabel;
3424 /* If the condition is a literal, then just jump to the */
3425 /* appropriate case label. */
3426 if (IS_LITERAL(getSpec(operandType(cond))))
3428 int switchVal, caseVal;
3430 switchVal = (int) floatFromVal (cond->operand.valOperand);
3433 caseVal = (int) floatFromVal (caseVals);
3434 if (caseVal == switchVal)
3436 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3437 tree->values.switchVals.swNum, caseVal);
3438 trueLabel = newiTempLabel (buffer);
3439 geniCodeGoto (trueLabel);
3442 caseVals = caseVals->next;
3444 goto defaultOrBreak;
3447 /* if we can make this a jump table */
3448 if (geniCodeJumpTable (cond, caseVals, tree))
3449 goto jumpTable; /* no need for the comparison */
3451 /* for the cases defined do */
3455 operand *compare = geniCodeLogic (cond,
3456 operandFromValue (caseVals),
3459 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3460 tree->values.switchVals.swNum,
3461 (int) floatFromVal (caseVals));
3462 trueLabel = newiTempLabel (buffer);
3464 ic = newiCodeCondition (compare, trueLabel, NULL);
3466 caseVals = caseVals->next;
3471 /* if default is present then goto break else break */
3472 if (tree->values.switchVals.swDefault)
3474 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3478 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3481 falseLabel = newiTempLabel (buffer);
3482 geniCodeGoto (falseLabel);
3485 ast2iCode (tree->right,lvl+1);
3488 /*-----------------------------------------------------------------*/
3489 /* geniCodeInline - intermediate code for inline assembler */
3490 /*-----------------------------------------------------------------*/
3492 geniCodeInline (ast * tree)
3496 ic = newiCode (INLINEASM, NULL, NULL);
3497 IC_INLINE (ic) = tree->values.inlineasm;
3501 /*-----------------------------------------------------------------*/
3502 /* geniCodeArrayInit - intermediate code for array initializer */
3503 /*-----------------------------------------------------------------*/
3505 geniCodeArrayInit (ast * tree, operand *array)
3509 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3510 ic = newiCode (ARRAYINIT, array, NULL);
3511 IC_ARRAYILIST (ic) = tree->values.constlist;
3513 operand *left=newOperand(), *right=newOperand();
3514 left->type=right->type=SYMBOL;
3515 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3516 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3517 ic = newiCode (ARRAYINIT, left, right);
3522 /*-----------------------------------------------------------------*/
3523 /* geniCodeCritical - intermediate code for a critical statement */
3524 /*-----------------------------------------------------------------*/
3526 geniCodeCritical (ast *tree, int lvl)
3531 /* If op is NULL, the original interrupt state will saved on */
3532 /* the stack. Otherwise, it will be saved in op. */
3534 /* Generate a save of the current interrupt state & disabled */
3535 ic = newiCode (CRITICAL, NULL, NULL);
3536 IC_RESULT (ic) = op;
3539 /* Generate the critical code sequence */
3540 if (tree->left && tree->left->type == EX_VALUE)
3541 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3543 ast2iCode (tree->left,lvl+1);
3545 /* Generate a restore of the original interrupt state */
3546 ic = newiCode (ENDCRITICAL, NULL, op);
3550 /*-----------------------------------------------------------------*/
3551 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3552 /* particular case. Ie : assigning or dereferencing array or ptr */
3553 /*-----------------------------------------------------------------*/
3554 set * lvaluereqSet = NULL;
3555 typedef struct lvalItem
3562 /*-----------------------------------------------------------------*/
3563 /* addLvaluereq - add a flag for lvalreq for current ast level */
3564 /*-----------------------------------------------------------------*/
3565 void addLvaluereq(int lvl)
3567 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3570 addSetHead(&lvaluereqSet,lpItem);
3573 /*-----------------------------------------------------------------*/
3574 /* delLvaluereq - del a flag for lvalreq for current ast level */
3575 /*-----------------------------------------------------------------*/
3579 lpItem = getSet(&lvaluereqSet);
3580 if(lpItem) Safe_free(lpItem);
3582 /*-----------------------------------------------------------------*/
3583 /* clearLvaluereq - clear lvalreq flag */
3584 /*-----------------------------------------------------------------*/
3585 void clearLvaluereq()
3588 lpItem = peekSet(lvaluereqSet);
3589 if(lpItem) lpItem->req = 0;
3591 /*-----------------------------------------------------------------*/
3592 /* getLvaluereq - get the last lvalreq level */
3593 /*-----------------------------------------------------------------*/
3594 int getLvaluereqLvl()
3597 lpItem = peekSet(lvaluereqSet);
3598 if(lpItem) return lpItem->lvl;
3601 /*-----------------------------------------------------------------*/
3602 /* isLvaluereq - is lvalreq valid for this level ? */
3603 /*-----------------------------------------------------------------*/
3604 int isLvaluereq(int lvl)
3607 lpItem = peekSet(lvaluereqSet);
3608 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3612 /*-----------------------------------------------------------------*/
3613 /* ast2iCode - creates an icodeList from an ast */
3614 /*-----------------------------------------------------------------*/
3616 ast2iCode (ast * tree,int lvl)
3618 operand *left = NULL;
3619 operand *right = NULL;
3623 /* set the global variables for filename & line number */
3625 filename = tree->filename;
3627 lineno = tree->lineno;
3629 block = tree->block;
3631 scopeLevel = tree->level;
3633 seqPoint = tree->seqPoint;
3635 if (tree->type == EX_VALUE)
3636 return operandFromValue (tree->opval.val);
3638 if (tree->type == EX_LINK)
3639 return operandFromLink (tree->opval.lnk);
3641 /* if we find a nullop */
3642 if (tree->type == EX_OP &&
3643 (tree->opval.op == NULLOP ||
3644 tree->opval.op == BLOCK))
3646 if (tree->left && tree->left->type == EX_VALUE)
3647 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3649 ast2iCode (tree->left,lvl+1);
3650 if (tree->right && tree->right->type == EX_VALUE)
3651 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3653 ast2iCode (tree->right,lvl+1);
3657 /* special cases for not evaluating */
3658 if (tree->opval.op != ':' &&
3659 tree->opval.op != '?' &&
3660 tree->opval.op != CALL &&
3661 tree->opval.op != IFX &&
3662 tree->opval.op != LABEL &&
3663 tree->opval.op != GOTO &&
3664 tree->opval.op != SWITCH &&
3665 tree->opval.op != FUNCTION &&
3666 tree->opval.op != INLINEASM &&
3667 tree->opval.op != CRITICAL)
3670 if (IS_ASSIGN_OP (tree->opval.op) ||
3671 IS_DEREF_OP (tree) ||
3672 (tree->opval.op == '&' && !tree->right) ||
3673 tree->opval.op == PTR_OP)
3676 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3677 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3680 left = operandFromAst (tree->left,lvl);
3682 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3683 left = geniCodeRValue (left, TRUE);
3687 left = operandFromAst (tree->left,lvl);
3689 if (tree->opval.op == INC_OP ||
3690 tree->opval.op == DEC_OP)
3693 right = operandFromAst (tree->right,lvl);
3698 right = operandFromAst (tree->right,lvl);
3702 /* now depending on the type of operand */
3703 /* this will be a biggy */
3704 switch (tree->opval.op)
3707 case '[': /* array operation */
3709 //sym_link *ltype = operandType (left);
3710 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3711 left = geniCodeRValue (left, FALSE);
3712 right = geniCodeRValue (right, TRUE);
3715 return geniCodeArray (left, right,lvl);
3717 case '.': /* structure dereference */
3718 if (IS_PTR (operandType (left)))
3719 left = geniCodeRValue (left, TRUE);
3721 left = geniCodeRValue (left, FALSE);
3723 return geniCodeStruct (left, right, tree->lvalue);
3725 case PTR_OP: /* structure pointer dereference */
3728 pType = operandType (left);
3729 left = geniCodeRValue (left, TRUE);
3731 setOClass (pType, getSpec (operandType (left)));
3734 return geniCodeStruct (left, right, tree->lvalue);
3736 case INC_OP: /* increment operator */
3738 return geniCodePostInc (left);
3740 return geniCodePreInc (right, tree->lvalue);
3742 case DEC_OP: /* decrement operator */
3744 return geniCodePostDec (left);
3746 return geniCodePreDec (right, tree->lvalue);
3748 case '&': /* bitwise and or address of operator */
3750 { /* this is a bitwise operator */
3751 left = geniCodeRValue (left, FALSE);
3752 right = geniCodeRValue (right, FALSE);
3753 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3756 return geniCodeAddressOf (left);
3758 case '|': /* bitwise or & xor */
3760 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3761 geniCodeRValue (right, FALSE),
3766 return geniCodeDivision (geniCodeRValue (left, FALSE),
3767 geniCodeRValue (right, FALSE));
3770 return geniCodeModulus (geniCodeRValue (left, FALSE),
3771 geniCodeRValue (right, FALSE));
3774 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3775 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3777 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3781 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3782 geniCodeRValue (right, FALSE));
3784 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3788 return geniCodeAdd (geniCodeRValue (left, FALSE),
3789 geniCodeRValue (right, FALSE),lvl);
3791 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3794 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3795 geniCodeRValue (right, FALSE));
3798 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3799 geniCodeRValue (right, FALSE));
3801 #if 0 // this indeed needs a second thought
3805 // let's keep this simple: get the rvalue we need
3806 op=geniCodeRValue (right, FALSE);
3807 // now cast it to whatever we want
3808 op=geniCodeCast (operandType(left), op, FALSE);
3809 // if this is going to be used as an lvalue, make it so
3815 #else // bug #604575, is it a bug ????
3816 return geniCodeCast (operandType (left),
3817 geniCodeRValue (right, FALSE), FALSE);
3824 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3829 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3830 setOperandType (op, UCHARTYPE);
3841 /* different compilers (even different gccs) evaluate
3842 the two calls in a different order. to get the same
3843 result on all machines we've to specify a clear sequence.
3844 return geniCodeLogic (geniCodeRValue (left, FALSE),
3845 geniCodeRValue (right, FALSE),
3849 operand *leftOp, *rightOp;
3851 rightOp = geniCodeRValue (right, FALSE);
3852 leftOp = geniCodeRValue (left , FALSE);
3854 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3857 return geniCodeConditional (tree,lvl);
3860 return operandFromLit (getSize (tree->right->ftype));
3864 sym_link *rtype = operandType (right);
3865 sym_link *ltype = operandType (left);
3866 if (IS_PTR (rtype) && IS_ITEMP (right)
3867 && right->isaddr && compareType (rtype->next, ltype) == 1)
3868 right = geniCodeRValue (right, TRUE);
3870 right = geniCodeRValue (right, FALSE);
3872 geniCodeAssign (left, right, 0);
3877 geniCodeAssign (left,
3878 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3880 geniCodeRValue (right, FALSE),FALSE), 0);
3884 geniCodeAssign (left,
3885 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3887 geniCodeRValue (right, FALSE)), 0);
3890 geniCodeAssign (left,
3891 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3893 geniCodeRValue (right, FALSE)), 0);
3896 sym_link *rtype = operandType (right);
3897 sym_link *ltype = operandType (left);
3898 if (IS_PTR (rtype) && IS_ITEMP (right)
3899 && right->isaddr && compareType (rtype->next, ltype) == 1)
3900 right = geniCodeRValue (right, TRUE);
3902 right = geniCodeRValue (right, FALSE);
3905 return geniCodeAssign (left,
3906 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3912 sym_link *rtype = operandType (right);
3913 sym_link *ltype = operandType (left);
3914 if (IS_PTR (rtype) && IS_ITEMP (right)
3915 && right->isaddr && compareType (rtype->next, ltype) == 1)
3917 right = geniCodeRValue (right, TRUE);
3921 right = geniCodeRValue (right, FALSE);
3924 geniCodeAssign (left,
3925 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3931 geniCodeAssign (left,
3932 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3934 geniCodeRValue (right, FALSE)), 0);
3937 geniCodeAssign (left,
3938 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3940 geniCodeRValue (right, FALSE)), 0);
3943 geniCodeAssign (left,
3944 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3946 geniCodeRValue (right, FALSE),
3948 operandType (left)), 0);
3951 geniCodeAssign (left,
3952 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3954 geniCodeRValue (right, FALSE),
3956 operandType (left)), 0);
3959 geniCodeAssign (left,
3960 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3962 geniCodeRValue (right, FALSE),
3964 operandType (left)), 0);
3966 return geniCodeRValue (right, FALSE);
3969 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3972 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3973 return ast2iCode (tree->right,lvl+1);
3976 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3977 return ast2iCode (tree->right,lvl+1);
3980 geniCodeFunctionBody (tree,lvl);
3984 geniCodeReturn (right);
3988 geniCodeIfx (tree,lvl);
3992 geniCodeSwitch (tree,lvl);
3996 geniCodeInline (tree);
4000 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4004 geniCodeCritical (tree, lvl);
4010 /*-----------------------------------------------------------------*/
4011 /* reverseICChain - gets from the list and creates a linkedlist */
4012 /*-----------------------------------------------------------------*/
4019 while ((loop = getSet (&iCodeChain)))
4031 /*-----------------------------------------------------------------*/
4032 /* iCodeFromAst - given an ast will convert it to iCode */
4033 /*-----------------------------------------------------------------*/
4035 iCodeFromAst (ast * tree)
4037 returnLabel = newiTempLabel ("_return");
4038 entryLabel = newiTempLabel ("_entry");
4040 return reverseiCChain ();
4043 static const char *opTypeToStr(OPTYPE op)
4047 case SYMBOL: return "symbol";
4048 case VALUE: return "value";
4049 case TYPE: return "type";
4051 return "undefined type";
4055 operand *validateOpType(operand *op,
4062 if (op && op->type == type)
4067 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4068 " expected %s, got %s\n",
4069 macro, args, file, line,
4070 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4072 return op; // never reached, makes compiler happy.