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 if (IS_FLOAT (let) ||
1225 retval = operandFromLit (operandLitValue (left) ==
1226 operandLitValue (right));
1230 /* this op doesn't care about signedness */
1233 l = (TYPE_UDWORD) operandLitValue (left);
1234 r = (TYPE_UDWORD) operandLitValue (right);
1235 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1236 neccessary to strip them to 16 bit.
1237 Literals are reduced to their cheapest type, therefore left and
1238 right might have different types. It's neccessary to find a
1239 common type: int (used for char too) or long */
1240 if (!IS_LONG (let) &&
1246 retval = operandFromLit (l == r);
1250 retval = operandFromLit (operandLitValue (left) <
1251 operandLitValue (right));
1254 retval = operandFromLit (operandLitValue (left) <=
1255 operandLitValue (right));
1258 retval = operandFromLit (operandLitValue (left) !=
1259 operandLitValue (right));
1262 retval = operandFromLit (operandLitValue (left) >
1263 operandLitValue (right));
1266 retval = operandFromLit (operandLitValue (left) >=
1267 operandLitValue (right));
1270 retval = operandFromValue (valCastLiteral (type,
1271 (TYPE_UDWORD)operandLitValue(left) &
1272 (TYPE_UDWORD)operandLitValue(right)));
1275 retval = operandFromValue (valCastLiteral (type,
1276 (TYPE_UDWORD)operandLitValue(left) |
1277 (TYPE_UDWORD)operandLitValue(right)));
1280 retval = operandFromValue (valCastLiteral (type,
1281 (TYPE_UDWORD)operandLitValue(left) ^
1282 (TYPE_UDWORD)operandLitValue(right)));
1285 retval = operandFromLit (operandLitValue (left) &&
1286 operandLitValue (right));
1289 retval = operandFromLit (operandLitValue (left) ||
1290 operandLitValue (right));
1294 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1296 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1302 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1304 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1310 retval = operandFromValue (valCastLiteral (type,
1311 -1 * operandLitValue (left)));
1315 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1319 retval = operandFromLit (!operandLitValue (left));
1323 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1324 " operandOperation invalid operator ");
1332 /*-----------------------------------------------------------------*/
1333 /* isOperandEqual - compares two operand & return 1 if they r = */
1334 /*-----------------------------------------------------------------*/
1336 isOperandEqual (operand * left, operand * right)
1338 /* if the pointers are equal then they are equal */
1342 /* if either of them null then false */
1343 if (!left || !right)
1346 if (left->type != right->type)
1349 if (IS_SYMOP (left) && IS_SYMOP (right))
1350 return left->key == right->key;
1352 /* if types are the same */
1356 return isSymbolEqual (left->operand.symOperand,
1357 right->operand.symOperand);
1359 return (floatFromVal (left->operand.valOperand) ==
1360 floatFromVal (right->operand.valOperand));
1362 if (compareType (left->operand.typeOperand,
1363 right->operand.typeOperand) == 1)
1370 /*-------------------------------------------------------------------*/
1371 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1372 /*-------------------------------------------------------------------*/
1374 isiCodeEqual (iCode * left, iCode * right)
1376 /* if the same pointer */
1380 /* if either of them null */
1381 if (!left || !right)
1384 /* if operand are the same */
1385 if (left->op == right->op)
1388 /* compare all the elements depending on type */
1389 if (left->op != IFX)
1391 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1393 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1399 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1401 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1403 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1412 /*-----------------------------------------------------------------*/
1413 /* newiTempFromOp - create a temp Operand with same attributes */
1414 /*-----------------------------------------------------------------*/
1416 newiTempFromOp (operand * op)
1426 nop = newiTempOperand (operandType (op), TRUE);
1427 nop->isaddr = op->isaddr;
1428 nop->isvolatile = op->isvolatile;
1429 nop->isGlobal = op->isGlobal;
1430 nop->isLiteral = op->isLiteral;
1431 nop->usesDefs = op->usesDefs;
1432 nop->isParm = op->isParm;
1436 /*-----------------------------------------------------------------*/
1437 /* operand from operand - creates an operand holder for the type */
1438 /*-----------------------------------------------------------------*/
1440 operandFromOperand (operand * op)
1446 nop = newOperand ();
1447 nop->type = op->type;
1448 nop->isaddr = op->isaddr;
1450 nop->isvolatile = op->isvolatile;
1451 nop->isGlobal = op->isGlobal;
1452 nop->isLiteral = op->isLiteral;
1453 nop->usesDefs = op->usesDefs;
1454 nop->isParm = op->isParm;
1459 nop->operand.symOperand = op->operand.symOperand;
1462 nop->operand.valOperand = op->operand.valOperand;
1465 nop->operand.typeOperand = op->operand.typeOperand;
1472 /*-----------------------------------------------------------------*/
1473 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1474 /*-----------------------------------------------------------------*/
1476 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1478 operand *nop = operandFromOperand (op);
1480 if (nop->type == SYMBOL)
1482 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1483 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1489 /*-----------------------------------------------------------------*/
1490 /* operandFromSymbol - creates an operand from a symbol */
1491 /*-----------------------------------------------------------------*/
1493 operandFromSymbol (symbol * sym)
1498 /* if the symbol's type is a literal */
1499 /* then it is an enumerator type */
1500 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1501 return operandFromValue (valFromType (sym->etype));
1504 sym->key = ++operandKey;
1506 /* if this an implicit variable, means struct/union */
1507 /* member so just return it */
1508 if (sym->implicit || IS_FUNC (sym->type))
1512 op->operand.symOperand = sym;
1514 op->isvolatile = isOperandVolatile (op, TRUE);
1515 op->isGlobal = isOperandGlobal (op);
1519 /* under the following conditions create a
1520 register equivalent for a local symbol */
1521 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1522 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1524 (!(options.model == MODEL_FLAT24)) ) &&
1525 options.stackAuto == 0)
1528 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1529 !IS_FUNC (sym->type) && /* not a function */
1530 !sym->_isparm && /* not a parameter */
1531 sym->level && /* is a local variable */
1532 !sym->addrtaken && /* whose address has not been taken */
1533 !sym->reqv && /* does not already have a reg equivalence */
1534 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1535 !IS_STATIC (sym->etype) && /* and not declared static */
1536 !sym->islbl && /* not a label */
1537 ok && /* farspace check */
1538 !IS_BITVAR (sym->etype) /* not a bit variable */
1542 /* we will use it after all optimizations
1543 and before liveRange calculation */
1544 sym->reqv = newiTempOperand (sym->type, 0);
1545 sym->reqv->key = sym->key;
1546 OP_SYMBOL (sym->reqv)->prereqv = sym;
1547 OP_SYMBOL (sym->reqv)->key = sym->key;
1548 OP_SYMBOL (sym->reqv)->isreqv = 1;
1549 OP_SYMBOL (sym->reqv)->islocal = 1;
1550 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1551 SPIL_LOC (sym->reqv) = sym;
1554 if (!IS_AGGREGATE (sym->type))
1558 op->operand.symOperand = sym;
1561 op->isvolatile = isOperandVolatile (op, TRUE);
1562 op->isGlobal = isOperandGlobal (op);
1563 op->isPtr = IS_PTR (operandType (op));
1564 op->isParm = sym->_isparm;
1569 /* itemp = &[_symbol] */
1571 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1572 IC_LEFT (ic)->type = SYMBOL;
1573 IC_LEFT (ic)->operand.symOperand = sym;
1574 IC_LEFT (ic)->key = sym->key;
1575 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1576 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1577 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1580 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1581 if (IS_ARRAY (sym->type))
1583 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1584 IC_RESULT (ic)->isaddr = 0;
1587 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1591 return IC_RESULT (ic);
1594 /*-----------------------------------------------------------------*/
1595 /* operandFromValue - creates an operand from value */
1596 /*-----------------------------------------------------------------*/
1598 operandFromValue (value * val)
1602 /* if this is a symbol then do the symbol thing */
1604 return operandFromSymbol (val->sym);
1606 /* this is not a symbol */
1609 op->operand.valOperand = val;
1610 op->isLiteral = isOperandLiteral (op);
1614 /*-----------------------------------------------------------------*/
1615 /* operandFromLink - operand from typeChain */
1616 /*-----------------------------------------------------------------*/
1618 operandFromLink (sym_link * type)
1622 /* operand from sym_link */
1628 op->operand.typeOperand = copyLinkChain (type);
1632 /*-----------------------------------------------------------------*/
1633 /* operandFromLit - makes an operand from a literal value */
1634 /*-----------------------------------------------------------------*/
1636 operandFromLit (double i)
1638 return operandFromValue (valueFromLit (i));
1641 /*-----------------------------------------------------------------*/
1642 /* operandFromAst - creates an operand from an ast */
1643 /*-----------------------------------------------------------------*/
1645 operandFromAst (ast * tree,int lvl)
1651 /* depending on type do */
1655 return ast2iCode (tree,lvl+1);
1659 return operandFromValue (tree->opval.val);
1663 return operandFromLink (tree->opval.lnk);
1670 /* Just to keep the compiler happy */
1671 return (operand *) 0;
1674 /*-----------------------------------------------------------------*/
1675 /* setOperandType - sets the operand's type to the given type */
1676 /*-----------------------------------------------------------------*/
1678 setOperandType (operand * op, sym_link * type)
1680 /* depending on the type of operand */
1685 op->operand.valOperand->etype =
1686 getSpec (op->operand.valOperand->type =
1687 copyLinkChain (type));
1691 if (op->operand.symOperand->isitmp)
1692 op->operand.symOperand->etype =
1693 getSpec (op->operand.symOperand->type =
1694 copyLinkChain (type));
1696 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1697 "attempt to modify type of source");
1701 op->operand.typeOperand = copyLinkChain (type);
1706 /*-----------------------------------------------------------------*/
1707 /* Get size in byte of ptr need to access an array */
1708 /*-----------------------------------------------------------------*/
1710 getArraySizePtr (operand * op)
1712 sym_link *ltype = operandType(op);
1716 int size = getSize(ltype);
1717 return(IS_GENPTR(ltype)?(size-1):size);
1722 sym_link *letype = getSpec(ltype);
1723 switch (PTR_TYPE (SPEC_OCLS (letype)))
1735 return (GPTRSIZE-1);
1744 /*-----------------------------------------------------------------*/
1745 /* perform "usual unary conversions" */
1746 /*-----------------------------------------------------------------*/
1749 usualUnaryConversions (operand * op)
1751 if (IS_INTEGRAL (operandType (op)))
1753 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1756 return geniCodeCast (INTTYPE, op, TRUE);
1763 /*-----------------------------------------------------------------*/
1764 /* perform "usual binary conversions" */
1765 /*-----------------------------------------------------------------*/
1768 usualBinaryConversions (operand ** op1, operand ** op2,
1769 bool resultIsInt, char op)
1772 sym_link *rtype = operandType (*op2);
1773 sym_link *ltype = operandType (*op1);
1775 #define OLDONEBYTEOPS 1
1777 #ifdef OLDONEBYTEOPS
1778 bool oldOneByteOps = FALSE;
1779 static bool saidHello = FALSE;
1781 if (strcmp (port->target, "pic14") == 0)
1782 oldOneByteOps = TRUE;
1783 if (getenv ("SDCC_NEWONEBYTEOPS"))
1787 fprintf (stderr, "Override: oldOneByteOps = FALSE\n");
1790 oldOneByteOps = FALSE;
1792 else if (getenv ("SDCC_OLDONEBYTEOPS"))
1796 fprintf (stderr, "Override: oldOneByteOps = TRUE\n");
1799 oldOneByteOps = TRUE;
1804 && ( (IS_CHAR (getSpec (ltype)) && !IS_UNSIGNED (getSpec (ltype)))
1805 || (IS_CHAR (getSpec (rtype)) && !IS_UNSIGNED (getSpec (rtype)))))
1806 /* one or two signed char operands: promote to int */
1810 ctype = computeType (ltype, rtype, resultIsInt);
1812 #ifdef OLDONEBYTEOPS
1817 && IS_CHAR (getSpec (ltype)) && IS_UNSIGNED (getSpec (ltype))
1818 && IS_CHAR (getSpec (rtype)) && IS_UNSIGNED (getSpec (rtype)))
1820 /* two unsigned char operands and Mult: no promotion */
1823 *op1 = geniCodeCast (ctype, *op1, TRUE);
1824 *op2 = geniCodeCast (ctype, *op2, TRUE);
1836 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1838 /* one byte operations: keep signedness for code generator */
1846 *op1 = geniCodeCast (ctype, *op1, TRUE);
1847 *op2 = geniCodeCast (ctype, *op2, TRUE);
1852 /*-----------------------------------------------------------------*/
1853 /* geniCodeValueAtAddress - generate intermeditate code for value */
1855 /*-----------------------------------------------------------------*/
1857 geniCodeRValue (operand * op, bool force)
1860 sym_link *type = operandType (op);
1861 sym_link *etype = getSpec (type);
1863 /* if this is an array & already */
1864 /* an address then return this */
1865 if (IS_AGGREGATE (type) ||
1866 (IS_PTR (type) && !force && !op->isaddr))
1867 return operandFromOperand (op);
1869 /* if this is not an address then must be */
1870 /* rvalue already so return this one */
1874 /* if this is not a temp symbol then */
1875 if (!IS_ITEMP (op) &&
1877 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1879 op = operandFromOperand (op);
1884 if (IS_SPEC (type) &&
1885 IS_TRUE_SYMOP (op) &&
1886 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1887 (options.model == MODEL_FLAT24) ))
1889 op = operandFromOperand (op);
1894 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1895 if (IS_PTR (type) && op->isaddr && force)
1898 type = copyLinkChain (type);
1900 IC_RESULT (ic) = newiTempOperand (type, 1);
1901 IC_RESULT (ic)->isaddr = 0;
1903 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1907 return IC_RESULT (ic);
1910 /*-----------------------------------------------------------------*/
1911 /* geniCodeCast - changes the value from one type to another */
1912 /*-----------------------------------------------------------------*/
1914 geniCodeCast (sym_link * type, operand * op, bool implicit)
1918 sym_link *opetype = getSpec (optype = operandType (op));
1922 /* one of them has size zero then error */
1923 if (IS_VOID (optype))
1925 werror (E_CAST_ZERO);
1929 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1931 geniCodeArray2Ptr (op);
1935 /* if the operand is already the desired type then do nothing */
1936 if (compareType (type, optype) == 1)
1939 /* if this is a literal then just change the type & return */
1940 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1942 return operandFromValue (valCastLiteral (type,
1943 operandLitValue (op)));
1946 /* if casting to/from pointers, do some checking */
1947 if (IS_PTR(type)) { // to a pointer
1948 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1949 if (IS_INTEGRAL(optype)) {
1950 // maybe this is NULL, than it's ok.
1951 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1952 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1953 // no way to set the storage
1954 if (IS_LITERAL(optype)) {
1955 werror(E_LITERAL_GENERIC);
1958 werror(E_NONPTR2_GENPTR);
1961 } else if (implicit) {
1962 werror(W_INTEGRAL2PTR_NOCAST);
1967 // shouldn't do that with float, array or structure unless to void
1968 if (!IS_VOID(getSpec(type)) &&
1969 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1970 werror(E_INCOMPAT_TYPES);
1974 } else { // from a pointer to a pointer
1975 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1976 // if not a pointer to a function
1977 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1978 if (implicit) { // if not to generic, they have to match
1979 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1980 werror(E_INCOMPAT_PTYPES);
1987 } else { // to a non pointer
1988 if (IS_PTR(optype)) { // from a pointer
1989 if (implicit) { // sneaky
1990 if (IS_INTEGRAL(type)) {
1991 werror(W_PTR2INTEGRAL_NOCAST);
1993 } else { // shouldn't do that with float, array or structure
1994 werror(E_INCOMPAT_TYPES);
2001 printFromToType (optype, type);
2004 /* if they are the same size create an assignment */
2006 /* This seems very dangerous to me, since there are several */
2007 /* optimizations (for example, gcse) that don't notice the */
2008 /* cast hidden in this assignement and may simplify an */
2009 /* iCode to use the original (uncasted) operand. */
2010 /* Unfortunately, other things break when this cast is */
2011 /* made explicit. Need to fix this someday. */
2012 /* -- EEP, 2004/01/21 */
2013 if (getSize (type) == getSize (optype) &&
2014 !IS_BITFIELD (type) &&
2016 !IS_FLOAT (optype) &&
2017 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2018 (!IS_SPEC (type) && !IS_SPEC (optype))))
2020 ic = newiCode ('=', NULL, op);
2021 IC_RESULT (ic) = newiTempOperand (type, 0);
2022 SPIL_LOC (IC_RESULT (ic)) =
2023 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2024 IC_RESULT (ic)->isaddr = 0;
2028 ic = newiCode (CAST, operandFromLink (type),
2029 geniCodeRValue (op, FALSE));
2031 IC_RESULT (ic) = newiTempOperand (type, 0);
2034 /* preserve the storage class & output class */
2035 /* of the original variable */
2036 restype = getSpec (operandType (IC_RESULT (ic)));
2037 if (!IS_LITERAL(opetype))
2038 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2039 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2042 return IC_RESULT (ic);
2045 /*-----------------------------------------------------------------*/
2046 /* geniCodeLabel - will create a Label */
2047 /*-----------------------------------------------------------------*/
2049 geniCodeLabel (symbol * label)
2053 ic = newiCodeLabelGoto (LABEL, label);
2057 /*-----------------------------------------------------------------*/
2058 /* geniCodeGoto - will create a Goto */
2059 /*-----------------------------------------------------------------*/
2061 geniCodeGoto (symbol * label)
2065 ic = newiCodeLabelGoto (GOTO, label);
2069 /*-----------------------------------------------------------------*/
2070 /* geniCodeMultiply - gen intermediate code for multiplication */
2071 /*-----------------------------------------------------------------*/
2073 geniCodeMultiply (operand * left, operand * right, bool resultIsInt)
2080 /* if they are both literal then we know the result */
2081 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2082 return operandFromValue (valMult (left->operand.valOperand,
2083 right->operand.valOperand));
2085 if (IS_LITERAL(retype)) {
2086 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2089 resType = usualBinaryConversions (&left, &right, resultIsInt, '*');
2091 rtype = operandType (right);
2092 retype = getSpec (rtype);
2093 ltype = operandType (left);
2094 letype = getSpec (ltype);
2097 /* if the right is a literal & power of 2 */
2098 /* then make it a left shift */
2099 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2100 efficient in most cases than 2 bytes result = 2 bytes << literal
2101 if port has 1 byte muldiv */
2102 if (p2 && !IS_FLOAT (letype)
2103 && !((resultIsInt) && (getSize (resType) != getSize (ltype))
2104 && (port->support.muldiv == 1))
2105 && strcmp (port->target, "pic14") != 0 /* don't shift for pic */
2106 && strcmp (port->target, "pic16") != 0)
2108 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2110 /* LEFT_OP need same size for left and result, */
2111 left = geniCodeCast (resType, left, TRUE);
2112 ltype = operandType (left);
2114 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2118 ic = newiCode ('*', left, right); /* normal multiplication */
2119 /* if the size left or right > 1 then support routine */
2120 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2124 IC_RESULT (ic) = newiTempOperand (resType, 1);
2127 return IC_RESULT (ic);
2130 /*-----------------------------------------------------------------*/
2131 /* geniCodeDivision - gen intermediate code for division */
2132 /*-----------------------------------------------------------------*/
2134 geniCodeDivision (operand * left, operand * right, bool resultIsInt)
2139 sym_link *rtype = operandType (right);
2140 sym_link *retype = getSpec (rtype);
2141 sym_link *ltype = operandType (left);
2142 sym_link *letype = getSpec (ltype);
2144 resType = usualBinaryConversions (&left, &right, resultIsInt, '/');
2146 /* if the right is a literal & power of 2
2147 and left is unsigned then make it a
2149 if (IS_LITERAL (retype) &&
2150 !IS_FLOAT (letype) &&
2151 IS_UNSIGNED(letype) &&
2152 (p2 = powof2 ((TYPE_UDWORD)
2153 floatFromVal (right->operand.valOperand)))) {
2154 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2158 ic = newiCode ('/', left, right); /* normal division */
2159 /* if the size left or right > 1 then support routine */
2160 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2163 IC_RESULT (ic) = newiTempOperand (resType, 0);
2166 return IC_RESULT (ic);
2168 /*-----------------------------------------------------------------*/
2169 /* geniCodeModulus - gen intermediate code for modulus */
2170 /*-----------------------------------------------------------------*/
2172 geniCodeModulus (operand * left, operand * right, bool resultIsInt)
2178 /* if they are both literal then we know the result */
2179 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2180 return operandFromValue (valMod (left->operand.valOperand,
2181 right->operand.valOperand));
2183 resType = usualBinaryConversions (&left, &right, resultIsInt, '%');
2185 /* now they are the same size */
2186 ic = newiCode ('%', left, right);
2188 /* if the size left or right > 1 then support routine */
2189 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2191 IC_RESULT (ic) = newiTempOperand (resType, 0);
2194 return IC_RESULT (ic);
2197 /*-----------------------------------------------------------------*/
2198 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2199 /*-----------------------------------------------------------------*/
2201 geniCodePtrPtrSubtract (operand * left, operand * right)
2207 /* if they are both literals then */
2208 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2210 result = operandFromValue (valMinus (left->operand.valOperand,
2211 right->operand.valOperand));
2215 ic = newiCode ('-', left, right);
2217 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2221 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2225 // should we really do this? is this ANSI?
2226 return geniCodeDivision (result,
2227 operandFromLit (getSize (ltype->next)),
2231 /*-----------------------------------------------------------------*/
2232 /* geniCodeSubtract - generates code for subtraction */
2233 /*-----------------------------------------------------------------*/
2235 geniCodeSubtract (operand * left, operand * right)
2242 /* if they both pointers then */
2243 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2244 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2245 return geniCodePtrPtrSubtract (left, right);
2247 /* if they are both literal then we know the result */
2248 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2249 && left->isLiteral && right->isLiteral)
2250 return operandFromValue (valMinus (left->operand.valOperand,
2251 right->operand.valOperand));
2253 /* if left is an array or pointer */
2254 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2256 isarray = left->isaddr;
2257 right = geniCodeMultiply (right,
2258 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2259 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2262 { /* make them the same size */
2263 resType = usualBinaryConversions (&left, &right, FALSE, '-');
2266 ic = newiCode ('-', left, right);
2268 IC_RESULT (ic) = newiTempOperand (resType, 1);
2269 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2271 /* if left or right is a float */
2272 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2276 return IC_RESULT (ic);
2279 /*-----------------------------------------------------------------*/
2280 /* geniCodeAdd - generates iCode for addition */
2281 /*-----------------------------------------------------------------*/
2283 geniCodeAdd (operand * left, operand * right, int lvl)
2292 /* if the right side is LITERAL zero */
2293 /* return the left side */
2294 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2297 /* if left is literal zero return right */
2298 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2301 /* if left is a pointer then size */
2302 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2304 isarray = left->isaddr;
2305 // there is no need to multiply with 1
2306 if (getSize (ltype->next) != 1)
2308 size = operandFromLit (getSize (ltype->next));
2309 SPEC_USIGN (getSpec (operandType (size))) = 1;
2310 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2311 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2312 /* Even if right is a 'unsigned char',
2313 the result will be a 'signed int' due to the promotion rules.
2314 It doesn't make sense when accessing arrays, so let's fix it here: */
2316 SPEC_USIGN (getSpec (operandType (right))) = 1;
2318 resType = copyLinkChain (ltype);
2321 { // make them the same size
2322 resType = usualBinaryConversions (&left, &right, FALSE, '+');
2325 /* if they are both literals then we know */
2326 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2327 && left->isLiteral && right->isLiteral)
2328 return operandFromValue (valPlus (valFromType (ltype),
2329 valFromType (rtype)));
2331 ic = newiCode ('+', left, right);
2333 IC_RESULT (ic) = newiTempOperand (resType, 1);
2334 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2336 /* if left or right is a float then support
2338 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2343 return IC_RESULT (ic);
2347 /*-----------------------------------------------------------------*/
2348 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2349 /*-----------------------------------------------------------------*/
2351 aggrToPtr (sym_link * type, bool force)
2356 if (IS_PTR (type) && !force)
2359 etype = getSpec (type);
2360 ptype = newLink (DECLARATOR);
2364 /* set the pointer depending on the storage class */
2365 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2369 /*-----------------------------------------------------------------*/
2370 /* geniCodeArray2Ptr - array to pointer */
2371 /*-----------------------------------------------------------------*/
2373 geniCodeArray2Ptr (operand * op)
2375 sym_link *optype = operandType (op);
2376 sym_link *opetype = getSpec (optype);
2378 /* set the pointer depending on the storage class */
2379 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2386 /*-----------------------------------------------------------------*/
2387 /* geniCodeArray - array access */
2388 /*-----------------------------------------------------------------*/
2390 geniCodeArray (operand * left, operand * right, int lvl)
2394 sym_link *ltype = operandType (left);
2399 if (IS_PTR (ltype->next) && left->isaddr)
2401 left = geniCodeRValue (left, FALSE);
2404 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2406 size = operandFromLit (getSize (ltype->next));
2407 SPEC_USIGN (getSpec (operandType (size))) = 1;
2408 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2409 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2410 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2411 It doesn't make sense when accessing arrays, so let's fix it here: */
2413 SPEC_USIGN (getSpec (operandType (right))) = 1;
2414 /* we can check for limits here */
2415 /* already done in SDCCast.c
2416 if (isOperandLiteral (right) &&
2419 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2421 werror (W_IDX_OUT_OF_BOUNDS,
2422 (int) operandLitValue (right) / getSize (ltype->next),
2427 ic = newiCode ('+', left, right);
2429 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2430 !IS_AGGREGATE (ltype->next) &&
2431 !IS_PTR (ltype->next))
2432 ? ltype : ltype->next), 0);
2434 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2437 return IC_RESULT (ic);
2440 /*-----------------------------------------------------------------*/
2441 /* geniCodeStruct - generates intermediate code for structures */
2442 /*-----------------------------------------------------------------*/
2444 geniCodeStruct (operand * left, operand * right, bool islval)
2447 sym_link *type = operandType (left);
2448 sym_link *etype = getSpec (type);
2450 symbol *element = getStructElement (SPEC_STRUCT (etype),
2451 right->operand.symOperand);
2453 wassert(IS_SYMOP(right));
2455 /* add the offset */
2456 ic = newiCode ('+', left, operandFromLit (element->offset));
2458 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2460 /* preserve the storage & output class of the struct */
2461 /* as well as the volatile attribute */
2462 retype = getSpec (operandType (IC_RESULT (ic)));
2463 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2464 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2465 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2466 SPEC_CONST (retype) |= SPEC_CONST (etype);
2468 if (IS_PTR (element->type))
2469 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2471 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2474 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2477 /*-----------------------------------------------------------------*/
2478 /* geniCodePostInc - generate int code for Post increment */
2479 /*-----------------------------------------------------------------*/
2481 geniCodePostInc (operand * op)
2485 sym_link *optype = operandType (op);
2487 operand *rv = (IS_ITEMP (op) ?
2488 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2490 sym_link *rvtype = operandType (rv);
2493 /* if this is not an address we have trouble */
2496 werror (E_LVALUE_REQUIRED, "++");
2500 rOp = newiTempOperand (rvtype, 0);
2501 OP_SYMBOL(rOp)->noSpilLoc = 1;
2504 OP_SYMBOL(rv)->noSpilLoc = 1;
2506 geniCodeAssign (rOp, rv, 0);
2508 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2509 if (IS_FLOAT (rvtype))
2510 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2512 ic = newiCode ('+', rv, operandFromLit (size));
2514 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2517 geniCodeAssign (op, result, 0);
2523 /*-----------------------------------------------------------------*/
2524 /* geniCodePreInc - generate code for preIncrement */
2525 /*-----------------------------------------------------------------*/
2527 geniCodePreInc (operand * op, bool lvalue)
2530 sym_link *optype = operandType (op);
2531 operand *rop = (IS_ITEMP (op) ?
2532 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2534 sym_link *roptype = operandType (rop);
2540 werror (E_LVALUE_REQUIRED, "++");
2545 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2546 if (IS_FLOAT (roptype))
2547 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2549 ic = newiCode ('+', rop, operandFromLit (size));
2550 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2553 (void) geniCodeAssign (op, result, 0);
2554 if (lvalue || IS_TRUE_SYMOP (op))
2560 /*-----------------------------------------------------------------*/
2561 /* geniCodePostDec - generates code for Post decrement */
2562 /*-----------------------------------------------------------------*/
2564 geniCodePostDec (operand * op)
2568 sym_link *optype = operandType (op);
2570 operand *rv = (IS_ITEMP (op) ?
2571 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2573 sym_link *rvtype = operandType (rv);
2576 /* if this is not an address we have trouble */
2579 werror (E_LVALUE_REQUIRED, "--");
2583 rOp = newiTempOperand (rvtype, 0);
2584 OP_SYMBOL(rOp)->noSpilLoc = 1;
2587 OP_SYMBOL(rv)->noSpilLoc = 1;
2589 geniCodeAssign (rOp, rv, 0);
2591 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2592 if (IS_FLOAT (rvtype))
2593 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2595 ic = newiCode ('-', rv, operandFromLit (size));
2597 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2600 geniCodeAssign (op, result, 0);
2606 /*-----------------------------------------------------------------*/
2607 /* geniCodePreDec - generate code for pre decrement */
2608 /*-----------------------------------------------------------------*/
2610 geniCodePreDec (operand * op, bool lvalue)
2613 sym_link *optype = operandType (op);
2614 operand *rop = (IS_ITEMP (op) ?
2615 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2617 sym_link *roptype = operandType (rop);
2623 werror (E_LVALUE_REQUIRED, "--");
2628 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2629 if (IS_FLOAT (roptype))
2630 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2632 ic = newiCode ('-', rop, operandFromLit (size));
2633 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2636 (void) geniCodeAssign (op, result, 0);
2637 if (lvalue || IS_TRUE_SYMOP (op))
2644 /*-----------------------------------------------------------------*/
2645 /* geniCodeBitwise - gen int code for bitWise operators */
2646 /*-----------------------------------------------------------------*/
2648 geniCodeBitwise (operand * left, operand * right,
2649 int oper, sym_link * resType)
2653 left = geniCodeCast (resType, left, TRUE);
2654 right = geniCodeCast (resType, right, TRUE);
2656 ic = newiCode (oper, left, right);
2657 IC_RESULT (ic) = newiTempOperand (resType, 0);
2660 return IC_RESULT (ic);
2663 /*-----------------------------------------------------------------*/
2664 /* geniCodeAddressOf - gens icode for '&' address of operator */
2665 /*-----------------------------------------------------------------*/
2667 geniCodeAddressOf (operand * op)
2671 sym_link *optype = operandType (op);
2672 sym_link *opetype = getSpec (optype);
2674 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2676 op = operandFromOperand (op);
2681 /* lvalue check already done in decorateType */
2682 /* this must be a lvalue */
2683 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2684 /* werror (E_LVALUE_REQUIRED,"&"); */
2688 p = newLink (DECLARATOR);
2690 /* set the pointer depending on the storage class */
2691 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2693 p->next = copyLinkChain (optype);
2695 /* if already a temp */
2698 setOperandType (op, p);
2703 /* other wise make this of the type coming in */
2704 ic = newiCode (ADDRESS_OF, op, NULL);
2705 IC_RESULT (ic) = newiTempOperand (p, 1);
2706 IC_RESULT (ic)->isaddr = 0;
2708 return IC_RESULT (ic);
2710 /*-----------------------------------------------------------------*/
2711 /* setOClass - sets the output class depending on the pointer type */
2712 /*-----------------------------------------------------------------*/
2714 setOClass (sym_link * ptr, sym_link * spec)
2716 switch (DCL_TYPE (ptr))
2719 SPEC_OCLS (spec) = data;
2723 SPEC_OCLS (spec) = generic;
2727 SPEC_OCLS (spec) = xdata;
2731 SPEC_OCLS (spec) = code;
2735 SPEC_OCLS (spec) = idata;
2739 SPEC_OCLS (spec) = xstack;
2743 SPEC_OCLS (spec) = eeprom;
2752 /*-----------------------------------------------------------------*/
2753 /* geniCodeDerefPtr - dereference pointer with '*' */
2754 /*-----------------------------------------------------------------*/
2756 geniCodeDerefPtr (operand * op,int lvl)
2758 sym_link *rtype, *retype;
2759 sym_link *optype = operandType (op);
2761 // if this is an array then array access
2762 if (IS_ARRAY (optype)) {
2763 // don't worry, this will be optimized out later
2764 return geniCodeArray (op, operandFromLit (0), lvl);
2767 // just in case someone screws up
2768 wassert (IS_PTR (optype));
2770 if (IS_TRUE_SYMOP (op))
2773 op = geniCodeRValue (op, TRUE);
2776 /* now get rid of the pointer part */
2777 if (isLvaluereq(lvl) && IS_ITEMP (op))
2779 retype = getSpec (rtype = copyLinkChain (optype));
2783 retype = getSpec (rtype = copyLinkChain (optype->next));
2784 /* outputclass needs 2b updated */
2785 setOClass (optype, retype);
2788 op->isGptr = IS_GENPTR (optype);
2790 op->isaddr = (IS_PTR (rtype) ||
2791 IS_STRUCT (rtype) ||
2796 if (!isLvaluereq(lvl))
2797 op = geniCodeRValue (op, TRUE);
2799 setOperandType (op, rtype);
2804 /*-----------------------------------------------------------------*/
2805 /* geniCodeUnaryMinus - does a unary minus of the operand */
2806 /*-----------------------------------------------------------------*/
2808 geniCodeUnaryMinus (operand * op)
2811 sym_link *optype = operandType (op);
2813 if (IS_LITERAL (optype))
2814 return operandFromLit (-floatFromVal (op->operand.valOperand));
2816 ic = newiCode (UNARYMINUS, op, NULL);
2817 IC_RESULT (ic) = newiTempOperand (optype, 0);
2819 return IC_RESULT (ic);
2822 /*-----------------------------------------------------------------*/
2823 /* geniCodeLeftShift - gen i code for left shift */
2824 /*-----------------------------------------------------------------*/
2826 geniCodeLeftShift (operand * left, operand * right)
2830 ic = newiCode (LEFT_OP, left, right);
2831 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2833 return IC_RESULT (ic);
2836 /*-----------------------------------------------------------------*/
2837 /* geniCodeRightShift - gen i code for right shift */
2838 /*-----------------------------------------------------------------*/
2840 geniCodeRightShift (operand * left, operand * right)
2844 ic = newiCode (RIGHT_OP, left, right);
2845 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2847 return IC_RESULT (ic);
2850 /*-----------------------------------------------------------------*/
2851 /* geniCodeLogic- logic code */
2852 /*-----------------------------------------------------------------*/
2854 geniCodeLogic (operand * left, operand * right, int op)
2858 sym_link *rtype = operandType (right);
2859 sym_link *ltype = operandType (left);
2861 /* left is integral type and right is literal then
2862 check if the literal value is within bounds */
2863 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2865 checkConstantRange(ltype,
2866 OP_VALUE(right), "compare operation", 1);
2869 /* if one operand is a pointer and the other is a literal generic void pointer,
2870 change the type of the literal generic void pointer to match the other pointer */
2871 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2872 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2874 /* find left's definition */
2875 ic = (iCode *) setFirstItem (iCodeChain);
2878 if (((ic->op == CAST) || (ic->op == '='))
2879 && isOperandEqual(left, IC_RESULT (ic)))
2882 ic = setNextItem (iCodeChain);
2884 /* if casting literal to generic pointer, then cast to rtype instead */
2885 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2887 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2888 ltype = operandType(left);
2891 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2892 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2894 /* find right's definition */
2895 ic = (iCode *) setFirstItem (iCodeChain);
2898 if (((ic->op == CAST) || (ic->op == '='))
2899 && isOperandEqual(right, IC_RESULT (ic)))
2902 ic = setNextItem (iCodeChain);
2904 /* if casting literal to generic pointer, then cast to rtype instead */
2905 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2907 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2908 rtype = operandType(right);
2912 ctype = usualBinaryConversions (&left, &right, FALSE, ' ');
2914 ic = newiCode (op, left, right);
2915 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2917 /* if comparing float
2918 and not a '==' || '!=' || '&&' || '||' (these
2920 if (IS_FLOAT(ctype) &&
2928 return IC_RESULT (ic);
2931 /*-----------------------------------------------------------------*/
2932 /* geniCodeUnary - for a a generic unary operation */
2933 /*-----------------------------------------------------------------*/
2935 geniCodeUnary (operand * op, int oper)
2937 iCode *ic = newiCode (oper, op, NULL);
2939 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2941 return IC_RESULT (ic);
2944 /*-----------------------------------------------------------------*/
2945 /* geniCodeConditional - geniCode for '?' ':' operation */
2946 /*-----------------------------------------------------------------*/
2948 geniCodeConditional (ast * tree,int lvl)
2951 symbol *falseLabel = newiTempLabel (NULL);
2952 symbol *exitLabel = newiTempLabel (NULL);
2953 operand *cond = ast2iCode (tree->left,lvl+1);
2954 operand *true, *false, *result;
2956 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2960 true = ast2iCode (tree->right->left,lvl+1);
2962 /* move the value to a new Operand */
2963 result = newiTempOperand (tree->right->ftype, 0);
2964 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2966 /* generate an unconditional goto */
2967 geniCodeGoto (exitLabel);
2969 /* now for the right side */
2970 geniCodeLabel (falseLabel);
2972 false = ast2iCode (tree->right->right,lvl+1);
2973 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2975 /* create the exit label */
2976 geniCodeLabel (exitLabel);
2981 /*-----------------------------------------------------------------*/
2982 /* geniCodeAssign - generate code for assignment */
2983 /*-----------------------------------------------------------------*/
2985 geniCodeAssign (operand * left, operand * right, int nosupdate)
2988 sym_link *ltype = operandType (left);
2989 sym_link *rtype = operandType (right);
2991 if (!left->isaddr && !IS_ITEMP (left))
2993 werror (E_LVALUE_REQUIRED, "assignment");
2997 /* left is integral type and right is literal then
2998 check if the literal value is within bounds */
2999 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3001 checkConstantRange(ltype,
3002 OP_VALUE(right), "= operation", 0);
3005 /* if the left & right type don't exactly match */
3006 /* if pointer set then make sure the check is
3007 done with the type & not the pointer */
3008 /* then cast rights type to left */
3010 /* first check the type for pointer assignement */
3011 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3012 compareType (ltype, rtype) <= 0)
3014 if (compareType (ltype->next, rtype) < 0)
3015 right = geniCodeCast (ltype->next, right, TRUE);
3017 else if (compareType (ltype, rtype) < 0)
3018 right = geniCodeCast (ltype, right, TRUE);
3020 /* If left is a true symbol & ! volatile
3021 create an assignment to temporary for
3022 the right & then assign this temporary
3023 to the symbol. This is SSA (static single
3024 assignment). Isn't it simple and folks have
3025 published mountains of paper on it */
3026 if (IS_TRUE_SYMOP (left) &&
3027 !isOperandVolatile (left, FALSE) &&
3028 isOperandGlobal (left))
3032 if (IS_TRUE_SYMOP (right))
3033 sym = OP_SYMBOL (right);
3034 ic = newiCode ('=', NULL, right);
3035 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3036 SPIL_LOC (right) = sym;
3040 ic = newiCode ('=', NULL, right);
3041 IC_RESULT (ic) = left;
3044 /* if left isgptr flag is set then support
3045 routine will be required */
3049 ic->nosupdate = nosupdate;
3053 /*-----------------------------------------------------------------*/
3054 /* geniCodeDummyRead - generate code for dummy read */
3055 /*-----------------------------------------------------------------*/
3057 geniCodeDummyRead (operand * op)
3060 sym_link *type = operandType (op);
3062 if (!IS_VOLATILE(type))
3065 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3071 /*-----------------------------------------------------------------*/
3072 /* geniCodeSEParms - generate code for side effecting fcalls */
3073 /*-----------------------------------------------------------------*/
3075 geniCodeSEParms (ast * parms,int lvl)
3080 if (parms->type == EX_OP && parms->opval.op == PARAM)
3082 geniCodeSEParms (parms->left,lvl);
3083 geniCodeSEParms (parms->right,lvl);
3087 /* hack don't like this but too lazy to think of
3089 if (IS_ADDRESS_OF_OP (parms))
3090 parms->left->lvalue = 1;
3092 if (IS_CAST_OP (parms) &&
3093 IS_PTR (parms->ftype) &&
3094 IS_ADDRESS_OF_OP (parms->right))
3095 parms->right->left->lvalue = 1;
3097 parms->opval.oprnd =
3098 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3100 parms->type = EX_OPERAND;
3101 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3102 SPEC_ARGREG(parms->ftype);
3105 /*-----------------------------------------------------------------*/
3106 /* geniCodeParms - generates parameters */
3107 /*-----------------------------------------------------------------*/
3109 geniCodeParms (ast * parms, value *argVals, int *stack,
3110 sym_link * ftype, int lvl)
3118 if (argVals==NULL) {
3120 argVals = FUNC_ARGS (ftype);
3123 /* if this is a param node then do the left & right */
3124 if (parms->type == EX_OP && parms->opval.op == PARAM)
3126 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3127 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3131 /* get the parameter value */
3132 if (parms->type == EX_OPERAND)
3133 pval = parms->opval.oprnd;
3136 /* maybe this else should go away ?? */
3137 /* hack don't like this but too lazy to think of
3139 if (IS_ADDRESS_OF_OP (parms))
3140 parms->left->lvalue = 1;
3142 if (IS_CAST_OP (parms) &&
3143 IS_PTR (parms->ftype) &&
3144 IS_ADDRESS_OF_OP (parms->right))
3145 parms->right->left->lvalue = 1;
3147 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3150 /* if register parm then make it a send */
3151 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3152 IFFUNC_ISBUILTIN(ftype))
3154 ic = newiCode (SEND, pval, NULL);
3155 ic->argreg = SPEC_ARGREG(parms->etype);
3156 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3161 /* now decide whether to push or assign */
3162 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3166 operand *top = operandFromSymbol (argVals->sym);
3167 /* clear useDef and other bitVectors */
3168 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3169 geniCodeAssign (top, pval, 1);
3173 sym_link *p = operandType (pval);
3175 ic = newiCode (IPUSH, pval, NULL);
3177 /* update the stack adjustment */
3178 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3183 argVals=argVals->next;
3187 /*-----------------------------------------------------------------*/
3188 /* geniCodeCall - generates temp code for calling */
3189 /*-----------------------------------------------------------------*/
3191 geniCodeCall (operand * left, ast * parms,int lvl)
3195 sym_link *type, *etype;
3199 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3200 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3201 werror (E_FUNCTION_EXPECTED);
3202 return operandFromValue(valueFromLit(0));
3205 /* take care of parameters with side-effecting
3206 function calls in them, this is required to take care
3207 of overlaying function parameters */
3208 geniCodeSEParms (parms,lvl);
3210 ftype = operandType (left);
3211 if (IS_CODEPTR (ftype))
3212 ftype = ftype->next;
3214 /* first the parameters */
3215 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3217 /* now call : if symbol then pcall */
3218 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3219 ic = newiCode (PCALL, left, NULL);
3221 ic = newiCode (CALL, left, NULL);
3224 type = copyLinkChain (ftype->next);
3225 etype = getSpec (type);
3226 SPEC_EXTR (etype) = 0;
3227 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3231 /* stack adjustment after call */
3232 ic->parmBytes = stack;
3237 /*-----------------------------------------------------------------*/
3238 /* geniCodeReceive - generate intermediate code for "receive" */
3239 /*-----------------------------------------------------------------*/
3241 geniCodeReceive (value * args)
3243 /* for all arguments that are passed in registers */
3247 if (IS_REGPARM (args->etype))
3249 operand *opr = operandFromValue (args);
3251 symbol *sym = OP_SYMBOL (opr);
3254 /* we will use it after all optimizations
3255 and before liveRange calculation */
3256 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3259 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3260 options.stackAuto == 0 &&
3261 (!(options.model == MODEL_FLAT24)) )
3266 opl = newiTempOperand (args->type, 0);
3268 sym->reqv->key = sym->key;
3269 OP_SYMBOL (sym->reqv)->key = sym->key;
3270 OP_SYMBOL (sym->reqv)->isreqv = 1;
3271 OP_SYMBOL (sym->reqv)->islocal = 0;
3272 SPIL_LOC (sym->reqv) = sym;
3276 ic = newiCode (RECEIVE, NULL, NULL);
3277 ic->argreg = SPEC_ARGREG(args->etype);
3279 currFunc->recvSize = getSize (sym->type);
3282 IC_RESULT (ic) = opr;
3290 /*-----------------------------------------------------------------*/
3291 /* geniCodeFunctionBody - create the function body */
3292 /*-----------------------------------------------------------------*/
3294 geniCodeFunctionBody (ast * tree,int lvl)
3301 /* reset the auto generation */
3307 func = ast2iCode (tree->left,lvl+1);
3308 fetype = getSpec (operandType (func));
3310 savelineno = lineno;
3311 lineno = OP_SYMBOL (func)->lineDef;
3312 /* create an entry label */
3313 geniCodeLabel (entryLabel);
3314 lineno = savelineno;
3316 /* create a proc icode */
3317 ic = newiCode (FUNCTION, func, NULL);
3318 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3322 /* for all parameters that are passed
3323 on registers add a "receive" */
3324 geniCodeReceive (tree->values.args);
3326 /* generate code for the body */
3327 ast2iCode (tree->right,lvl+1);
3329 /* create a label for return */
3330 geniCodeLabel (returnLabel);
3332 /* now generate the end proc */
3333 ic = newiCode (ENDFUNCTION, func, NULL);
3338 /*-----------------------------------------------------------------*/
3339 /* geniCodeReturn - gen icode for 'return' statement */
3340 /*-----------------------------------------------------------------*/
3342 geniCodeReturn (operand * op)
3346 /* if the operand is present force an rvalue */
3348 op = geniCodeRValue (op, FALSE);
3350 ic = newiCode (RETURN, op, NULL);
3354 /*-----------------------------------------------------------------*/
3355 /* geniCodeIfx - generates code for extended if statement */
3356 /*-----------------------------------------------------------------*/
3358 geniCodeIfx (ast * tree,int lvl)
3361 operand *condition = ast2iCode (tree->left,lvl+1);
3364 /* if condition is null then exit */
3368 condition = geniCodeRValue (condition, FALSE);
3370 cetype = getSpec (operandType (condition));
3371 /* if the condition is a literal */
3372 if (IS_LITERAL (cetype))
3374 if (floatFromVal (condition->operand.valOperand))
3376 if (tree->trueLabel)
3377 geniCodeGoto (tree->trueLabel);
3383 if (tree->falseLabel)
3384 geniCodeGoto (tree->falseLabel);
3391 if (tree->trueLabel)
3393 ic = newiCodeCondition (condition,
3398 if (tree->falseLabel)
3399 geniCodeGoto (tree->falseLabel);
3403 ic = newiCodeCondition (condition,
3410 ast2iCode (tree->right,lvl+1);
3413 /*-----------------------------------------------------------------*/
3414 /* geniCodeJumpTable - tries to create a jump table for switch */
3415 /*-----------------------------------------------------------------*/
3417 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3419 int min = 0, max = 0, t, cnt = 0;
3425 int needRangeCheck = !optimize.noJTabBoundary
3426 || tree->values.switchVals.swDefault;
3428 if (!tree || !caseVals)
3431 /* the criteria for creating a jump table is */
3432 /* all integer numbers between the maximum & minimum must */
3433 /* be present , the maximum value should not exceed 255 */
3434 min = max = (int) floatFromVal (vch = caseVals);
3435 SNPRINTF (buffer, sizeof(buffer),
3437 tree->values.switchVals.swNum,
3439 addSet (&labels, newiTempLabel (buffer));
3441 /* if there is only one case value then no need */
3442 if (!(vch = vch->next))
3447 if (((t = (int) floatFromVal (vch)) - max) != 1)
3449 SNPRINTF (buffer, sizeof(buffer),
3451 tree->values.switchVals.swNum,
3453 addSet (&labels, newiTempLabel (buffer));
3459 /* if the number of case statements <= 2 then */
3460 /* it is not economical to create the jump table */
3461 /* since two compares are needed for boundary conditions */
3462 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3465 if (tree->values.switchVals.swDefault)
3467 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3471 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3475 falseLabel = newiTempLabel (buffer);
3477 /* so we can create a jumptable */
3478 /* first we rule out the boundary conditions */
3479 /* if only optimization says so */
3482 sym_link *cetype = getSpec (operandType (cond));
3483 /* no need to check the lower bound if
3484 the condition is unsigned & minimum value is zero */
3485 if (!(min == 0 && IS_UNSIGNED (cetype)))
3487 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3488 ic = newiCodeCondition (boundary, falseLabel, NULL);
3492 /* now for upper bounds */
3493 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3494 ic = newiCodeCondition (boundary, falseLabel, NULL);
3498 /* if the min is not zero then we no make it zero */
3501 cond = geniCodeSubtract (cond, operandFromLit (min));
3502 if (!IS_LITERAL(getSpec(operandType(cond))))
3503 setOperandType (cond, UCHARTYPE);
3506 /* now create the jumptable */
3507 ic = newiCode (JUMPTABLE, NULL, NULL);
3508 IC_JTCOND (ic) = cond;
3509 IC_JTLABELS (ic) = labels;
3514 /*-----------------------------------------------------------------*/
3515 /* geniCodeSwitch - changes a switch to a if statement */
3516 /*-----------------------------------------------------------------*/
3518 geniCodeSwitch (ast * tree,int lvl)
3521 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3522 value *caseVals = tree->values.switchVals.swVals;
3523 symbol *trueLabel, *falseLabel;
3525 /* If the condition is a literal, then just jump to the */
3526 /* appropriate case label. */
3527 if (IS_LITERAL(getSpec(operandType(cond))))
3529 int switchVal, caseVal;
3531 switchVal = (int) floatFromVal (cond->operand.valOperand);
3534 caseVal = (int) floatFromVal (caseVals);
3535 if (caseVal == switchVal)
3537 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3538 tree->values.switchVals.swNum, caseVal);
3539 trueLabel = newiTempLabel (buffer);
3540 geniCodeGoto (trueLabel);
3543 caseVals = caseVals->next;
3545 goto defaultOrBreak;
3548 /* if we can make this a jump table */
3549 if (geniCodeJumpTable (cond, caseVals, tree))
3550 goto jumpTable; /* no need for the comparison */
3552 /* for the cases defined do */
3556 operand *compare = geniCodeLogic (cond,
3557 operandFromValue (caseVals),
3560 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3561 tree->values.switchVals.swNum,
3562 (int) floatFromVal (caseVals));
3563 trueLabel = newiTempLabel (buffer);
3565 ic = newiCodeCondition (compare, trueLabel, NULL);
3567 caseVals = caseVals->next;
3572 /* if default is present then goto break else break */
3573 if (tree->values.switchVals.swDefault)
3575 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3579 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3582 falseLabel = newiTempLabel (buffer);
3583 geniCodeGoto (falseLabel);
3586 ast2iCode (tree->right,lvl+1);
3589 /*-----------------------------------------------------------------*/
3590 /* geniCodeInline - intermediate code for inline assembler */
3591 /*-----------------------------------------------------------------*/
3593 geniCodeInline (ast * tree)
3597 ic = newiCode (INLINEASM, NULL, NULL);
3598 IC_INLINE (ic) = tree->values.inlineasm;
3602 /*-----------------------------------------------------------------*/
3603 /* geniCodeArrayInit - intermediate code for array initializer */
3604 /*-----------------------------------------------------------------*/
3606 geniCodeArrayInit (ast * tree, operand *array)
3610 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3611 ic = newiCode (ARRAYINIT, array, NULL);
3612 IC_ARRAYILIST (ic) = tree->values.constlist;
3614 operand *left=newOperand(), *right=newOperand();
3615 left->type=right->type=SYMBOL;
3616 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3617 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3618 ic = newiCode (ARRAYINIT, left, right);
3623 /*-----------------------------------------------------------------*/
3624 /* geniCodeCritical - intermediate code for a critical statement */
3625 /*-----------------------------------------------------------------*/
3627 geniCodeCritical (ast *tree, int lvl)
3632 /* If op is NULL, the original interrupt state will saved on */
3633 /* the stack. Otherwise, it will be saved in op. */
3635 /* Generate a save of the current interrupt state & disabled */
3636 ic = newiCode (CRITICAL, NULL, NULL);
3637 IC_RESULT (ic) = op;
3640 /* Generate the critical code sequence */
3641 if (tree->left && tree->left->type == EX_VALUE)
3642 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3644 ast2iCode (tree->left,lvl+1);
3646 /* Generate a restore of the original interrupt state */
3647 ic = newiCode (ENDCRITICAL, NULL, op);
3651 /*-----------------------------------------------------------------*/
3652 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3653 /* particular case. Ie : assigning or dereferencing array or ptr */
3654 /*-----------------------------------------------------------------*/
3655 set * lvaluereqSet = NULL;
3656 typedef struct lvalItem
3663 /*-----------------------------------------------------------------*/
3664 /* addLvaluereq - add a flag for lvalreq for current ast level */
3665 /*-----------------------------------------------------------------*/
3666 void addLvaluereq(int lvl)
3668 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3671 addSetHead(&lvaluereqSet,lpItem);
3674 /*-----------------------------------------------------------------*/
3675 /* delLvaluereq - del a flag for lvalreq for current ast level */
3676 /*-----------------------------------------------------------------*/
3680 lpItem = getSet(&lvaluereqSet);
3681 if(lpItem) Safe_free(lpItem);
3683 /*-----------------------------------------------------------------*/
3684 /* clearLvaluereq - clear lvalreq flag */
3685 /*-----------------------------------------------------------------*/
3686 void clearLvaluereq()
3689 lpItem = peekSet(lvaluereqSet);
3690 if(lpItem) lpItem->req = 0;
3692 /*-----------------------------------------------------------------*/
3693 /* getLvaluereq - get the last lvalreq level */
3694 /*-----------------------------------------------------------------*/
3695 int getLvaluereqLvl()
3698 lpItem = peekSet(lvaluereqSet);
3699 if(lpItem) return lpItem->lvl;
3702 /*-----------------------------------------------------------------*/
3703 /* isLvaluereq - is lvalreq valid for this level ? */
3704 /*-----------------------------------------------------------------*/
3705 int isLvaluereq(int lvl)
3708 lpItem = peekSet(lvaluereqSet);
3709 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3713 /*-----------------------------------------------------------------*/
3714 /* ast2iCode - creates an icodeList from an ast */
3715 /*-----------------------------------------------------------------*/
3717 ast2iCode (ast * tree,int lvl)
3719 operand *left = NULL;
3720 operand *right = NULL;
3724 /* set the global variables for filename & line number */
3726 filename = tree->filename;
3728 lineno = tree->lineno;
3730 block = tree->block;
3732 scopeLevel = tree->level;
3734 seqPoint = tree->seqPoint;
3736 if (tree->type == EX_VALUE)
3737 return operandFromValue (tree->opval.val);
3739 if (tree->type == EX_LINK)
3740 return operandFromLink (tree->opval.lnk);
3742 /* if we find a nullop */
3743 if (tree->type == EX_OP &&
3744 (tree->opval.op == NULLOP ||
3745 tree->opval.op == BLOCK))
3747 if (tree->left && tree->left->type == EX_VALUE)
3748 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3750 ast2iCode (tree->left,lvl+1);
3751 if (tree->right && tree->right->type == EX_VALUE)
3752 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3754 ast2iCode (tree->right,lvl+1);
3758 /* special cases for not evaluating */
3759 if (tree->opval.op != ':' &&
3760 tree->opval.op != '?' &&
3761 tree->opval.op != CALL &&
3762 tree->opval.op != IFX &&
3763 tree->opval.op != LABEL &&
3764 tree->opval.op != GOTO &&
3765 tree->opval.op != SWITCH &&
3766 tree->opval.op != FUNCTION &&
3767 tree->opval.op != INLINEASM &&
3768 tree->opval.op != CRITICAL)
3771 if (IS_ASSIGN_OP (tree->opval.op) ||
3772 IS_DEREF_OP (tree) ||
3773 (tree->opval.op == '&' && !tree->right) ||
3774 tree->opval.op == PTR_OP)
3777 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3778 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3781 left = operandFromAst (tree->left,lvl);
3783 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3784 left = geniCodeRValue (left, TRUE);
3788 left = operandFromAst (tree->left,lvl);
3790 if (tree->opval.op == INC_OP ||
3791 tree->opval.op == DEC_OP)
3794 right = operandFromAst (tree->right,lvl);
3799 right = operandFromAst (tree->right,lvl);
3803 /* now depending on the type of operand */
3804 /* this will be a biggy */
3805 switch (tree->opval.op)
3808 case '[': /* array operation */
3810 //sym_link *ltype = operandType (left);
3811 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3812 left = geniCodeRValue (left, FALSE);
3813 right = geniCodeRValue (right, TRUE);
3816 return geniCodeArray (left, right,lvl);
3818 case '.': /* structure dereference */
3819 if (IS_PTR (operandType (left)))
3820 left = geniCodeRValue (left, TRUE);
3822 left = geniCodeRValue (left, FALSE);
3824 return geniCodeStruct (left, right, tree->lvalue);
3826 case PTR_OP: /* structure pointer dereference */
3829 pType = operandType (left);
3830 left = geniCodeRValue (left, TRUE);
3832 setOClass (pType, getSpec (operandType (left)));
3835 return geniCodeStruct (left, right, tree->lvalue);
3837 case INC_OP: /* increment operator */
3839 return geniCodePostInc (left);
3841 return geniCodePreInc (right, tree->lvalue);
3843 case DEC_OP: /* decrement operator */
3845 return geniCodePostDec (left);
3847 return geniCodePreDec (right, tree->lvalue);
3849 case '&': /* bitwise and or address of operator */
3851 { /* this is a bitwise operator */
3852 left = geniCodeRValue (left, FALSE);
3853 right = geniCodeRValue (right, FALSE);
3854 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3857 return geniCodeAddressOf (left);
3859 case '|': /* bitwise or & xor */
3861 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3862 geniCodeRValue (right, FALSE),
3867 return geniCodeDivision (geniCodeRValue (left, FALSE),
3868 geniCodeRValue (right, FALSE),
3869 IS_INT (tree->ftype));
3872 return geniCodeModulus (geniCodeRValue (left, FALSE),
3873 geniCodeRValue (right, FALSE),
3874 IS_INT (tree->ftype));
3877 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3878 geniCodeRValue (right, FALSE),
3879 IS_INT (tree->ftype));
3881 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3885 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3886 geniCodeRValue (right, FALSE));
3888 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3892 return geniCodeAdd (geniCodeRValue (left, FALSE),
3893 geniCodeRValue (right, FALSE),lvl);
3895 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3898 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3899 geniCodeRValue (right, FALSE));
3902 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3903 geniCodeRValue (right, FALSE));
3905 #if 0 // this indeed needs a second thought
3909 // let's keep this simple: get the rvalue we need
3910 op=geniCodeRValue (right, FALSE);
3911 // now cast it to whatever we want
3912 op=geniCodeCast (operandType(left), op, FALSE);
3913 // if this is going to be used as an lvalue, make it so
3919 #else // bug #604575, is it a bug ????
3920 return geniCodeCast (operandType (left),
3921 geniCodeRValue (right, FALSE), FALSE);
3928 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3933 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3934 setOperandType (op, UCHARTYPE);
3945 /* different compilers (even different gccs) evaluate
3946 the two calls in a different order. to get the same
3947 result on all machines we've to specify a clear sequence.
3948 return geniCodeLogic (geniCodeRValue (left, FALSE),
3949 geniCodeRValue (right, FALSE),
3953 operand *leftOp, *rightOp;
3955 rightOp = geniCodeRValue (right, FALSE);
3956 leftOp = geniCodeRValue (left , FALSE);
3958 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3961 return geniCodeConditional (tree,lvl);
3964 return operandFromLit (getSize (tree->right->ftype));
3968 sym_link *rtype = operandType (right);
3969 sym_link *ltype = operandType (left);
3970 if (IS_PTR (rtype) && IS_ITEMP (right)
3971 && right->isaddr && compareType (rtype->next, ltype) == 1)
3972 right = geniCodeRValue (right, TRUE);
3974 right = geniCodeRValue (right, FALSE);
3976 geniCodeAssign (left, right, 0);
3981 geniCodeAssign (left,
3982 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3984 geniCodeRValue (right, FALSE),FALSE), 0);
3988 geniCodeAssign (left,
3989 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3991 geniCodeRValue (right, FALSE),
3992 IS_INT (tree->ftype)),
3996 geniCodeAssign (left,
3997 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3999 geniCodeRValue (right, FALSE),
4000 IS_INT (tree->ftype)),
4004 sym_link *rtype = operandType (right);
4005 sym_link *ltype = operandType (left);
4006 if (IS_PTR (rtype) && IS_ITEMP (right)
4007 && right->isaddr && compareType (rtype->next, ltype) == 1)
4008 right = geniCodeRValue (right, TRUE);
4010 right = geniCodeRValue (right, FALSE);
4013 return geniCodeAssign (left,
4014 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4020 sym_link *rtype = operandType (right);
4021 sym_link *ltype = operandType (left);
4022 if (IS_PTR (rtype) && IS_ITEMP (right)
4023 && right->isaddr && compareType (rtype->next, ltype) == 1)
4025 right = geniCodeRValue (right, TRUE);
4029 right = geniCodeRValue (right, FALSE);
4032 geniCodeAssign (left,
4033 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4039 geniCodeAssign (left,
4040 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4042 geniCodeRValue (right, FALSE)), 0);
4045 geniCodeAssign (left,
4046 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4048 geniCodeRValue (right, FALSE)), 0);
4051 geniCodeAssign (left,
4052 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4054 geniCodeRValue (right, FALSE),
4056 operandType (left)), 0);
4059 geniCodeAssign (left,
4060 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4062 geniCodeRValue (right, FALSE),
4064 operandType (left)), 0);
4067 geniCodeAssign (left,
4068 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4070 geniCodeRValue (right, FALSE),
4072 operandType (left)), 0);
4074 return geniCodeRValue (right, FALSE);
4077 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4080 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4081 return ast2iCode (tree->right,lvl+1);
4084 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4085 return ast2iCode (tree->right,lvl+1);
4088 geniCodeFunctionBody (tree,lvl);
4092 geniCodeReturn (right);
4096 geniCodeIfx (tree,lvl);
4100 geniCodeSwitch (tree,lvl);
4104 geniCodeInline (tree);
4108 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4112 geniCodeCritical (tree, lvl);
4118 /*-----------------------------------------------------------------*/
4119 /* reverseICChain - gets from the list and creates a linkedlist */
4120 /*-----------------------------------------------------------------*/
4127 while ((loop = getSet (&iCodeChain)))
4139 /*-----------------------------------------------------------------*/
4140 /* iCodeFromAst - given an ast will convert it to iCode */
4141 /*-----------------------------------------------------------------*/
4143 iCodeFromAst (ast * tree)
4145 returnLabel = newiTempLabel ("_return");
4146 entryLabel = newiTempLabel ("_entry");
4148 return reverseiCChain ();
4151 static const char *opTypeToStr(OPTYPE op)
4155 case SYMBOL: return "symbol";
4156 case VALUE: return "value";
4157 case TYPE: return "type";
4159 return "undefined type";
4163 operand *validateOpType(operand *op,
4170 if (op && op->type == type)
4175 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4176 " expected %s, got %s\n",
4177 macro, args, file, line,
4178 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4180 return op; // never reached, makes compiler happy.