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 *, bool);
49 operand *geniCodeAssign (operand *, operand *, int);
50 static operand *geniCodeArray (operand *, operand *,int);
51 static operand *geniCodeArray2Ptr (operand *);
52 operand *geniCodeRValue (operand *, bool);
53 operand *geniCodeDerefPtr (operand *,int);
54 int isLvaluereq(int lvl);
55 void setOClass (sym_link * ptr, sym_link * spec);
56 static operand *geniCodeCast (sym_link *, operand *, bool);
58 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
59 /* forward definition of ic print functions */
60 PRINTFUNC (picGetValueAtAddr);
61 PRINTFUNC (picSetValueAtAddr);
62 PRINTFUNC (picAddrOf);
63 PRINTFUNC (picGeneric);
64 PRINTFUNC (picGenericOne);
66 PRINTFUNC (picAssign);
70 PRINTFUNC (picJumpTable);
71 PRINTFUNC (picInline);
72 PRINTFUNC (picReceive);
73 PRINTFUNC (picDummyRead);
74 PRINTFUNC (picCritical);
75 PRINTFUNC (picEndCritical);
77 iCodeTable codeTable[] =
79 {'!', "not", picGenericOne, NULL},
80 {'~', "~", picGenericOne, NULL},
81 {RRC, "rrc", picGenericOne, NULL},
82 {RLC, "rlc", picGenericOne, NULL},
83 {GETHBIT, "ghbit", picGenericOne, NULL},
84 {UNARYMINUS, "-", picGenericOne, NULL},
85 {IPUSH, "push", picGenericOne, NULL},
86 {IPOP, "pop", picGenericOne, NULL},
87 {CALL, "call", picGenericOne, NULL},
88 {PCALL, "pcall", picGenericOne, NULL},
89 {FUNCTION, "proc", picGenericOne, NULL},
90 {ENDFUNCTION, "eproc", picGenericOne, NULL},
91 {RETURN, "ret", picGenericOne, NULL},
92 {'+', "+", picGeneric, NULL},
93 {'-', "-", picGeneric, NULL},
94 {'*', "*", picGeneric, NULL},
95 {'/', "/", picGeneric, NULL},
96 {'%', "%", picGeneric, NULL},
97 {'>', ">", picGeneric, NULL},
98 {'<', "<", picGeneric, NULL},
99 {LE_OP, "<=", picGeneric, NULL},
100 {GE_OP, ">=", picGeneric, NULL},
101 {EQ_OP, "==", picGeneric, NULL},
102 {NE_OP, "!=", picGeneric, NULL},
103 {AND_OP, "&&", picGeneric, NULL},
104 {OR_OP, "||", picGeneric, NULL},
105 {'^', "^", picGeneric, NULL},
106 {'|', "|", picGeneric, NULL},
107 {BITWISEAND, "&", picGeneric, NULL},
108 {LEFT_OP, "<<", picGeneric, NULL},
109 {RIGHT_OP, ">>", picGeneric, NULL},
110 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
111 {ADDRESS_OF, "&", picAddrOf, NULL},
112 {CAST, "<>", picCast, NULL},
113 {'=', ":=", picAssign, NULL},
114 {LABEL, "", picLabel, NULL},
115 {GOTO, "", picGoto, NULL},
116 {JUMPTABLE, "jtab", picJumpTable, NULL},
117 {IFX, "if", picIfx, NULL},
118 {INLINEASM, "", picInline, NULL},
119 {RECEIVE, "recv", picReceive, NULL},
120 {SEND, "send", picGenericOne, NULL},
121 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
122 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
123 {CRITICAL, "critical_start", picCritical, NULL},
124 {ENDCRITICAL, "critical_end", picEndCritical, NULL}
127 /*-----------------------------------------------------------------*/
128 /* checkConstantRange: check a constant against the type */
129 /*-----------------------------------------------------------------*/
132 /* pedantic=0: allmost anything is allowed as long as the absolute
133 value is within the bit range of the type, and -1 is treated as
134 0xf..f for unsigned types (e.g. in assign)
135 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
136 pedantic>1: "char c=200" is not allowed (evaluates to -56)
139 void checkConstantRange(sym_link *ltype, value *val, char *msg,
146 max = pow ((double)2.0, (double)bitsForType(ltype));
148 if (IS_LONG(val->type)) {
149 if (IS_UNSIGNED(val->type)) {
150 v=SPEC_CVAL(val->type).v_ulong;
152 v=SPEC_CVAL(val->type).v_long;
155 if (IS_UNSIGNED(val->type)) {
156 v=SPEC_CVAL(val->type).v_uint;
158 v=SPEC_CVAL(val->type).v_int;
164 // this could be a good idea
165 if (options.pedantic)
169 if (IS_FLOAT(ltype)) {
174 if (!IS_UNSIGNED(val->type) && v<0) {
176 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
182 // if very pedantic: "char c=200" is not allowed
183 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
184 max = max/2 + negative;
191 #if 0 // temporary disabled, leaving the warning as a reminder
193 SNPRINTF (message, sizeof(message), "for %s %s in %s",
194 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
195 nounName(ltype), msg);
196 werror (W_CONST_RANGE, message);
204 /*-----------------------------------------------------------------*/
205 /* operandName - returns the name of the operand */
206 /*-----------------------------------------------------------------*/
208 printOperand (operand * op, FILE * file)
225 opetype = getSpec (operandType (op));
226 if (IS_FLOAT (opetype))
227 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
229 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
230 printTypeChain (operandType (op), file);
237 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
238 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
240 OP_LIVEFROM (op), OP_LIVETO (op),
241 OP_SYMBOL (op)->stack,
242 op->isaddr, OP_SYMBOL (op)->isreqv,
243 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
244 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
248 printTypeChain (operandType (op), file);
249 if (SPIL_LOC (op) && IS_ITEMP (op))
250 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
255 /* if assigned to registers */
256 if (OP_SYMBOL (op)->nRegs)
258 if (OP_SYMBOL (op)->isspilt)
260 if (!OP_SYMBOL (op)->remat)
261 if (OP_SYMBOL (op)->usl.spillLoc)
262 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
263 OP_SYMBOL (op)->usl.spillLoc->rname :
264 OP_SYMBOL (op)->usl.spillLoc->name));
266 fprintf (file, "[err]");
268 fprintf (file, "[remat]");
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
280 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
281 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
282 /* if assigned to registers */
283 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
287 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
288 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
289 OP_SYMBOL (op)->regs[i]->name :
298 printTypeChain (op->operand.typeOperand, file);
304 fprintf (file, "\n");
309 /*-----------------------------------------------------------------*/
310 /* print functions */
311 /*-----------------------------------------------------------------*/
312 PRINTFUNC (picGetValueAtAddr)
315 printOperand (IC_RESULT (ic), of);
318 printOperand (IC_LEFT (ic), of);
324 PRINTFUNC (picSetValueAtAddr)
328 printOperand (IC_LEFT (ic), of);
329 fprintf (of, "] = ");
330 printOperand (IC_RIGHT (ic), of);
334 PRINTFUNC (picAddrOf)
337 printOperand (IC_RESULT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
341 fprintf (of, " = &[");
342 printOperand (IC_LEFT (ic), of);
345 if (IS_ITEMP (IC_LEFT (ic)))
346 fprintf (of, " offsetAdd ");
349 printOperand (IC_RIGHT (ic), of);
351 if (IS_ITEMP (IC_LEFT (ic)))
357 PRINTFUNC (picJumpTable)
362 fprintf (of, "%s\t", s);
363 printOperand (IC_JTCOND (ic), of);
365 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
366 sym = setNextItem (IC_JTLABELS (ic)))
367 fprintf (of, "\t\t\t%s\n", sym->name);
370 PRINTFUNC (picGeneric)
373 printOperand (IC_RESULT (ic), of);
375 printOperand (IC_LEFT (ic), of);
376 fprintf (of, " %s ", s);
377 printOperand (IC_RIGHT (ic), of);
381 PRINTFUNC (picGenericOne)
386 printOperand (IC_RESULT (ic), of);
392 fprintf (of, "%s ", s);
393 printOperand (IC_LEFT (ic), of);
396 if (!IC_RESULT (ic) && !IC_LEFT (ic))
399 if (ic->op == SEND || ic->op == RECEIVE) {
400 fprintf(of,"{argreg = %d}",ic->argreg);
408 printOperand (IC_RESULT (ic), of);
410 printOperand (IC_LEFT (ic), of);
411 printOperand (IC_RIGHT (ic), of);
416 PRINTFUNC (picAssign)
420 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
423 printOperand (IC_RESULT (ic), of);
425 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
428 fprintf (of, " %s ", s);
429 printOperand (IC_RIGHT (ic), of);
436 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
442 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
449 printOperand (IC_COND (ic), of);
452 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
455 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
457 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
461 PRINTFUNC (picInline)
463 fprintf (of, "%s", IC_INLINE (ic));
466 PRINTFUNC (picReceive)
468 printOperand (IC_RESULT (ic), of);
469 fprintf (of, " = %s ", s);
470 printOperand (IC_LEFT (ic), of);
474 PRINTFUNC (picDummyRead)
477 fprintf (of, "%s ", s);
478 printOperand (IC_RIGHT (ic), of);
482 PRINTFUNC (picCritical)
486 printOperand (IC_RESULT (ic), of);
488 fprintf (of, "(stack)");
489 fprintf (of, " = %s ", s);
493 PRINTFUNC (picEndCritical)
496 fprintf (of, "%s = ", s);
498 printOperand (IC_RIGHT (ic), of);
500 fprintf (of, "(stack)");
504 /*-----------------------------------------------------------------*/
505 /* piCode - prints one iCode */
506 /*-----------------------------------------------------------------*/
508 piCode (void *item, FILE * of)
516 icTab = getTableEntry (ic->op);
517 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
518 ic->filename, ic->lineno,
519 ic->seq, ic->key, ic->depth, ic->supportRtn);
520 icTab->iCodePrint (of, ic, icTab->printName);
526 printiCChain(ic,stdout);
528 /*-----------------------------------------------------------------*/
529 /* printiCChain - prints intermediate code for humans */
530 /*-----------------------------------------------------------------*/
532 printiCChain (iCode * icChain, FILE * of)
539 for (loop = icChain; loop; loop = loop->next)
541 if ((icTab = getTableEntry (loop->op)))
543 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
544 loop->filename, loop->lineno,
545 loop->seq, loop->key, loop->depth, loop->supportRtn);
547 icTab->iCodePrint (of, loop, icTab->printName);
553 /*-----------------------------------------------------------------*/
554 /* newOperand - allocate, init & return a new iCode */
555 /*-----------------------------------------------------------------*/
561 op = Safe_alloc ( sizeof (operand));
567 /*-----------------------------------------------------------------*/
568 /* newiCode - create and return a new iCode entry initialised */
569 /*-----------------------------------------------------------------*/
571 newiCode (int op, operand * left, operand * right)
575 ic = Safe_alloc ( sizeof (iCode));
577 ic->seqPoint = seqPoint;
579 ic->filename = filename;
581 ic->level = scopeLevel;
583 ic->key = iCodeKey++;
585 IC_RIGHT (ic) = right;
590 /*-----------------------------------------------------------------*/
591 /* newiCode for conditional statements */
592 /*-----------------------------------------------------------------*/
594 newiCodeCondition (operand * condition,
600 if (IS_VOID(operandType(condition))) {
601 werror(E_VOID_VALUE_USED);
604 ic = newiCode (IFX, NULL, NULL);
605 IC_COND (ic) = condition;
606 IC_TRUE (ic) = trueLabel;
607 IC_FALSE (ic) = falseLabel;
611 /*-----------------------------------------------------------------*/
612 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
613 /*-----------------------------------------------------------------*/
615 newiCodeLabelGoto (int op, symbol * label)
619 ic = newiCode (op, NULL, NULL);
623 IC_RIGHT (ic) = NULL;
624 IC_RESULT (ic) = NULL;
628 /*-----------------------------------------------------------------*/
629 /* newiTemp - allocate & return a newItemp Variable */
630 /*-----------------------------------------------------------------*/
638 SNPRINTF (buffer, sizeof(buffer), "%s", s);
642 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
645 itmp = newSymbol (buffer, 1);
646 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
652 /*-----------------------------------------------------------------*/
653 /* newiTempLabel - creates a temp variable label */
654 /*-----------------------------------------------------------------*/
656 newiTempLabel (char *s)
660 /* check if this alredy exists */
661 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
666 itmplbl = newSymbol (s, 1);
670 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
671 itmplbl = newSymbol (buffer, 1);
676 itmplbl->key = labelKey++;
677 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
681 /*-----------------------------------------------------------------*/
682 /* newiTempPreheaderLabel - creates a new preheader label */
683 /*-----------------------------------------------------------------*/
685 newiTempPreheaderLabel ()
689 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
690 itmplbl = newSymbol (buffer, 1);
694 itmplbl->key = labelKey++;
695 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
700 /*-----------------------------------------------------------------*/
701 /* initiCode - initialises some iCode related stuff */
702 /*-----------------------------------------------------------------*/
709 /*-----------------------------------------------------------------*/
710 /* copyiCode - make a copy of the iCode given */
711 /*-----------------------------------------------------------------*/
713 copyiCode (iCode * ic)
715 iCode *nic = newiCode (ic->op, NULL, NULL);
717 nic->lineno = ic->lineno;
718 nic->filename = ic->filename;
719 nic->block = ic->block;
720 nic->level = ic->level;
721 nic->parmBytes = ic->parmBytes;
723 /* deal with the special cases first */
727 IC_COND (nic) = operandFromOperand (IC_COND (ic));
728 IC_TRUE (nic) = IC_TRUE (ic);
729 IC_FALSE (nic) = IC_FALSE (ic);
733 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
734 IC_JTLABELS (nic) = IC_JTLABELS (ic);
739 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
740 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
744 IC_INLINE (nic) = IC_INLINE (ic);
748 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
752 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
753 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
754 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
760 /*-----------------------------------------------------------------*/
761 /* getTableEntry - gets the table entry for the given operator */
762 /*-----------------------------------------------------------------*/
764 getTableEntry (int oper)
768 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
769 if (oper == codeTable[i].icode)
770 return &codeTable[i];
775 /*-----------------------------------------------------------------*/
776 /* newiTempOperand - new intermediate temp operand */
777 /*-----------------------------------------------------------------*/
779 newiTempOperand (sym_link * type, char throwType)
782 operand *op = newOperand ();
786 itmp = newiTemp (NULL);
788 etype = getSpec (type);
790 if (IS_LITERAL (etype))
793 /* copy the type information */
795 itmp->etype = getSpec (itmp->type = (throwType ? type :
796 copyLinkChain (type)));
797 if (IS_LITERAL (itmp->etype))
799 SPEC_SCLS (itmp->etype) = S_REGISTER;
800 SPEC_OCLS (itmp->etype) = reg;
803 op->operand.symOperand = itmp;
804 op->key = itmp->key = ++operandKey;
808 /*-----------------------------------------------------------------*/
809 /* operandType - returns the type chain for an operand */
810 /*-----------------------------------------------------------------*/
812 operandType (operand * op)
814 /* depending on type of operand */
819 return op->operand.valOperand->type;
822 return op->operand.symOperand->type;
825 return op->operand.typeOperand;
827 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
828 " operand type not known ");
829 assert (0); /* should never come here */
830 /* Just to keep the compiler happy */
831 return (sym_link *) 0;
835 /*-----------------------------------------------------------------*/
836 /* isParamterToCall - will return 1 if op is a parameter to args */
837 /*-----------------------------------------------------------------*/
839 isParameterToCall (value * args, operand * op)
843 wassert (IS_SYMOP(op));
848 isSymbolEqual (op->operand.symOperand, tval->sym))
855 /*-----------------------------------------------------------------*/
856 /* isOperandGlobal - return 1 if operand is a global variable */
857 /*-----------------------------------------------------------------*/
859 isOperandGlobal (operand * op)
868 (op->operand.symOperand->level == 0 ||
869 IS_STATIC (op->operand.symOperand->etype) ||
870 IS_EXTERN (op->operand.symOperand->etype))
877 /*-----------------------------------------------------------------*/
878 /* isOperandVolatile - return 1 if the operand is volatile */
879 /*-----------------------------------------------------------------*/
881 isOperandVolatile (operand * op, bool chkTemp)
886 if (IS_ITEMP (op) && !chkTemp)
889 opetype = getSpec (optype = operandType (op));
891 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
894 if (IS_VOLATILE (opetype))
899 /*-----------------------------------------------------------------*/
900 /* isOperandLiteral - returns 1 if an operand contains a literal */
901 /*-----------------------------------------------------------------*/
903 isOperandLiteral (operand * op)
910 opetype = getSpec (operandType (op));
912 if (IS_LITERAL (opetype))
918 /*-----------------------------------------------------------------*/
919 /* isOperandInFarSpace - will return true if operand is in farSpace */
920 /*-----------------------------------------------------------------*/
922 isOperandInFarSpace (operand * op)
932 if (!IS_TRUE_SYMOP (op))
935 etype = SPIL_LOC (op)->etype;
941 etype = getSpec (operandType (op));
943 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
946 /*------------------------------------------------------------------*/
947 /* isOperandInDirSpace - will return true if operand is in dirSpace */
948 /*------------------------------------------------------------------*/
950 isOperandInDirSpace (operand * op)
960 if (!IS_TRUE_SYMOP (op))
963 etype = SPIL_LOC (op)->etype;
969 etype = getSpec (operandType (op));
971 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
974 /*--------------------------------------------------------------------*/
975 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
976 /*--------------------------------------------------------------------*/
978 isOperandInCodeSpace (operand * op)
988 etype = getSpec (operandType (op));
990 if (!IS_TRUE_SYMOP (op))
993 etype = SPIL_LOC (op)->etype;
999 etype = getSpec (operandType (op));
1001 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1004 /*-----------------------------------------------------------------*/
1005 /* isOperandOnStack - will return true if operand is on stack */
1006 /*-----------------------------------------------------------------*/
1008 isOperandOnStack (operand * op)
1018 etype = getSpec (operandType (op));
1019 if (IN_STACK (etype) ||
1020 OP_SYMBOL(op)->onStack ||
1021 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1027 /*-----------------------------------------------------------------*/
1028 /* isOclsExpensive - will return true if accesses to an output */
1029 /* storage class are expensive */
1030 /*-----------------------------------------------------------------*/
1032 isOclsExpensive (struct memmap *oclass)
1034 if (port->oclsExpense)
1035 return port->oclsExpense (oclass) > 0;
1037 /* In the absence of port specific guidance, assume only */
1038 /* farspace is expensive. */
1039 return IN_FARSPACE (oclass);
1042 /*-----------------------------------------------------------------*/
1043 /* operandLitValue - literal value of an operand */
1044 /*-----------------------------------------------------------------*/
1046 operandLitValue (operand * op)
1048 assert (isOperandLiteral (op));
1050 return floatFromVal (op->operand.valOperand);
1053 /*-----------------------------------------------------------------*/
1054 /* getBuiltInParms - returns parameters to a builtin functions */
1055 /*-----------------------------------------------------------------*/
1056 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1061 /* builtin functions uses only SEND for parameters */
1062 while (ic->op != CALL) {
1063 assert(ic->op == SEND && ic->builtinSEND);
1064 ic->generated = 1; /* mark the icode as generated */
1065 parms[*pcount] = IC_LEFT(ic);
1071 /* make sure this is a builtin function call */
1072 assert(IS_SYMOP(IC_LEFT(ic)));
1073 ftype = operandType(IC_LEFT(ic));
1074 assert(IFFUNC_ISBUILTIN(ftype));
1078 /*-----------------------------------------------------------------*/
1079 /* operandOperation - performs operations on operands */
1080 /*-----------------------------------------------------------------*/
1082 operandOperation (operand * left, operand * right,
1083 int op, sym_link * type)
1085 sym_link *let , *ret=NULL;
1086 operand *retval = (operand *) 0;
1088 assert (isOperandLiteral (left));
1089 let = getSpec(operandType(left));
1091 assert (isOperandLiteral (right));
1092 ret = getSpec(operandType(right));
1098 retval = operandFromValue (valCastLiteral (type,
1099 operandLitValue (left) +
1100 operandLitValue (right)));
1103 retval = operandFromValue (valCastLiteral (type,
1104 operandLitValue (left) -
1105 operandLitValue (right)));
1109 retval = operandFromValue (valCastLiteral (type,
1110 operandLitValue (left) *
1111 operandLitValue (right)));
1112 This could be all we've to do, but with gcc we've to take care about
1113 overflows. Two examples:
1114 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1115 significant bits are lost (52 in fraction, 63 bits would be
1116 necessary to keep full precision).
1117 If the resulting double value is greater than ULONG_MAX (resp.
1118 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1121 /* if it is not a specifier then we can assume that */
1122 /* it will be an unsigned long */
1123 if (IS_INT (type) ||
1126 /* long is handled here, because it can overflow with double */
1127 if (IS_LONG (type) ||
1129 /* signed and unsigned mul are the same, as long as the precision
1130 of the result isn't bigger than the precision of the operands. */
1131 retval = operandFromValue (valCastLiteral (type,
1132 (TYPE_UDWORD) operandLitValue (left) *
1133 (TYPE_UDWORD) operandLitValue (right)));
1134 else if (IS_UNSIGNED (type)) /* unsigned int */
1136 /* unsigned int is handled here in order to detect overflow */
1137 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1138 (TYPE_UWORD) operandLitValue (right);
1140 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1141 if (ul != (TYPE_UWORD) ul)
1144 else /* signed int */
1146 /* signed int is handled here in order to detect overflow */
1147 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1148 (TYPE_WORD) operandLitValue (right);
1150 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1151 if (l != (TYPE_WORD) l)
1156 /* all others go here: */
1157 retval = operandFromValue (valCastLiteral (type,
1158 operandLitValue (left) *
1159 operandLitValue (right)));
1162 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1164 werror (E_DIVIDE_BY_ZERO);
1170 if (IS_UNSIGNED (type))
1172 SPEC_USIGN (let) = 1;
1173 SPEC_USIGN (ret) = 1;
1174 retval = operandFromValue (valCastLiteral (type,
1175 (TYPE_UDWORD) operandLitValue (left) /
1176 (TYPE_UDWORD) operandLitValue (right)));
1180 retval = operandFromValue (valCastLiteral (type,
1181 operandLitValue (left) /
1182 operandLitValue (right)));
1187 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1189 werror (E_DIVIDE_BY_ZERO);
1194 if (IS_UNSIGNED (type))
1195 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1196 (TYPE_UDWORD) operandLitValue (right));
1198 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1199 (TYPE_DWORD) operandLitValue (right));
1203 /* The number of left shifts is always unsigned. Signed doesn't make
1204 sense here. Shifting by a negative number is impossible. */
1205 retval = operandFromValue (valCastLiteral (type,
1206 ((TYPE_UDWORD) operandLitValue (left) <<
1207 (TYPE_UDWORD) operandLitValue (right))));
1210 /* The number of right shifts is always unsigned. Signed doesn't make
1211 sense here. Shifting by a negative number is impossible. */
1212 if (IS_UNSIGNED(let))
1213 /* unsigned: logic shift right */
1214 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1215 (TYPE_UDWORD) operandLitValue (right));
1217 /* signed: arithmetic shift right */
1218 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1219 (TYPE_UDWORD) operandLitValue (right));
1222 /* this op doesn't care about signedness */
1226 l = (TYPE_UDWORD) operandLitValue (left);
1227 if (IS_CHAR(OP_VALUE(left)->type))
1229 else if (!IS_LONG (OP_VALUE(left)->type))
1231 r = (TYPE_UDWORD) operandLitValue (right);
1232 if (IS_CHAR(OP_VALUE(right)->type))
1234 else if (!IS_LONG (OP_VALUE(right)->type))
1236 retval = operandFromLit (l == r);
1240 retval = operandFromLit (operandLitValue (left) <
1241 operandLitValue (right));
1244 retval = operandFromLit (operandLitValue (left) <=
1245 operandLitValue (right));
1248 retval = operandFromLit (operandLitValue (left) !=
1249 operandLitValue (right));
1252 retval = operandFromLit (operandLitValue (left) >
1253 operandLitValue (right));
1256 retval = operandFromLit (operandLitValue (left) >=
1257 operandLitValue (right));
1260 retval = operandFromValue (valCastLiteral (type,
1261 (TYPE_UDWORD)operandLitValue(left) &
1262 (TYPE_UDWORD)operandLitValue(right)));
1265 retval = operandFromValue (valCastLiteral (type,
1266 (TYPE_UDWORD)operandLitValue(left) |
1267 (TYPE_UDWORD)operandLitValue(right)));
1270 retval = operandFromValue (valCastLiteral (type,
1271 (TYPE_UDWORD)operandLitValue(left) ^
1272 (TYPE_UDWORD)operandLitValue(right)));
1275 retval = operandFromLit (operandLitValue (left) &&
1276 operandLitValue (right));
1279 retval = operandFromLit (operandLitValue (left) ||
1280 operandLitValue (right));
1284 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1286 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1292 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1294 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1300 retval = operandFromValue (valCastLiteral (type,
1301 -1 * operandLitValue (left)));
1305 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1309 retval = operandFromLit (!operandLitValue (left));
1313 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1314 " operandOperation invalid operator ");
1322 /*-----------------------------------------------------------------*/
1323 /* isOperandEqual - compares two operand & return 1 if they r = */
1324 /*-----------------------------------------------------------------*/
1326 isOperandEqual (operand * left, operand * right)
1328 /* if the pointers are equal then they are equal */
1332 /* if either of them null then false */
1333 if (!left || !right)
1336 if (left->type != right->type)
1339 if (IS_SYMOP (left) && IS_SYMOP (right))
1340 return left->key == right->key;
1342 /* if types are the same */
1346 return isSymbolEqual (left->operand.symOperand,
1347 right->operand.symOperand);
1349 return (floatFromVal (left->operand.valOperand) ==
1350 floatFromVal (right->operand.valOperand));
1352 if (compareType (left->operand.typeOperand,
1353 right->operand.typeOperand) == 1)
1360 /*-------------------------------------------------------------------*/
1361 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1362 /*-------------------------------------------------------------------*/
1364 isiCodeEqual (iCode * left, iCode * right)
1366 /* if the same pointer */
1370 /* if either of them null */
1371 if (!left || !right)
1374 /* if operand are the same */
1375 if (left->op == right->op)
1378 /* compare all the elements depending on type */
1379 if (left->op != IFX)
1381 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1383 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1389 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1391 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1393 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1402 /*-----------------------------------------------------------------*/
1403 /* newiTempFromOp - create a temp Operand with same attributes */
1404 /*-----------------------------------------------------------------*/
1406 newiTempFromOp (operand * op)
1416 nop = newiTempOperand (operandType (op), TRUE);
1417 nop->isaddr = op->isaddr;
1418 nop->isvolatile = op->isvolatile;
1419 nop->isGlobal = op->isGlobal;
1420 nop->isLiteral = op->isLiteral;
1421 nop->usesDefs = op->usesDefs;
1422 nop->isParm = op->isParm;
1426 /*-----------------------------------------------------------------*/
1427 /* operand from operand - creates an operand holder for the type */
1428 /*-----------------------------------------------------------------*/
1430 operandFromOperand (operand * op)
1436 nop = newOperand ();
1437 nop->type = op->type;
1438 nop->isaddr = op->isaddr;
1440 nop->isvolatile = op->isvolatile;
1441 nop->isGlobal = op->isGlobal;
1442 nop->isLiteral = op->isLiteral;
1443 nop->usesDefs = op->usesDefs;
1444 nop->isParm = op->isParm;
1449 nop->operand.symOperand = op->operand.symOperand;
1452 nop->operand.valOperand = op->operand.valOperand;
1455 nop->operand.typeOperand = op->operand.typeOperand;
1462 /*-----------------------------------------------------------------*/
1463 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1464 /*-----------------------------------------------------------------*/
1466 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1468 operand *nop = operandFromOperand (op);
1470 if (nop->type == SYMBOL)
1472 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1473 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1479 /*-----------------------------------------------------------------*/
1480 /* operandFromSymbol - creates an operand from a symbol */
1481 /*-----------------------------------------------------------------*/
1483 operandFromSymbol (symbol * sym)
1488 /* if the symbol's type is a literal */
1489 /* then it is an enumerator type */
1490 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1491 return operandFromValue (valFromType (sym->etype));
1494 sym->key = ++operandKey;
1496 /* if this an implicit variable, means struct/union */
1497 /* member so just return it */
1498 if (sym->implicit || IS_FUNC (sym->type))
1502 op->operand.symOperand = sym;
1504 op->isvolatile = isOperandVolatile (op, TRUE);
1505 op->isGlobal = isOperandGlobal (op);
1509 /* under the following conditions create a
1510 register equivalent for a local symbol */
1511 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1512 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1514 (!(options.model == MODEL_FLAT24)) ) &&
1515 options.stackAuto == 0)
1518 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1519 !IS_FUNC (sym->type) && /* not a function */
1520 !sym->_isparm && /* not a parameter */
1521 sym->level && /* is a local variable */
1522 !sym->addrtaken && /* whose address has not been taken */
1523 !sym->reqv && /* does not already have a reg equivalence */
1524 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1525 !IS_STATIC (sym->etype) && /* and not declared static */
1526 !sym->islbl && /* not a label */
1527 ok && /* farspace check */
1528 !IS_BITVAR (sym->etype) /* not a bit variable */
1532 /* we will use it after all optimizations
1533 and before liveRange calculation */
1534 sym->reqv = newiTempOperand (sym->type, 0);
1535 sym->reqv->key = sym->key;
1536 OP_SYMBOL (sym->reqv)->prereqv = sym;
1537 OP_SYMBOL (sym->reqv)->key = sym->key;
1538 OP_SYMBOL (sym->reqv)->isreqv = 1;
1539 OP_SYMBOL (sym->reqv)->islocal = 1;
1540 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1541 SPIL_LOC (sym->reqv) = sym;
1544 if (!IS_AGGREGATE (sym->type))
1548 op->operand.symOperand = sym;
1551 op->isvolatile = isOperandVolatile (op, TRUE);
1552 op->isGlobal = isOperandGlobal (op);
1553 op->isPtr = IS_PTR (operandType (op));
1554 op->isParm = sym->_isparm;
1559 /* itemp = &[_symbol] */
1561 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1562 IC_LEFT (ic)->type = SYMBOL;
1563 IC_LEFT (ic)->operand.symOperand = sym;
1564 IC_LEFT (ic)->key = sym->key;
1565 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1566 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1567 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1570 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1571 if (IS_ARRAY (sym->type))
1573 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1574 IC_RESULT (ic)->isaddr = 0;
1577 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1581 return IC_RESULT (ic);
1584 /*-----------------------------------------------------------------*/
1585 /* operandFromValue - creates an operand from value */
1586 /*-----------------------------------------------------------------*/
1588 operandFromValue (value * val)
1592 /* if this is a symbol then do the symbol thing */
1594 return operandFromSymbol (val->sym);
1596 /* this is not a symbol */
1599 op->operand.valOperand = val;
1600 op->isLiteral = isOperandLiteral (op);
1604 /*-----------------------------------------------------------------*/
1605 /* operandFromLink - operand from typeChain */
1606 /*-----------------------------------------------------------------*/
1608 operandFromLink (sym_link * type)
1612 /* operand from sym_link */
1618 op->operand.typeOperand = copyLinkChain (type);
1622 /*-----------------------------------------------------------------*/
1623 /* operandFromLit - makes an operand from a literal value */
1624 /*-----------------------------------------------------------------*/
1626 operandFromLit (double i)
1628 return operandFromValue (valueFromLit (i));
1631 /*-----------------------------------------------------------------*/
1632 /* operandFromAst - creates an operand from an ast */
1633 /*-----------------------------------------------------------------*/
1635 operandFromAst (ast * tree,int lvl)
1641 /* depending on type do */
1645 return ast2iCode (tree,lvl+1);
1649 return operandFromValue (tree->opval.val);
1653 return operandFromLink (tree->opval.lnk);
1660 /* Just to keep the compiler happy */
1661 return (operand *) 0;
1664 /*-----------------------------------------------------------------*/
1665 /* setOperandType - sets the operand's type to the given type */
1666 /*-----------------------------------------------------------------*/
1668 setOperandType (operand * op, sym_link * type)
1670 /* depending on the type of operand */
1675 op->operand.valOperand->etype =
1676 getSpec (op->operand.valOperand->type =
1677 copyLinkChain (type));
1681 if (op->operand.symOperand->isitmp)
1682 op->operand.symOperand->etype =
1683 getSpec (op->operand.symOperand->type =
1684 copyLinkChain (type));
1686 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1687 "attempt to modify type of source");
1691 op->operand.typeOperand = copyLinkChain (type);
1696 /*-----------------------------------------------------------------*/
1697 /* Get size in byte of ptr need to access an array */
1698 /*-----------------------------------------------------------------*/
1700 getArraySizePtr (operand * op)
1702 sym_link *ltype = operandType(op);
1706 int size = getSize(ltype);
1707 return(IS_GENPTR(ltype)?(size-1):size);
1712 sym_link *letype = getSpec(ltype);
1713 switch (PTR_TYPE (SPEC_OCLS (letype)))
1725 return (GPTRSIZE-1);
1734 /*-----------------------------------------------------------------*/
1735 /* perform "usual unary conversions" */
1736 /*-----------------------------------------------------------------*/
1739 usualUnaryConversions (operand * op)
1741 if (IS_INTEGRAL (operandType (op)))
1743 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1746 return geniCodeCast (INTTYPE, op, TRUE);
1753 /*-----------------------------------------------------------------*/
1754 /* perform "usual binary conversions" */
1755 /*-----------------------------------------------------------------*/
1758 usualBinaryConversions (operand ** op1, operand ** op2,
1759 bool resultIsInt, char op)
1762 sym_link *rtype = operandType (*op2);
1763 sym_link *ltype = operandType (*op1);
1765 #define OLDONEBYTEOPS 1
1767 #ifdef OLDONEBYTEOPS
1768 bool oldOneByteOps = FALSE;
1769 static bool saidHello = FALSE;
1771 if ( strcmp (port->target, "pic14") == 0
1772 || strcmp (port->target, "pic16") == 0)
1773 oldOneByteOps = TRUE;
1774 if (getenv ("SDCC_NEWONEBYTEOPS"))
1778 fprintf (stderr, "Override: oldOneByteOps = FALSE\n");
1781 oldOneByteOps = FALSE;
1783 else if (getenv ("SDCC_OLDONEBYTEOPS"))
1787 fprintf (stderr, "Override: oldOneByteOps = TRUE\n");
1790 oldOneByteOps = TRUE;
1795 && ( (IS_CHAR (getSpec (ltype)) && !IS_UNSIGNED (getSpec (ltype)))
1796 || (IS_CHAR (getSpec (rtype)) && !IS_UNSIGNED (getSpec (rtype)))))
1797 /* one or two signed char operands: promote to int */
1801 ctype = computeType (ltype, rtype, resultIsInt);
1803 #ifdef OLDONEBYTEOPS
1808 && IS_CHAR (getSpec (ltype)) && IS_UNSIGNED (getSpec (ltype))
1809 && IS_CHAR (getSpec (rtype)) && IS_UNSIGNED (getSpec (rtype)))
1811 /* two unsigned char operands and Mult: no promotion */
1814 *op1 = geniCodeCast (ctype, *op1, TRUE);
1815 *op2 = geniCodeCast (ctype, *op2, TRUE);
1827 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1829 /* one byte operations: keep signedness for code generator */
1837 *op1 = geniCodeCast (ctype, *op1, TRUE);
1838 *op2 = geniCodeCast (ctype, *op2, TRUE);
1843 /*-----------------------------------------------------------------*/
1844 /* geniCodeValueAtAddress - generate intermeditate code for value */
1846 /*-----------------------------------------------------------------*/
1848 geniCodeRValue (operand * op, bool force)
1851 sym_link *type = operandType (op);
1852 sym_link *etype = getSpec (type);
1854 /* if this is an array & already */
1855 /* an address then return this */
1856 if (IS_AGGREGATE (type) ||
1857 (IS_PTR (type) && !force && !op->isaddr))
1858 return operandFromOperand (op);
1860 /* if this is not an address then must be */
1861 /* rvalue already so return this one */
1865 /* if this is not a temp symbol then */
1866 if (!IS_ITEMP (op) &&
1868 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1870 op = operandFromOperand (op);
1875 if (IS_SPEC (type) &&
1876 IS_TRUE_SYMOP (op) &&
1877 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1878 (options.model == MODEL_FLAT24) ))
1880 op = operandFromOperand (op);
1885 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1886 if (IS_PTR (type) && op->isaddr && force)
1889 type = copyLinkChain (type);
1891 IC_RESULT (ic) = newiTempOperand (type, 1);
1892 IC_RESULT (ic)->isaddr = 0;
1894 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1898 return IC_RESULT (ic);
1901 /*-----------------------------------------------------------------*/
1902 /* geniCodeCast - changes the value from one type to another */
1903 /*-----------------------------------------------------------------*/
1905 geniCodeCast (sym_link * type, operand * op, bool implicit)
1909 sym_link *opetype = getSpec (optype = operandType (op));
1913 /* one of them has size zero then error */
1914 if (IS_VOID (optype))
1916 werror (E_CAST_ZERO);
1920 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1922 geniCodeArray2Ptr (op);
1926 /* if the operand is already the desired type then do nothing */
1927 if (compareType (type, optype) == 1)
1930 /* if this is a literal then just change the type & return */
1931 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1933 return operandFromValue (valCastLiteral (type,
1934 operandLitValue (op)));
1937 /* if casting to/from pointers, do some checking */
1938 if (IS_PTR(type)) { // to a pointer
1939 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1940 if (IS_INTEGRAL(optype)) {
1941 // maybe this is NULL, than it's ok.
1942 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1943 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1944 // no way to set the storage
1945 if (IS_LITERAL(optype)) {
1946 werror(E_LITERAL_GENERIC);
1949 werror(E_NONPTR2_GENPTR);
1952 } else if (implicit) {
1953 werror(W_INTEGRAL2PTR_NOCAST);
1958 // shouldn't do that with float, array or structure unless to void
1959 if (!IS_VOID(getSpec(type)) &&
1960 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1961 werror(E_INCOMPAT_TYPES);
1965 } else { // from a pointer to a pointer
1966 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1967 // if not a pointer to a function
1968 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1969 if (implicit) { // if not to generic, they have to match
1970 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1971 werror(E_INCOMPAT_PTYPES);
1978 } else { // to a non pointer
1979 if (IS_PTR(optype)) { // from a pointer
1980 if (implicit) { // sneaky
1981 if (IS_INTEGRAL(type)) {
1982 werror(W_PTR2INTEGRAL_NOCAST);
1984 } else { // shouldn't do that with float, array or structure
1985 werror(E_INCOMPAT_TYPES);
1992 printFromToType (optype, type);
1995 /* if they are the same size create an assignment */
1997 /* This seems very dangerous to me, since there are several */
1998 /* optimizations (for example, gcse) that don't notice the */
1999 /* cast hidden in this assignement and may simplify an */
2000 /* iCode to use the original (uncasted) operand. */
2001 /* Unfortunately, other things break when this cast is */
2002 /* made explicit. Need to fix this someday. */
2003 /* -- EEP, 2004/01/21 */
2004 if (getSize (type) == getSize (optype) &&
2005 !IS_BITFIELD (type) &&
2007 !IS_FLOAT (optype) &&
2008 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2009 (!IS_SPEC (type) && !IS_SPEC (optype))))
2011 ic = newiCode ('=', NULL, op);
2012 IC_RESULT (ic) = newiTempOperand (type, 0);
2013 SPIL_LOC (IC_RESULT (ic)) =
2014 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2015 IC_RESULT (ic)->isaddr = 0;
2019 ic = newiCode (CAST, operandFromLink (type),
2020 geniCodeRValue (op, FALSE));
2022 IC_RESULT (ic) = newiTempOperand (type, 0);
2025 /* preserve the storage class & output class */
2026 /* of the original variable */
2027 restype = getSpec (operandType (IC_RESULT (ic)));
2028 if (!IS_LITERAL(opetype))
2029 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2030 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2033 return IC_RESULT (ic);
2036 /*-----------------------------------------------------------------*/
2037 /* geniCodeLabel - will create a Label */
2038 /*-----------------------------------------------------------------*/
2040 geniCodeLabel (symbol * label)
2044 ic = newiCodeLabelGoto (LABEL, label);
2048 /*-----------------------------------------------------------------*/
2049 /* geniCodeGoto - will create a Goto */
2050 /*-----------------------------------------------------------------*/
2052 geniCodeGoto (symbol * label)
2056 ic = newiCodeLabelGoto (GOTO, label);
2060 /*-----------------------------------------------------------------*/
2061 /* geniCodeMultiply - gen intermediate code for multiplication */
2062 /*-----------------------------------------------------------------*/
2064 geniCodeMultiply (operand * left, operand * right, bool resultIsInt)
2071 /* if they are both literal then we know the result */
2072 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2073 return operandFromValue (valMult (left->operand.valOperand,
2074 right->operand.valOperand));
2076 if (IS_LITERAL(retype)) {
2077 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2080 resType = usualBinaryConversions (&left, &right, resultIsInt, '*');
2082 rtype = operandType (right);
2083 retype = getSpec (rtype);
2084 ltype = operandType (left);
2085 letype = getSpec (ltype);
2088 /* if the right is a literal & power of 2 */
2089 /* then make it a left shift */
2090 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2091 efficient in most cases than 2 bytes result = 2 bytes << literal
2092 if port has 1 byte muldiv */
2093 if (p2 && !IS_FLOAT (letype) &&
2094 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
2095 (port->support.muldiv == 1)))
2097 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2099 /* LEFT_OP need same size for left and result, */
2100 left = geniCodeCast (resType, left, TRUE);
2101 ltype = operandType (left);
2103 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2107 ic = newiCode ('*', left, right); /* normal multiplication */
2108 /* if the size left or right > 1 then support routine */
2109 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2113 IC_RESULT (ic) = newiTempOperand (resType, 1);
2116 return IC_RESULT (ic);
2119 /*-----------------------------------------------------------------*/
2120 /* geniCodeDivision - gen intermediate code for division */
2121 /*-----------------------------------------------------------------*/
2123 geniCodeDivision (operand * left, operand * right, bool resultIsInt)
2128 sym_link *rtype = operandType (right);
2129 sym_link *retype = getSpec (rtype);
2130 sym_link *ltype = operandType (left);
2131 sym_link *letype = getSpec (ltype);
2133 resType = usualBinaryConversions (&left, &right, resultIsInt, '/');
2135 /* if the right is a literal & power of 2
2136 and left is unsigned then make it a
2138 if (IS_LITERAL (retype) &&
2139 !IS_FLOAT (letype) &&
2140 IS_UNSIGNED(letype) &&
2141 (p2 = powof2 ((TYPE_UDWORD)
2142 floatFromVal (right->operand.valOperand)))) {
2143 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2147 ic = newiCode ('/', left, right); /* normal division */
2148 /* if the size left or right > 1 then support routine */
2149 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2152 IC_RESULT (ic) = newiTempOperand (resType, 0);
2155 return IC_RESULT (ic);
2157 /*-----------------------------------------------------------------*/
2158 /* geniCodeModulus - gen intermediate code for modulus */
2159 /*-----------------------------------------------------------------*/
2161 geniCodeModulus (operand * left, operand * right, bool resultIsInt)
2167 /* if they are both literal then we know the result */
2168 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2169 return operandFromValue (valMod (left->operand.valOperand,
2170 right->operand.valOperand));
2172 resType = usualBinaryConversions (&left, &right, resultIsInt, '%');
2174 /* now they are the same size */
2175 ic = newiCode ('%', left, right);
2177 /* if the size left or right > 1 then support routine */
2178 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2180 IC_RESULT (ic) = newiTempOperand (resType, 0);
2183 return IC_RESULT (ic);
2186 /*-----------------------------------------------------------------*/
2187 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2188 /*-----------------------------------------------------------------*/
2190 geniCodePtrPtrSubtract (operand * left, operand * right)
2196 /* if they are both literals then */
2197 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2199 result = operandFromValue (valMinus (left->operand.valOperand,
2200 right->operand.valOperand));
2204 ic = newiCode ('-', left, right);
2206 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2210 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2214 // should we really do this? is this ANSI?
2215 return geniCodeDivision (result,
2216 operandFromLit (getSize (ltype->next)),
2220 /*-----------------------------------------------------------------*/
2221 /* geniCodeSubtract - generates code for subtraction */
2222 /*-----------------------------------------------------------------*/
2224 geniCodeSubtract (operand * left, operand * right)
2231 /* if they both pointers then */
2232 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2233 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2234 return geniCodePtrPtrSubtract (left, right);
2236 /* if they are both literal then we know the result */
2237 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2238 && left->isLiteral && right->isLiteral)
2239 return operandFromValue (valMinus (left->operand.valOperand,
2240 right->operand.valOperand));
2242 /* if left is an array or pointer */
2243 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2245 isarray = left->isaddr;
2246 right = geniCodeMultiply (right,
2247 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2248 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2251 { /* make them the same size */
2252 resType = usualBinaryConversions (&left, &right, FALSE, '-');
2255 ic = newiCode ('-', left, right);
2257 IC_RESULT (ic) = newiTempOperand (resType, 1);
2258 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2260 /* if left or right is a float */
2261 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2265 return IC_RESULT (ic);
2268 /*-----------------------------------------------------------------*/
2269 /* geniCodeAdd - generates iCode for addition */
2270 /*-----------------------------------------------------------------*/
2272 geniCodeAdd (operand * left, operand * right, int lvl)
2281 /* if the right side is LITERAL zero */
2282 /* return the left side */
2283 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2286 /* if left is literal zero return right */
2287 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2290 /* if left is a pointer then size */
2291 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2293 isarray = left->isaddr;
2294 // there is no need to multiply with 1
2295 if (getSize (ltype->next) != 1)
2297 size = operandFromLit (getSize (ltype->next));
2298 SPEC_USIGN (getSpec (operandType (size))) = 1;
2299 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2300 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2301 /* Even if right is a 'unsigned char',
2302 the result will be a 'signed int' due to the promotion rules.
2303 It doesn't make sense when accessing arrays, so let's fix it here: */
2305 SPEC_USIGN (getSpec (operandType (right))) = 1;
2307 resType = copyLinkChain (ltype);
2310 { // make them the same size
2311 resType = usualBinaryConversions (&left, &right, FALSE, '+');
2314 /* if they are both literals then we know */
2315 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2316 && left->isLiteral && right->isLiteral)
2317 return operandFromValue (valPlus (valFromType (ltype),
2318 valFromType (rtype)));
2320 ic = newiCode ('+', left, right);
2322 IC_RESULT (ic) = newiTempOperand (resType, 1);
2323 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2325 /* if left or right is a float then support
2327 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2332 return IC_RESULT (ic);
2336 /*-----------------------------------------------------------------*/
2337 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2338 /*-----------------------------------------------------------------*/
2340 aggrToPtr (sym_link * type, bool force)
2345 if (IS_PTR (type) && !force)
2348 etype = getSpec (type);
2349 ptype = newLink (DECLARATOR);
2353 /* set the pointer depending on the storage class */
2354 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2358 /*-----------------------------------------------------------------*/
2359 /* geniCodeArray2Ptr - array to pointer */
2360 /*-----------------------------------------------------------------*/
2362 geniCodeArray2Ptr (operand * op)
2364 sym_link *optype = operandType (op);
2365 sym_link *opetype = getSpec (optype);
2367 /* set the pointer depending on the storage class */
2368 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2375 /*-----------------------------------------------------------------*/
2376 /* geniCodeArray - array access */
2377 /*-----------------------------------------------------------------*/
2379 geniCodeArray (operand * left, operand * right, int lvl)
2383 sym_link *ltype = operandType (left);
2388 if (IS_PTR (ltype->next) && left->isaddr)
2390 left = geniCodeRValue (left, FALSE);
2393 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2395 size = operandFromLit (getSize (ltype->next));
2396 SPEC_USIGN (getSpec (operandType (size))) = 1;
2397 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2398 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2399 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2400 It doesn't make sense when accessing arrays, so let's fix it here: */
2402 SPEC_USIGN (getSpec (operandType (right))) = 1;
2403 /* we can check for limits here */
2404 /* already done in SDCCast.c
2405 if (isOperandLiteral (right) &&
2408 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2410 werror (W_IDX_OUT_OF_BOUNDS,
2411 (int) operandLitValue (right) / getSize (ltype->next),
2416 ic = newiCode ('+', left, right);
2418 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2419 !IS_AGGREGATE (ltype->next) &&
2420 !IS_PTR (ltype->next))
2421 ? ltype : ltype->next), 0);
2423 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2426 return IC_RESULT (ic);
2429 /*-----------------------------------------------------------------*/
2430 /* geniCodeStruct - generates intermediate code for structures */
2431 /*-----------------------------------------------------------------*/
2433 geniCodeStruct (operand * left, operand * right, bool islval)
2436 sym_link *type = operandType (left);
2437 sym_link *etype = getSpec (type);
2439 symbol *element = getStructElement (SPEC_STRUCT (etype),
2440 right->operand.symOperand);
2442 wassert(IS_SYMOP(right));
2444 /* add the offset */
2445 ic = newiCode ('+', left, operandFromLit (element->offset));
2447 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2449 /* preserve the storage & output class of the struct */
2450 /* as well as the volatile attribute */
2451 retype = getSpec (operandType (IC_RESULT (ic)));
2452 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2453 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2454 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2455 SPEC_CONST (retype) |= SPEC_CONST (etype);
2457 if (IS_PTR (element->type))
2458 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2460 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2463 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2466 /*-----------------------------------------------------------------*/
2467 /* geniCodePostInc - generate int code for Post increment */
2468 /*-----------------------------------------------------------------*/
2470 geniCodePostInc (operand * op)
2474 sym_link *optype = operandType (op);
2476 operand *rv = (IS_ITEMP (op) ?
2477 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2479 sym_link *rvtype = operandType (rv);
2482 /* if this is not an address we have trouble */
2485 werror (E_LVALUE_REQUIRED, "++");
2489 rOp = newiTempOperand (rvtype, 0);
2490 OP_SYMBOL(rOp)->noSpilLoc = 1;
2493 OP_SYMBOL(rv)->noSpilLoc = 1;
2495 geniCodeAssign (rOp, rv, 0);
2497 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2498 if (IS_FLOAT (rvtype))
2499 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2501 ic = newiCode ('+', rv, operandFromLit (size));
2503 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2506 geniCodeAssign (op, result, 0);
2512 /*-----------------------------------------------------------------*/
2513 /* geniCodePreInc - generate code for preIncrement */
2514 /*-----------------------------------------------------------------*/
2516 geniCodePreInc (operand * op, bool lvalue)
2519 sym_link *optype = operandType (op);
2520 operand *rop = (IS_ITEMP (op) ?
2521 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2523 sym_link *roptype = operandType (rop);
2529 werror (E_LVALUE_REQUIRED, "++");
2534 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2535 if (IS_FLOAT (roptype))
2536 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2538 ic = newiCode ('+', rop, operandFromLit (size));
2539 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2542 (void) geniCodeAssign (op, result, 0);
2543 if (lvalue || IS_TRUE_SYMOP (op))
2549 /*-----------------------------------------------------------------*/
2550 /* geniCodePostDec - generates code for Post decrement */
2551 /*-----------------------------------------------------------------*/
2553 geniCodePostDec (operand * op)
2557 sym_link *optype = operandType (op);
2559 operand *rv = (IS_ITEMP (op) ?
2560 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2562 sym_link *rvtype = operandType (rv);
2565 /* if this is not an address we have trouble */
2568 werror (E_LVALUE_REQUIRED, "--");
2572 rOp = newiTempOperand (rvtype, 0);
2573 OP_SYMBOL(rOp)->noSpilLoc = 1;
2576 OP_SYMBOL(rv)->noSpilLoc = 1;
2578 geniCodeAssign (rOp, rv, 0);
2580 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2581 if (IS_FLOAT (rvtype))
2582 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2584 ic = newiCode ('-', rv, operandFromLit (size));
2586 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2589 geniCodeAssign (op, result, 0);
2595 /*-----------------------------------------------------------------*/
2596 /* geniCodePreDec - generate code for pre decrement */
2597 /*-----------------------------------------------------------------*/
2599 geniCodePreDec (operand * op, bool lvalue)
2602 sym_link *optype = operandType (op);
2603 operand *rop = (IS_ITEMP (op) ?
2604 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2606 sym_link *roptype = operandType (rop);
2612 werror (E_LVALUE_REQUIRED, "--");
2617 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2618 if (IS_FLOAT (roptype))
2619 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2621 ic = newiCode ('-', rop, operandFromLit (size));
2622 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2625 (void) geniCodeAssign (op, result, 0);
2626 if (lvalue || IS_TRUE_SYMOP (op))
2633 /*-----------------------------------------------------------------*/
2634 /* geniCodeBitwise - gen int code for bitWise operators */
2635 /*-----------------------------------------------------------------*/
2637 geniCodeBitwise (operand * left, operand * right,
2638 int oper, sym_link * resType)
2642 left = geniCodeCast (resType, left, TRUE);
2643 right = geniCodeCast (resType, right, TRUE);
2645 ic = newiCode (oper, left, right);
2646 IC_RESULT (ic) = newiTempOperand (resType, 0);
2649 return IC_RESULT (ic);
2652 /*-----------------------------------------------------------------*/
2653 /* geniCodeAddressOf - gens icode for '&' address of operator */
2654 /*-----------------------------------------------------------------*/
2656 geniCodeAddressOf (operand * op)
2660 sym_link *optype = operandType (op);
2661 sym_link *opetype = getSpec (optype);
2663 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2665 op = operandFromOperand (op);
2670 /* lvalue check already done in decorateType */
2671 /* this must be a lvalue */
2672 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2673 /* werror (E_LVALUE_REQUIRED,"&"); */
2677 p = newLink (DECLARATOR);
2679 /* set the pointer depending on the storage class */
2680 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2682 p->next = copyLinkChain (optype);
2684 /* if already a temp */
2687 setOperandType (op, p);
2692 /* other wise make this of the type coming in */
2693 ic = newiCode (ADDRESS_OF, op, NULL);
2694 IC_RESULT (ic) = newiTempOperand (p, 1);
2695 IC_RESULT (ic)->isaddr = 0;
2697 return IC_RESULT (ic);
2699 /*-----------------------------------------------------------------*/
2700 /* setOClass - sets the output class depending on the pointer type */
2701 /*-----------------------------------------------------------------*/
2703 setOClass (sym_link * ptr, sym_link * spec)
2705 switch (DCL_TYPE (ptr))
2708 SPEC_OCLS (spec) = data;
2712 SPEC_OCLS (spec) = generic;
2716 SPEC_OCLS (spec) = xdata;
2720 SPEC_OCLS (spec) = code;
2724 SPEC_OCLS (spec) = idata;
2728 SPEC_OCLS (spec) = xstack;
2732 SPEC_OCLS (spec) = eeprom;
2741 /*-----------------------------------------------------------------*/
2742 /* geniCodeDerefPtr - dereference pointer with '*' */
2743 /*-----------------------------------------------------------------*/
2745 geniCodeDerefPtr (operand * op,int lvl)
2747 sym_link *rtype, *retype;
2748 sym_link *optype = operandType (op);
2750 // if this is an array then array access
2751 if (IS_ARRAY (optype)) {
2752 // don't worry, this will be optimized out later
2753 return geniCodeArray (op, operandFromLit (0), lvl);
2756 // just in case someone screws up
2757 wassert (IS_PTR (optype));
2759 if (IS_TRUE_SYMOP (op))
2762 op = geniCodeRValue (op, TRUE);
2765 /* now get rid of the pointer part */
2766 if (isLvaluereq(lvl) && IS_ITEMP (op))
2768 retype = getSpec (rtype = copyLinkChain (optype));
2772 retype = getSpec (rtype = copyLinkChain (optype->next));
2773 /* outputclass needs 2b updated */
2774 setOClass (optype, retype);
2777 op->isGptr = IS_GENPTR (optype);
2779 op->isaddr = (IS_PTR (rtype) ||
2780 IS_STRUCT (rtype) ||
2785 if (!isLvaluereq(lvl))
2786 op = geniCodeRValue (op, TRUE);
2788 setOperandType (op, rtype);
2793 /*-----------------------------------------------------------------*/
2794 /* geniCodeUnaryMinus - does a unary minus of the operand */
2795 /*-----------------------------------------------------------------*/
2797 geniCodeUnaryMinus (operand * op)
2800 sym_link *optype = operandType (op);
2802 if (IS_LITERAL (optype))
2803 return operandFromLit (-floatFromVal (op->operand.valOperand));
2805 ic = newiCode (UNARYMINUS, op, NULL);
2806 IC_RESULT (ic) = newiTempOperand (optype, 0);
2808 return IC_RESULT (ic);
2811 /*-----------------------------------------------------------------*/
2812 /* geniCodeLeftShift - gen i code for left shift */
2813 /*-----------------------------------------------------------------*/
2815 geniCodeLeftShift (operand * left, operand * right)
2819 ic = newiCode (LEFT_OP, left, right);
2820 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2822 return IC_RESULT (ic);
2825 /*-----------------------------------------------------------------*/
2826 /* geniCodeRightShift - gen i code for right shift */
2827 /*-----------------------------------------------------------------*/
2829 geniCodeRightShift (operand * left, operand * right)
2833 ic = newiCode (RIGHT_OP, left, right);
2834 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2836 return IC_RESULT (ic);
2839 /*-----------------------------------------------------------------*/
2840 /* geniCodeLogic- logic code */
2841 /*-----------------------------------------------------------------*/
2843 geniCodeLogic (operand * left, operand * right, int op)
2847 sym_link *rtype = operandType (right);
2848 sym_link *ltype = operandType (left);
2850 /* left is integral type and right is literal then
2851 check if the literal value is within bounds */
2852 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2854 checkConstantRange(ltype,
2855 OP_VALUE(right), "compare operation", 1);
2858 /* if one operand is a pointer and the other is a literal generic void pointer,
2859 change the type of the literal generic void pointer to match the other pointer */
2860 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2861 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2863 /* find left's definition */
2864 ic = (iCode *) setFirstItem (iCodeChain);
2867 if (((ic->op == CAST) || (ic->op == '='))
2868 && isOperandEqual(left, IC_RESULT (ic)))
2871 ic = setNextItem (iCodeChain);
2873 /* if casting literal to generic pointer, then cast to rtype instead */
2874 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2876 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2877 ltype = operandType(left);
2880 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2881 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2883 /* find right's definition */
2884 ic = (iCode *) setFirstItem (iCodeChain);
2887 if (((ic->op == CAST) || (ic->op == '='))
2888 && isOperandEqual(right, IC_RESULT (ic)))
2891 ic = setNextItem (iCodeChain);
2893 /* if casting literal to generic pointer, then cast to rtype instead */
2894 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2896 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2897 rtype = operandType(right);
2901 ctype = usualBinaryConversions (&left, &right, FALSE, ' ');
2903 ic = newiCode (op, left, right);
2904 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2906 /* if comparing float
2907 and not a '==' || '!=' || '&&' || '||' (these
2909 if (IS_FLOAT(ctype) &&
2917 return IC_RESULT (ic);
2920 /*-----------------------------------------------------------------*/
2921 /* geniCodeUnary - for a a generic unary operation */
2922 /*-----------------------------------------------------------------*/
2924 geniCodeUnary (operand * op, int oper)
2926 iCode *ic = newiCode (oper, op, NULL);
2928 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2930 return IC_RESULT (ic);
2933 /*-----------------------------------------------------------------*/
2934 /* geniCodeConditional - geniCode for '?' ':' operation */
2935 /*-----------------------------------------------------------------*/
2937 geniCodeConditional (ast * tree,int lvl)
2940 symbol *falseLabel = newiTempLabel (NULL);
2941 symbol *exitLabel = newiTempLabel (NULL);
2942 operand *cond = ast2iCode (tree->left,lvl+1);
2943 operand *true, *false, *result;
2945 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2949 true = ast2iCode (tree->right->left,lvl+1);
2951 /* move the value to a new Operand */
2952 result = newiTempOperand (tree->right->ftype, 0);
2953 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2955 /* generate an unconditional goto */
2956 geniCodeGoto (exitLabel);
2958 /* now for the right side */
2959 geniCodeLabel (falseLabel);
2961 false = ast2iCode (tree->right->right,lvl+1);
2962 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2964 /* create the exit label */
2965 geniCodeLabel (exitLabel);
2970 /*-----------------------------------------------------------------*/
2971 /* geniCodeAssign - generate code for assignment */
2972 /*-----------------------------------------------------------------*/
2974 geniCodeAssign (operand * left, operand * right, int nosupdate)
2977 sym_link *ltype = operandType (left);
2978 sym_link *rtype = operandType (right);
2980 if (!left->isaddr && !IS_ITEMP (left))
2982 werror (E_LVALUE_REQUIRED, "assignment");
2986 /* left is integral type and right is literal then
2987 check if the literal value is within bounds */
2988 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2990 checkConstantRange(ltype,
2991 OP_VALUE(right), "= operation", 0);
2994 /* if the left & right type don't exactly match */
2995 /* if pointer set then make sure the check is
2996 done with the type & not the pointer */
2997 /* then cast rights type to left */
2999 /* first check the type for pointer assignement */
3000 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3001 compareType (ltype, rtype) <= 0)
3003 if (compareType (ltype->next, rtype) < 0)
3004 right = geniCodeCast (ltype->next, right, TRUE);
3006 else if (compareType (ltype, rtype) < 0)
3007 right = geniCodeCast (ltype, right, TRUE);
3009 /* If left is a true symbol & ! volatile
3010 create an assignment to temporary for
3011 the right & then assign this temporary
3012 to the symbol. This is SSA (static single
3013 assignment). Isn't it simple and folks have
3014 published mountains of paper on it */
3015 if (IS_TRUE_SYMOP (left) &&
3016 !isOperandVolatile (left, FALSE) &&
3017 isOperandGlobal (left))
3021 if (IS_TRUE_SYMOP (right))
3022 sym = OP_SYMBOL (right);
3023 ic = newiCode ('=', NULL, right);
3024 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3025 SPIL_LOC (right) = sym;
3029 ic = newiCode ('=', NULL, right);
3030 IC_RESULT (ic) = left;
3033 /* if left isgptr flag is set then support
3034 routine will be required */
3038 ic->nosupdate = nosupdate;
3042 /*-----------------------------------------------------------------*/
3043 /* geniCodeDummyRead - generate code for dummy read */
3044 /*-----------------------------------------------------------------*/
3046 geniCodeDummyRead (operand * op)
3049 sym_link *type = operandType (op);
3051 if (!IS_VOLATILE(type))
3054 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3060 /*-----------------------------------------------------------------*/
3061 /* geniCodeSEParms - generate code for side effecting fcalls */
3062 /*-----------------------------------------------------------------*/
3064 geniCodeSEParms (ast * parms,int lvl)
3069 if (parms->type == EX_OP && parms->opval.op == PARAM)
3071 geniCodeSEParms (parms->left,lvl);
3072 geniCodeSEParms (parms->right,lvl);
3076 /* hack don't like this but too lazy to think of
3078 if (IS_ADDRESS_OF_OP (parms))
3079 parms->left->lvalue = 1;
3081 if (IS_CAST_OP (parms) &&
3082 IS_PTR (parms->ftype) &&
3083 IS_ADDRESS_OF_OP (parms->right))
3084 parms->right->left->lvalue = 1;
3086 parms->opval.oprnd =
3087 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3089 parms->type = EX_OPERAND;
3090 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3091 SPEC_ARGREG(parms->ftype);
3094 /*-----------------------------------------------------------------*/
3095 /* geniCodeParms - generates parameters */
3096 /*-----------------------------------------------------------------*/
3098 geniCodeParms (ast * parms, value *argVals, int *stack,
3099 sym_link * ftype, int lvl)
3107 if (argVals==NULL) {
3109 argVals = FUNC_ARGS (ftype);
3112 /* if this is a param node then do the left & right */
3113 if (parms->type == EX_OP && parms->opval.op == PARAM)
3115 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3116 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3120 /* get the parameter value */
3121 if (parms->type == EX_OPERAND)
3122 pval = parms->opval.oprnd;
3125 /* maybe this else should go away ?? */
3126 /* hack don't like this but too lazy to think of
3128 if (IS_ADDRESS_OF_OP (parms))
3129 parms->left->lvalue = 1;
3131 if (IS_CAST_OP (parms) &&
3132 IS_PTR (parms->ftype) &&
3133 IS_ADDRESS_OF_OP (parms->right))
3134 parms->right->left->lvalue = 1;
3136 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3139 /* if register parm then make it a send */
3140 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3141 IFFUNC_ISBUILTIN(ftype))
3143 ic = newiCode (SEND, pval, NULL);
3144 ic->argreg = SPEC_ARGREG(parms->etype);
3145 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3150 /* now decide whether to push or assign */
3151 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3155 operand *top = operandFromSymbol (argVals->sym);
3156 /* clear useDef and other bitVectors */
3157 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3158 geniCodeAssign (top, pval, 1);
3162 sym_link *p = operandType (pval);
3164 ic = newiCode (IPUSH, pval, NULL);
3166 /* update the stack adjustment */
3167 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3172 argVals=argVals->next;
3176 /*-----------------------------------------------------------------*/
3177 /* geniCodeCall - generates temp code for calling */
3178 /*-----------------------------------------------------------------*/
3180 geniCodeCall (operand * left, ast * parms,int lvl)
3184 sym_link *type, *etype;
3188 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3189 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3190 werror (E_FUNCTION_EXPECTED);
3191 return operandFromValue(valueFromLit(0));
3194 /* take care of parameters with side-effecting
3195 function calls in them, this is required to take care
3196 of overlaying function parameters */
3197 geniCodeSEParms (parms,lvl);
3199 ftype = operandType (left);
3200 if (IS_CODEPTR (ftype))
3201 ftype = ftype->next;
3203 /* first the parameters */
3204 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3206 /* now call : if symbol then pcall */
3207 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3208 ic = newiCode (PCALL, left, NULL);
3210 ic = newiCode (CALL, left, NULL);
3213 type = copyLinkChain (ftype->next);
3214 etype = getSpec (type);
3215 SPEC_EXTR (etype) = 0;
3216 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3220 /* stack adjustment after call */
3221 ic->parmBytes = stack;
3226 /*-----------------------------------------------------------------*/
3227 /* geniCodeReceive - generate intermediate code for "receive" */
3228 /*-----------------------------------------------------------------*/
3230 geniCodeReceive (value * args)
3232 /* for all arguments that are passed in registers */
3236 if (IS_REGPARM (args->etype))
3238 operand *opr = operandFromValue (args);
3240 symbol *sym = OP_SYMBOL (opr);
3243 /* we will use it after all optimizations
3244 and before liveRange calculation */
3245 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3248 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3249 options.stackAuto == 0 &&
3250 (!(options.model == MODEL_FLAT24)) )
3255 opl = newiTempOperand (args->type, 0);
3257 sym->reqv->key = sym->key;
3258 OP_SYMBOL (sym->reqv)->key = sym->key;
3259 OP_SYMBOL (sym->reqv)->isreqv = 1;
3260 OP_SYMBOL (sym->reqv)->islocal = 0;
3261 SPIL_LOC (sym->reqv) = sym;
3265 ic = newiCode (RECEIVE, NULL, NULL);
3266 ic->argreg = SPEC_ARGREG(args->etype);
3268 currFunc->recvSize = getSize (sym->type);
3271 IC_RESULT (ic) = opr;
3279 /*-----------------------------------------------------------------*/
3280 /* geniCodeFunctionBody - create the function body */
3281 /*-----------------------------------------------------------------*/
3283 geniCodeFunctionBody (ast * tree,int lvl)
3290 /* reset the auto generation */
3296 func = ast2iCode (tree->left,lvl+1);
3297 fetype = getSpec (operandType (func));
3299 savelineno = lineno;
3300 lineno = OP_SYMBOL (func)->lineDef;
3301 /* create an entry label */
3302 geniCodeLabel (entryLabel);
3303 lineno = savelineno;
3305 /* create a proc icode */
3306 ic = newiCode (FUNCTION, func, NULL);
3307 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3311 /* for all parameters that are passed
3312 on registers add a "receive" */
3313 geniCodeReceive (tree->values.args);
3315 /* generate code for the body */
3316 ast2iCode (tree->right,lvl+1);
3318 /* create a label for return */
3319 geniCodeLabel (returnLabel);
3321 /* now generate the end proc */
3322 ic = newiCode (ENDFUNCTION, func, NULL);
3327 /*-----------------------------------------------------------------*/
3328 /* geniCodeReturn - gen icode for 'return' statement */
3329 /*-----------------------------------------------------------------*/
3331 geniCodeReturn (operand * op)
3335 /* if the operand is present force an rvalue */
3337 op = geniCodeRValue (op, FALSE);
3339 ic = newiCode (RETURN, op, NULL);
3343 /*-----------------------------------------------------------------*/
3344 /* geniCodeIfx - generates code for extended if statement */
3345 /*-----------------------------------------------------------------*/
3347 geniCodeIfx (ast * tree,int lvl)
3350 operand *condition = ast2iCode (tree->left,lvl+1);
3353 /* if condition is null then exit */
3357 condition = geniCodeRValue (condition, FALSE);
3359 cetype = getSpec (operandType (condition));
3360 /* if the condition is a literal */
3361 if (IS_LITERAL (cetype))
3363 if (floatFromVal (condition->operand.valOperand))
3365 if (tree->trueLabel)
3366 geniCodeGoto (tree->trueLabel);
3372 if (tree->falseLabel)
3373 geniCodeGoto (tree->falseLabel);
3380 if (tree->trueLabel)
3382 ic = newiCodeCondition (condition,
3387 if (tree->falseLabel)
3388 geniCodeGoto (tree->falseLabel);
3392 ic = newiCodeCondition (condition,
3399 ast2iCode (tree->right,lvl+1);
3402 /*-----------------------------------------------------------------*/
3403 /* geniCodeJumpTable - tries to create a jump table for switch */
3404 /*-----------------------------------------------------------------*/
3406 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3408 int min = 0, max = 0, t, cnt = 0;
3414 int needRangeCheck = !optimize.noJTabBoundary
3415 || tree->values.switchVals.swDefault;
3417 if (!tree || !caseVals)
3420 /* the criteria for creating a jump table is */
3421 /* all integer numbers between the maximum & minimum must */
3422 /* be present , the maximum value should not exceed 255 */
3423 min = max = (int) floatFromVal (vch = caseVals);
3424 SNPRINTF (buffer, sizeof(buffer),
3426 tree->values.switchVals.swNum,
3428 addSet (&labels, newiTempLabel (buffer));
3430 /* if there is only one case value then no need */
3431 if (!(vch = vch->next))
3436 if (((t = (int) floatFromVal (vch)) - max) != 1)
3438 SNPRINTF (buffer, sizeof(buffer),
3440 tree->values.switchVals.swNum,
3442 addSet (&labels, newiTempLabel (buffer));
3448 /* if the number of case statements <= 2 then */
3449 /* it is not economical to create the jump table */
3450 /* since two compares are needed for boundary conditions */
3451 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3454 if (tree->values.switchVals.swDefault)
3456 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3460 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3464 falseLabel = newiTempLabel (buffer);
3466 /* so we can create a jumptable */
3467 /* first we rule out the boundary conditions */
3468 /* if only optimization says so */
3471 sym_link *cetype = getSpec (operandType (cond));
3472 /* no need to check the lower bound if
3473 the condition is unsigned & minimum value is zero */
3474 if (!(min == 0 && IS_UNSIGNED (cetype)))
3476 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3477 ic = newiCodeCondition (boundary, falseLabel, NULL);
3481 /* now for upper bounds */
3482 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3483 ic = newiCodeCondition (boundary, falseLabel, NULL);
3487 /* if the min is not zero then we no make it zero */
3490 cond = geniCodeSubtract (cond, operandFromLit (min));
3491 if (!IS_LITERAL(getSpec(operandType(cond))))
3492 setOperandType (cond, UCHARTYPE);
3495 /* now create the jumptable */
3496 ic = newiCode (JUMPTABLE, NULL, NULL);
3497 IC_JTCOND (ic) = cond;
3498 IC_JTLABELS (ic) = labels;
3503 /*-----------------------------------------------------------------*/
3504 /* geniCodeSwitch - changes a switch to a if statement */
3505 /*-----------------------------------------------------------------*/
3507 geniCodeSwitch (ast * tree,int lvl)
3510 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3511 value *caseVals = tree->values.switchVals.swVals;
3512 symbol *trueLabel, *falseLabel;
3514 /* If the condition is a literal, then just jump to the */
3515 /* appropriate case label. */
3516 if (IS_LITERAL(getSpec(operandType(cond))))
3518 int switchVal, caseVal;
3520 switchVal = (int) floatFromVal (cond->operand.valOperand);
3523 caseVal = (int) floatFromVal (caseVals);
3524 if (caseVal == switchVal)
3526 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3527 tree->values.switchVals.swNum, caseVal);
3528 trueLabel = newiTempLabel (buffer);
3529 geniCodeGoto (trueLabel);
3532 caseVals = caseVals->next;
3534 goto defaultOrBreak;
3537 /* if we can make this a jump table */
3538 if (geniCodeJumpTable (cond, caseVals, tree))
3539 goto jumpTable; /* no need for the comparison */
3541 /* for the cases defined do */
3545 operand *compare = geniCodeLogic (cond,
3546 operandFromValue (caseVals),
3549 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3550 tree->values.switchVals.swNum,
3551 (int) floatFromVal (caseVals));
3552 trueLabel = newiTempLabel (buffer);
3554 ic = newiCodeCondition (compare, trueLabel, NULL);
3556 caseVals = caseVals->next;
3561 /* if default is present then goto break else break */
3562 if (tree->values.switchVals.swDefault)
3564 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3568 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3571 falseLabel = newiTempLabel (buffer);
3572 geniCodeGoto (falseLabel);
3575 ast2iCode (tree->right,lvl+1);
3578 /*-----------------------------------------------------------------*/
3579 /* geniCodeInline - intermediate code for inline assembler */
3580 /*-----------------------------------------------------------------*/
3582 geniCodeInline (ast * tree)
3586 ic = newiCode (INLINEASM, NULL, NULL);
3587 IC_INLINE (ic) = tree->values.inlineasm;
3591 /*-----------------------------------------------------------------*/
3592 /* geniCodeArrayInit - intermediate code for array initializer */
3593 /*-----------------------------------------------------------------*/
3595 geniCodeArrayInit (ast * tree, operand *array)
3599 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3600 ic = newiCode (ARRAYINIT, array, NULL);
3601 IC_ARRAYILIST (ic) = tree->values.constlist;
3603 operand *left=newOperand(), *right=newOperand();
3604 left->type=right->type=SYMBOL;
3605 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3606 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3607 ic = newiCode (ARRAYINIT, left, right);
3612 /*-----------------------------------------------------------------*/
3613 /* geniCodeCritical - intermediate code for a critical statement */
3614 /*-----------------------------------------------------------------*/
3616 geniCodeCritical (ast *tree, int lvl)
3621 /* If op is NULL, the original interrupt state will saved on */
3622 /* the stack. Otherwise, it will be saved in op. */
3624 /* Generate a save of the current interrupt state & disabled */
3625 ic = newiCode (CRITICAL, NULL, NULL);
3626 IC_RESULT (ic) = op;
3629 /* Generate the critical code sequence */
3630 if (tree->left && tree->left->type == EX_VALUE)
3631 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3633 ast2iCode (tree->left,lvl+1);
3635 /* Generate a restore of the original interrupt state */
3636 ic = newiCode (ENDCRITICAL, NULL, op);
3640 /*-----------------------------------------------------------------*/
3641 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3642 /* particular case. Ie : assigning or dereferencing array or ptr */
3643 /*-----------------------------------------------------------------*/
3644 set * lvaluereqSet = NULL;
3645 typedef struct lvalItem
3652 /*-----------------------------------------------------------------*/
3653 /* addLvaluereq - add a flag for lvalreq for current ast level */
3654 /*-----------------------------------------------------------------*/
3655 void addLvaluereq(int lvl)
3657 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3660 addSetHead(&lvaluereqSet,lpItem);
3663 /*-----------------------------------------------------------------*/
3664 /* delLvaluereq - del a flag for lvalreq for current ast level */
3665 /*-----------------------------------------------------------------*/
3669 lpItem = getSet(&lvaluereqSet);
3670 if(lpItem) Safe_free(lpItem);
3672 /*-----------------------------------------------------------------*/
3673 /* clearLvaluereq - clear lvalreq flag */
3674 /*-----------------------------------------------------------------*/
3675 void clearLvaluereq()
3678 lpItem = peekSet(lvaluereqSet);
3679 if(lpItem) lpItem->req = 0;
3681 /*-----------------------------------------------------------------*/
3682 /* getLvaluereq - get the last lvalreq level */
3683 /*-----------------------------------------------------------------*/
3684 int getLvaluereqLvl()
3687 lpItem = peekSet(lvaluereqSet);
3688 if(lpItem) return lpItem->lvl;
3691 /*-----------------------------------------------------------------*/
3692 /* isLvaluereq - is lvalreq valid for this level ? */
3693 /*-----------------------------------------------------------------*/
3694 int isLvaluereq(int lvl)
3697 lpItem = peekSet(lvaluereqSet);
3698 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3702 /*-----------------------------------------------------------------*/
3703 /* ast2iCode - creates an icodeList from an ast */
3704 /*-----------------------------------------------------------------*/
3706 ast2iCode (ast * tree,int lvl)
3708 operand *left = NULL;
3709 operand *right = NULL;
3713 /* set the global variables for filename & line number */
3715 filename = tree->filename;
3717 lineno = tree->lineno;
3719 block = tree->block;
3721 scopeLevel = tree->level;
3723 seqPoint = tree->seqPoint;
3725 if (tree->type == EX_VALUE)
3726 return operandFromValue (tree->opval.val);
3728 if (tree->type == EX_LINK)
3729 return operandFromLink (tree->opval.lnk);
3731 /* if we find a nullop */
3732 if (tree->type == EX_OP &&
3733 (tree->opval.op == NULLOP ||
3734 tree->opval.op == BLOCK))
3736 if (tree->left && tree->left->type == EX_VALUE)
3737 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3739 ast2iCode (tree->left,lvl+1);
3740 if (tree->right && tree->right->type == EX_VALUE)
3741 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3743 ast2iCode (tree->right,lvl+1);
3747 /* special cases for not evaluating */
3748 if (tree->opval.op != ':' &&
3749 tree->opval.op != '?' &&
3750 tree->opval.op != CALL &&
3751 tree->opval.op != IFX &&
3752 tree->opval.op != LABEL &&
3753 tree->opval.op != GOTO &&
3754 tree->opval.op != SWITCH &&
3755 tree->opval.op != FUNCTION &&
3756 tree->opval.op != INLINEASM &&
3757 tree->opval.op != CRITICAL)
3760 if (IS_ASSIGN_OP (tree->opval.op) ||
3761 IS_DEREF_OP (tree) ||
3762 (tree->opval.op == '&' && !tree->right) ||
3763 tree->opval.op == PTR_OP)
3766 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3767 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3770 left = operandFromAst (tree->left,lvl);
3772 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3773 left = geniCodeRValue (left, TRUE);
3777 left = operandFromAst (tree->left,lvl);
3779 if (tree->opval.op == INC_OP ||
3780 tree->opval.op == DEC_OP)
3783 right = operandFromAst (tree->right,lvl);
3788 right = operandFromAst (tree->right,lvl);
3792 /* now depending on the type of operand */
3793 /* this will be a biggy */
3794 switch (tree->opval.op)
3797 case '[': /* array operation */
3799 //sym_link *ltype = operandType (left);
3800 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3801 left = geniCodeRValue (left, FALSE);
3802 right = geniCodeRValue (right, TRUE);
3805 return geniCodeArray (left, right,lvl);
3807 case '.': /* structure dereference */
3808 if (IS_PTR (operandType (left)))
3809 left = geniCodeRValue (left, TRUE);
3811 left = geniCodeRValue (left, FALSE);
3813 return geniCodeStruct (left, right, tree->lvalue);
3815 case PTR_OP: /* structure pointer dereference */
3818 pType = operandType (left);
3819 left = geniCodeRValue (left, TRUE);
3821 setOClass (pType, getSpec (operandType (left)));
3824 return geniCodeStruct (left, right, tree->lvalue);
3826 case INC_OP: /* increment operator */
3828 return geniCodePostInc (left);
3830 return geniCodePreInc (right, tree->lvalue);
3832 case DEC_OP: /* decrement operator */
3834 return geniCodePostDec (left);
3836 return geniCodePreDec (right, tree->lvalue);
3838 case '&': /* bitwise and or address of operator */
3840 { /* this is a bitwise operator */
3841 left = geniCodeRValue (left, FALSE);
3842 right = geniCodeRValue (right, FALSE);
3843 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3846 return geniCodeAddressOf (left);
3848 case '|': /* bitwise or & xor */
3850 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3851 geniCodeRValue (right, FALSE),
3856 return geniCodeDivision (geniCodeRValue (left, FALSE),
3857 geniCodeRValue (right, FALSE),
3858 IS_INT (tree->ftype));
3861 return geniCodeModulus (geniCodeRValue (left, FALSE),
3862 geniCodeRValue (right, FALSE),
3863 IS_INT (tree->ftype));
3866 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3867 geniCodeRValue (right, FALSE),
3868 IS_INT (tree->ftype));
3870 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3874 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3875 geniCodeRValue (right, FALSE));
3877 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3881 return geniCodeAdd (geniCodeRValue (left, FALSE),
3882 geniCodeRValue (right, FALSE),lvl);
3884 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3887 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3888 geniCodeRValue (right, FALSE));
3891 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3892 geniCodeRValue (right, FALSE));
3894 #if 0 // this indeed needs a second thought
3898 // let's keep this simple: get the rvalue we need
3899 op=geniCodeRValue (right, FALSE);
3900 // now cast it to whatever we want
3901 op=geniCodeCast (operandType(left), op, FALSE);
3902 // if this is going to be used as an lvalue, make it so
3908 #else // bug #604575, is it a bug ????
3909 return geniCodeCast (operandType (left),
3910 geniCodeRValue (right, FALSE), FALSE);
3917 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3922 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3923 setOperandType (op, UCHARTYPE);
3934 /* different compilers (even different gccs) evaluate
3935 the two calls in a different order. to get the same
3936 result on all machines we've to specify a clear sequence.
3937 return geniCodeLogic (geniCodeRValue (left, FALSE),
3938 geniCodeRValue (right, FALSE),
3942 operand *leftOp, *rightOp;
3944 rightOp = geniCodeRValue (right, FALSE);
3945 leftOp = geniCodeRValue (left , FALSE);
3947 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3950 return geniCodeConditional (tree,lvl);
3953 return operandFromLit (getSize (tree->right->ftype));
3957 sym_link *rtype = operandType (right);
3958 sym_link *ltype = operandType (left);
3959 if (IS_PTR (rtype) && IS_ITEMP (right)
3960 && right->isaddr && compareType (rtype->next, ltype) == 1)
3961 right = geniCodeRValue (right, TRUE);
3963 right = geniCodeRValue (right, FALSE);
3965 geniCodeAssign (left, right, 0);
3970 geniCodeAssign (left,
3971 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3973 geniCodeRValue (right, FALSE),FALSE), 0);
3977 geniCodeAssign (left,
3978 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3980 geniCodeRValue (right, FALSE),
3981 IS_INT (tree->ftype)),
3985 geniCodeAssign (left,
3986 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3988 geniCodeRValue (right, FALSE),
3989 IS_INT (tree->ftype)),
3993 sym_link *rtype = operandType (right);
3994 sym_link *ltype = operandType (left);
3995 if (IS_PTR (rtype) && IS_ITEMP (right)
3996 && right->isaddr && compareType (rtype->next, ltype) == 1)
3997 right = geniCodeRValue (right, TRUE);
3999 right = geniCodeRValue (right, FALSE);
4002 return geniCodeAssign (left,
4003 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4009 sym_link *rtype = operandType (right);
4010 sym_link *ltype = operandType (left);
4011 if (IS_PTR (rtype) && IS_ITEMP (right)
4012 && right->isaddr && compareType (rtype->next, ltype) == 1)
4014 right = geniCodeRValue (right, TRUE);
4018 right = geniCodeRValue (right, FALSE);
4021 geniCodeAssign (left,
4022 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4028 geniCodeAssign (left,
4029 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4031 geniCodeRValue (right, FALSE)), 0);
4034 geniCodeAssign (left,
4035 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4037 geniCodeRValue (right, FALSE)), 0);
4040 geniCodeAssign (left,
4041 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4043 geniCodeRValue (right, FALSE),
4045 operandType (left)), 0);
4048 geniCodeAssign (left,
4049 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4051 geniCodeRValue (right, FALSE),
4053 operandType (left)), 0);
4056 geniCodeAssign (left,
4057 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4059 geniCodeRValue (right, FALSE),
4061 operandType (left)), 0);
4063 return geniCodeRValue (right, FALSE);
4066 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4069 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4070 return ast2iCode (tree->right,lvl+1);
4073 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4074 return ast2iCode (tree->right,lvl+1);
4077 geniCodeFunctionBody (tree,lvl);
4081 geniCodeReturn (right);
4085 geniCodeIfx (tree,lvl);
4089 geniCodeSwitch (tree,lvl);
4093 geniCodeInline (tree);
4097 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4101 geniCodeCritical (tree, lvl);
4107 /*-----------------------------------------------------------------*/
4108 /* reverseICChain - gets from the list and creates a linkedlist */
4109 /*-----------------------------------------------------------------*/
4116 while ((loop = getSet (&iCodeChain)))
4128 /*-----------------------------------------------------------------*/
4129 /* iCodeFromAst - given an ast will convert it to iCode */
4130 /*-----------------------------------------------------------------*/
4132 iCodeFromAst (ast * tree)
4134 returnLabel = newiTempLabel ("_return");
4135 entryLabel = newiTempLabel ("_entry");
4137 return reverseiCChain ();
4140 static const char *opTypeToStr(OPTYPE op)
4144 case SYMBOL: return "symbol";
4145 case VALUE: return "value";
4146 case TYPE: return "type";
4148 return "undefined type";
4152 operand *validateOpType(operand *op,
4159 if (op && op->type == type)
4164 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4165 " expected %s, got %s\n",
4166 macro, args, file, line,
4167 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4169 return op; // never reached, makes compiler happy.