1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
43 symbol *returnLabel; /* function return label */
44 symbol *entryLabel; /* function entry label */
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeDivision (operand *, operand *);
49 operand *geniCodeAssign (operand *, operand *, int);
50 operand *geniCodeArray (operand *, operand *,int);
51 operand *geniCodeArray2Ptr (operand *);
52 operand *geniCodeRValue (operand *, bool);
53 operand *geniCodeDerefPtr (operand *,int);
54 int isLvaluereq(int lvl);
55 void setOClass (sym_link * ptr, sym_link * spec);
56 static operand *geniCodeCast (sym_link *, operand *, bool);
58 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
59 /* forward definition of ic print functions */
60 PRINTFUNC (picGetValueAtAddr);
61 PRINTFUNC (picSetValueAtAddr);
62 PRINTFUNC (picAddrOf);
63 PRINTFUNC (picGeneric);
64 PRINTFUNC (picGenericOne);
66 PRINTFUNC (picAssign);
70 PRINTFUNC (picJumpTable);
71 PRINTFUNC (picInline);
72 PRINTFUNC (picReceive);
73 PRINTFUNC (picDummyRead);
74 PRINTFUNC (picCritical);
75 PRINTFUNC (picEndCritical);
77 iCodeTable codeTable[] =
79 {'!', "not", picGenericOne, NULL},
80 {'~', "~", picGenericOne, NULL},
81 {RRC, "rrc", picGenericOne, NULL},
82 {RLC, "rlc", picGenericOne, NULL},
83 {GETHBIT, "ghbit", picGenericOne, NULL},
84 {UNARYMINUS, "-", picGenericOne, NULL},
85 {IPUSH, "push", picGenericOne, NULL},
86 {IPOP, "pop", picGenericOne, NULL},
87 {CALL, "call", picGenericOne, NULL},
88 {PCALL, "pcall", picGenericOne, NULL},
89 {FUNCTION, "proc", picGenericOne, NULL},
90 {ENDFUNCTION, "eproc", picGenericOne, NULL},
91 {RETURN, "ret", picGenericOne, NULL},
92 {'+', "+", picGeneric, NULL},
93 {'-', "-", picGeneric, NULL},
94 {'*', "*", picGeneric, NULL},
95 {'/', "/", picGeneric, NULL},
96 {'%', "%", picGeneric, NULL},
97 {'>', ">", picGeneric, NULL},
98 {'<', "<", picGeneric, NULL},
99 {LE_OP, "<=", picGeneric, NULL},
100 {GE_OP, ">=", picGeneric, NULL},
101 {EQ_OP, "==", picGeneric, NULL},
102 {NE_OP, "!=", picGeneric, NULL},
103 {AND_OP, "&&", picGeneric, NULL},
104 {OR_OP, "||", picGeneric, NULL},
105 {'^', "^", picGeneric, NULL},
106 {'|', "|", picGeneric, NULL},
107 {BITWISEAND, "&", picGeneric, NULL},
108 {LEFT_OP, "<<", picGeneric, NULL},
109 {RIGHT_OP, ">>", picGeneric, NULL},
110 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
111 {ADDRESS_OF, "&", picAddrOf, NULL},
112 {CAST, "<>", picCast, NULL},
113 {'=', ":=", picAssign, NULL},
114 {LABEL, "", picLabel, NULL},
115 {GOTO, "", picGoto, NULL},
116 {JUMPTABLE, "jtab", picJumpTable, NULL},
117 {IFX, "if", picIfx, NULL},
118 {INLINEASM, "", picInline, NULL},
119 {RECEIVE, "recv", picReceive, NULL},
120 {SEND, "send", picGenericOne, NULL},
121 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
122 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
123 {CRITICAL, "critical_start", picCritical, NULL},
124 {ENDCRITICAL, "critical_end", picEndCritical, NULL}
127 /*-----------------------------------------------------------------*/
128 /* checkConstantRange: check a constant against the type */
129 /*-----------------------------------------------------------------*/
132 /* pedantic=0: allmost anything is allowed as long as the absolute
133 value is within the bit range of the type, and -1 is treated as
134 0xf..f for unsigned types (e.g. in assign)
135 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
136 pedantic>1: "char c=200" is not allowed (evaluates to -56)
139 void checkConstantRange(sym_link *ltype, value *val, char *msg,
146 max = pow ((double)2.0, (double)bitsForType(ltype));
148 if (IS_LONG(val->type)) {
149 if (IS_UNSIGNED(val->type)) {
150 v=SPEC_CVAL(val->type).v_ulong;
152 v=SPEC_CVAL(val->type).v_long;
155 if (IS_UNSIGNED(val->type)) {
156 v=SPEC_CVAL(val->type).v_uint;
158 v=SPEC_CVAL(val->type).v_int;
164 // this could be a good idea
165 if (options.pedantic)
169 if (IS_FLOAT(ltype)) {
174 if (!IS_UNSIGNED(val->type) && v<0) {
176 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
182 // if very pedantic: "char c=200" is not allowed
183 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
184 max = max/2 + negative;
191 #if 0 // temporary disabled, leaving the warning as a reminder
193 SNPRINTF (message, sizeof(message), "for %s %s in %s",
194 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
195 nounName(ltype), msg);
196 werror (W_CONST_RANGE, message);
204 /*-----------------------------------------------------------------*/
205 /* operandName - returns the name of the operand */
206 /*-----------------------------------------------------------------*/
208 printOperand (operand * op, FILE * file)
225 opetype = getSpec (operandType (op));
226 if (IS_FLOAT (opetype))
227 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
229 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
230 printTypeChain (operandType (op), file);
237 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
238 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
240 OP_LIVEFROM (op), OP_LIVETO (op),
241 OP_SYMBOL (op)->stack,
242 op->isaddr, OP_SYMBOL (op)->isreqv,
243 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
244 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
248 printTypeChain (operandType (op), file);
249 if (SPIL_LOC (op) && IS_ITEMP (op))
250 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
255 /* if assigned to registers */
256 if (OP_SYMBOL (op)->nRegs)
258 if (OP_SYMBOL (op)->isspilt)
260 if (!OP_SYMBOL (op)->remat)
261 if (OP_SYMBOL (op)->usl.spillLoc)
262 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
263 OP_SYMBOL (op)->usl.spillLoc->rname :
264 OP_SYMBOL (op)->usl.spillLoc->name));
266 fprintf (file, "[err]");
268 fprintf (file, "[remat]");
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
280 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
281 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
282 /* if assigned to registers */
283 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
287 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
288 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
289 OP_SYMBOL (op)->regs[i]->name :
298 printTypeChain (op->operand.typeOperand, file);
304 fprintf (file, "\n");
309 /*-----------------------------------------------------------------*/
310 /* print functions */
311 /*-----------------------------------------------------------------*/
312 PRINTFUNC (picGetValueAtAddr)
315 printOperand (IC_RESULT (ic), of);
318 printOperand (IC_LEFT (ic), of);
324 PRINTFUNC (picSetValueAtAddr)
328 printOperand (IC_LEFT (ic), of);
329 fprintf (of, "] = ");
330 printOperand (IC_RIGHT (ic), of);
334 PRINTFUNC (picAddrOf)
337 printOperand (IC_RESULT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
341 fprintf (of, " = &[");
342 printOperand (IC_LEFT (ic), of);
345 if (IS_ITEMP (IC_LEFT (ic)))
346 fprintf (of, " offsetAdd ");
349 printOperand (IC_RIGHT (ic), of);
351 if (IS_ITEMP (IC_LEFT (ic)))
357 PRINTFUNC (picJumpTable)
362 fprintf (of, "%s\t", s);
363 printOperand (IC_JTCOND (ic), of);
365 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
366 sym = setNextItem (IC_JTLABELS (ic)))
367 fprintf (of, "\t\t\t%s\n", sym->name);
370 PRINTFUNC (picGeneric)
373 printOperand (IC_RESULT (ic), of);
375 printOperand (IC_LEFT (ic), of);
376 fprintf (of, " %s ", s);
377 printOperand (IC_RIGHT (ic), of);
381 PRINTFUNC (picGenericOne)
386 printOperand (IC_RESULT (ic), of);
392 fprintf (of, "%s ", s);
393 printOperand (IC_LEFT (ic), of);
396 if (!IC_RESULT (ic) && !IC_LEFT (ic))
399 if (ic->op == SEND || ic->op == RECEIVE) {
400 fprintf(of,"{argreg = %d}",ic->argreg);
408 printOperand (IC_RESULT (ic), of);
410 printOperand (IC_LEFT (ic), of);
411 printOperand (IC_RIGHT (ic), of);
416 PRINTFUNC (picAssign)
420 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
423 printOperand (IC_RESULT (ic), of);
425 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
428 fprintf (of, " %s ", s);
429 printOperand (IC_RIGHT (ic), of);
436 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
442 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
449 printOperand (IC_COND (ic), of);
452 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
455 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
457 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
461 PRINTFUNC (picInline)
463 fprintf (of, "%s", IC_INLINE (ic));
466 PRINTFUNC (picReceive)
468 printOperand (IC_RESULT (ic), of);
469 fprintf (of, " = %s ", s);
470 printOperand (IC_LEFT (ic), of);
474 PRINTFUNC (picDummyRead)
477 fprintf (of, "%s ", s);
478 printOperand (IC_RIGHT (ic), of);
482 PRINTFUNC (picCritical)
486 printOperand (IC_RESULT (ic), of);
488 fprintf (of, "(stack)");
489 fprintf (of, " = %s ", s);
493 PRINTFUNC (picEndCritical)
496 fprintf (of, "%s = ", s);
498 printOperand (IC_RIGHT (ic), of);
500 fprintf (of, "(stack)");
504 /*-----------------------------------------------------------------*/
505 /* piCode - prints one iCode */
506 /*-----------------------------------------------------------------*/
508 piCode (void *item, FILE * of)
516 icTab = getTableEntry (ic->op);
517 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
518 ic->filename, ic->lineno,
519 ic->seq, ic->key, ic->depth, ic->supportRtn);
520 icTab->iCodePrint (of, ic, icTab->printName);
526 printiCChain(ic,stdout);
528 /*-----------------------------------------------------------------*/
529 /* printiCChain - prints intermediate code for humans */
530 /*-----------------------------------------------------------------*/
532 printiCChain (iCode * icChain, FILE * of)
539 for (loop = icChain; loop; loop = loop->next)
541 if ((icTab = getTableEntry (loop->op)))
543 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
544 loop->filename, loop->lineno,
545 loop->seq, loop->key, loop->depth, loop->supportRtn);
547 icTab->iCodePrint (of, loop, icTab->printName);
553 /*-----------------------------------------------------------------*/
554 /* newOperand - allocate, init & return a new iCode */
555 /*-----------------------------------------------------------------*/
561 op = Safe_alloc ( sizeof (operand));
567 /*-----------------------------------------------------------------*/
568 /* newiCode - create and return a new iCode entry initialised */
569 /*-----------------------------------------------------------------*/
571 newiCode (int op, operand * left, operand * right)
575 ic = Safe_alloc ( sizeof (iCode));
577 ic->seqPoint = seqPoint;
579 ic->filename = filename;
581 ic->level = scopeLevel;
583 ic->key = iCodeKey++;
585 IC_RIGHT (ic) = right;
590 /*-----------------------------------------------------------------*/
591 /* newiCode for conditional statements */
592 /*-----------------------------------------------------------------*/
594 newiCodeCondition (operand * condition,
600 if (IS_VOID(operandType(condition))) {
601 werror(E_VOID_VALUE_USED);
604 ic = newiCode (IFX, NULL, NULL);
605 IC_COND (ic) = condition;
606 IC_TRUE (ic) = trueLabel;
607 IC_FALSE (ic) = falseLabel;
611 /*-----------------------------------------------------------------*/
612 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
613 /*-----------------------------------------------------------------*/
615 newiCodeLabelGoto (int op, symbol * label)
619 ic = newiCode (op, NULL, NULL);
623 IC_RIGHT (ic) = NULL;
624 IC_RESULT (ic) = NULL;
628 /*-----------------------------------------------------------------*/
629 /* newiTemp - allocate & return a newItemp Variable */
630 /*-----------------------------------------------------------------*/
638 SNPRINTF (buffer, sizeof(buffer), "%s", s);
642 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
645 itmp = newSymbol (buffer, 1);
646 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
652 /*-----------------------------------------------------------------*/
653 /* newiTempLabel - creates a temp variable label */
654 /*-----------------------------------------------------------------*/
656 newiTempLabel (char *s)
660 /* check if this alredy exists */
661 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
666 itmplbl = newSymbol (s, 1);
670 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
671 itmplbl = newSymbol (buffer, 1);
676 itmplbl->key = labelKey++;
677 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
681 /*-----------------------------------------------------------------*/
682 /* newiTempPreheaderLabel - creates a new preheader label */
683 /*-----------------------------------------------------------------*/
685 newiTempPreheaderLabel ()
689 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
690 itmplbl = newSymbol (buffer, 1);
694 itmplbl->key = labelKey++;
695 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
700 /*-----------------------------------------------------------------*/
701 /* initiCode - initialises some iCode related stuff */
702 /*-----------------------------------------------------------------*/
709 /*-----------------------------------------------------------------*/
710 /* copyiCode - make a copy of the iCode given */
711 /*-----------------------------------------------------------------*/
713 copyiCode (iCode * ic)
715 iCode *nic = newiCode (ic->op, NULL, NULL);
717 nic->lineno = ic->lineno;
718 nic->filename = ic->filename;
719 nic->block = ic->block;
720 nic->level = ic->level;
721 nic->parmBytes = ic->parmBytes;
723 /* deal with the special cases first */
727 IC_COND (nic) = operandFromOperand (IC_COND (ic));
728 IC_TRUE (nic) = IC_TRUE (ic);
729 IC_FALSE (nic) = IC_FALSE (ic);
733 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
734 IC_JTLABELS (nic) = IC_JTLABELS (ic);
739 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
740 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
744 IC_INLINE (nic) = IC_INLINE (ic);
748 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
752 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
753 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
754 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
760 /*-----------------------------------------------------------------*/
761 /* getTableEntry - gets the table entry for the given operator */
762 /*-----------------------------------------------------------------*/
764 getTableEntry (int oper)
768 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
769 if (oper == codeTable[i].icode)
770 return &codeTable[i];
775 /*-----------------------------------------------------------------*/
776 /* newiTempOperand - new intermediate temp operand */
777 /*-----------------------------------------------------------------*/
779 newiTempOperand (sym_link * type, char throwType)
782 operand *op = newOperand ();
786 itmp = newiTemp (NULL);
788 etype = getSpec (type);
790 if (IS_LITERAL (etype))
793 /* copy the type information */
795 itmp->etype = getSpec (itmp->type = (throwType ? type :
796 copyLinkChain (type)));
797 if (IS_LITERAL (itmp->etype))
799 SPEC_SCLS (itmp->etype) = S_REGISTER;
800 SPEC_OCLS (itmp->etype) = reg;
803 op->operand.symOperand = itmp;
804 op->key = itmp->key = ++operandKey;
808 /*-----------------------------------------------------------------*/
809 /* operandType - returns the type chain for an operand */
810 /*-----------------------------------------------------------------*/
812 operandType (operand * op)
814 /* depending on type of operand */
819 return op->operand.valOperand->type;
822 return op->operand.symOperand->type;
825 return op->operand.typeOperand;
827 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
828 " operand type not known ");
829 assert (0); /* should never come here */
830 /* Just to keep the compiler happy */
831 return (sym_link *) 0;
835 /*-----------------------------------------------------------------*/
836 /* isParamterToCall - will return 1 if op is a parameter to args */
837 /*-----------------------------------------------------------------*/
839 isParameterToCall (value * args, operand * op)
843 wassert (IS_SYMOP(op));
848 isSymbolEqual (op->operand.symOperand, tval->sym))
855 /*-----------------------------------------------------------------*/
856 /* isOperandGlobal - return 1 if operand is a global variable */
857 /*-----------------------------------------------------------------*/
859 isOperandGlobal (operand * op)
868 (op->operand.symOperand->level == 0 ||
869 IS_STATIC (op->operand.symOperand->etype) ||
870 IS_EXTERN (op->operand.symOperand->etype))
877 /*-----------------------------------------------------------------*/
878 /* isOperandVolatile - return 1 if the operand is volatile */
879 /*-----------------------------------------------------------------*/
881 isOperandVolatile (operand * op, bool chkTemp)
886 if (IS_ITEMP (op) && !chkTemp)
889 opetype = getSpec (optype = operandType (op));
891 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
894 if (IS_VOLATILE (opetype))
899 /*-----------------------------------------------------------------*/
900 /* isOperandLiteral - returns 1 if an operand contains a literal */
901 /*-----------------------------------------------------------------*/
903 isOperandLiteral (operand * op)
910 opetype = getSpec (operandType (op));
912 if (IS_LITERAL (opetype))
918 /*-----------------------------------------------------------------*/
919 /* isOperandInFarSpace - will return true if operand is in farSpace */
920 /*-----------------------------------------------------------------*/
922 isOperandInFarSpace (operand * op)
932 if (!IS_TRUE_SYMOP (op))
935 etype = SPIL_LOC (op)->etype;
941 etype = getSpec (operandType (op));
943 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
946 /*------------------------------------------------------------------*/
947 /* isOperandInDirSpace - will return true if operand is in dirSpace */
948 /*------------------------------------------------------------------*/
950 isOperandInDirSpace (operand * op)
960 if (!IS_TRUE_SYMOP (op))
963 etype = SPIL_LOC (op)->etype;
969 etype = getSpec (operandType (op));
971 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
974 /*--------------------------------------------------------------------*/
975 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
976 /*--------------------------------------------------------------------*/
978 isOperandInCodeSpace (operand * op)
988 etype = getSpec (operandType (op));
990 if (!IS_TRUE_SYMOP (op))
993 etype = SPIL_LOC (op)->etype;
999 etype = getSpec (operandType (op));
1001 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1004 /*-----------------------------------------------------------------*/
1005 /* isOperandOnStack - will return true if operand is on stack */
1006 /*-----------------------------------------------------------------*/
1008 isOperandOnStack (operand * op)
1018 etype = getSpec (operandType (op));
1019 if (IN_STACK (etype) ||
1020 OP_SYMBOL(op)->onStack ||
1021 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1027 /*-----------------------------------------------------------------*/
1028 /* isOclsExpensive - will return true if accesses to an output */
1029 /* storage class are expensive */
1030 /*-----------------------------------------------------------------*/
1032 isOclsExpensive (struct memmap *oclass)
1034 if (port->oclsExpense)
1035 return port->oclsExpense (oclass) > 0;
1037 /* In the absence of port specific guidance, assume only */
1038 /* farspace is expensive. */
1039 return IN_FARSPACE (oclass);
1042 /*-----------------------------------------------------------------*/
1043 /* operandLitValue - literal value of an operand */
1044 /*-----------------------------------------------------------------*/
1046 operandLitValue (operand * op)
1048 assert (isOperandLiteral (op));
1050 return floatFromVal (op->operand.valOperand);
1053 /*-----------------------------------------------------------------*/
1054 /* getBuiltInParms - returns parameters to a builtin functions */
1055 /*-----------------------------------------------------------------*/
1056 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1061 /* builtin functions uses only SEND for parameters */
1062 while (ic->op != CALL) {
1063 assert(ic->op == SEND && ic->builtinSEND);
1064 ic->generated = 1; /* mark the icode as generated */
1065 parms[*pcount] = IC_LEFT(ic);
1071 /* make sure this is a builtin function call */
1072 assert(IS_SYMOP(IC_LEFT(ic)));
1073 ftype = operandType(IC_LEFT(ic));
1074 assert(IFFUNC_ISBUILTIN(ftype));
1078 /*-----------------------------------------------------------------*/
1079 /* operandOperation - performs operations on operands */
1080 /*-----------------------------------------------------------------*/
1082 operandOperation (operand * left, operand * right,
1083 int op, sym_link * type)
1085 sym_link *let , *ret=NULL;
1086 operand *retval = (operand *) 0;
1088 assert (isOperandLiteral (left));
1089 let = getSpec(operandType(left));
1091 assert (isOperandLiteral (right));
1092 ret = getSpec(operandType(right));
1098 retval = operandFromValue (valCastLiteral (type,
1099 operandLitValue (left) +
1100 operandLitValue (right)));
1103 retval = operandFromValue (valCastLiteral (type,
1104 operandLitValue (left) -
1105 operandLitValue (right)));
1109 retval = operandFromValue (valCastLiteral (type,
1110 operandLitValue (left) *
1111 operandLitValue (right)));
1112 This could be all we've to do, but with gcc we've to take care about
1113 overflows. Two examples:
1114 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1115 significant bits are lost (52 in fraction, 63 bits would be
1116 necessary to keep full precision).
1117 If the resulting double value is greater than ULONG_MAX (resp.
1118 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1121 /* if it is not a specifier then we can assume that */
1122 /* it will be an unsigned long */
1123 if (IS_INT (type) ||
1126 /* long is handled here, because it can overflow with double */
1127 if (IS_LONG (type) ||
1129 /* signed and unsigned mul are the same, as long as the precision
1130 of the result isn't bigger than the precision of the operands. */
1131 retval = operandFromValue (valCastLiteral (type,
1132 (TYPE_UDWORD) operandLitValue (left) *
1133 (TYPE_UDWORD) operandLitValue (right)));
1134 else if (IS_UNSIGNED (type)) /* unsigned int */
1136 /* unsigned int is handled here in order to detect overflow */
1137 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1138 (TYPE_UWORD) operandLitValue (right);
1140 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1141 if (ul != (TYPE_UWORD) ul)
1144 else /* signed int */
1146 /* signed int is handled here in order to detect overflow */
1147 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1148 (TYPE_WORD) operandLitValue (right);
1150 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1151 if (l != (TYPE_WORD) l)
1156 /* all others go here: */
1157 retval = operandFromValue (valCastLiteral (type,
1158 operandLitValue (left) *
1159 operandLitValue (right)));
1162 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1164 werror (E_DIVIDE_BY_ZERO);
1170 if (IS_UNSIGNED (type))
1172 SPEC_USIGN (let) = 1;
1173 SPEC_USIGN (ret) = 1;
1174 retval = operandFromValue (valCastLiteral (type,
1175 (TYPE_UDWORD) operandLitValue (left) /
1176 (TYPE_UDWORD) operandLitValue (right)));
1180 retval = operandFromValue (valCastLiteral (type,
1181 operandLitValue (left) /
1182 operandLitValue (right)));
1187 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1189 werror (E_DIVIDE_BY_ZERO);
1194 if (IS_UNSIGNED (type))
1195 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1196 (TYPE_UDWORD) operandLitValue (right));
1198 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1199 (TYPE_DWORD) operandLitValue (right));
1203 /* The number of left shifts is always unsigned. Signed doesn't make
1204 sense here. Shifting by a negative number is impossible. */
1205 retval = operandFromValue (valCastLiteral (type,
1206 ((TYPE_UDWORD) operandLitValue (left) <<
1207 (TYPE_UDWORD) operandLitValue (right))));
1210 /* The number of right shifts is always unsigned. Signed doesn't make
1211 sense here. Shifting by a negative number is impossible. */
1212 if (IS_UNSIGNED(let))
1213 /* unsigned: logic shift right */
1214 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1215 (TYPE_UDWORD) operandLitValue (right));
1217 /* signed: arithmetic shift right */
1218 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1219 (TYPE_UDWORD) operandLitValue (right));
1222 /* this op doesn't care about signedness */
1226 l = (TYPE_UDWORD) operandLitValue (left);
1227 if (IS_CHAR(OP_VALUE(left)->type))
1229 else if (!IS_LONG (OP_VALUE(left)->type))
1231 r = (TYPE_UDWORD) operandLitValue (right);
1232 if (IS_CHAR(OP_VALUE(right)->type))
1234 else if (!IS_LONG (OP_VALUE(right)->type))
1236 retval = operandFromLit (l == r);
1240 retval = operandFromLit (operandLitValue (left) <
1241 operandLitValue (right));
1244 retval = operandFromLit (operandLitValue (left) <=
1245 operandLitValue (right));
1248 retval = operandFromLit (operandLitValue (left) !=
1249 operandLitValue (right));
1252 retval = operandFromLit (operandLitValue (left) >
1253 operandLitValue (right));
1256 retval = operandFromLit (operandLitValue (left) >=
1257 operandLitValue (right));
1260 retval = operandFromValue (valCastLiteral (type,
1261 (TYPE_UDWORD)operandLitValue(left) &
1262 (TYPE_UDWORD)operandLitValue(right)));
1265 retval = operandFromValue (valCastLiteral (type,
1266 (TYPE_UDWORD)operandLitValue(left) |
1267 (TYPE_UDWORD)operandLitValue(right)));
1270 retval = operandFromValue (valCastLiteral (type,
1271 (TYPE_UDWORD)operandLitValue(left) ^
1272 (TYPE_UDWORD)operandLitValue(right)));
1275 retval = operandFromLit (operandLitValue (left) &&
1276 operandLitValue (right));
1279 retval = operandFromLit (operandLitValue (left) ||
1280 operandLitValue (right));
1284 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1286 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1292 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1294 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1300 retval = operandFromValue (valCastLiteral (type,
1301 -1 * operandLitValue (left)));
1305 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1309 retval = operandFromLit (!operandLitValue (left));
1313 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1314 " operandOperation invalid operator ");
1322 /*-----------------------------------------------------------------*/
1323 /* isOperandEqual - compares two operand & return 1 if they r = */
1324 /*-----------------------------------------------------------------*/
1326 isOperandEqual (operand * left, operand * right)
1328 /* if the pointers are equal then they are equal */
1332 /* if either of them null then false */
1333 if (!left || !right)
1336 if (left->type != right->type)
1339 if (IS_SYMOP (left) && IS_SYMOP (right))
1340 return left->key == right->key;
1342 /* if types are the same */
1346 return isSymbolEqual (left->operand.symOperand,
1347 right->operand.symOperand);
1349 return (floatFromVal (left->operand.valOperand) ==
1350 floatFromVal (right->operand.valOperand));
1352 if (compareType (left->operand.typeOperand,
1353 right->operand.typeOperand) == 1)
1360 /*-------------------------------------------------------------------*/
1361 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1362 /*-------------------------------------------------------------------*/
1364 isiCodeEqual (iCode * left, iCode * right)
1366 /* if the same pointer */
1370 /* if either of them null */
1371 if (!left || !right)
1374 /* if operand are the same */
1375 if (left->op == right->op)
1378 /* compare all the elements depending on type */
1379 if (left->op != IFX)
1381 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1383 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1389 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1391 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1393 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1402 /*-----------------------------------------------------------------*/
1403 /* newiTempFromOp - create a temp Operand with same attributes */
1404 /*-----------------------------------------------------------------*/
1406 newiTempFromOp (operand * op)
1416 nop = newiTempOperand (operandType (op), TRUE);
1417 nop->isaddr = op->isaddr;
1418 nop->isvolatile = op->isvolatile;
1419 nop->isGlobal = op->isGlobal;
1420 nop->isLiteral = op->isLiteral;
1421 nop->usesDefs = op->usesDefs;
1422 nop->isParm = op->isParm;
1426 /*-----------------------------------------------------------------*/
1427 /* operand from operand - creates an operand holder for the type */
1428 /*-----------------------------------------------------------------*/
1430 operandFromOperand (operand * op)
1436 nop = newOperand ();
1437 nop->type = op->type;
1438 nop->isaddr = op->isaddr;
1440 nop->isvolatile = op->isvolatile;
1441 nop->isGlobal = op->isGlobal;
1442 nop->isLiteral = op->isLiteral;
1443 nop->usesDefs = op->usesDefs;
1444 nop->isParm = op->isParm;
1449 nop->operand.symOperand = op->operand.symOperand;
1452 nop->operand.valOperand = op->operand.valOperand;
1455 nop->operand.typeOperand = op->operand.typeOperand;
1462 /*-----------------------------------------------------------------*/
1463 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1464 /*-----------------------------------------------------------------*/
1466 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1468 operand *nop = operandFromOperand (op);
1470 if (nop->type == SYMBOL)
1472 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1473 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1479 /*-----------------------------------------------------------------*/
1480 /* operandFromSymbol - creates an operand from a symbol */
1481 /*-----------------------------------------------------------------*/
1483 operandFromSymbol (symbol * sym)
1488 /* if the symbol's type is a literal */
1489 /* then it is an enumerator type */
1490 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1491 return operandFromValue (valFromType (sym->etype));
1494 sym->key = ++operandKey;
1496 /* if this an implicit variable, means struct/union */
1497 /* member so just return it */
1498 if (sym->implicit || IS_FUNC (sym->type))
1502 op->operand.symOperand = sym;
1504 op->isvolatile = isOperandVolatile (op, TRUE);
1505 op->isGlobal = isOperandGlobal (op);
1509 /* under the following conditions create a
1510 register equivalent for a local symbol */
1511 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1512 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1514 (!(options.model == MODEL_FLAT24)) ) &&
1515 options.stackAuto == 0)
1518 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1519 !IS_FUNC (sym->type) && /* not a function */
1520 !sym->_isparm && /* not a parameter */
1521 sym->level && /* is a local variable */
1522 !sym->addrtaken && /* whose address has not been taken */
1523 !sym->reqv && /* does not already have a reg equivalence */
1524 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1525 !IS_STATIC (sym->etype) && /* and not declared static */
1526 !sym->islbl && /* not a label */
1527 ok && /* farspace check */
1528 !IS_BITVAR (sym->etype) /* not a bit variable */
1532 /* we will use it after all optimizations
1533 and before liveRange calculation */
1534 sym->reqv = newiTempOperand (sym->type, 0);
1535 sym->reqv->key = sym->key;
1536 OP_SYMBOL (sym->reqv)->key = sym->key;
1537 OP_SYMBOL (sym->reqv)->isreqv = 1;
1538 OP_SYMBOL (sym->reqv)->islocal = 1;
1539 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1540 SPIL_LOC (sym->reqv) = sym;
1543 if (!IS_AGGREGATE (sym->type))
1547 op->operand.symOperand = sym;
1550 op->isvolatile = isOperandVolatile (op, TRUE);
1551 op->isGlobal = isOperandGlobal (op);
1552 op->isPtr = IS_PTR (operandType (op));
1553 op->isParm = sym->_isparm;
1558 /* itemp = &[_symbol] */
1560 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1561 IC_LEFT (ic)->type = SYMBOL;
1562 IC_LEFT (ic)->operand.symOperand = sym;
1563 IC_LEFT (ic)->key = sym->key;
1564 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1565 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1566 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1569 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1570 if (IS_ARRAY (sym->type))
1572 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1573 IC_RESULT (ic)->isaddr = 0;
1576 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1580 return IC_RESULT (ic);
1583 /*-----------------------------------------------------------------*/
1584 /* operandFromValue - creates an operand from value */
1585 /*-----------------------------------------------------------------*/
1587 operandFromValue (value * val)
1591 /* if this is a symbol then do the symbol thing */
1593 return operandFromSymbol (val->sym);
1595 /* this is not a symbol */
1598 op->operand.valOperand = val;
1599 op->isLiteral = isOperandLiteral (op);
1603 /*-----------------------------------------------------------------*/
1604 /* operandFromLink - operand from typeChain */
1605 /*-----------------------------------------------------------------*/
1607 operandFromLink (sym_link * type)
1611 /* operand from sym_link */
1617 op->operand.typeOperand = copyLinkChain (type);
1621 /*-----------------------------------------------------------------*/
1622 /* operandFromLit - makes an operand from a literal value */
1623 /*-----------------------------------------------------------------*/
1625 operandFromLit (double i)
1627 return operandFromValue (valueFromLit (i));
1630 /*-----------------------------------------------------------------*/
1631 /* operandFromAst - creates an operand from an ast */
1632 /*-----------------------------------------------------------------*/
1634 operandFromAst (ast * tree,int lvl)
1640 /* depending on type do */
1644 return ast2iCode (tree,lvl+1);
1648 return operandFromValue (tree->opval.val);
1652 return operandFromLink (tree->opval.lnk);
1659 /* Just to keep the compiler happy */
1660 return (operand *) 0;
1663 /*-----------------------------------------------------------------*/
1664 /* setOperandType - sets the operand's type to the given type */
1665 /*-----------------------------------------------------------------*/
1667 setOperandType (operand * op, sym_link * type)
1669 /* depending on the type of operand */
1674 op->operand.valOperand->etype =
1675 getSpec (op->operand.valOperand->type =
1676 copyLinkChain (type));
1680 if (op->operand.symOperand->isitmp)
1681 op->operand.symOperand->etype =
1682 getSpec (op->operand.symOperand->type =
1683 copyLinkChain (type));
1685 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1686 "attempt to modify type of source");
1690 op->operand.typeOperand = copyLinkChain (type);
1695 /*-----------------------------------------------------------------*/
1696 /* Get size in byte of ptr need to access an array */
1697 /*-----------------------------------------------------------------*/
1699 getArraySizePtr (operand * op)
1701 sym_link *ltype = operandType(op);
1705 int size = getSize(ltype);
1706 return(IS_GENPTR(ltype)?(size-1):size);
1711 sym_link *letype = getSpec(ltype);
1712 switch (PTR_TYPE (SPEC_OCLS (letype)))
1724 return (GPTRSIZE-1);
1733 /*-----------------------------------------------------------------*/
1734 /* perform "usual unary conversions" */
1735 /*-----------------------------------------------------------------*/
1737 usualUnaryConversions (operand * op)
1739 if (IS_INTEGRAL (operandType (op)))
1741 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1744 return geniCodeCast (INTTYPE, op, TRUE);
1750 /*-----------------------------------------------------------------*/
1751 /* perform "usual binary conversions" */
1752 /*-----------------------------------------------------------------*/
1754 usualBinaryConversions (operand ** op1, operand ** op2,
1755 bool promoteCharToInt, bool isMul)
1758 sym_link *rtype = operandType (*op2);
1759 sym_link *ltype = operandType (*op1);
1761 ctype = computeType (ltype, rtype, promoteCharToInt);
1763 /* special for multiplication:
1764 This if for 'mul a,b', which takes two chars and returns an int */
1766 /* && promoteCharToInt superfluous, already handled by computeType() */
1767 && IS_CHAR (getSpec (ltype))
1768 && IS_CHAR (getSpec (rtype))
1769 && !(IS_UNSIGNED (getSpec (rtype)) ^ IS_UNSIGNED (getSpec (ltype)))
1770 && IS_INT (getSpec (ctype)))
1773 *op1 = geniCodeCast (ctype, *op1, TRUE);
1774 *op2 = geniCodeCast (ctype, *op2, TRUE);
1779 /*-----------------------------------------------------------------*/
1780 /* geniCodeValueAtAddress - generate intermeditate code for value */
1782 /*-----------------------------------------------------------------*/
1784 geniCodeRValue (operand * op, bool force)
1787 sym_link *type = operandType (op);
1788 sym_link *etype = getSpec (type);
1790 /* if this is an array & already */
1791 /* an address then return this */
1792 if (IS_AGGREGATE (type) ||
1793 (IS_PTR (type) && !force && !op->isaddr))
1794 return operandFromOperand (op);
1796 /* if this is not an address then must be */
1797 /* rvalue already so return this one */
1801 /* if this is not a temp symbol then */
1802 if (!IS_ITEMP (op) &&
1804 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1806 op = operandFromOperand (op);
1811 if (IS_SPEC (type) &&
1812 IS_TRUE_SYMOP (op) &&
1813 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1814 (options.model == MODEL_FLAT24) ))
1816 op = operandFromOperand (op);
1821 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1822 if (IS_PTR (type) && op->isaddr && force)
1825 type = copyLinkChain (type);
1827 IC_RESULT (ic) = newiTempOperand (type, 1);
1828 IC_RESULT (ic)->isaddr = 0;
1830 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1834 return IC_RESULT (ic);
1837 /*-----------------------------------------------------------------*/
1838 /* geniCodeCast - changes the value from one type to another */
1839 /*-----------------------------------------------------------------*/
1841 geniCodeCast (sym_link * type, operand * op, bool implicit)
1845 sym_link *opetype = getSpec (optype = operandType (op));
1849 /* one of them has size zero then error */
1850 if (IS_VOID (optype))
1852 werror (E_CAST_ZERO);
1856 /* if the operand is already the desired type then do nothing */
1857 if (compareType (type, optype) == 1)
1860 /* if this is a literal then just change the type & return */
1861 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1863 return operandFromValue (valCastLiteral (type,
1864 operandLitValue (op)));
1867 /* if casting to/from pointers, do some checking */
1868 if (IS_PTR(type)) { // to a pointer
1869 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1870 if (IS_INTEGRAL(optype)) {
1871 // maybe this is NULL, than it's ok.
1872 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1873 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1874 // no way to set the storage
1875 if (IS_LITERAL(optype)) {
1876 werror(E_LITERAL_GENERIC);
1879 werror(E_NONPTR2_GENPTR);
1882 } else if (implicit) {
1883 werror(W_INTEGRAL2PTR_NOCAST);
1888 // shouldn't do that with float, array or structure unless to void
1889 if (!IS_VOID(getSpec(type)) &&
1890 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1891 werror(E_INCOMPAT_TYPES);
1895 } else { // from a pointer to a pointer
1896 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1897 // if not a pointer to a function
1898 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1899 if (implicit) { // if not to generic, they have to match
1900 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1901 werror(E_INCOMPAT_PTYPES);
1908 } else { // to a non pointer
1909 if (IS_PTR(optype)) { // from a pointer
1910 if (implicit) { // sneaky
1911 if (IS_INTEGRAL(type)) {
1912 werror(W_PTR2INTEGRAL_NOCAST);
1914 } else { // shouldn't do that with float, array or structure
1915 werror(E_INCOMPAT_TYPES);
1922 printFromToType (optype, type);
1925 /* if they are the same size create an assignment */
1926 if (getSize (type) == getSize (optype) &&
1927 !IS_BITFIELD (type) &&
1929 !IS_FLOAT (optype) &&
1930 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1931 (!IS_SPEC (type) && !IS_SPEC (optype))))
1933 ic = newiCode ('=', NULL, op);
1934 IC_RESULT (ic) = newiTempOperand (type, 0);
1935 SPIL_LOC (IC_RESULT (ic)) =
1936 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1937 IC_RESULT (ic)->isaddr = 0;
1941 ic = newiCode (CAST, operandFromLink (type),
1942 geniCodeRValue (op, FALSE));
1944 IC_RESULT (ic) = newiTempOperand (type, 0);
1947 /* preserve the storage class & output class */
1948 /* of the original variable */
1949 restype = getSpec (operandType (IC_RESULT (ic)));
1950 if (!IS_LITERAL(opetype))
1951 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1952 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1955 return IC_RESULT (ic);
1958 /*-----------------------------------------------------------------*/
1959 /* geniCodeLabel - will create a Label */
1960 /*-----------------------------------------------------------------*/
1962 geniCodeLabel (symbol * label)
1966 ic = newiCodeLabelGoto (LABEL, label);
1970 /*-----------------------------------------------------------------*/
1971 /* geniCodeGoto - will create a Goto */
1972 /*-----------------------------------------------------------------*/
1974 geniCodeGoto (symbol * label)
1978 ic = newiCodeLabelGoto (GOTO, label);
1982 /*-----------------------------------------------------------------*/
1983 /* geniCodeMultiply - gen intermediate code for multiplication */
1984 /*-----------------------------------------------------------------*/
1986 geniCodeMultiply (operand * left, operand * right, int resultIsInt)
1993 /* if they are both literal then we know the result */
1994 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1995 return operandFromValue (valMult (left->operand.valOperand,
1996 right->operand.valOperand));
1998 if (IS_LITERAL(retype)) {
1999 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2002 resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE);
2004 rtype = operandType (right);
2005 retype = getSpec (rtype);
2006 ltype = operandType (left);
2007 letype = getSpec (ltype);
2010 /* if the right is a literal & power of 2 */
2011 /* then make it a left shift */
2012 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2013 efficient in most cases than 2 bytes result = 2 bytes << literal
2014 if port has 1 byte muldiv */
2015 if (p2 && !IS_FLOAT (letype) &&
2016 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
2017 (port->support.muldiv == 1)))
2019 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2021 /* LEFT_OP need same size for left and result, */
2022 left = geniCodeCast (resType, left, TRUE);
2023 ltype = operandType (left);
2025 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2029 ic = newiCode ('*', left, right); /* normal multiplication */
2030 /* if the size left or right > 1 then support routine */
2031 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2035 IC_RESULT (ic) = newiTempOperand (resType, 1);
2038 return IC_RESULT (ic);
2041 /*-----------------------------------------------------------------*/
2042 /* geniCodeDivision - gen intermediate code for division */
2043 /*-----------------------------------------------------------------*/
2045 geniCodeDivision (operand * left, operand * right)
2050 sym_link *rtype = operandType (right);
2051 sym_link *retype = getSpec (rtype);
2052 sym_link *ltype = operandType (left);
2053 sym_link *letype = getSpec (ltype);
2055 resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
2057 /* if the right is a literal & power of 2
2058 and left is unsigned then make it a
2060 if (IS_LITERAL (retype) &&
2061 !IS_FLOAT (letype) &&
2062 IS_UNSIGNED(letype) &&
2063 (p2 = powof2 ((TYPE_UDWORD)
2064 floatFromVal (right->operand.valOperand)))) {
2065 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2069 ic = newiCode ('/', left, right); /* normal division */
2070 /* if the size left or right > 1 then support routine */
2071 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2074 IC_RESULT (ic) = newiTempOperand (resType, 0);
2077 return IC_RESULT (ic);
2079 /*-----------------------------------------------------------------*/
2080 /* geniCodeModulus - gen intermediate code for modulus */
2081 /*-----------------------------------------------------------------*/
2083 geniCodeModulus (operand * left, operand * right)
2089 /* if they are both literal then we know the result */
2090 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2091 return operandFromValue (valMod (left->operand.valOperand,
2092 right->operand.valOperand));
2094 resType = usualBinaryConversions (&left, &right, TRUE, FALSE);
2096 /* now they are the same size */
2097 ic = newiCode ('%', left, right);
2099 /* if the size left or right > 1 then support routine */
2100 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2102 IC_RESULT (ic) = newiTempOperand (resType, 0);
2105 return IC_RESULT (ic);
2108 /*-----------------------------------------------------------------*/
2109 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2110 /*-----------------------------------------------------------------*/
2112 geniCodePtrPtrSubtract (operand * left, operand * right)
2118 /* if they are both literals then */
2119 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2121 result = operandFromValue (valMinus (left->operand.valOperand,
2122 right->operand.valOperand));
2126 ic = newiCode ('-', left, right);
2128 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2132 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2136 // should we really do this? is this ANSI?
2137 return geniCodeDivision (result,
2138 operandFromLit (getSize (ltype->next)));
2141 /*-----------------------------------------------------------------*/
2142 /* geniCodeSubtract - generates code for subtraction */
2143 /*-----------------------------------------------------------------*/
2145 geniCodeSubtract (operand * left, operand * right)
2152 /* if they both pointers then */
2153 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2154 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2155 return geniCodePtrPtrSubtract (left, right);
2157 /* if they are both literal then we know the result */
2158 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2159 && left->isLiteral && right->isLiteral)
2160 return operandFromValue (valMinus (left->operand.valOperand,
2161 right->operand.valOperand));
2163 /* if left is an array or pointer */
2164 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2166 isarray = left->isaddr;
2167 right = geniCodeMultiply (right,
2168 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2169 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2172 { /* make them the same size */
2173 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2176 ic = newiCode ('-', left, right);
2178 IC_RESULT (ic) = newiTempOperand (resType, 1);
2179 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2181 /* if left or right is a float */
2182 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2186 return IC_RESULT (ic);
2189 /*-----------------------------------------------------------------*/
2190 /* geniCodeAdd - generates iCode for addition */
2191 /*-----------------------------------------------------------------*/
2193 geniCodeAdd (operand * left, operand * right, int lvl)
2202 /* if the right side is LITERAL zero */
2203 /* return the left side */
2204 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2207 /* if left is literal zero return right */
2208 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2211 /* if left is a pointer then size */
2212 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2214 isarray = left->isaddr;
2215 // there is no need to multiply with 1
2216 if (getSize (ltype->next) != 1)
2218 size = operandFromLit (getSize (ltype->next));
2219 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2220 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2221 /* Even if right is a 'unsigned char',
2222 the result will be a 'signed int' due to the promotion rules.
2223 It doesn't make sense when accessing arrays, so let's fix it here: */
2225 SPEC_USIGN (getSpec (operandType (right))) = 1;
2227 resType = copyLinkChain (ltype);
2230 { // make them the same size
2231 resType = usualBinaryConversions (&left, &right, FALSE, FALSE);
2234 /* if they are both literals then we know */
2235 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2236 && left->isLiteral && right->isLiteral)
2237 return operandFromValue (valPlus (valFromType (ltype),
2238 valFromType (rtype)));
2240 ic = newiCode ('+', left, right);
2242 IC_RESULT (ic) = newiTempOperand (resType, 1);
2243 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2245 /* if left or right is a float then support
2247 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2252 return IC_RESULT (ic);
2256 /*-----------------------------------------------------------------*/
2257 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2258 /*-----------------------------------------------------------------*/
2260 aggrToPtr (sym_link * type, bool force)
2265 if (IS_PTR (type) && !force)
2268 etype = getSpec (type);
2269 ptype = newLink (DECLARATOR);
2273 /* set the pointer depending on the storage class */
2274 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2278 /*-----------------------------------------------------------------*/
2279 /* geniCodeArray2Ptr - array to pointer */
2280 /*-----------------------------------------------------------------*/
2282 geniCodeArray2Ptr (operand * op)
2284 sym_link *optype = operandType (op);
2285 sym_link *opetype = getSpec (optype);
2287 /* set the pointer depending on the storage class */
2288 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2295 /*-----------------------------------------------------------------*/
2296 /* geniCodeArray - array access */
2297 /*-----------------------------------------------------------------*/
2299 geniCodeArray (operand * left, operand * right,int lvl)
2302 sym_link *ltype = operandType (left);
2307 if (IS_PTR (ltype->next) && left->isaddr)
2309 left = geniCodeRValue (left, FALSE);
2312 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2314 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2315 right = geniCodeMultiply (right,
2316 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2317 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2318 It doesn't make sense when accessing arrays, so let's fix it here: */
2320 SPEC_USIGN (getSpec (operandType (right))) = 1;
2321 /* we can check for limits here */
2322 if (isOperandLiteral (right) &&
2325 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2327 werror (E_ARRAY_BOUND);
2328 right = operandFromLit (0);
2331 ic = newiCode ('+', left, right);
2333 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2334 !IS_AGGREGATE (ltype->next) &&
2335 !IS_PTR (ltype->next))
2336 ? ltype : ltype->next), 0);
2338 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2341 return IC_RESULT (ic);
2344 /*-----------------------------------------------------------------*/
2345 /* geniCodeStruct - generates intermediate code for structures */
2346 /*-----------------------------------------------------------------*/
2348 geniCodeStruct (operand * left, operand * right, bool islval)
2351 sym_link *type = operandType (left);
2352 sym_link *etype = getSpec (type);
2354 symbol *element = getStructElement (SPEC_STRUCT (etype),
2355 right->operand.symOperand);
2357 wassert(IS_SYMOP(right));
2359 /* add the offset */
2360 ic = newiCode ('+', left, operandFromLit (element->offset));
2362 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2364 /* preserve the storage & output class of the struct */
2365 /* as well as the volatile attribute */
2366 retype = getSpec (operandType (IC_RESULT (ic)));
2367 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2368 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2369 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2370 SPEC_CONST (retype) |= SPEC_CONST (etype);
2372 if (IS_PTR (element->type))
2373 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2375 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2378 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2381 /*-----------------------------------------------------------------*/
2382 /* geniCodePostInc - generate int code for Post increment */
2383 /*-----------------------------------------------------------------*/
2385 geniCodePostInc (operand * op)
2389 sym_link *optype = operandType (op);
2391 operand *rv = (IS_ITEMP (op) ?
2392 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2394 sym_link *rvtype = operandType (rv);
2397 /* if this is not an address we have trouble */
2400 werror (E_LVALUE_REQUIRED, "++");
2404 rOp = newiTempOperand (rvtype, 0);
2405 OP_SYMBOL(rOp)->noSpilLoc = 1;
2408 OP_SYMBOL(rv)->noSpilLoc = 1;
2410 geniCodeAssign (rOp, rv, 0);
2412 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2413 if (IS_FLOAT (rvtype))
2414 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2416 ic = newiCode ('+', rv, operandFromLit (size));
2418 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2421 geniCodeAssign (op, result, 0);
2427 /*-----------------------------------------------------------------*/
2428 /* geniCodePreInc - generate code for preIncrement */
2429 /*-----------------------------------------------------------------*/
2431 geniCodePreInc (operand * op, bool lvalue)
2434 sym_link *optype = operandType (op);
2435 operand *rop = (IS_ITEMP (op) ?
2436 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2438 sym_link *roptype = operandType (rop);
2444 werror (E_LVALUE_REQUIRED, "++");
2449 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2450 if (IS_FLOAT (roptype))
2451 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2453 ic = newiCode ('+', rop, operandFromLit (size));
2454 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2457 (void) geniCodeAssign (op, result, 0);
2458 if (lvalue || IS_TRUE_SYMOP (op))
2464 /*-----------------------------------------------------------------*/
2465 /* geniCodePostDec - generates code for Post decrement */
2466 /*-----------------------------------------------------------------*/
2468 geniCodePostDec (operand * op)
2472 sym_link *optype = operandType (op);
2474 operand *rv = (IS_ITEMP (op) ?
2475 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2477 sym_link *rvtype = operandType (rv);
2480 /* if this is not an address we have trouble */
2483 werror (E_LVALUE_REQUIRED, "--");
2487 rOp = newiTempOperand (rvtype, 0);
2488 OP_SYMBOL(rOp)->noSpilLoc = 1;
2491 OP_SYMBOL(rv)->noSpilLoc = 1;
2493 geniCodeAssign (rOp, rv, 0);
2495 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2496 if (IS_FLOAT (rvtype))
2497 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2499 ic = newiCode ('-', rv, operandFromLit (size));
2501 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2504 geniCodeAssign (op, result, 0);
2510 /*-----------------------------------------------------------------*/
2511 /* geniCodePreDec - generate code for pre decrement */
2512 /*-----------------------------------------------------------------*/
2514 geniCodePreDec (operand * op, bool lvalue)
2517 sym_link *optype = operandType (op);
2518 operand *rop = (IS_ITEMP (op) ?
2519 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2521 sym_link *roptype = operandType (rop);
2527 werror (E_LVALUE_REQUIRED, "--");
2532 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2533 if (IS_FLOAT (roptype))
2534 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2536 ic = newiCode ('-', rop, operandFromLit (size));
2537 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2540 (void) geniCodeAssign (op, result, 0);
2541 if (lvalue || IS_TRUE_SYMOP (op))
2548 /*-----------------------------------------------------------------*/
2549 /* geniCodeBitwise - gen int code for bitWise operators */
2550 /*-----------------------------------------------------------------*/
2552 geniCodeBitwise (operand * left, operand * right,
2553 int oper, sym_link * resType)
2557 left = geniCodeCast (resType, left, TRUE);
2558 right = geniCodeCast (resType, right, TRUE);
2560 ic = newiCode (oper, left, right);
2561 IC_RESULT (ic) = newiTempOperand (resType, 0);
2564 return IC_RESULT (ic);
2567 /*-----------------------------------------------------------------*/
2568 /* geniCodeAddressOf - gens icode for '&' address of operator */
2569 /*-----------------------------------------------------------------*/
2571 geniCodeAddressOf (operand * op)
2575 sym_link *optype = operandType (op);
2576 sym_link *opetype = getSpec (optype);
2578 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2580 op = operandFromOperand (op);
2585 /* lvalue check already done in decorateType */
2586 /* this must be a lvalue */
2587 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2588 /* werror (E_LVALUE_REQUIRED,"&"); */
2592 p = newLink (DECLARATOR);
2594 /* set the pointer depending on the storage class */
2595 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2597 p->next = copyLinkChain (optype);
2599 /* if already a temp */
2602 setOperandType (op, p);
2607 /* other wise make this of the type coming in */
2608 ic = newiCode (ADDRESS_OF, op, NULL);
2609 IC_RESULT (ic) = newiTempOperand (p, 1);
2610 IC_RESULT (ic)->isaddr = 0;
2612 return IC_RESULT (ic);
2614 /*-----------------------------------------------------------------*/
2615 /* setOClass - sets the output class depending on the pointer type */
2616 /*-----------------------------------------------------------------*/
2618 setOClass (sym_link * ptr, sym_link * spec)
2620 switch (DCL_TYPE (ptr))
2623 SPEC_OCLS (spec) = data;
2627 SPEC_OCLS (spec) = generic;
2631 SPEC_OCLS (spec) = xdata;
2635 SPEC_OCLS (spec) = code;
2639 SPEC_OCLS (spec) = idata;
2643 SPEC_OCLS (spec) = xstack;
2647 SPEC_OCLS (spec) = eeprom;
2656 /*-----------------------------------------------------------------*/
2657 /* geniCodeDerefPtr - dereference pointer with '*' */
2658 /*-----------------------------------------------------------------*/
2660 geniCodeDerefPtr (operand * op,int lvl)
2662 sym_link *rtype, *retype;
2663 sym_link *optype = operandType (op);
2665 // if this is an array then array access
2666 if (IS_ARRAY (optype)) {
2667 // don't worry, this will be optimized out later
2668 return geniCodeArray (op, operandFromLit (0), lvl);
2671 // just in case someone screws up
2672 wassert (IS_PTR (optype));
2674 if (IS_TRUE_SYMOP (op))
2677 op = geniCodeRValue (op, TRUE);
2680 /* now get rid of the pointer part */
2681 if (isLvaluereq(lvl) && IS_ITEMP (op))
2683 retype = getSpec (rtype = copyLinkChain (optype));
2687 retype = getSpec (rtype = copyLinkChain (optype->next));
2688 /* outputclass needs 2b updated */
2689 setOClass (optype, retype);
2692 op->isGptr = IS_GENPTR (optype);
2694 op->isaddr = (IS_PTR (rtype) ||
2695 IS_STRUCT (rtype) ||
2700 if (!isLvaluereq(lvl))
2701 op = geniCodeRValue (op, TRUE);
2703 setOperandType (op, rtype);
2708 /*-----------------------------------------------------------------*/
2709 /* geniCodeUnaryMinus - does a unary minus of the operand */
2710 /*-----------------------------------------------------------------*/
2712 geniCodeUnaryMinus (operand * op)
2715 sym_link *optype = operandType (op);
2717 if (IS_LITERAL (optype))
2718 return operandFromLit (-floatFromVal (op->operand.valOperand));
2720 ic = newiCode (UNARYMINUS, op, NULL);
2721 IC_RESULT (ic) = newiTempOperand (optype, 0);
2723 return IC_RESULT (ic);
2726 /*-----------------------------------------------------------------*/
2727 /* geniCodeLeftShift - gen i code for left shift */
2728 /*-----------------------------------------------------------------*/
2730 geniCodeLeftShift (operand * left, operand * right)
2734 left = usualUnaryConversions (left);
2735 ic = newiCode (LEFT_OP, left, right);
2736 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2738 return IC_RESULT (ic);
2741 /*-----------------------------------------------------------------*/
2742 /* geniCodeRightShift - gen i code for right shift */
2743 /*-----------------------------------------------------------------*/
2745 geniCodeRightShift (operand * left, operand * right)
2749 ic = newiCode (RIGHT_OP, left, right);
2750 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2752 return IC_RESULT (ic);
2755 /*-----------------------------------------------------------------*/
2756 /* geniCodeLogic- logic code */
2757 /*-----------------------------------------------------------------*/
2759 geniCodeLogic (operand * left, operand * right, int op)
2763 sym_link *rtype = operandType (right);
2764 sym_link *ltype = operandType (left);
2766 /* left is integral type and right is literal then
2767 check if the literal value is within bounds */
2768 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2770 checkConstantRange(ltype,
2771 OP_VALUE(right), "compare operation", 1);
2774 /* if one operand is a pointer and the other is a literal generic void pointer,
2775 change the type of the literal generic void pointer to match the other pointer */
2776 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2777 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2779 /* find left's definition */
2780 ic = (iCode *) setFirstItem (iCodeChain);
2783 if (((ic->op == CAST) || (ic->op == '='))
2784 && isOperandEqual(left, IC_RESULT (ic)))
2787 ic = setNextItem (iCodeChain);
2789 /* if casting literal to generic pointer, then cast to rtype instead */
2790 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2792 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2793 ltype = operandType(left);
2796 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2797 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2799 /* find right's definition */
2800 ic = (iCode *) setFirstItem (iCodeChain);
2803 if (((ic->op == CAST) || (ic->op == '='))
2804 && isOperandEqual(right, IC_RESULT (ic)))
2807 ic = setNextItem (iCodeChain);
2809 /* if casting literal to generic pointer, then cast to rtype instead */
2810 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2812 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2813 rtype = operandType(right);
2817 ctype = usualBinaryConversions (&left, &right, FALSE, FALSE);
2819 ic = newiCode (op, left, right);
2820 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2822 /* if comparing float
2823 and not a '==' || '!=' || '&&' || '||' (these
2825 if (IS_FLOAT(ctype) &&
2833 return IC_RESULT (ic);
2836 /*-----------------------------------------------------------------*/
2837 /* geniCodeUnary - for a a generic unary operation */
2838 /*-----------------------------------------------------------------*/
2840 geniCodeUnary (operand * op, int oper)
2842 iCode *ic = newiCode (oper, op, NULL);
2844 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2846 return IC_RESULT (ic);
2849 /*-----------------------------------------------------------------*/
2850 /* geniCodeConditional - geniCode for '?' ':' operation */
2851 /*-----------------------------------------------------------------*/
2853 geniCodeConditional (ast * tree,int lvl)
2856 symbol *falseLabel = newiTempLabel (NULL);
2857 symbol *exitLabel = newiTempLabel (NULL);
2858 operand *cond = ast2iCode (tree->left,lvl+1);
2859 operand *true, *false, *result;
2861 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2865 true = ast2iCode (tree->right->left,lvl+1);
2867 /* move the value to a new Operand */
2868 result = newiTempOperand (tree->right->ftype, 0);
2869 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2871 /* generate an unconditional goto */
2872 geniCodeGoto (exitLabel);
2874 /* now for the right side */
2875 geniCodeLabel (falseLabel);
2877 false = ast2iCode (tree->right->right,lvl+1);
2878 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2880 /* create the exit label */
2881 geniCodeLabel (exitLabel);
2886 /*-----------------------------------------------------------------*/
2887 /* geniCodeAssign - generate code for assignment */
2888 /*-----------------------------------------------------------------*/
2890 geniCodeAssign (operand * left, operand * right, int nosupdate)
2893 sym_link *ltype = operandType (left);
2894 sym_link *rtype = operandType (right);
2896 if (!left->isaddr && !IS_ITEMP (left))
2898 werror (E_LVALUE_REQUIRED, "assignment");
2902 /* left is integral type and right is literal then
2903 check if the literal value is within bounds */
2904 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2906 checkConstantRange(ltype,
2907 OP_VALUE(right), "= operation", 0);
2910 /* if the left & right type don't exactly match */
2911 /* if pointer set then make sure the check is
2912 done with the type & not the pointer */
2913 /* then cast rights type to left */
2915 /* first check the type for pointer assignement */
2916 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2917 compareType (ltype, rtype) <= 0)
2919 if (compareType (ltype->next, rtype) < 0)
2920 right = geniCodeCast (ltype->next, right, TRUE);
2922 else if (compareType (ltype, rtype) < 0)
2923 right = geniCodeCast (ltype, right, TRUE);
2925 /* If left is a true symbol & ! volatile
2926 create an assignment to temporary for
2927 the right & then assign this temporary
2928 to the symbol. This is SSA (static single
2929 assignment). Isn't it simple and folks have
2930 published mountains of paper on it */
2931 if (IS_TRUE_SYMOP (left) &&
2932 !isOperandVolatile (left, FALSE) &&
2933 isOperandGlobal (left))
2937 if (IS_TRUE_SYMOP (right))
2938 sym = OP_SYMBOL (right);
2939 ic = newiCode ('=', NULL, right);
2940 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2941 SPIL_LOC (right) = sym;
2945 ic = newiCode ('=', NULL, right);
2946 IC_RESULT (ic) = left;
2949 /* if left isgptr flag is set then support
2950 routine will be required */
2954 ic->nosupdate = nosupdate;
2958 /*-----------------------------------------------------------------*/
2959 /* geniCodeDummyRead - generate code for dummy read */
2960 /*-----------------------------------------------------------------*/
2962 geniCodeDummyRead (operand * op)
2965 sym_link *type = operandType (op);
2967 if (!IS_VOLATILE(type))
2970 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
2976 /*-----------------------------------------------------------------*/
2977 /* geniCodeSEParms - generate code for side effecting fcalls */
2978 /*-----------------------------------------------------------------*/
2980 geniCodeSEParms (ast * parms,int lvl)
2985 if (parms->type == EX_OP && parms->opval.op == PARAM)
2987 geniCodeSEParms (parms->left,lvl);
2988 geniCodeSEParms (parms->right,lvl);
2992 /* hack don't like this but too lazy to think of
2994 if (IS_ADDRESS_OF_OP (parms))
2995 parms->left->lvalue = 1;
2997 if (IS_CAST_OP (parms) &&
2998 IS_PTR (parms->ftype) &&
2999 IS_ADDRESS_OF_OP (parms->right))
3000 parms->right->left->lvalue = 1;
3002 parms->opval.oprnd =
3003 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3005 parms->type = EX_OPERAND;
3006 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3007 SPEC_ARGREG(parms->ftype);
3010 /*-----------------------------------------------------------------*/
3011 /* geniCodeParms - generates parameters */
3012 /*-----------------------------------------------------------------*/
3014 geniCodeParms (ast * parms, value *argVals, int *stack,
3015 sym_link * fetype, symbol * func,int lvl)
3023 if (argVals==NULL) {
3025 argVals=FUNC_ARGS(func->type);
3028 /* if this is a param node then do the left & right */
3029 if (parms->type == EX_OP && parms->opval.op == PARAM)
3031 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
3032 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
3036 /* get the parameter value */
3037 if (parms->type == EX_OPERAND)
3038 pval = parms->opval.oprnd;
3041 /* maybe this else should go away ?? */
3042 /* hack don't like this but too lazy to think of
3044 if (IS_ADDRESS_OF_OP (parms))
3045 parms->left->lvalue = 1;
3047 if (IS_CAST_OP (parms) &&
3048 IS_PTR (parms->ftype) &&
3049 IS_ADDRESS_OF_OP (parms->right))
3050 parms->right->left->lvalue = 1;
3052 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3055 /* if register parm then make it a send */
3056 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
3057 IFFUNC_ISBUILTIN(func->type))
3059 ic = newiCode (SEND, pval, NULL);
3060 ic->argreg = SPEC_ARGREG(parms->etype);
3061 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
3066 /* now decide whether to push or assign */
3067 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
3071 operand *top = operandFromSymbol (argVals->sym);
3072 /* clear useDef and other bitVectors */
3073 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3074 geniCodeAssign (top, pval, 1);
3078 sym_link *p = operandType (pval);
3080 ic = newiCode (IPUSH, pval, NULL);
3082 /* update the stack adjustment */
3083 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3088 argVals=argVals->next;
3092 /*-----------------------------------------------------------------*/
3093 /* geniCodeCall - generates temp code for calling */
3094 /*-----------------------------------------------------------------*/
3096 geniCodeCall (operand * left, ast * parms,int lvl)
3100 sym_link *type, *etype;
3103 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3104 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3105 werror (E_FUNCTION_EXPECTED);
3106 return operandFromValue(valueFromLit(0));
3109 /* take care of parameters with side-effecting
3110 function calls in them, this is required to take care
3111 of overlaying function parameters */
3112 geniCodeSEParms (parms,lvl);
3114 /* first the parameters */
3115 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3117 /* now call : if symbol then pcall */
3118 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3119 ic = newiCode (PCALL, left, NULL);
3121 ic = newiCode (CALL, left, NULL);
3124 type = copyLinkChain (operandType (left)->next);
3125 etype = getSpec (type);
3126 SPEC_EXTR (etype) = 0;
3127 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3131 /* stack adjustment after call */
3132 ic->parmBytes = stack;
3137 /*-----------------------------------------------------------------*/
3138 /* geniCodeReceive - generate intermediate code for "receive" */
3139 /*-----------------------------------------------------------------*/
3141 geniCodeReceive (value * args)
3143 /* for all arguments that are passed in registers */
3147 if (IS_REGPARM (args->etype))
3149 operand *opr = operandFromValue (args);
3151 symbol *sym = OP_SYMBOL (opr);
3154 /* we will use it after all optimizations
3155 and before liveRange calculation */
3156 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3159 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3160 options.stackAuto == 0 &&
3161 (!(options.model == MODEL_FLAT24)) )
3166 opl = newiTempOperand (args->type, 0);
3168 sym->reqv->key = sym->key;
3169 OP_SYMBOL (sym->reqv)->key = sym->key;
3170 OP_SYMBOL (sym->reqv)->isreqv = 1;
3171 OP_SYMBOL (sym->reqv)->islocal = 0;
3172 SPIL_LOC (sym->reqv) = sym;
3176 ic = newiCode (RECEIVE, NULL, NULL);
3177 ic->argreg = SPEC_ARGREG(args->etype);
3179 currFunc->recvSize = getSize (sym->type);
3182 IC_RESULT (ic) = opr;
3190 /*-----------------------------------------------------------------*/
3191 /* geniCodeFunctionBody - create the function body */
3192 /*-----------------------------------------------------------------*/
3194 geniCodeFunctionBody (ast * tree,int lvl)
3201 /* reset the auto generation */
3207 func = ast2iCode (tree->left,lvl+1);
3208 fetype = getSpec (operandType (func));
3210 savelineno = lineno;
3211 lineno = OP_SYMBOL (func)->lineDef;
3212 /* create an entry label */
3213 geniCodeLabel (entryLabel);
3214 lineno = savelineno;
3216 /* create a proc icode */
3217 ic = newiCode (FUNCTION, func, NULL);
3218 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3222 /* for all parameters that are passed
3223 on registers add a "receive" */
3224 geniCodeReceive (tree->values.args);
3226 /* generate code for the body */
3227 ast2iCode (tree->right,lvl+1);
3229 /* create a label for return */
3230 geniCodeLabel (returnLabel);
3232 /* now generate the end proc */
3233 ic = newiCode (ENDFUNCTION, func, NULL);
3238 /*-----------------------------------------------------------------*/
3239 /* geniCodeReturn - gen icode for 'return' statement */
3240 /*-----------------------------------------------------------------*/
3242 geniCodeReturn (operand * op)
3246 /* if the operand is present force an rvalue */
3248 op = geniCodeRValue (op, FALSE);
3250 ic = newiCode (RETURN, op, NULL);
3254 /*-----------------------------------------------------------------*/
3255 /* geniCodeIfx - generates code for extended if statement */
3256 /*-----------------------------------------------------------------*/
3258 geniCodeIfx (ast * tree,int lvl)
3261 operand *condition = ast2iCode (tree->left,lvl+1);
3264 /* if condition is null then exit */
3268 condition = geniCodeRValue (condition, FALSE);
3270 cetype = getSpec (operandType (condition));
3271 /* if the condition is a literal */
3272 if (IS_LITERAL (cetype))
3274 if (floatFromVal (condition->operand.valOperand))
3276 if (tree->trueLabel)
3277 geniCodeGoto (tree->trueLabel);
3283 if (tree->falseLabel)
3284 geniCodeGoto (tree->falseLabel);
3291 if (tree->trueLabel)
3293 ic = newiCodeCondition (condition,
3298 if (tree->falseLabel)
3299 geniCodeGoto (tree->falseLabel);
3303 ic = newiCodeCondition (condition,
3310 ast2iCode (tree->right,lvl+1);
3313 /*-----------------------------------------------------------------*/
3314 /* geniCodeJumpTable - tries to create a jump table for switch */
3315 /*-----------------------------------------------------------------*/
3317 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3319 int min = 0, max = 0, t, cnt = 0;
3325 int needRangeCheck = !optimize.noJTabBoundary
3326 || tree->values.switchVals.swDefault;
3328 if (!tree || !caseVals)
3331 /* the criteria for creating a jump table is */
3332 /* all integer numbers between the maximum & minimum must */
3333 /* be present , the maximum value should not exceed 255 */
3334 min = max = (int) floatFromVal (vch = caseVals);
3335 SNPRINTF (buffer, sizeof(buffer),
3337 tree->values.switchVals.swNum,
3339 addSet (&labels, newiTempLabel (buffer));
3341 /* if there is only one case value then no need */
3342 if (!(vch = vch->next))
3347 if (((t = (int) floatFromVal (vch)) - max) != 1)
3349 SNPRINTF (buffer, sizeof(buffer),
3351 tree->values.switchVals.swNum,
3353 addSet (&labels, newiTempLabel (buffer));
3359 /* if the number of case statements <= 2 then */
3360 /* it is not economical to create the jump table */
3361 /* since two compares are needed for boundary conditions */
3362 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3365 if (tree->values.switchVals.swDefault)
3367 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3371 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3375 falseLabel = newiTempLabel (buffer);
3377 /* so we can create a jumptable */
3378 /* first we rule out the boundary conditions */
3379 /* if only optimization says so */
3382 sym_link *cetype = getSpec (operandType (cond));
3383 /* no need to check the lower bound if
3384 the condition is unsigned & minimum value is zero */
3385 if (!(min == 0 && IS_UNSIGNED (cetype)))
3387 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3388 ic = newiCodeCondition (boundary, falseLabel, NULL);
3392 /* now for upper bounds */
3393 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3394 ic = newiCodeCondition (boundary, falseLabel, NULL);
3398 /* if the min is not zero then we no make it zero */
3401 cond = geniCodeSubtract (cond, operandFromLit (min));
3402 if (!IS_LITERAL(getSpec(operandType(cond))))
3403 setOperandType (cond, UCHARTYPE);
3406 /* now create the jumptable */
3407 ic = newiCode (JUMPTABLE, NULL, NULL);
3408 IC_JTCOND (ic) = cond;
3409 IC_JTLABELS (ic) = labels;
3414 /*-----------------------------------------------------------------*/
3415 /* geniCodeSwitch - changes a switch to a if statement */
3416 /*-----------------------------------------------------------------*/
3418 geniCodeSwitch (ast * tree,int lvl)
3421 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3422 value *caseVals = tree->values.switchVals.swVals;
3423 symbol *trueLabel, *falseLabel;
3425 /* If the condition is a literal, then just jump to the */
3426 /* appropriate case label. */
3427 if (IS_LITERAL(getSpec(operandType(cond))))
3429 int switchVal, caseVal;
3431 switchVal = (int) floatFromVal (cond->operand.valOperand);
3434 caseVal = (int) floatFromVal (caseVals);
3435 if (caseVal == switchVal)
3437 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3438 tree->values.switchVals.swNum, caseVal);
3439 trueLabel = newiTempLabel (buffer);
3440 geniCodeGoto (trueLabel);
3443 caseVals = caseVals->next;
3445 goto defaultOrBreak;
3448 /* if we can make this a jump table */
3449 if (geniCodeJumpTable (cond, caseVals, tree))
3450 goto jumpTable; /* no need for the comparison */
3452 /* for the cases defined do */
3456 operand *compare = geniCodeLogic (cond,
3457 operandFromValue (caseVals),
3460 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3461 tree->values.switchVals.swNum,
3462 (int) floatFromVal (caseVals));
3463 trueLabel = newiTempLabel (buffer);
3465 ic = newiCodeCondition (compare, trueLabel, NULL);
3467 caseVals = caseVals->next;
3472 /* if default is present then goto break else break */
3473 if (tree->values.switchVals.swDefault)
3475 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3479 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3482 falseLabel = newiTempLabel (buffer);
3483 geniCodeGoto (falseLabel);
3486 ast2iCode (tree->right,lvl+1);
3489 /*-----------------------------------------------------------------*/
3490 /* geniCodeInline - intermediate code for inline assembler */
3491 /*-----------------------------------------------------------------*/
3493 geniCodeInline (ast * tree)
3497 ic = newiCode (INLINEASM, NULL, NULL);
3498 IC_INLINE (ic) = tree->values.inlineasm;
3502 /*-----------------------------------------------------------------*/
3503 /* geniCodeArrayInit - intermediate code for array initializer */
3504 /*-----------------------------------------------------------------*/
3506 geniCodeArrayInit (ast * tree, operand *array)
3510 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3511 ic = newiCode (ARRAYINIT, array, NULL);
3512 IC_ARRAYILIST (ic) = tree->values.constlist;
3514 operand *left=newOperand(), *right=newOperand();
3515 left->type=right->type=SYMBOL;
3516 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3517 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3518 ic = newiCode (ARRAYINIT, left, right);
3523 /*-----------------------------------------------------------------*/
3524 /* geniCodeCritical - intermediate code for a critical statement */
3525 /*-----------------------------------------------------------------*/
3527 geniCodeCritical (ast *tree, int lvl)
3532 /* If op is NULL, the original interrupt state will saved on */
3533 /* the stack. Otherwise, it will be saved in op. */
3535 /* Generate a save of the current interrupt state & disabled */
3536 ic = newiCode (CRITICAL, NULL, NULL);
3537 IC_RESULT (ic) = op;
3540 /* Generate the critical code sequence */
3541 if (tree->left && tree->left->type == EX_VALUE)
3542 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3544 ast2iCode (tree->left,lvl+1);
3546 /* Generate a restore of the original interrupt state */
3547 ic = newiCode (ENDCRITICAL, NULL, op);
3551 /*-----------------------------------------------------------------*/
3552 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3553 /* particular case. Ie : assigning or dereferencing array or ptr */
3554 /*-----------------------------------------------------------------*/
3555 set * lvaluereqSet = NULL;
3556 typedef struct lvalItem
3563 /*-----------------------------------------------------------------*/
3564 /* addLvaluereq - add a flag for lvalreq for current ast level */
3565 /*-----------------------------------------------------------------*/
3566 void addLvaluereq(int lvl)
3568 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3571 addSetHead(&lvaluereqSet,lpItem);
3574 /*-----------------------------------------------------------------*/
3575 /* delLvaluereq - del a flag for lvalreq for current ast level */
3576 /*-----------------------------------------------------------------*/
3580 lpItem = getSet(&lvaluereqSet);
3581 if(lpItem) Safe_free(lpItem);
3583 /*-----------------------------------------------------------------*/
3584 /* clearLvaluereq - clear lvalreq flag */
3585 /*-----------------------------------------------------------------*/
3586 void clearLvaluereq()
3589 lpItem = peekSet(lvaluereqSet);
3590 if(lpItem) lpItem->req = 0;
3592 /*-----------------------------------------------------------------*/
3593 /* getLvaluereq - get the last lvalreq level */
3594 /*-----------------------------------------------------------------*/
3595 int getLvaluereqLvl()
3598 lpItem = peekSet(lvaluereqSet);
3599 if(lpItem) return lpItem->lvl;
3602 /*-----------------------------------------------------------------*/
3603 /* isLvaluereq - is lvalreq valid for this level ? */
3604 /*-----------------------------------------------------------------*/
3605 int isLvaluereq(int lvl)
3608 lpItem = peekSet(lvaluereqSet);
3609 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3613 /*-----------------------------------------------------------------*/
3614 /* ast2iCode - creates an icodeList from an ast */
3615 /*-----------------------------------------------------------------*/
3617 ast2iCode (ast * tree,int lvl)
3619 operand *left = NULL;
3620 operand *right = NULL;
3624 /* set the global variables for filename & line number */
3626 filename = tree->filename;
3628 lineno = tree->lineno;
3630 block = tree->block;
3632 scopeLevel = tree->level;
3634 seqPoint = tree->seqPoint;
3636 if (tree->type == EX_VALUE)
3637 return operandFromValue (tree->opval.val);
3639 if (tree->type == EX_LINK)
3640 return operandFromLink (tree->opval.lnk);
3642 /* if we find a nullop */
3643 if (tree->type == EX_OP &&
3644 (tree->opval.op == NULLOP ||
3645 tree->opval.op == BLOCK))
3647 if (tree->left && tree->left->type == EX_VALUE)
3648 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3650 ast2iCode (tree->left,lvl+1);
3651 if (tree->right && tree->right->type == EX_VALUE)
3652 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3654 ast2iCode (tree->right,lvl+1);
3658 /* special cases for not evaluating */
3659 if (tree->opval.op != ':' &&
3660 tree->opval.op != '?' &&
3661 tree->opval.op != CALL &&
3662 tree->opval.op != IFX &&
3663 tree->opval.op != LABEL &&
3664 tree->opval.op != GOTO &&
3665 tree->opval.op != SWITCH &&
3666 tree->opval.op != FUNCTION &&
3667 tree->opval.op != INLINEASM &&
3668 tree->opval.op != CRITICAL)
3671 if (IS_ASSIGN_OP (tree->opval.op) ||
3672 IS_DEREF_OP (tree) ||
3673 (tree->opval.op == '&' && !tree->right) ||
3674 tree->opval.op == PTR_OP)
3677 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3678 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3681 left = operandFromAst (tree->left,lvl);
3683 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3684 left = geniCodeRValue (left, TRUE);
3688 left = operandFromAst (tree->left,lvl);
3690 if (tree->opval.op == INC_OP ||
3691 tree->opval.op == DEC_OP)
3694 right = operandFromAst (tree->right,lvl);
3699 right = operandFromAst (tree->right,lvl);
3703 /* now depending on the type of operand */
3704 /* this will be a biggy */
3705 switch (tree->opval.op)
3708 case '[': /* array operation */
3710 //sym_link *ltype = operandType (left);
3711 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3712 left = geniCodeRValue (left, FALSE);
3713 right = geniCodeRValue (right, TRUE);
3716 return geniCodeArray (left, right,lvl);
3718 case '.': /* structure dereference */
3719 if (IS_PTR (operandType (left)))
3720 left = geniCodeRValue (left, TRUE);
3722 left = geniCodeRValue (left, FALSE);
3724 return geniCodeStruct (left, right, tree->lvalue);
3726 case PTR_OP: /* structure pointer dereference */
3729 pType = operandType (left);
3730 left = geniCodeRValue (left, TRUE);
3732 setOClass (pType, getSpec (operandType (left)));
3735 return geniCodeStruct (left, right, tree->lvalue);
3737 case INC_OP: /* increment operator */
3739 return geniCodePostInc (left);
3741 return geniCodePreInc (right, tree->lvalue);
3743 case DEC_OP: /* decrement operator */
3745 return geniCodePostDec (left);
3747 return geniCodePreDec (right, tree->lvalue);
3749 case '&': /* bitwise and or address of operator */
3751 { /* this is a bitwise operator */
3752 left = geniCodeRValue (left, FALSE);
3753 right = geniCodeRValue (right, FALSE);
3754 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3757 return geniCodeAddressOf (left);
3759 case '|': /* bitwise or & xor */
3761 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3762 geniCodeRValue (right, FALSE),
3767 return geniCodeDivision (geniCodeRValue (left, FALSE),
3768 geniCodeRValue (right, FALSE));
3771 return geniCodeModulus (geniCodeRValue (left, FALSE),
3772 geniCodeRValue (right, FALSE));
3775 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3776 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3778 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3782 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3783 geniCodeRValue (right, FALSE));
3785 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3789 return geniCodeAdd (geniCodeRValue (left, FALSE),
3790 geniCodeRValue (right, FALSE),lvl);
3792 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3795 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3796 geniCodeRValue (right, FALSE));
3799 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3800 geniCodeRValue (right, FALSE));
3802 #if 0 // this indeed needs a second thought
3806 // let's keep this simple: get the rvalue we need
3807 op=geniCodeRValue (right, FALSE);
3808 // now cast it to whatever we want
3809 op=geniCodeCast (operandType(left), op, FALSE);
3810 // if this is going to be used as an lvalue, make it so
3816 #else // bug #604575, is it a bug ????
3817 return geniCodeCast (operandType (left),
3818 geniCodeRValue (right, FALSE), FALSE);
3825 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3830 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3831 setOperandType (op, UCHARTYPE);
3842 /* different compilers (even different gccs) evaluate
3843 the two calls in a different order. to get the same
3844 result on all machines we've to specify a clear sequence.
3845 return geniCodeLogic (geniCodeRValue (left, FALSE),
3846 geniCodeRValue (right, FALSE),
3850 operand *leftOp, *rightOp;
3852 rightOp = geniCodeRValue (right, FALSE);
3853 leftOp = geniCodeRValue (left , FALSE);
3855 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3858 return geniCodeConditional (tree,lvl);
3861 return operandFromLit (getSize (tree->right->ftype));
3865 sym_link *rtype = operandType (right);
3866 sym_link *ltype = operandType (left);
3867 if (IS_PTR (rtype) && IS_ITEMP (right)
3868 && right->isaddr && compareType (rtype->next, ltype) == 1)
3869 right = geniCodeRValue (right, TRUE);
3871 right = geniCodeRValue (right, FALSE);
3873 geniCodeAssign (left, right, 0);
3878 geniCodeAssign (left,
3879 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3881 geniCodeRValue (right, FALSE),FALSE), 0);
3885 geniCodeAssign (left,
3886 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3888 geniCodeRValue (right, FALSE)), 0);
3891 geniCodeAssign (left,
3892 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3894 geniCodeRValue (right, FALSE)), 0);
3897 sym_link *rtype = operandType (right);
3898 sym_link *ltype = operandType (left);
3899 if (IS_PTR (rtype) && IS_ITEMP (right)
3900 && right->isaddr && compareType (rtype->next, ltype) == 1)
3901 right = geniCodeRValue (right, TRUE);
3903 right = geniCodeRValue (right, FALSE);
3906 return geniCodeAssign (left,
3907 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3913 sym_link *rtype = operandType (right);
3914 sym_link *ltype = operandType (left);
3915 if (IS_PTR (rtype) && IS_ITEMP (right)
3916 && right->isaddr && compareType (rtype->next, ltype) == 1)
3918 right = geniCodeRValue (right, TRUE);
3922 right = geniCodeRValue (right, FALSE);
3925 geniCodeAssign (left,
3926 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3932 geniCodeAssign (left,
3933 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3935 geniCodeRValue (right, FALSE)), 0);
3938 geniCodeAssign (left,
3939 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3941 geniCodeRValue (right, FALSE)), 0);
3944 geniCodeAssign (left,
3945 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3947 geniCodeRValue (right, FALSE),
3949 operandType (left)), 0);
3952 geniCodeAssign (left,
3953 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3955 geniCodeRValue (right, FALSE),
3957 operandType (left)), 0);
3960 geniCodeAssign (left,
3961 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3963 geniCodeRValue (right, FALSE),
3965 operandType (left)), 0);
3967 return geniCodeRValue (right, FALSE);
3970 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3973 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3974 return ast2iCode (tree->right,lvl+1);
3977 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3978 return ast2iCode (tree->right,lvl+1);
3981 geniCodeFunctionBody (tree,lvl);
3985 geniCodeReturn (right);
3989 geniCodeIfx (tree,lvl);
3993 geniCodeSwitch (tree,lvl);
3997 geniCodeInline (tree);
4001 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4005 geniCodeCritical (tree, lvl);
4011 /*-----------------------------------------------------------------*/
4012 /* reverseICChain - gets from the list and creates a linkedlist */
4013 /*-----------------------------------------------------------------*/
4020 while ((loop = getSet (&iCodeChain)))
4032 /*-----------------------------------------------------------------*/
4033 /* iCodeFromAst - given an ast will convert it to iCode */
4034 /*-----------------------------------------------------------------*/
4036 iCodeFromAst (ast * tree)
4038 returnLabel = newiTempLabel ("_return");
4039 entryLabel = newiTempLabel ("_entry");
4041 return reverseiCChain ();
4044 static const char *opTypeToStr(OPTYPE op)
4048 case SYMBOL: return "symbol";
4049 case VALUE: return "value";
4050 case TYPE: return "type";
4052 return "undefined type";
4056 operand *validateOpType(operand *op,
4063 if (op && op->type == type)
4068 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4069 " expected %s, got %s\n",
4070 macro, args, file, line,
4071 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4073 return op; // never reached, makes compiler happy.