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 ic = newiCode (LEFT_OP, left, right);
2734 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2736 return IC_RESULT (ic);
2739 /*-----------------------------------------------------------------*/
2740 /* geniCodeRightShift - gen i code for right shift */
2741 /*-----------------------------------------------------------------*/
2743 geniCodeRightShift (operand * left, operand * right)
2747 ic = newiCode (RIGHT_OP, left, right);
2748 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2750 return IC_RESULT (ic);
2753 /*-----------------------------------------------------------------*/
2754 /* geniCodeLogic- logic code */
2755 /*-----------------------------------------------------------------*/
2757 geniCodeLogic (operand * left, operand * right, int op)
2761 sym_link *rtype = operandType (right);
2762 sym_link *ltype = operandType (left);
2764 /* left is integral type and right is literal then
2765 check if the literal value is within bounds */
2766 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2768 checkConstantRange(ltype,
2769 OP_VALUE(right), "compare operation", 1);
2772 /* if one operand is a pointer and the other is a literal generic void pointer,
2773 change the type of the literal generic void pointer to match the other pointer */
2774 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2775 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2777 /* find left's definition */
2778 ic = (iCode *) setFirstItem (iCodeChain);
2781 if (((ic->op == CAST) || (ic->op == '='))
2782 && isOperandEqual(left, IC_RESULT (ic)))
2785 ic = setNextItem (iCodeChain);
2787 /* if casting literal to generic pointer, then cast to rtype instead */
2788 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2790 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2791 ltype = operandType(left);
2794 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2795 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2797 /* find right's definition */
2798 ic = (iCode *) setFirstItem (iCodeChain);
2801 if (((ic->op == CAST) || (ic->op == '='))
2802 && isOperandEqual(right, IC_RESULT (ic)))
2805 ic = setNextItem (iCodeChain);
2807 /* if casting literal to generic pointer, then cast to rtype instead */
2808 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2810 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2811 rtype = operandType(right);
2815 ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
2817 ic = newiCode (op, left, right);
2818 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2820 /* if comparing float
2821 and not a '==' || '!=' || '&&' || '||' (these
2823 if (IS_FLOAT(ctype) &&
2831 return IC_RESULT (ic);
2834 /*-----------------------------------------------------------------*/
2835 /* geniCodeUnary - for a a generic unary operation */
2836 /*-----------------------------------------------------------------*/
2838 geniCodeUnary (operand * op, int oper)
2840 iCode *ic = newiCode (oper, op, NULL);
2842 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2844 return IC_RESULT (ic);
2847 /*-----------------------------------------------------------------*/
2848 /* geniCodeConditional - geniCode for '?' ':' operation */
2849 /*-----------------------------------------------------------------*/
2851 geniCodeConditional (ast * tree,int lvl)
2854 symbol *falseLabel = newiTempLabel (NULL);
2855 symbol *exitLabel = newiTempLabel (NULL);
2856 operand *cond = ast2iCode (tree->left,lvl+1);
2857 operand *true, *false, *result;
2859 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2863 true = ast2iCode (tree->right->left,lvl+1);
2865 /* move the value to a new Operand */
2866 result = newiTempOperand (tree->right->ftype, 0);
2867 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2869 /* generate an unconditional goto */
2870 geniCodeGoto (exitLabel);
2872 /* now for the right side */
2873 geniCodeLabel (falseLabel);
2875 false = ast2iCode (tree->right->right,lvl+1);
2876 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2878 /* create the exit label */
2879 geniCodeLabel (exitLabel);
2884 /*-----------------------------------------------------------------*/
2885 /* geniCodeAssign - generate code for assignment */
2886 /*-----------------------------------------------------------------*/
2888 geniCodeAssign (operand * left, operand * right, int nosupdate)
2891 sym_link *ltype = operandType (left);
2892 sym_link *rtype = operandType (right);
2894 if (!left->isaddr && !IS_ITEMP (left))
2896 werror (E_LVALUE_REQUIRED, "assignment");
2900 /* left is integral type and right is literal then
2901 check if the literal value is within bounds */
2902 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2904 checkConstantRange(ltype,
2905 OP_VALUE(right), "= operation", 0);
2908 /* if the left & right type don't exactly match */
2909 /* if pointer set then make sure the check is
2910 done with the type & not the pointer */
2911 /* then cast rights type to left */
2913 /* first check the type for pointer assignement */
2914 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2915 compareType (ltype, rtype) <= 0)
2917 if (compareType (ltype->next, rtype) < 0)
2918 right = geniCodeCast (ltype->next, right, TRUE);
2920 else if (compareType (ltype, rtype) < 0)
2921 right = geniCodeCast (ltype, right, TRUE);
2923 /* If left is a true symbol & ! volatile
2924 create an assignment to temporary for
2925 the right & then assign this temporary
2926 to the symbol. This is SSA (static single
2927 assignment). Isn't it simple and folks have
2928 published mountains of paper on it */
2929 if (IS_TRUE_SYMOP (left) &&
2930 !isOperandVolatile (left, FALSE) &&
2931 isOperandGlobal (left))
2935 if (IS_TRUE_SYMOP (right))
2936 sym = OP_SYMBOL (right);
2937 ic = newiCode ('=', NULL, right);
2938 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2939 SPIL_LOC (right) = sym;
2943 ic = newiCode ('=', NULL, right);
2944 IC_RESULT (ic) = left;
2947 /* if left isgptr flag is set then support
2948 routine will be required */
2952 ic->nosupdate = nosupdate;
2956 /*-----------------------------------------------------------------*/
2957 /* geniCodeDummyRead - generate code for dummy read */
2958 /*-----------------------------------------------------------------*/
2960 geniCodeDummyRead (operand * op)
2963 sym_link *type = operandType (op);
2965 if (!IS_VOLATILE(type))
2968 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2974 /*-----------------------------------------------------------------*/
2975 /* geniCodeSEParms - generate code for side effecting fcalls */
2976 /*-----------------------------------------------------------------*/
2978 geniCodeSEParms (ast * parms,int lvl)
2983 if (parms->type == EX_OP && parms->opval.op == PARAM)
2985 geniCodeSEParms (parms->left,lvl);
2986 geniCodeSEParms (parms->right,lvl);
2990 /* hack don't like this but too lazy to think of
2992 if (IS_ADDRESS_OF_OP (parms))
2993 parms->left->lvalue = 1;
2995 if (IS_CAST_OP (parms) &&
2996 IS_PTR (parms->ftype) &&
2997 IS_ADDRESS_OF_OP (parms->right))
2998 parms->right->left->lvalue = 1;
3000 parms->opval.oprnd =
3001 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3003 parms->type = EX_OPERAND;
3004 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3005 SPEC_ARGREG(parms->ftype);
3008 /*-----------------------------------------------------------------*/
3009 /* geniCodeParms - generates parameters */
3010 /*-----------------------------------------------------------------*/
3012 geniCodeParms (ast * parms, value *argVals, int *stack,
3013 sym_link * fetype, symbol * func,int lvl)
3021 if (argVals==NULL) {
3023 argVals=FUNC_ARGS(func->type);
3026 /* if this is a param node then do the left & right */
3027 if (parms->type == EX_OP && parms->opval.op == PARAM)
3029 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
3030 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
3034 /* get the parameter value */
3035 if (parms->type == EX_OPERAND)
3036 pval = parms->opval.oprnd;
3039 /* maybe this else should go away ?? */
3040 /* hack don't like this but too lazy to think of
3042 if (IS_ADDRESS_OF_OP (parms))
3043 parms->left->lvalue = 1;
3045 if (IS_CAST_OP (parms) &&
3046 IS_PTR (parms->ftype) &&
3047 IS_ADDRESS_OF_OP (parms->right))
3048 parms->right->left->lvalue = 1;
3050 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3053 /* if register parm then make it a send */
3054 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
3055 IFFUNC_ISBUILTIN(func->type))
3057 ic = newiCode (SEND, pval, NULL);
3058 ic->argreg = SPEC_ARGREG(parms->etype);
3059 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
3064 /* now decide whether to push or assign */
3065 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
3069 operand *top = operandFromSymbol (argVals->sym);
3070 /* clear useDef and other bitVectors */
3071 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3072 geniCodeAssign (top, pval, 1);
3076 sym_link *p = operandType (pval);
3078 ic = newiCode (IPUSH, pval, NULL);
3080 /* update the stack adjustment */
3081 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3086 argVals=argVals->next;
3090 /*-----------------------------------------------------------------*/
3091 /* geniCodeCall - generates temp code for calling */
3092 /*-----------------------------------------------------------------*/
3094 geniCodeCall (operand * left, ast * parms,int lvl)
3098 sym_link *type, *etype;
3101 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3102 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3103 werror (E_FUNCTION_EXPECTED);
3104 return operandFromValue(valueFromLit(0));
3107 /* take care of parameters with side-effecting
3108 function calls in them, this is required to take care
3109 of overlaying function parameters */
3110 geniCodeSEParms (parms,lvl);
3112 /* first the parameters */
3113 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3115 /* now call : if symbol then pcall */
3116 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3117 ic = newiCode (PCALL, left, NULL);
3119 ic = newiCode (CALL, left, NULL);
3122 type = copyLinkChain (operandType (left)->next);
3123 etype = getSpec (type);
3124 SPEC_EXTR (etype) = 0;
3125 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3129 /* stack adjustment after call */
3130 ic->parmBytes = stack;
3135 /*-----------------------------------------------------------------*/
3136 /* geniCodeReceive - generate intermediate code for "receive" */
3137 /*-----------------------------------------------------------------*/
3139 geniCodeReceive (value * args)
3141 /* for all arguments that are passed in registers */
3145 if (IS_REGPARM (args->etype))
3147 operand *opr = operandFromValue (args);
3149 symbol *sym = OP_SYMBOL (opr);
3152 /* we will use it after all optimizations
3153 and before liveRange calculation */
3154 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3157 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3158 options.stackAuto == 0 &&
3159 (!(options.model == MODEL_FLAT24)) )
3164 opl = newiTempOperand (args->type, 0);
3166 sym->reqv->key = sym->key;
3167 OP_SYMBOL (sym->reqv)->key = sym->key;
3168 OP_SYMBOL (sym->reqv)->isreqv = 1;
3169 OP_SYMBOL (sym->reqv)->islocal = 0;
3170 SPIL_LOC (sym->reqv) = sym;
3174 ic = newiCode (RECEIVE, NULL, NULL);
3175 ic->argreg = SPEC_ARGREG(args->etype);
3177 currFunc->recvSize = getSize (sym->type);
3180 IC_RESULT (ic) = opr;
3188 /*-----------------------------------------------------------------*/
3189 /* geniCodeFunctionBody - create the function body */
3190 /*-----------------------------------------------------------------*/
3192 geniCodeFunctionBody (ast * tree,int lvl)
3199 /* reset the auto generation */
3205 func = ast2iCode (tree->left,lvl+1);
3206 fetype = getSpec (operandType (func));
3208 savelineno = lineno;
3209 lineno = OP_SYMBOL (func)->lineDef;
3210 /* create an entry label */
3211 geniCodeLabel (entryLabel);
3212 lineno = savelineno;
3214 /* create a proc icode */
3215 ic = newiCode (FUNCTION, func, NULL);
3216 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3220 /* for all parameters that are passed
3221 on registers add a "receive" */
3222 geniCodeReceive (tree->values.args);
3224 /* generate code for the body */
3225 ast2iCode (tree->right,lvl+1);
3227 /* create a label for return */
3228 geniCodeLabel (returnLabel);
3230 /* now generate the end proc */
3231 ic = newiCode (ENDFUNCTION, func, NULL);
3236 /*-----------------------------------------------------------------*/
3237 /* geniCodeReturn - gen icode for 'return' statement */
3238 /*-----------------------------------------------------------------*/
3240 geniCodeReturn (operand * op)
3244 /* if the operand is present force an rvalue */
3246 op = geniCodeRValue (op, FALSE);
3248 ic = newiCode (RETURN, op, NULL);
3252 /*-----------------------------------------------------------------*/
3253 /* geniCodeIfx - generates code for extended if statement */
3254 /*-----------------------------------------------------------------*/
3256 geniCodeIfx (ast * tree,int lvl)
3259 operand *condition = ast2iCode (tree->left,lvl+1);
3262 /* if condition is null then exit */
3266 condition = geniCodeRValue (condition, FALSE);
3268 cetype = getSpec (operandType (condition));
3269 /* if the condition is a literal */
3270 if (IS_LITERAL (cetype))
3272 if (floatFromVal (condition->operand.valOperand))
3274 if (tree->trueLabel)
3275 geniCodeGoto (tree->trueLabel);
3281 if (tree->falseLabel)
3282 geniCodeGoto (tree->falseLabel);
3289 if (tree->trueLabel)
3291 ic = newiCodeCondition (condition,
3296 if (tree->falseLabel)
3297 geniCodeGoto (tree->falseLabel);
3301 ic = newiCodeCondition (condition,
3308 ast2iCode (tree->right,lvl+1);
3311 /*-----------------------------------------------------------------*/
3312 /* geniCodeJumpTable - tries to create a jump table for switch */
3313 /*-----------------------------------------------------------------*/
3315 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3317 int min = 0, max = 0, t, cnt = 0;
3323 int needRangeCheck = !optimize.noJTabBoundary
3324 || tree->values.switchVals.swDefault;
3326 if (!tree || !caseVals)
3329 /* the criteria for creating a jump table is */
3330 /* all integer numbers between the maximum & minimum must */
3331 /* be present , the maximum value should not exceed 255 */
3332 min = max = (int) floatFromVal (vch = caseVals);
3333 SNPRINTF (buffer, sizeof(buffer),
3335 tree->values.switchVals.swNum,
3337 addSet (&labels, newiTempLabel (buffer));
3339 /* if there is only one case value then no need */
3340 if (!(vch = vch->next))
3345 if (((t = (int) floatFromVal (vch)) - max) != 1)
3347 SNPRINTF (buffer, sizeof(buffer),
3349 tree->values.switchVals.swNum,
3351 addSet (&labels, newiTempLabel (buffer));
3357 /* if the number of case statements <= 2 then */
3358 /* it is not economical to create the jump table */
3359 /* since two compares are needed for boundary conditions */
3360 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3363 if (tree->values.switchVals.swDefault)
3365 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3369 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3373 falseLabel = newiTempLabel (buffer);
3375 /* so we can create a jumptable */
3376 /* first we rule out the boundary conditions */
3377 /* if only optimization says so */
3380 sym_link *cetype = getSpec (operandType (cond));
3381 /* no need to check the lower bound if
3382 the condition is unsigned & minimum value is zero */
3383 if (!(min == 0 && IS_UNSIGNED (cetype)))
3385 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3386 ic = newiCodeCondition (boundary, falseLabel, NULL);
3390 /* now for upper bounds */
3391 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3392 ic = newiCodeCondition (boundary, falseLabel, NULL);
3396 /* if the min is not zero then we no make it zero */
3399 cond = geniCodeSubtract (cond, operandFromLit (min));
3400 if (!IS_LITERAL(getSpec(operandType(cond))))
3401 setOperandType (cond, UCHARTYPE);
3404 /* now create the jumptable */
3405 ic = newiCode (JUMPTABLE, NULL, NULL);
3406 IC_JTCOND (ic) = cond;
3407 IC_JTLABELS (ic) = labels;
3412 /*-----------------------------------------------------------------*/
3413 /* geniCodeSwitch - changes a switch to a if statement */
3414 /*-----------------------------------------------------------------*/
3416 geniCodeSwitch (ast * tree,int lvl)
3419 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3420 value *caseVals = tree->values.switchVals.swVals;
3421 symbol *trueLabel, *falseLabel;
3423 /* If the condition is a literal, then just jump to the */
3424 /* appropriate case label. */
3425 if (IS_LITERAL(getSpec(operandType(cond))))
3427 int switchVal, caseVal;
3429 switchVal = (int) floatFromVal (cond->operand.valOperand);
3432 caseVal = (int) floatFromVal (caseVals);
3433 if (caseVal == switchVal)
3435 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3436 tree->values.switchVals.swNum, caseVal);
3437 trueLabel = newiTempLabel (buffer);
3438 geniCodeGoto (trueLabel);
3441 caseVals = caseVals->next;
3443 goto defaultOrBreak;
3446 /* if we can make this a jump table */
3447 if (geniCodeJumpTable (cond, caseVals, tree))
3448 goto jumpTable; /* no need for the comparison */
3450 /* for the cases defined do */
3454 operand *compare = geniCodeLogic (cond,
3455 operandFromValue (caseVals),
3458 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3459 tree->values.switchVals.swNum,
3460 (int) floatFromVal (caseVals));
3461 trueLabel = newiTempLabel (buffer);
3463 ic = newiCodeCondition (compare, trueLabel, NULL);
3465 caseVals = caseVals->next;
3470 /* if default is present then goto break else break */
3471 if (tree->values.switchVals.swDefault)
3473 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3477 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3480 falseLabel = newiTempLabel (buffer);
3481 geniCodeGoto (falseLabel);
3484 ast2iCode (tree->right,lvl+1);
3487 /*-----------------------------------------------------------------*/
3488 /* geniCodeInline - intermediate code for inline assembler */
3489 /*-----------------------------------------------------------------*/
3491 geniCodeInline (ast * tree)
3495 ic = newiCode (INLINEASM, NULL, NULL);
3496 IC_INLINE (ic) = tree->values.inlineasm;
3500 /*-----------------------------------------------------------------*/
3501 /* geniCodeArrayInit - intermediate code for array initializer */
3502 /*-----------------------------------------------------------------*/
3504 geniCodeArrayInit (ast * tree, operand *array)
3508 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3509 ic = newiCode (ARRAYINIT, array, NULL);
3510 IC_ARRAYILIST (ic) = tree->values.constlist;
3512 operand *left=newOperand(), *right=newOperand();
3513 left->type=right->type=SYMBOL;
3514 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3515 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3516 ic = newiCode (ARRAYINIT, left, right);
3521 /*-----------------------------------------------------------------*/
3522 /* geniCodeCritical - intermediate code for a critical statement */
3523 /*-----------------------------------------------------------------*/
3525 geniCodeCritical (ast *tree, int lvl)
3530 /* If op is NULL, the original interrupt state will saved on */
3531 /* the stack. Otherwise, it will be saved in op. */
3533 /* Generate a save of the current interrupt state & disabled */
3534 ic = newiCode (CRITICAL, NULL, NULL);
3535 IC_RESULT (ic) = op;
3538 /* Generate the critical code sequence */
3539 if (tree->left && tree->left->type == EX_VALUE)
3540 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3542 ast2iCode (tree->left,lvl+1);
3544 /* Generate a restore of the original interrupt state */
3545 ic = newiCode (ENDCRITICAL, NULL, op);
3549 /*-----------------------------------------------------------------*/
3550 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3551 /* particular case. Ie : assigning or dereferencing array or ptr */
3552 /*-----------------------------------------------------------------*/
3553 set * lvaluereqSet = NULL;
3554 typedef struct lvalItem
3561 /*-----------------------------------------------------------------*/
3562 /* addLvaluereq - add a flag for lvalreq for current ast level */
3563 /*-----------------------------------------------------------------*/
3564 void addLvaluereq(int lvl)
3566 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3569 addSetHead(&lvaluereqSet,lpItem);
3572 /*-----------------------------------------------------------------*/
3573 /* delLvaluereq - del a flag for lvalreq for current ast level */
3574 /*-----------------------------------------------------------------*/
3578 lpItem = getSet(&lvaluereqSet);
3579 if(lpItem) Safe_free(lpItem);
3581 /*-----------------------------------------------------------------*/
3582 /* clearLvaluereq - clear lvalreq flag */
3583 /*-----------------------------------------------------------------*/
3584 void clearLvaluereq()
3587 lpItem = peekSet(lvaluereqSet);
3588 if(lpItem) lpItem->req = 0;
3590 /*-----------------------------------------------------------------*/
3591 /* getLvaluereq - get the last lvalreq level */
3592 /*-----------------------------------------------------------------*/
3593 int getLvaluereqLvl()
3596 lpItem = peekSet(lvaluereqSet);
3597 if(lpItem) return lpItem->lvl;
3600 /*-----------------------------------------------------------------*/
3601 /* isLvaluereq - is lvalreq valid for this level ? */
3602 /*-----------------------------------------------------------------*/
3603 int isLvaluereq(int lvl)
3606 lpItem = peekSet(lvaluereqSet);
3607 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3611 /*-----------------------------------------------------------------*/
3612 /* ast2iCode - creates an icodeList from an ast */
3613 /*-----------------------------------------------------------------*/
3615 ast2iCode (ast * tree,int lvl)
3617 operand *left = NULL;
3618 operand *right = NULL;
3622 /* set the global variables for filename & line number */
3624 filename = tree->filename;
3626 lineno = tree->lineno;
3628 block = tree->block;
3630 scopeLevel = tree->level;
3632 seqPoint = tree->seqPoint;
3634 if (tree->type == EX_VALUE)
3635 return operandFromValue (tree->opval.val);
3637 if (tree->type == EX_LINK)
3638 return operandFromLink (tree->opval.lnk);
3640 /* if we find a nullop */
3641 if (tree->type == EX_OP &&
3642 (tree->opval.op == NULLOP ||
3643 tree->opval.op == BLOCK))
3645 if (tree->left && tree->left->type == EX_VALUE)
3646 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3648 ast2iCode (tree->left,lvl+1);
3649 if (tree->right && tree->right->type == EX_VALUE)
3650 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3652 ast2iCode (tree->right,lvl+1);
3656 /* special cases for not evaluating */
3657 if (tree->opval.op != ':' &&
3658 tree->opval.op != '?' &&
3659 tree->opval.op != CALL &&
3660 tree->opval.op != IFX &&
3661 tree->opval.op != LABEL &&
3662 tree->opval.op != GOTO &&
3663 tree->opval.op != SWITCH &&
3664 tree->opval.op != FUNCTION &&
3665 tree->opval.op != INLINEASM &&
3666 tree->opval.op != CRITICAL)
3669 if (IS_ASSIGN_OP (tree->opval.op) ||
3670 IS_DEREF_OP (tree) ||
3671 (tree->opval.op == '&' && !tree->right) ||
3672 tree->opval.op == PTR_OP)
3675 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3676 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3679 left = operandFromAst (tree->left,lvl);
3681 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3682 left = geniCodeRValue (left, TRUE);
3686 left = operandFromAst (tree->left,lvl);
3688 if (tree->opval.op == INC_OP ||
3689 tree->opval.op == DEC_OP)
3692 right = operandFromAst (tree->right,lvl);
3697 right = operandFromAst (tree->right,lvl);
3701 /* now depending on the type of operand */
3702 /* this will be a biggy */
3703 switch (tree->opval.op)
3706 case '[': /* array operation */
3708 //sym_link *ltype = operandType (left);
3709 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3710 left = geniCodeRValue (left, FALSE);
3711 right = geniCodeRValue (right, TRUE);
3714 return geniCodeArray (left, right,lvl);
3716 case '.': /* structure dereference */
3717 if (IS_PTR (operandType (left)))
3718 left = geniCodeRValue (left, TRUE);
3720 left = geniCodeRValue (left, FALSE);
3722 return geniCodeStruct (left, right, tree->lvalue);
3724 case PTR_OP: /* structure pointer dereference */
3727 pType = operandType (left);
3728 left = geniCodeRValue (left, TRUE);
3730 setOClass (pType, getSpec (operandType (left)));
3733 return geniCodeStruct (left, right, tree->lvalue);
3735 case INC_OP: /* increment operator */
3737 return geniCodePostInc (left);
3739 return geniCodePreInc (right, tree->lvalue);
3741 case DEC_OP: /* decrement operator */
3743 return geniCodePostDec (left);
3745 return geniCodePreDec (right, tree->lvalue);
3747 case '&': /* bitwise and or address of operator */
3749 { /* this is a bitwise operator */
3750 left = geniCodeRValue (left, FALSE);
3751 right = geniCodeRValue (right, FALSE);
3752 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3755 return geniCodeAddressOf (left);
3757 case '|': /* bitwise or & xor */
3759 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3760 geniCodeRValue (right, FALSE),
3765 return geniCodeDivision (geniCodeRValue (left, FALSE),
3766 geniCodeRValue (right, FALSE));
3769 return geniCodeModulus (geniCodeRValue (left, FALSE),
3770 geniCodeRValue (right, FALSE));
3773 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3774 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3776 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3780 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3781 geniCodeRValue (right, FALSE));
3783 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3787 return geniCodeAdd (geniCodeRValue (left, FALSE),
3788 geniCodeRValue (right, FALSE),lvl);
3790 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3793 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3794 geniCodeRValue (right, FALSE));
3797 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3798 geniCodeRValue (right, FALSE));
3800 #if 0 // this indeed needs a second thought
3804 // let's keep this simple: get the rvalue we need
3805 op=geniCodeRValue (right, FALSE);
3806 // now cast it to whatever we want
3807 op=geniCodeCast (operandType(left), op, FALSE);
3808 // if this is going to be used as an lvalue, make it so
3814 #else // bug #604575, is it a bug ????
3815 return geniCodeCast (operandType (left),
3816 geniCodeRValue (right, FALSE), FALSE);
3823 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3828 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3829 setOperandType (op, UCHARTYPE);
3840 /* different compilers (even different gccs) evaluate
3841 the two calls in a different order. to get the same
3842 result on all machines we've to specify a clear sequence.
3843 return geniCodeLogic (geniCodeRValue (left, FALSE),
3844 geniCodeRValue (right, FALSE),
3848 operand *leftOp, *rightOp;
3850 rightOp = geniCodeRValue (right, FALSE);
3851 leftOp = geniCodeRValue (left , FALSE);
3853 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3856 return geniCodeConditional (tree,lvl);
3859 return operandFromLit (getSize (tree->right->ftype));
3863 sym_link *rtype = operandType (right);
3864 sym_link *ltype = operandType (left);
3865 if (IS_PTR (rtype) && IS_ITEMP (right)
3866 && right->isaddr && compareType (rtype->next, ltype) == 1)
3867 right = geniCodeRValue (right, TRUE);
3869 right = geniCodeRValue (right, FALSE);
3871 geniCodeAssign (left, right, 0);
3876 geniCodeAssign (left,
3877 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3879 geniCodeRValue (right, FALSE),FALSE), 0);
3883 geniCodeAssign (left,
3884 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3886 geniCodeRValue (right, FALSE)), 0);
3889 geniCodeAssign (left,
3890 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3892 geniCodeRValue (right, FALSE)), 0);
3895 sym_link *rtype = operandType (right);
3896 sym_link *ltype = operandType (left);
3897 if (IS_PTR (rtype) && IS_ITEMP (right)
3898 && right->isaddr && compareType (rtype->next, ltype) == 1)
3899 right = geniCodeRValue (right, TRUE);
3901 right = geniCodeRValue (right, FALSE);
3904 return geniCodeAssign (left,
3905 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3911 sym_link *rtype = operandType (right);
3912 sym_link *ltype = operandType (left);
3913 if (IS_PTR (rtype) && IS_ITEMP (right)
3914 && right->isaddr && compareType (rtype->next, ltype) == 1)
3916 right = geniCodeRValue (right, TRUE);
3920 right = geniCodeRValue (right, FALSE);
3923 geniCodeAssign (left,
3924 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3930 geniCodeAssign (left,
3931 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3933 geniCodeRValue (right, FALSE)), 0);
3936 geniCodeAssign (left,
3937 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3939 geniCodeRValue (right, FALSE)), 0);
3942 geniCodeAssign (left,
3943 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3945 geniCodeRValue (right, FALSE),
3947 operandType (left)), 0);
3950 geniCodeAssign (left,
3951 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3953 geniCodeRValue (right, FALSE),
3955 operandType (left)), 0);
3958 geniCodeAssign (left,
3959 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3961 geniCodeRValue (right, FALSE),
3963 operandType (left)), 0);
3965 return geniCodeRValue (right, FALSE);
3968 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3971 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3972 return ast2iCode (tree->right,lvl+1);
3975 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3976 return ast2iCode (tree->right,lvl+1);
3979 geniCodeFunctionBody (tree,lvl);
3983 geniCodeReturn (right);
3987 geniCodeIfx (tree,lvl);
3991 geniCodeSwitch (tree,lvl);
3995 geniCodeInline (tree);
3999 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4003 geniCodeCritical (tree, lvl);
4009 /*-----------------------------------------------------------------*/
4010 /* reverseICChain - gets from the list and creates a linkedlist */
4011 /*-----------------------------------------------------------------*/
4018 while ((loop = getSet (&iCodeChain)))
4030 /*-----------------------------------------------------------------*/
4031 /* iCodeFromAst - given an ast will convert it to iCode */
4032 /*-----------------------------------------------------------------*/
4034 iCodeFromAst (ast * tree)
4036 returnLabel = newiTempLabel ("_return");
4037 entryLabel = newiTempLabel ("_entry");
4039 return reverseiCChain ();
4042 static const char *opTypeToStr(OPTYPE op)
4046 case SYMBOL: return "symbol";
4047 case VALUE: return "value";
4048 case TYPE: return "type";
4050 return "undefined type";
4054 operand *validateOpType(operand *op,
4061 if (op && op->type == type)
4066 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4067 " expected %s, got %s\n",
4068 macro, args, file, line,
4069 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4071 return op; // never reached, makes compiler happy.