1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
43 symbol *returnLabel; /* function return label */
44 symbol *entryLabel; /* function entry label */
46 /*-----------------------------------------------------------------*/
47 /* forward definition of some functions */
48 operand *geniCodeDivision (operand *, operand *, bool);
49 operand *geniCodeAssign (operand *, operand *, int);
50 static operand *geniCodeArray (operand *, operand *,int);
51 static operand *geniCodeArray2Ptr (operand *);
52 operand *geniCodeRValue (operand *, bool);
53 operand *geniCodeDerefPtr (operand *,int);
54 int isLvaluereq(int lvl);
55 void setOClass (sym_link * ptr, sym_link * spec);
56 static operand *geniCodeCast (sym_link *, operand *, bool);
58 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
59 /* forward definition of ic print functions */
60 PRINTFUNC (picGetValueAtAddr);
61 PRINTFUNC (picSetValueAtAddr);
62 PRINTFUNC (picAddrOf);
63 PRINTFUNC (picGeneric);
64 PRINTFUNC (picGenericOne);
66 PRINTFUNC (picAssign);
70 PRINTFUNC (picJumpTable);
71 PRINTFUNC (picInline);
72 PRINTFUNC (picReceive);
73 PRINTFUNC (picDummyRead);
74 PRINTFUNC (picCritical);
75 PRINTFUNC (picEndCritical);
77 iCodeTable codeTable[] =
79 {'!', "not", picGenericOne, NULL},
80 {'~', "~", picGenericOne, NULL},
81 {RRC, "rrc", picGenericOne, NULL},
82 {RLC, "rlc", picGenericOne, NULL},
83 {GETHBIT, "ghbit", picGenericOne, NULL},
84 {UNARYMINUS, "-", picGenericOne, NULL},
85 {IPUSH, "push", picGenericOne, NULL},
86 {IPOP, "pop", picGenericOne, NULL},
87 {CALL, "call", picGenericOne, NULL},
88 {PCALL, "pcall", picGenericOne, NULL},
89 {FUNCTION, "proc", picGenericOne, NULL},
90 {ENDFUNCTION, "eproc", picGenericOne, NULL},
91 {RETURN, "ret", picGenericOne, NULL},
92 {'+', "+", picGeneric, NULL},
93 {'-', "-", picGeneric, NULL},
94 {'*', "*", picGeneric, NULL},
95 {'/', "/", picGeneric, NULL},
96 {'%', "%", picGeneric, NULL},
97 {'>', ">", picGeneric, NULL},
98 {'<', "<", picGeneric, NULL},
99 {LE_OP, "<=", picGeneric, NULL},
100 {GE_OP, ">=", picGeneric, NULL},
101 {EQ_OP, "==", picGeneric, NULL},
102 {NE_OP, "!=", picGeneric, NULL},
103 {AND_OP, "&&", picGeneric, NULL},
104 {OR_OP, "||", picGeneric, NULL},
105 {'^', "^", picGeneric, NULL},
106 {'|', "|", picGeneric, NULL},
107 {BITWISEAND, "&", picGeneric, NULL},
108 {LEFT_OP, "<<", picGeneric, NULL},
109 {RIGHT_OP, ">>", picGeneric, NULL},
110 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
111 {ADDRESS_OF, "&", picAddrOf, NULL},
112 {CAST, "<>", picCast, NULL},
113 {'=', ":=", picAssign, NULL},
114 {LABEL, "", picLabel, NULL},
115 {GOTO, "", picGoto, NULL},
116 {JUMPTABLE, "jtab", picJumpTable, NULL},
117 {IFX, "if", picIfx, NULL},
118 {INLINEASM, "", picInline, NULL},
119 {RECEIVE, "recv", picReceive, NULL},
120 {SEND, "send", picGenericOne, NULL},
121 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
122 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
123 {CRITICAL, "critical_start", picCritical, NULL},
124 {ENDCRITICAL, "critical_end", picEndCritical, NULL}
127 /*-----------------------------------------------------------------*/
128 /* checkConstantRange: check a constant against the type */
129 /*-----------------------------------------------------------------*/
132 /* pedantic=0: allmost anything is allowed as long as the absolute
133 value is within the bit range of the type, and -1 is treated as
134 0xf..f for unsigned types (e.g. in assign)
135 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
136 pedantic>1: "char c=200" is not allowed (evaluates to -56)
139 void checkConstantRange(sym_link *ltype, value *val, char *msg,
146 max = pow ((double)2.0, (double)bitsForType(ltype));
148 if (IS_LONG(val->type)) {
149 if (IS_UNSIGNED(val->type)) {
150 v=SPEC_CVAL(val->type).v_ulong;
152 v=SPEC_CVAL(val->type).v_long;
155 if (IS_UNSIGNED(val->type)) {
156 v=SPEC_CVAL(val->type).v_uint;
158 v=SPEC_CVAL(val->type).v_int;
164 // this could be a good idea
165 if (options.pedantic)
169 if (IS_FLOAT(ltype)) {
174 if (!IS_UNSIGNED(val->type) && v<0) {
176 if (IS_UNSIGNED(ltype) && (pedantic>1)) {
182 // if very pedantic: "char c=200" is not allowed
183 if (pedantic>1 && !IS_UNSIGNED(ltype)) {
184 max = max/2 + negative;
191 #if 0 // temporary disabled, leaving the warning as a reminder
193 SNPRINTF (message, sizeof(message), "for %s %s in %s",
194 IS_UNSIGNED(ltype) ? "unsigned" : "signed",
195 nounName(ltype), msg);
196 werror (W_CONST_RANGE, message);
204 /*-----------------------------------------------------------------*/
205 /* operandName - returns the name of the operand */
206 /*-----------------------------------------------------------------*/
208 printOperand (operand * op, FILE * file)
225 opetype = getSpec (operandType (op));
226 if (IS_FLOAT (opetype))
227 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
229 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
230 printTypeChain (operandType (op), file);
237 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
238 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
240 OP_LIVEFROM (op), OP_LIVETO (op),
241 OP_SYMBOL (op)->stack,
242 op->isaddr, OP_SYMBOL (op)->isreqv,
243 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
244 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
248 printTypeChain (operandType (op), file);
249 if (SPIL_LOC (op) && IS_ITEMP (op))
250 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
255 /* if assigned to registers */
256 if (OP_SYMBOL (op)->nRegs)
258 if (OP_SYMBOL (op)->isspilt)
260 if (!OP_SYMBOL (op)->remat)
261 if (OP_SYMBOL (op)->usl.spillLoc)
262 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
263 OP_SYMBOL (op)->usl.spillLoc->rname :
264 OP_SYMBOL (op)->usl.spillLoc->name));
266 fprintf (file, "[err]");
268 fprintf (file, "[remat]");
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
280 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
281 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
282 /* if assigned to registers */
283 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
287 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
288 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
289 OP_SYMBOL (op)->regs[i]->name :
298 printTypeChain (op->operand.typeOperand, file);
304 fprintf (file, "\n");
309 /*-----------------------------------------------------------------*/
310 /* print functions */
311 /*-----------------------------------------------------------------*/
312 PRINTFUNC (picGetValueAtAddr)
315 printOperand (IC_RESULT (ic), of);
318 printOperand (IC_LEFT (ic), of);
324 PRINTFUNC (picSetValueAtAddr)
328 printOperand (IC_LEFT (ic), of);
329 fprintf (of, "] = ");
330 printOperand (IC_RIGHT (ic), of);
334 PRINTFUNC (picAddrOf)
337 printOperand (IC_RESULT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
341 fprintf (of, " = &[");
342 printOperand (IC_LEFT (ic), of);
345 if (IS_ITEMP (IC_LEFT (ic)))
346 fprintf (of, " offsetAdd ");
349 printOperand (IC_RIGHT (ic), of);
351 if (IS_ITEMP (IC_LEFT (ic)))
357 PRINTFUNC (picJumpTable)
362 fprintf (of, "%s\t", s);
363 printOperand (IC_JTCOND (ic), of);
365 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
366 sym = setNextItem (IC_JTLABELS (ic)))
367 fprintf (of, "\t\t\t%s\n", sym->name);
370 PRINTFUNC (picGeneric)
373 printOperand (IC_RESULT (ic), of);
375 printOperand (IC_LEFT (ic), of);
376 fprintf (of, " %s ", s);
377 printOperand (IC_RIGHT (ic), of);
381 PRINTFUNC (picGenericOne)
386 printOperand (IC_RESULT (ic), of);
392 fprintf (of, "%s ", s);
393 printOperand (IC_LEFT (ic), of);
396 if (!IC_RESULT (ic) && !IC_LEFT (ic))
399 if (ic->op == SEND || ic->op == RECEIVE) {
400 fprintf(of,"{argreg = %d}",ic->argreg);
408 printOperand (IC_RESULT (ic), of);
410 printOperand (IC_LEFT (ic), of);
411 printOperand (IC_RIGHT (ic), of);
416 PRINTFUNC (picAssign)
420 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
423 printOperand (IC_RESULT (ic), of);
425 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
428 fprintf (of, " %s ", s);
429 printOperand (IC_RIGHT (ic), of);
436 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
442 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
449 printOperand (IC_COND (ic), of);
452 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
455 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
457 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
461 PRINTFUNC (picInline)
463 fprintf (of, "%s", IC_INLINE (ic));
466 PRINTFUNC (picReceive)
468 printOperand (IC_RESULT (ic), of);
469 fprintf (of, " = %s ", s);
470 printOperand (IC_LEFT (ic), of);
474 PRINTFUNC (picDummyRead)
477 fprintf (of, "%s ", s);
478 printOperand (IC_RIGHT (ic), of);
482 PRINTFUNC (picCritical)
486 printOperand (IC_RESULT (ic), of);
488 fprintf (of, "(stack)");
489 fprintf (of, " = %s ", s);
493 PRINTFUNC (picEndCritical)
496 fprintf (of, "%s = ", s);
498 printOperand (IC_RIGHT (ic), of);
500 fprintf (of, "(stack)");
504 /*-----------------------------------------------------------------*/
505 /* piCode - prints one iCode */
506 /*-----------------------------------------------------------------*/
508 piCode (void *item, FILE * of)
516 icTab = getTableEntry (ic->op);
517 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
518 ic->filename, ic->lineno,
519 ic->seq, ic->key, ic->depth, ic->supportRtn);
520 icTab->iCodePrint (of, ic, icTab->printName);
526 printiCChain(ic,stdout);
528 /*-----------------------------------------------------------------*/
529 /* printiCChain - prints intermediate code for humans */
530 /*-----------------------------------------------------------------*/
532 printiCChain (iCode * icChain, FILE * of)
539 for (loop = icChain; loop; loop = loop->next)
541 if ((icTab = getTableEntry (loop->op)))
543 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
544 loop->filename, loop->lineno,
545 loop->seq, loop->key, loop->depth, loop->supportRtn);
547 icTab->iCodePrint (of, loop, icTab->printName);
553 /*-----------------------------------------------------------------*/
554 /* newOperand - allocate, init & return a new iCode */
555 /*-----------------------------------------------------------------*/
561 op = Safe_alloc ( sizeof (operand));
567 /*-----------------------------------------------------------------*/
568 /* newiCode - create and return a new iCode entry initialised */
569 /*-----------------------------------------------------------------*/
571 newiCode (int op, operand * left, operand * right)
575 ic = Safe_alloc ( sizeof (iCode));
577 ic->seqPoint = seqPoint;
579 ic->filename = filename;
581 ic->level = scopeLevel;
583 ic->key = iCodeKey++;
585 IC_RIGHT (ic) = right;
590 /*-----------------------------------------------------------------*/
591 /* newiCode for conditional statements */
592 /*-----------------------------------------------------------------*/
594 newiCodeCondition (operand * condition,
600 if (IS_VOID(operandType(condition))) {
601 werror(E_VOID_VALUE_USED);
604 ic = newiCode (IFX, NULL, NULL);
605 IC_COND (ic) = condition;
606 IC_TRUE (ic) = trueLabel;
607 IC_FALSE (ic) = falseLabel;
611 /*-----------------------------------------------------------------*/
612 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
613 /*-----------------------------------------------------------------*/
615 newiCodeLabelGoto (int op, symbol * label)
619 ic = newiCode (op, NULL, NULL);
623 IC_RIGHT (ic) = NULL;
624 IC_RESULT (ic) = NULL;
628 /*-----------------------------------------------------------------*/
629 /* newiTemp - allocate & return a newItemp Variable */
630 /*-----------------------------------------------------------------*/
638 SNPRINTF (buffer, sizeof(buffer), "%s", s);
642 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
645 itmp = newSymbol (buffer, 1);
646 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
652 /*-----------------------------------------------------------------*/
653 /* newiTempLabel - creates a temp variable label */
654 /*-----------------------------------------------------------------*/
656 newiTempLabel (char *s)
660 /* check if this alredy exists */
661 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
666 itmplbl = newSymbol (s, 1);
670 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
671 itmplbl = newSymbol (buffer, 1);
676 itmplbl->key = labelKey++;
677 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
681 /*-----------------------------------------------------------------*/
682 /* newiTempPreheaderLabel - creates a new preheader label */
683 /*-----------------------------------------------------------------*/
685 newiTempPreheaderLabel ()
689 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
690 itmplbl = newSymbol (buffer, 1);
694 itmplbl->key = labelKey++;
695 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
700 /*-----------------------------------------------------------------*/
701 /* initiCode - initialises some iCode related stuff */
702 /*-----------------------------------------------------------------*/
709 /*-----------------------------------------------------------------*/
710 /* copyiCode - make a copy of the iCode given */
711 /*-----------------------------------------------------------------*/
713 copyiCode (iCode * ic)
715 iCode *nic = newiCode (ic->op, NULL, NULL);
717 nic->lineno = ic->lineno;
718 nic->filename = ic->filename;
719 nic->block = ic->block;
720 nic->level = ic->level;
721 nic->parmBytes = ic->parmBytes;
723 /* deal with the special cases first */
727 IC_COND (nic) = operandFromOperand (IC_COND (ic));
728 IC_TRUE (nic) = IC_TRUE (ic);
729 IC_FALSE (nic) = IC_FALSE (ic);
733 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
734 IC_JTLABELS (nic) = IC_JTLABELS (ic);
739 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
740 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
744 IC_INLINE (nic) = IC_INLINE (ic);
748 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
752 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
753 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
754 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
760 /*-----------------------------------------------------------------*/
761 /* getTableEntry - gets the table entry for the given operator */
762 /*-----------------------------------------------------------------*/
764 getTableEntry (int oper)
768 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
769 if (oper == codeTable[i].icode)
770 return &codeTable[i];
775 /*-----------------------------------------------------------------*/
776 /* newiTempOperand - new intermediate temp operand */
777 /*-----------------------------------------------------------------*/
779 newiTempOperand (sym_link * type, char throwType)
782 operand *op = newOperand ();
786 itmp = newiTemp (NULL);
788 etype = getSpec (type);
790 if (IS_LITERAL (etype))
793 /* copy the type information */
795 itmp->etype = getSpec (itmp->type = (throwType ? type :
796 copyLinkChain (type)));
797 if (IS_LITERAL (itmp->etype))
799 SPEC_SCLS (itmp->etype) = S_REGISTER;
800 SPEC_OCLS (itmp->etype) = reg;
803 op->operand.symOperand = itmp;
804 op->key = itmp->key = ++operandKey;
808 /*-----------------------------------------------------------------*/
809 /* operandType - returns the type chain for an operand */
810 /*-----------------------------------------------------------------*/
812 operandType (operand * op)
814 /* depending on type of operand */
819 return op->operand.valOperand->type;
822 return op->operand.symOperand->type;
825 return op->operand.typeOperand;
827 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
828 " operand type not known ");
829 assert (0); /* should never come here */
830 /* Just to keep the compiler happy */
831 return (sym_link *) 0;
835 /*-----------------------------------------------------------------*/
836 /* isParamterToCall - will return 1 if op is a parameter to args */
837 /*-----------------------------------------------------------------*/
839 isParameterToCall (value * args, operand * op)
843 wassert (IS_SYMOP(op));
848 isSymbolEqual (op->operand.symOperand, tval->sym))
855 /*-----------------------------------------------------------------*/
856 /* isOperandGlobal - return 1 if operand is a global variable */
857 /*-----------------------------------------------------------------*/
859 isOperandGlobal (operand * op)
868 (op->operand.symOperand->level == 0 ||
869 IS_STATIC (op->operand.symOperand->etype) ||
870 IS_EXTERN (op->operand.symOperand->etype))
877 /*-----------------------------------------------------------------*/
878 /* isOperandVolatile - return 1 if the operand is volatile */
879 /*-----------------------------------------------------------------*/
881 isOperandVolatile (operand * op, bool chkTemp)
886 if (IS_ITEMP (op) && !chkTemp)
889 opetype = getSpec (optype = operandType (op));
891 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
894 if (IS_VOLATILE (opetype))
899 /*-----------------------------------------------------------------*/
900 /* isOperandLiteral - returns 1 if an operand contains a literal */
901 /*-----------------------------------------------------------------*/
903 isOperandLiteral (operand * op)
910 opetype = getSpec (operandType (op));
912 if (IS_LITERAL (opetype))
918 /*-----------------------------------------------------------------*/
919 /* isOperandInFarSpace - will return true if operand is in farSpace */
920 /*-----------------------------------------------------------------*/
922 isOperandInFarSpace (operand * op)
932 if (!IS_TRUE_SYMOP (op))
935 etype = SPIL_LOC (op)->etype;
941 etype = getSpec (operandType (op));
943 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
946 /*------------------------------------------------------------------*/
947 /* isOperandInDirSpace - will return true if operand is in dirSpace */
948 /*------------------------------------------------------------------*/
950 isOperandInDirSpace (operand * op)
960 if (!IS_TRUE_SYMOP (op))
963 etype = SPIL_LOC (op)->etype;
969 etype = getSpec (operandType (op));
971 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
974 /*--------------------------------------------------------------------*/
975 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
976 /*--------------------------------------------------------------------*/
978 isOperandInCodeSpace (operand * op)
988 etype = getSpec (operandType (op));
990 if (!IS_TRUE_SYMOP (op))
993 etype = SPIL_LOC (op)->etype;
999 etype = getSpec (operandType (op));
1001 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1004 /*-----------------------------------------------------------------*/
1005 /* isOperandOnStack - will return true if operand is on stack */
1006 /*-----------------------------------------------------------------*/
1008 isOperandOnStack (operand * op)
1018 etype = getSpec (operandType (op));
1019 if (IN_STACK (etype) ||
1020 OP_SYMBOL(op)->onStack ||
1021 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1027 /*-----------------------------------------------------------------*/
1028 /* isOclsExpensive - will return true if accesses to an output */
1029 /* storage class are expensive */
1030 /*-----------------------------------------------------------------*/
1032 isOclsExpensive (struct memmap *oclass)
1034 if (port->oclsExpense)
1035 return port->oclsExpense (oclass) > 0;
1037 /* In the absence of port specific guidance, assume only */
1038 /* farspace is expensive. */
1039 return IN_FARSPACE (oclass);
1042 /*-----------------------------------------------------------------*/
1043 /* operandLitValue - literal value of an operand */
1044 /*-----------------------------------------------------------------*/
1046 operandLitValue (operand * op)
1048 assert (isOperandLiteral (op));
1050 return floatFromVal (op->operand.valOperand);
1053 /*-----------------------------------------------------------------*/
1054 /* getBuiltInParms - returns parameters to a builtin functions */
1055 /*-----------------------------------------------------------------*/
1056 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1061 /* builtin functions uses only SEND for parameters */
1062 while (ic->op != CALL) {
1063 assert(ic->op == SEND && ic->builtinSEND);
1064 ic->generated = 1; /* mark the icode as generated */
1065 parms[*pcount] = IC_LEFT(ic);
1071 /* make sure this is a builtin function call */
1072 assert(IS_SYMOP(IC_LEFT(ic)));
1073 ftype = operandType(IC_LEFT(ic));
1074 assert(IFFUNC_ISBUILTIN(ftype));
1078 /*-----------------------------------------------------------------*/
1079 /* operandOperation - performs operations on operands */
1080 /*-----------------------------------------------------------------*/
1082 operandOperation (operand * left, operand * right,
1083 int op, sym_link * type)
1085 sym_link *let , *ret=NULL;
1086 operand *retval = (operand *) 0;
1088 assert (isOperandLiteral (left));
1089 let = getSpec(operandType(left));
1091 assert (isOperandLiteral (right));
1092 ret = getSpec(operandType(right));
1098 retval = operandFromValue (valCastLiteral (type,
1099 operandLitValue (left) +
1100 operandLitValue (right)));
1103 retval = operandFromValue (valCastLiteral (type,
1104 operandLitValue (left) -
1105 operandLitValue (right)));
1109 retval = operandFromValue (valCastLiteral (type,
1110 operandLitValue (left) *
1111 operandLitValue (right)));
1112 This could be all we've to do, but with gcc we've to take care about
1113 overflows. Two examples:
1114 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1115 significant bits are lost (52 in fraction, 63 bits would be
1116 necessary to keep full precision).
1117 If the resulting double value is greater than ULONG_MAX (resp.
1118 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1121 /* if it is not a specifier then we can assume that */
1122 /* it will be an unsigned long */
1123 if (IS_INT (type) ||
1126 /* long is handled here, because it can overflow with double */
1127 if (IS_LONG (type) ||
1129 /* signed and unsigned mul are the same, as long as the precision
1130 of the result isn't bigger than the precision of the operands. */
1131 retval = operandFromValue (valCastLiteral (type,
1132 (TYPE_UDWORD) operandLitValue (left) *
1133 (TYPE_UDWORD) operandLitValue (right)));
1134 else if (IS_UNSIGNED (type)) /* unsigned int */
1136 /* unsigned int is handled here in order to detect overflow */
1137 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1138 (TYPE_UWORD) operandLitValue (right);
1140 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1141 if (ul != (TYPE_UWORD) ul)
1144 else /* signed int */
1146 /* signed int is handled here in order to detect overflow */
1147 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1148 (TYPE_WORD) operandLitValue (right);
1150 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1151 if (l != (TYPE_WORD) l)
1156 /* all others go here: */
1157 retval = operandFromValue (valCastLiteral (type,
1158 operandLitValue (left) *
1159 operandLitValue (right)));
1162 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1164 werror (E_DIVIDE_BY_ZERO);
1170 if (IS_UNSIGNED (type))
1172 SPEC_USIGN (let) = 1;
1173 SPEC_USIGN (ret) = 1;
1174 retval = operandFromValue (valCastLiteral (type,
1175 (TYPE_UDWORD) operandLitValue (left) /
1176 (TYPE_UDWORD) operandLitValue (right)));
1180 retval = operandFromValue (valCastLiteral (type,
1181 operandLitValue (left) /
1182 operandLitValue (right)));
1187 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1189 werror (E_DIVIDE_BY_ZERO);
1194 if (IS_UNSIGNED (type))
1195 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1196 (TYPE_UDWORD) operandLitValue (right));
1198 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1199 (TYPE_DWORD) operandLitValue (right));
1203 /* The number of left shifts is always unsigned. Signed doesn't make
1204 sense here. Shifting by a negative number is impossible. */
1205 retval = operandFromValue (valCastLiteral (type,
1206 ((TYPE_UDWORD) operandLitValue (left) <<
1207 (TYPE_UDWORD) operandLitValue (right))));
1210 /* The number of right shifts is always unsigned. Signed doesn't make
1211 sense here. Shifting by a negative number is impossible. */
1212 if (IS_UNSIGNED(let))
1213 /* unsigned: logic shift right */
1214 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1215 (TYPE_UDWORD) operandLitValue (right));
1217 /* signed: arithmetic shift right */
1218 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1219 (TYPE_UDWORD) operandLitValue (right));
1222 /* this op doesn't care about signedness */
1226 l = (TYPE_UDWORD) operandLitValue (left);
1227 if (IS_CHAR(OP_VALUE(left)->type))
1229 else if (!IS_LONG (OP_VALUE(left)->type))
1231 r = (TYPE_UDWORD) operandLitValue (right);
1232 if (IS_CHAR(OP_VALUE(right)->type))
1234 else if (!IS_LONG (OP_VALUE(right)->type))
1236 retval = operandFromLit (l == r);
1240 retval = operandFromLit (operandLitValue (left) <
1241 operandLitValue (right));
1244 retval = operandFromLit (operandLitValue (left) <=
1245 operandLitValue (right));
1248 retval = operandFromLit (operandLitValue (left) !=
1249 operandLitValue (right));
1252 retval = operandFromLit (operandLitValue (left) >
1253 operandLitValue (right));
1256 retval = operandFromLit (operandLitValue (left) >=
1257 operandLitValue (right));
1260 retval = operandFromValue (valCastLiteral (type,
1261 (TYPE_UDWORD)operandLitValue(left) &
1262 (TYPE_UDWORD)operandLitValue(right)));
1265 retval = operandFromValue (valCastLiteral (type,
1266 (TYPE_UDWORD)operandLitValue(left) |
1267 (TYPE_UDWORD)operandLitValue(right)));
1270 retval = operandFromValue (valCastLiteral (type,
1271 (TYPE_UDWORD)operandLitValue(left) ^
1272 (TYPE_UDWORD)operandLitValue(right)));
1275 retval = operandFromLit (operandLitValue (left) &&
1276 operandLitValue (right));
1279 retval = operandFromLit (operandLitValue (left) ||
1280 operandLitValue (right));
1284 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1286 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1292 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1294 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1300 retval = operandFromValue (valCastLiteral (type,
1301 -1 * operandLitValue (left)));
1305 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1309 retval = operandFromLit (!operandLitValue (left));
1313 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1314 " operandOperation invalid operator ");
1322 /*-----------------------------------------------------------------*/
1323 /* isOperandEqual - compares two operand & return 1 if they r = */
1324 /*-----------------------------------------------------------------*/
1326 isOperandEqual (operand * left, operand * right)
1328 /* if the pointers are equal then they are equal */
1332 /* if either of them null then false */
1333 if (!left || !right)
1336 if (left->type != right->type)
1339 if (IS_SYMOP (left) && IS_SYMOP (right))
1340 return left->key == right->key;
1342 /* if types are the same */
1346 return isSymbolEqual (left->operand.symOperand,
1347 right->operand.symOperand);
1349 return (floatFromVal (left->operand.valOperand) ==
1350 floatFromVal (right->operand.valOperand));
1352 if (compareType (left->operand.typeOperand,
1353 right->operand.typeOperand) == 1)
1360 /*-------------------------------------------------------------------*/
1361 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1362 /*-------------------------------------------------------------------*/
1364 isiCodeEqual (iCode * left, iCode * right)
1366 /* if the same pointer */
1370 /* if either of them null */
1371 if (!left || !right)
1374 /* if operand are the same */
1375 if (left->op == right->op)
1378 /* compare all the elements depending on type */
1379 if (left->op != IFX)
1381 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1383 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1389 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1391 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1393 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1402 /*-----------------------------------------------------------------*/
1403 /* newiTempFromOp - create a temp Operand with same attributes */
1404 /*-----------------------------------------------------------------*/
1406 newiTempFromOp (operand * op)
1416 nop = newiTempOperand (operandType (op), TRUE);
1417 nop->isaddr = op->isaddr;
1418 nop->isvolatile = op->isvolatile;
1419 nop->isGlobal = op->isGlobal;
1420 nop->isLiteral = op->isLiteral;
1421 nop->usesDefs = op->usesDefs;
1422 nop->isParm = op->isParm;
1426 /*-----------------------------------------------------------------*/
1427 /* operand from operand - creates an operand holder for the type */
1428 /*-----------------------------------------------------------------*/
1430 operandFromOperand (operand * op)
1436 nop = newOperand ();
1437 nop->type = op->type;
1438 nop->isaddr = op->isaddr;
1440 nop->isvolatile = op->isvolatile;
1441 nop->isGlobal = op->isGlobal;
1442 nop->isLiteral = op->isLiteral;
1443 nop->usesDefs = op->usesDefs;
1444 nop->isParm = op->isParm;
1449 nop->operand.symOperand = op->operand.symOperand;
1452 nop->operand.valOperand = op->operand.valOperand;
1455 nop->operand.typeOperand = op->operand.typeOperand;
1462 /*-----------------------------------------------------------------*/
1463 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1464 /*-----------------------------------------------------------------*/
1466 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1468 operand *nop = operandFromOperand (op);
1470 if (nop->type == SYMBOL)
1472 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1473 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1479 /*-----------------------------------------------------------------*/
1480 /* operandFromSymbol - creates an operand from a symbol */
1481 /*-----------------------------------------------------------------*/
1483 operandFromSymbol (symbol * sym)
1488 /* if the symbol's type is a literal */
1489 /* then it is an enumerator type */
1490 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1491 return operandFromValue (valFromType (sym->etype));
1494 sym->key = ++operandKey;
1496 /* if this an implicit variable, means struct/union */
1497 /* member so just return it */
1498 if (sym->implicit || IS_FUNC (sym->type))
1502 op->operand.symOperand = sym;
1504 op->isvolatile = isOperandVolatile (op, TRUE);
1505 op->isGlobal = isOperandGlobal (op);
1509 /* under the following conditions create a
1510 register equivalent for a local symbol */
1511 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1512 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1514 (!(options.model == MODEL_FLAT24)) ) &&
1515 options.stackAuto == 0)
1518 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1519 !IS_FUNC (sym->type) && /* not a function */
1520 !sym->_isparm && /* not a parameter */
1521 sym->level && /* is a local variable */
1522 !sym->addrtaken && /* whose address has not been taken */
1523 !sym->reqv && /* does not already have a reg equivalence */
1524 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1525 !IS_STATIC (sym->etype) && /* and not declared static */
1526 !sym->islbl && /* not a label */
1527 ok && /* farspace check */
1528 !IS_BITVAR (sym->etype) /* not a bit variable */
1532 /* we will use it after all optimizations
1533 and before liveRange calculation */
1534 sym->reqv = newiTempOperand (sym->type, 0);
1535 sym->reqv->key = sym->key;
1536 OP_SYMBOL (sym->reqv)->prereqv = sym;
1537 OP_SYMBOL (sym->reqv)->key = sym->key;
1538 OP_SYMBOL (sym->reqv)->isreqv = 1;
1539 OP_SYMBOL (sym->reqv)->islocal = 1;
1540 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1541 SPIL_LOC (sym->reqv) = sym;
1544 if (!IS_AGGREGATE (sym->type))
1548 op->operand.symOperand = sym;
1551 op->isvolatile = isOperandVolatile (op, TRUE);
1552 op->isGlobal = isOperandGlobal (op);
1553 op->isPtr = IS_PTR (operandType (op));
1554 op->isParm = sym->_isparm;
1559 /* itemp = &[_symbol] */
1561 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1562 IC_LEFT (ic)->type = SYMBOL;
1563 IC_LEFT (ic)->operand.symOperand = sym;
1564 IC_LEFT (ic)->key = sym->key;
1565 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1566 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1567 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1570 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1571 if (IS_ARRAY (sym->type))
1573 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1574 IC_RESULT (ic)->isaddr = 0;
1577 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1581 return IC_RESULT (ic);
1584 /*-----------------------------------------------------------------*/
1585 /* operandFromValue - creates an operand from value */
1586 /*-----------------------------------------------------------------*/
1588 operandFromValue (value * val)
1592 /* if this is a symbol then do the symbol thing */
1594 return operandFromSymbol (val->sym);
1596 /* this is not a symbol */
1599 op->operand.valOperand = val;
1600 op->isLiteral = isOperandLiteral (op);
1604 /*-----------------------------------------------------------------*/
1605 /* operandFromLink - operand from typeChain */
1606 /*-----------------------------------------------------------------*/
1608 operandFromLink (sym_link * type)
1612 /* operand from sym_link */
1618 op->operand.typeOperand = copyLinkChain (type);
1622 /*-----------------------------------------------------------------*/
1623 /* operandFromLit - makes an operand from a literal value */
1624 /*-----------------------------------------------------------------*/
1626 operandFromLit (double i)
1628 return operandFromValue (valueFromLit (i));
1631 /*-----------------------------------------------------------------*/
1632 /* operandFromAst - creates an operand from an ast */
1633 /*-----------------------------------------------------------------*/
1635 operandFromAst (ast * tree,int lvl)
1641 /* depending on type do */
1645 return ast2iCode (tree,lvl+1);
1649 return operandFromValue (tree->opval.val);
1653 return operandFromLink (tree->opval.lnk);
1660 /* Just to keep the compiler happy */
1661 return (operand *) 0;
1664 /*-----------------------------------------------------------------*/
1665 /* setOperandType - sets the operand's type to the given type */
1666 /*-----------------------------------------------------------------*/
1668 setOperandType (operand * op, sym_link * type)
1670 /* depending on the type of operand */
1675 op->operand.valOperand->etype =
1676 getSpec (op->operand.valOperand->type =
1677 copyLinkChain (type));
1681 if (op->operand.symOperand->isitmp)
1682 op->operand.symOperand->etype =
1683 getSpec (op->operand.symOperand->type =
1684 copyLinkChain (type));
1686 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1687 "attempt to modify type of source");
1691 op->operand.typeOperand = copyLinkChain (type);
1696 /*-----------------------------------------------------------------*/
1697 /* Get size in byte of ptr need to access an array */
1698 /*-----------------------------------------------------------------*/
1700 getArraySizePtr (operand * op)
1702 sym_link *ltype = operandType(op);
1706 int size = getSize(ltype);
1707 return(IS_GENPTR(ltype)?(size-1):size);
1712 sym_link *letype = getSpec(ltype);
1713 switch (PTR_TYPE (SPEC_OCLS (letype)))
1725 return (GPTRSIZE-1);
1734 /*-----------------------------------------------------------------*/
1735 /* perform "usual unary conversions" */
1736 /*-----------------------------------------------------------------*/
1739 usualUnaryConversions (operand * op)
1741 if (IS_INTEGRAL (operandType (op)))
1743 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1746 return geniCodeCast (INTTYPE, op, TRUE);
1753 /*-----------------------------------------------------------------*/
1754 /* perform "usual binary conversions" */
1755 /*-----------------------------------------------------------------*/
1758 usualBinaryConversions (operand ** op1, operand ** op2,
1759 bool resultIsInt, char op)
1762 sym_link *rtype = operandType (*op2);
1763 sym_link *ltype = operandType (*op1);
1765 #define OLDONEBYTEOPS 1
1767 #ifdef OLDONEBYTEOPS
1768 bool oldOneByteOps = FALSE;
1769 static bool saidHello = FALSE;
1771 if (strcmp (port->target, "pic14") == 0)
1772 oldOneByteOps = TRUE;
1773 if (getenv ("SDCC_NEWONEBYTEOPS"))
1777 fprintf (stderr, "Override: oldOneByteOps = FALSE\n");
1780 oldOneByteOps = FALSE;
1782 else if (getenv ("SDCC_OLDONEBYTEOPS"))
1786 fprintf (stderr, "Override: oldOneByteOps = TRUE\n");
1789 oldOneByteOps = TRUE;
1794 && ( (IS_CHAR (getSpec (ltype)) && !IS_UNSIGNED (getSpec (ltype)))
1795 || (IS_CHAR (getSpec (rtype)) && !IS_UNSIGNED (getSpec (rtype)))))
1796 /* one or two signed char operands: promote to int */
1800 ctype = computeType (ltype, rtype, resultIsInt);
1802 #ifdef OLDONEBYTEOPS
1807 && IS_CHAR (getSpec (ltype)) && IS_UNSIGNED (getSpec (ltype))
1808 && IS_CHAR (getSpec (rtype)) && IS_UNSIGNED (getSpec (rtype)))
1810 /* two unsigned char operands and Mult: no promotion */
1813 *op1 = geniCodeCast (ctype, *op1, TRUE);
1814 *op2 = geniCodeCast (ctype, *op2, TRUE);
1826 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1828 /* one byte operations: keep signedness for code generator */
1836 *op1 = geniCodeCast (ctype, *op1, TRUE);
1837 *op2 = geniCodeCast (ctype, *op2, TRUE);
1842 /*-----------------------------------------------------------------*/
1843 /* geniCodeValueAtAddress - generate intermeditate code for value */
1845 /*-----------------------------------------------------------------*/
1847 geniCodeRValue (operand * op, bool force)
1850 sym_link *type = operandType (op);
1851 sym_link *etype = getSpec (type);
1853 /* if this is an array & already */
1854 /* an address then return this */
1855 if (IS_AGGREGATE (type) ||
1856 (IS_PTR (type) && !force && !op->isaddr))
1857 return operandFromOperand (op);
1859 /* if this is not an address then must be */
1860 /* rvalue already so return this one */
1864 /* if this is not a temp symbol then */
1865 if (!IS_ITEMP (op) &&
1867 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1869 op = operandFromOperand (op);
1874 if (IS_SPEC (type) &&
1875 IS_TRUE_SYMOP (op) &&
1876 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1877 (options.model == MODEL_FLAT24) ))
1879 op = operandFromOperand (op);
1884 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1885 if (IS_PTR (type) && op->isaddr && force)
1888 type = copyLinkChain (type);
1890 IC_RESULT (ic) = newiTempOperand (type, 1);
1891 IC_RESULT (ic)->isaddr = 0;
1893 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1897 return IC_RESULT (ic);
1900 /*-----------------------------------------------------------------*/
1901 /* geniCodeCast - changes the value from one type to another */
1902 /*-----------------------------------------------------------------*/
1904 geniCodeCast (sym_link * type, operand * op, bool implicit)
1908 sym_link *opetype = getSpec (optype = operandType (op));
1912 /* one of them has size zero then error */
1913 if (IS_VOID (optype))
1915 werror (E_CAST_ZERO);
1919 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1921 geniCodeArray2Ptr (op);
1925 /* if the operand is already the desired type then do nothing */
1926 if (compareType (type, optype) == 1)
1929 /* if this is a literal then just change the type & return */
1930 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1932 return operandFromValue (valCastLiteral (type,
1933 operandLitValue (op)));
1936 /* if casting to/from pointers, do some checking */
1937 if (IS_PTR(type)) { // to a pointer
1938 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1939 if (IS_INTEGRAL(optype)) {
1940 // maybe this is NULL, than it's ok.
1941 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1942 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1943 // no way to set the storage
1944 if (IS_LITERAL(optype)) {
1945 werror(E_LITERAL_GENERIC);
1948 werror(E_NONPTR2_GENPTR);
1951 } else if (implicit) {
1952 werror(W_INTEGRAL2PTR_NOCAST);
1957 // shouldn't do that with float, array or structure unless to void
1958 if (!IS_VOID(getSpec(type)) &&
1959 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1960 werror(E_INCOMPAT_TYPES);
1964 } else { // from a pointer to a pointer
1965 if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1966 // if not a pointer to a function
1967 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1968 if (implicit) { // if not to generic, they have to match
1969 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1970 werror(E_INCOMPAT_PTYPES);
1977 } else { // to a non pointer
1978 if (IS_PTR(optype)) { // from a pointer
1979 if (implicit) { // sneaky
1980 if (IS_INTEGRAL(type)) {
1981 werror(W_PTR2INTEGRAL_NOCAST);
1983 } else { // shouldn't do that with float, array or structure
1984 werror(E_INCOMPAT_TYPES);
1991 printFromToType (optype, type);
1994 /* if they are the same size create an assignment */
1996 /* This seems very dangerous to me, since there are several */
1997 /* optimizations (for example, gcse) that don't notice the */
1998 /* cast hidden in this assignement and may simplify an */
1999 /* iCode to use the original (uncasted) operand. */
2000 /* Unfortunately, other things break when this cast is */
2001 /* made explicit. Need to fix this someday. */
2002 /* -- EEP, 2004/01/21 */
2003 if (getSize (type) == getSize (optype) &&
2004 !IS_BITFIELD (type) &&
2006 !IS_FLOAT (optype) &&
2007 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2008 (!IS_SPEC (type) && !IS_SPEC (optype))))
2010 ic = newiCode ('=', NULL, op);
2011 IC_RESULT (ic) = newiTempOperand (type, 0);
2012 SPIL_LOC (IC_RESULT (ic)) =
2013 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
2014 IC_RESULT (ic)->isaddr = 0;
2018 ic = newiCode (CAST, operandFromLink (type),
2019 geniCodeRValue (op, FALSE));
2021 IC_RESULT (ic) = newiTempOperand (type, 0);
2024 /* preserve the storage class & output class */
2025 /* of the original variable */
2026 restype = getSpec (operandType (IC_RESULT (ic)));
2027 if (!IS_LITERAL(opetype))
2028 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2029 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2032 return IC_RESULT (ic);
2035 /*-----------------------------------------------------------------*/
2036 /* geniCodeLabel - will create a Label */
2037 /*-----------------------------------------------------------------*/
2039 geniCodeLabel (symbol * label)
2043 ic = newiCodeLabelGoto (LABEL, label);
2047 /*-----------------------------------------------------------------*/
2048 /* geniCodeGoto - will create a Goto */
2049 /*-----------------------------------------------------------------*/
2051 geniCodeGoto (symbol * label)
2055 ic = newiCodeLabelGoto (GOTO, label);
2059 /*-----------------------------------------------------------------*/
2060 /* geniCodeMultiply - gen intermediate code for multiplication */
2061 /*-----------------------------------------------------------------*/
2063 geniCodeMultiply (operand * left, operand * right, bool resultIsInt)
2070 /* if they are both literal then we know the result */
2071 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2072 return operandFromValue (valMult (left->operand.valOperand,
2073 right->operand.valOperand));
2075 if (IS_LITERAL(retype)) {
2076 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2079 resType = usualBinaryConversions (&left, &right, resultIsInt, '*');
2081 rtype = operandType (right);
2082 retype = getSpec (rtype);
2083 ltype = operandType (left);
2084 letype = getSpec (ltype);
2087 /* if the right is a literal & power of 2 */
2088 /* then make it a left shift */
2089 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2090 efficient in most cases than 2 bytes result = 2 bytes << literal
2091 if port has 1 byte muldiv */
2092 if (p2 && !IS_FLOAT (letype)
2093 && !((resultIsInt) && (getSize (resType) != getSize (ltype))
2094 && (port->support.muldiv == 1))
2095 && strcmp (port->target, "pic14") != 0 /* don't shift for pic */
2096 && strcmp (port->target, "pic16") != 0)
2098 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
2100 /* LEFT_OP need same size for left and result, */
2101 left = geniCodeCast (resType, left, TRUE);
2102 ltype = operandType (left);
2104 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2108 ic = newiCode ('*', left, right); /* normal multiplication */
2109 /* if the size left or right > 1 then support routine */
2110 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2114 IC_RESULT (ic) = newiTempOperand (resType, 1);
2117 return IC_RESULT (ic);
2120 /*-----------------------------------------------------------------*/
2121 /* geniCodeDivision - gen intermediate code for division */
2122 /*-----------------------------------------------------------------*/
2124 geniCodeDivision (operand * left, operand * right, bool resultIsInt)
2129 sym_link *rtype = operandType (right);
2130 sym_link *retype = getSpec (rtype);
2131 sym_link *ltype = operandType (left);
2132 sym_link *letype = getSpec (ltype);
2134 resType = usualBinaryConversions (&left, &right, resultIsInt, '/');
2136 /* if the right is a literal & power of 2
2137 and left is unsigned then make it a
2139 if (IS_LITERAL (retype) &&
2140 !IS_FLOAT (letype) &&
2141 IS_UNSIGNED(letype) &&
2142 (p2 = powof2 ((TYPE_UDWORD)
2143 floatFromVal (right->operand.valOperand)))) {
2144 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2148 ic = newiCode ('/', left, right); /* normal division */
2149 /* if the size left or right > 1 then support routine */
2150 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2153 IC_RESULT (ic) = newiTempOperand (resType, 0);
2156 return IC_RESULT (ic);
2158 /*-----------------------------------------------------------------*/
2159 /* geniCodeModulus - gen intermediate code for modulus */
2160 /*-----------------------------------------------------------------*/
2162 geniCodeModulus (operand * left, operand * right, bool resultIsInt)
2168 /* if they are both literal then we know the result */
2169 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2170 return operandFromValue (valMod (left->operand.valOperand,
2171 right->operand.valOperand));
2173 resType = usualBinaryConversions (&left, &right, resultIsInt, '%');
2175 /* now they are the same size */
2176 ic = newiCode ('%', left, right);
2178 /* if the size left or right > 1 then support routine */
2179 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2181 IC_RESULT (ic) = newiTempOperand (resType, 0);
2184 return IC_RESULT (ic);
2187 /*-----------------------------------------------------------------*/
2188 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2189 /*-----------------------------------------------------------------*/
2191 geniCodePtrPtrSubtract (operand * left, operand * right)
2197 /* if they are both literals then */
2198 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2200 result = operandFromValue (valMinus (left->operand.valOperand,
2201 right->operand.valOperand));
2205 ic = newiCode ('-', left, right);
2207 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2211 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2215 // should we really do this? is this ANSI?
2216 return geniCodeDivision (result,
2217 operandFromLit (getSize (ltype->next)),
2221 /*-----------------------------------------------------------------*/
2222 /* geniCodeSubtract - generates code for subtraction */
2223 /*-----------------------------------------------------------------*/
2225 geniCodeSubtract (operand * left, operand * right)
2232 /* if they both pointers then */
2233 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2234 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2235 return geniCodePtrPtrSubtract (left, right);
2237 /* if they are both literal then we know the result */
2238 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2239 && left->isLiteral && right->isLiteral)
2240 return operandFromValue (valMinus (left->operand.valOperand,
2241 right->operand.valOperand));
2243 /* if left is an array or pointer */
2244 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2246 isarray = left->isaddr;
2247 right = geniCodeMultiply (right,
2248 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2249 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2252 { /* make them the same size */
2253 resType = usualBinaryConversions (&left, &right, FALSE, '-');
2256 ic = newiCode ('-', left, right);
2258 IC_RESULT (ic) = newiTempOperand (resType, 1);
2259 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2261 /* if left or right is a float */
2262 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2266 return IC_RESULT (ic);
2269 /*-----------------------------------------------------------------*/
2270 /* geniCodeAdd - generates iCode for addition */
2271 /*-----------------------------------------------------------------*/
2273 geniCodeAdd (operand * left, operand * right, int lvl)
2282 /* if the right side is LITERAL zero */
2283 /* return the left side */
2284 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2287 /* if left is literal zero return right */
2288 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2291 /* if left is a pointer then size */
2292 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2294 isarray = left->isaddr;
2295 // there is no need to multiply with 1
2296 if (getSize (ltype->next) != 1)
2298 size = operandFromLit (getSize (ltype->next));
2299 SPEC_USIGN (getSpec (operandType (size))) = 1;
2300 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2301 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2302 /* Even if right is a 'unsigned char',
2303 the result will be a 'signed int' due to the promotion rules.
2304 It doesn't make sense when accessing arrays, so let's fix it here: */
2306 SPEC_USIGN (getSpec (operandType (right))) = 1;
2308 resType = copyLinkChain (ltype);
2311 { // make them the same size
2312 resType = usualBinaryConversions (&left, &right, FALSE, '+');
2315 /* if they are both literals then we know */
2316 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2317 && left->isLiteral && right->isLiteral)
2318 return operandFromValue (valPlus (valFromType (ltype),
2319 valFromType (rtype)));
2321 ic = newiCode ('+', left, right);
2323 IC_RESULT (ic) = newiTempOperand (resType, 1);
2324 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2326 /* if left or right is a float then support
2328 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2333 return IC_RESULT (ic);
2337 /*-----------------------------------------------------------------*/
2338 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2339 /*-----------------------------------------------------------------*/
2341 aggrToPtr (sym_link * type, bool force)
2346 if (IS_PTR (type) && !force)
2349 etype = getSpec (type);
2350 ptype = newLink (DECLARATOR);
2354 /* set the pointer depending on the storage class */
2355 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2359 /*-----------------------------------------------------------------*/
2360 /* geniCodeArray2Ptr - array to pointer */
2361 /*-----------------------------------------------------------------*/
2363 geniCodeArray2Ptr (operand * op)
2365 sym_link *optype = operandType (op);
2366 sym_link *opetype = getSpec (optype);
2368 /* set the pointer depending on the storage class */
2369 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2376 /*-----------------------------------------------------------------*/
2377 /* geniCodeArray - array access */
2378 /*-----------------------------------------------------------------*/
2380 geniCodeArray (operand * left, operand * right, int lvl)
2384 sym_link *ltype = operandType (left);
2389 if (IS_PTR (ltype->next) && left->isaddr)
2391 left = geniCodeRValue (left, FALSE);
2394 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2396 size = operandFromLit (getSize (ltype->next));
2397 SPEC_USIGN (getSpec (operandType (size))) = 1;
2398 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2399 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2400 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2401 It doesn't make sense when accessing arrays, so let's fix it here: */
2403 SPEC_USIGN (getSpec (operandType (right))) = 1;
2404 /* we can check for limits here */
2405 /* already done in SDCCast.c
2406 if (isOperandLiteral (right) &&
2409 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2411 werror (W_IDX_OUT_OF_BOUNDS,
2412 (int) operandLitValue (right) / getSize (ltype->next),
2417 ic = newiCode ('+', left, right);
2419 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2420 !IS_AGGREGATE (ltype->next) &&
2421 !IS_PTR (ltype->next))
2422 ? ltype : ltype->next), 0);
2424 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2427 return IC_RESULT (ic);
2430 /*-----------------------------------------------------------------*/
2431 /* geniCodeStruct - generates intermediate code for structures */
2432 /*-----------------------------------------------------------------*/
2434 geniCodeStruct (operand * left, operand * right, bool islval)
2437 sym_link *type = operandType (left);
2438 sym_link *etype = getSpec (type);
2440 symbol *element = getStructElement (SPEC_STRUCT (etype),
2441 right->operand.symOperand);
2443 wassert(IS_SYMOP(right));
2445 /* add the offset */
2446 ic = newiCode ('+', left, operandFromLit (element->offset));
2448 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2450 /* preserve the storage & output class of the struct */
2451 /* as well as the volatile attribute */
2452 retype = getSpec (operandType (IC_RESULT (ic)));
2453 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2454 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2455 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2456 SPEC_CONST (retype) |= SPEC_CONST (etype);
2458 if (IS_PTR (element->type))
2459 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2461 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2464 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2467 /*-----------------------------------------------------------------*/
2468 /* geniCodePostInc - generate int code for Post increment */
2469 /*-----------------------------------------------------------------*/
2471 geniCodePostInc (operand * op)
2475 sym_link *optype = operandType (op);
2477 operand *rv = (IS_ITEMP (op) ?
2478 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2480 sym_link *rvtype = operandType (rv);
2483 /* if this is not an address we have trouble */
2486 werror (E_LVALUE_REQUIRED, "++");
2490 rOp = newiTempOperand (rvtype, 0);
2491 OP_SYMBOL(rOp)->noSpilLoc = 1;
2494 OP_SYMBOL(rv)->noSpilLoc = 1;
2496 geniCodeAssign (rOp, rv, 0);
2498 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2499 if (IS_FLOAT (rvtype))
2500 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2502 ic = newiCode ('+', rv, operandFromLit (size));
2504 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2507 geniCodeAssign (op, result, 0);
2513 /*-----------------------------------------------------------------*/
2514 /* geniCodePreInc - generate code for preIncrement */
2515 /*-----------------------------------------------------------------*/
2517 geniCodePreInc (operand * op, bool lvalue)
2520 sym_link *optype = operandType (op);
2521 operand *rop = (IS_ITEMP (op) ?
2522 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2524 sym_link *roptype = operandType (rop);
2530 werror (E_LVALUE_REQUIRED, "++");
2535 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2536 if (IS_FLOAT (roptype))
2537 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2539 ic = newiCode ('+', rop, operandFromLit (size));
2540 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2543 (void) geniCodeAssign (op, result, 0);
2544 if (lvalue || IS_TRUE_SYMOP (op))
2550 /*-----------------------------------------------------------------*/
2551 /* geniCodePostDec - generates code for Post decrement */
2552 /*-----------------------------------------------------------------*/
2554 geniCodePostDec (operand * op)
2558 sym_link *optype = operandType (op);
2560 operand *rv = (IS_ITEMP (op) ?
2561 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2563 sym_link *rvtype = operandType (rv);
2566 /* if this is not an address we have trouble */
2569 werror (E_LVALUE_REQUIRED, "--");
2573 rOp = newiTempOperand (rvtype, 0);
2574 OP_SYMBOL(rOp)->noSpilLoc = 1;
2577 OP_SYMBOL(rv)->noSpilLoc = 1;
2579 geniCodeAssign (rOp, rv, 0);
2581 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2582 if (IS_FLOAT (rvtype))
2583 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2585 ic = newiCode ('-', rv, operandFromLit (size));
2587 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2590 geniCodeAssign (op, result, 0);
2596 /*-----------------------------------------------------------------*/
2597 /* geniCodePreDec - generate code for pre decrement */
2598 /*-----------------------------------------------------------------*/
2600 geniCodePreDec (operand * op, bool lvalue)
2603 sym_link *optype = operandType (op);
2604 operand *rop = (IS_ITEMP (op) ?
2605 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2607 sym_link *roptype = operandType (rop);
2613 werror (E_LVALUE_REQUIRED, "--");
2618 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2619 if (IS_FLOAT (roptype))
2620 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2622 ic = newiCode ('-', rop, operandFromLit (size));
2623 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2626 (void) geniCodeAssign (op, result, 0);
2627 if (lvalue || IS_TRUE_SYMOP (op))
2634 /*-----------------------------------------------------------------*/
2635 /* geniCodeBitwise - gen int code for bitWise operators */
2636 /*-----------------------------------------------------------------*/
2638 geniCodeBitwise (operand * left, operand * right,
2639 int oper, sym_link * resType)
2643 left = geniCodeCast (resType, left, TRUE);
2644 right = geniCodeCast (resType, right, TRUE);
2646 ic = newiCode (oper, left, right);
2647 IC_RESULT (ic) = newiTempOperand (resType, 0);
2650 return IC_RESULT (ic);
2653 /*-----------------------------------------------------------------*/
2654 /* geniCodeAddressOf - gens icode for '&' address of operator */
2655 /*-----------------------------------------------------------------*/
2657 geniCodeAddressOf (operand * op)
2661 sym_link *optype = operandType (op);
2662 sym_link *opetype = getSpec (optype);
2664 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2666 op = operandFromOperand (op);
2671 /* lvalue check already done in decorateType */
2672 /* this must be a lvalue */
2673 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2674 /* werror (E_LVALUE_REQUIRED,"&"); */
2678 p = newLink (DECLARATOR);
2680 /* set the pointer depending on the storage class */
2681 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2683 p->next = copyLinkChain (optype);
2685 /* if already a temp */
2688 setOperandType (op, p);
2693 /* other wise make this of the type coming in */
2694 ic = newiCode (ADDRESS_OF, op, NULL);
2695 IC_RESULT (ic) = newiTempOperand (p, 1);
2696 IC_RESULT (ic)->isaddr = 0;
2698 return IC_RESULT (ic);
2700 /*-----------------------------------------------------------------*/
2701 /* setOClass - sets the output class depending on the pointer type */
2702 /*-----------------------------------------------------------------*/
2704 setOClass (sym_link * ptr, sym_link * spec)
2706 switch (DCL_TYPE (ptr))
2709 SPEC_OCLS (spec) = data;
2713 SPEC_OCLS (spec) = generic;
2717 SPEC_OCLS (spec) = xdata;
2721 SPEC_OCLS (spec) = code;
2725 SPEC_OCLS (spec) = idata;
2729 SPEC_OCLS (spec) = xstack;
2733 SPEC_OCLS (spec) = eeprom;
2742 /*-----------------------------------------------------------------*/
2743 /* geniCodeDerefPtr - dereference pointer with '*' */
2744 /*-----------------------------------------------------------------*/
2746 geniCodeDerefPtr (operand * op,int lvl)
2748 sym_link *rtype, *retype;
2749 sym_link *optype = operandType (op);
2751 // if this is an array then array access
2752 if (IS_ARRAY (optype)) {
2753 // don't worry, this will be optimized out later
2754 return geniCodeArray (op, operandFromLit (0), lvl);
2757 // just in case someone screws up
2758 wassert (IS_PTR (optype));
2760 if (IS_TRUE_SYMOP (op))
2763 op = geniCodeRValue (op, TRUE);
2766 /* now get rid of the pointer part */
2767 if (isLvaluereq(lvl) && IS_ITEMP (op))
2769 retype = getSpec (rtype = copyLinkChain (optype));
2773 retype = getSpec (rtype = copyLinkChain (optype->next));
2774 /* outputclass needs 2b updated */
2775 setOClass (optype, retype);
2778 op->isGptr = IS_GENPTR (optype);
2780 op->isaddr = (IS_PTR (rtype) ||
2781 IS_STRUCT (rtype) ||
2786 if (!isLvaluereq(lvl))
2787 op = geniCodeRValue (op, TRUE);
2789 setOperandType (op, rtype);
2794 /*-----------------------------------------------------------------*/
2795 /* geniCodeUnaryMinus - does a unary minus of the operand */
2796 /*-----------------------------------------------------------------*/
2798 geniCodeUnaryMinus (operand * op)
2801 sym_link *optype = operandType (op);
2803 if (IS_LITERAL (optype))
2804 return operandFromLit (-floatFromVal (op->operand.valOperand));
2806 ic = newiCode (UNARYMINUS, op, NULL);
2807 IC_RESULT (ic) = newiTempOperand (optype, 0);
2809 return IC_RESULT (ic);
2812 /*-----------------------------------------------------------------*/
2813 /* geniCodeLeftShift - gen i code for left shift */
2814 /*-----------------------------------------------------------------*/
2816 geniCodeLeftShift (operand * left, operand * right)
2820 ic = newiCode (LEFT_OP, left, right);
2821 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2823 return IC_RESULT (ic);
2826 /*-----------------------------------------------------------------*/
2827 /* geniCodeRightShift - gen i code for right shift */
2828 /*-----------------------------------------------------------------*/
2830 geniCodeRightShift (operand * left, operand * right)
2834 ic = newiCode (RIGHT_OP, left, right);
2835 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2837 return IC_RESULT (ic);
2840 /*-----------------------------------------------------------------*/
2841 /* geniCodeLogic- logic code */
2842 /*-----------------------------------------------------------------*/
2844 geniCodeLogic (operand * left, operand * right, int op)
2848 sym_link *rtype = operandType (right);
2849 sym_link *ltype = operandType (left);
2851 /* left is integral type and right is literal then
2852 check if the literal value is within bounds */
2853 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2855 checkConstantRange(ltype,
2856 OP_VALUE(right), "compare operation", 1);
2859 /* if one operand is a pointer and the other is a literal generic void pointer,
2860 change the type of the literal generic void pointer to match the other pointer */
2861 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2862 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2864 /* find left's definition */
2865 ic = (iCode *) setFirstItem (iCodeChain);
2868 if (((ic->op == CAST) || (ic->op == '='))
2869 && isOperandEqual(left, IC_RESULT (ic)))
2872 ic = setNextItem (iCodeChain);
2874 /* if casting literal to generic pointer, then cast to rtype instead */
2875 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2877 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2878 ltype = operandType(left);
2881 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2882 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2884 /* find right's definition */
2885 ic = (iCode *) setFirstItem (iCodeChain);
2888 if (((ic->op == CAST) || (ic->op == '='))
2889 && isOperandEqual(right, IC_RESULT (ic)))
2892 ic = setNextItem (iCodeChain);
2894 /* if casting literal to generic pointer, then cast to rtype instead */
2895 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2897 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2898 rtype = operandType(right);
2902 ctype = usualBinaryConversions (&left, &right, FALSE, ' ');
2904 ic = newiCode (op, left, right);
2905 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2907 /* if comparing float
2908 and not a '==' || '!=' || '&&' || '||' (these
2910 if (IS_FLOAT(ctype) &&
2918 return IC_RESULT (ic);
2921 /*-----------------------------------------------------------------*/
2922 /* geniCodeUnary - for a a generic unary operation */
2923 /*-----------------------------------------------------------------*/
2925 geniCodeUnary (operand * op, int oper)
2927 iCode *ic = newiCode (oper, op, NULL);
2929 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2931 return IC_RESULT (ic);
2934 /*-----------------------------------------------------------------*/
2935 /* geniCodeConditional - geniCode for '?' ':' operation */
2936 /*-----------------------------------------------------------------*/
2938 geniCodeConditional (ast * tree,int lvl)
2941 symbol *falseLabel = newiTempLabel (NULL);
2942 symbol *exitLabel = newiTempLabel (NULL);
2943 operand *cond = ast2iCode (tree->left,lvl+1);
2944 operand *true, *false, *result;
2946 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2950 true = ast2iCode (tree->right->left,lvl+1);
2952 /* move the value to a new Operand */
2953 result = newiTempOperand (tree->right->ftype, 0);
2954 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2956 /* generate an unconditional goto */
2957 geniCodeGoto (exitLabel);
2959 /* now for the right side */
2960 geniCodeLabel (falseLabel);
2962 false = ast2iCode (tree->right->right,lvl+1);
2963 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2965 /* create the exit label */
2966 geniCodeLabel (exitLabel);
2971 /*-----------------------------------------------------------------*/
2972 /* geniCodeAssign - generate code for assignment */
2973 /*-----------------------------------------------------------------*/
2975 geniCodeAssign (operand * left, operand * right, int nosupdate)
2978 sym_link *ltype = operandType (left);
2979 sym_link *rtype = operandType (right);
2981 if (!left->isaddr && !IS_ITEMP (left))
2983 werror (E_LVALUE_REQUIRED, "assignment");
2987 /* left is integral type and right is literal then
2988 check if the literal value is within bounds */
2989 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2991 checkConstantRange(ltype,
2992 OP_VALUE(right), "= operation", 0);
2995 /* if the left & right type don't exactly match */
2996 /* if pointer set then make sure the check is
2997 done with the type & not the pointer */
2998 /* then cast rights type to left */
3000 /* first check the type for pointer assignement */
3001 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3002 compareType (ltype, rtype) <= 0)
3004 if (compareType (ltype->next, rtype) < 0)
3005 right = geniCodeCast (ltype->next, right, TRUE);
3007 else if (compareType (ltype, rtype) < 0)
3008 right = geniCodeCast (ltype, right, TRUE);
3010 /* If left is a true symbol & ! volatile
3011 create an assignment to temporary for
3012 the right & then assign this temporary
3013 to the symbol. This is SSA (static single
3014 assignment). Isn't it simple and folks have
3015 published mountains of paper on it */
3016 if (IS_TRUE_SYMOP (left) &&
3017 !isOperandVolatile (left, FALSE) &&
3018 isOperandGlobal (left))
3022 if (IS_TRUE_SYMOP (right))
3023 sym = OP_SYMBOL (right);
3024 ic = newiCode ('=', NULL, right);
3025 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3026 SPIL_LOC (right) = sym;
3030 ic = newiCode ('=', NULL, right);
3031 IC_RESULT (ic) = left;
3034 /* if left isgptr flag is set then support
3035 routine will be required */
3039 ic->nosupdate = nosupdate;
3043 /*-----------------------------------------------------------------*/
3044 /* geniCodeDummyRead - generate code for dummy read */
3045 /*-----------------------------------------------------------------*/
3047 geniCodeDummyRead (operand * op)
3050 sym_link *type = operandType (op);
3052 if (!IS_VOLATILE(type))
3055 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3061 /*-----------------------------------------------------------------*/
3062 /* geniCodeSEParms - generate code for side effecting fcalls */
3063 /*-----------------------------------------------------------------*/
3065 geniCodeSEParms (ast * parms,int lvl)
3070 if (parms->type == EX_OP && parms->opval.op == PARAM)
3072 geniCodeSEParms (parms->left,lvl);
3073 geniCodeSEParms (parms->right,lvl);
3077 /* hack don't like this but too lazy to think of
3079 if (IS_ADDRESS_OF_OP (parms))
3080 parms->left->lvalue = 1;
3082 if (IS_CAST_OP (parms) &&
3083 IS_PTR (parms->ftype) &&
3084 IS_ADDRESS_OF_OP (parms->right))
3085 parms->right->left->lvalue = 1;
3087 parms->opval.oprnd =
3088 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3090 parms->type = EX_OPERAND;
3091 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3092 SPEC_ARGREG(parms->ftype);
3095 /*-----------------------------------------------------------------*/
3096 /* geniCodeParms - generates parameters */
3097 /*-----------------------------------------------------------------*/
3099 geniCodeParms (ast * parms, value *argVals, int *stack,
3100 sym_link * ftype, int lvl)
3108 if (argVals==NULL) {
3110 argVals = FUNC_ARGS (ftype);
3113 /* if this is a param node then do the left & right */
3114 if (parms->type == EX_OP && parms->opval.op == PARAM)
3116 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3117 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3121 /* get the parameter value */
3122 if (parms->type == EX_OPERAND)
3123 pval = parms->opval.oprnd;
3126 /* maybe this else should go away ?? */
3127 /* hack don't like this but too lazy to think of
3129 if (IS_ADDRESS_OF_OP (parms))
3130 parms->left->lvalue = 1;
3132 if (IS_CAST_OP (parms) &&
3133 IS_PTR (parms->ftype) &&
3134 IS_ADDRESS_OF_OP (parms->right))
3135 parms->right->left->lvalue = 1;
3137 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3140 /* if register parm then make it a send */
3141 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3142 IFFUNC_ISBUILTIN(ftype))
3144 ic = newiCode (SEND, pval, NULL);
3145 ic->argreg = SPEC_ARGREG(parms->etype);
3146 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3151 /* now decide whether to push or assign */
3152 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3156 operand *top = operandFromSymbol (argVals->sym);
3157 /* clear useDef and other bitVectors */
3158 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3159 geniCodeAssign (top, pval, 1);
3163 sym_link *p = operandType (pval);
3165 ic = newiCode (IPUSH, pval, NULL);
3167 /* update the stack adjustment */
3168 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3173 argVals=argVals->next;
3177 /*-----------------------------------------------------------------*/
3178 /* geniCodeCall - generates temp code for calling */
3179 /*-----------------------------------------------------------------*/
3181 geniCodeCall (operand * left, ast * parms,int lvl)
3185 sym_link *type, *etype;
3189 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3190 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3191 werror (E_FUNCTION_EXPECTED);
3192 return operandFromValue(valueFromLit(0));
3195 /* take care of parameters with side-effecting
3196 function calls in them, this is required to take care
3197 of overlaying function parameters */
3198 geniCodeSEParms (parms,lvl);
3200 ftype = operandType (left);
3201 if (IS_CODEPTR (ftype))
3202 ftype = ftype->next;
3204 /* first the parameters */
3205 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3207 /* now call : if symbol then pcall */
3208 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3209 ic = newiCode (PCALL, left, NULL);
3211 ic = newiCode (CALL, left, NULL);
3214 type = copyLinkChain (ftype->next);
3215 etype = getSpec (type);
3216 SPEC_EXTR (etype) = 0;
3217 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3221 /* stack adjustment after call */
3222 ic->parmBytes = stack;
3227 /*-----------------------------------------------------------------*/
3228 /* geniCodeReceive - generate intermediate code for "receive" */
3229 /*-----------------------------------------------------------------*/
3231 geniCodeReceive (value * args)
3233 /* for all arguments that are passed in registers */
3237 if (IS_REGPARM (args->etype))
3239 operand *opr = operandFromValue (args);
3241 symbol *sym = OP_SYMBOL (opr);
3244 /* we will use it after all optimizations
3245 and before liveRange calculation */
3246 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3249 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3250 options.stackAuto == 0 &&
3251 (!(options.model == MODEL_FLAT24)) )
3256 opl = newiTempOperand (args->type, 0);
3258 sym->reqv->key = sym->key;
3259 OP_SYMBOL (sym->reqv)->key = sym->key;
3260 OP_SYMBOL (sym->reqv)->isreqv = 1;
3261 OP_SYMBOL (sym->reqv)->islocal = 0;
3262 SPIL_LOC (sym->reqv) = sym;
3266 ic = newiCode (RECEIVE, NULL, NULL);
3267 ic->argreg = SPEC_ARGREG(args->etype);
3269 currFunc->recvSize = getSize (sym->type);
3272 IC_RESULT (ic) = opr;
3280 /*-----------------------------------------------------------------*/
3281 /* geniCodeFunctionBody - create the function body */
3282 /*-----------------------------------------------------------------*/
3284 geniCodeFunctionBody (ast * tree,int lvl)
3291 /* reset the auto generation */
3297 func = ast2iCode (tree->left,lvl+1);
3298 fetype = getSpec (operandType (func));
3300 savelineno = lineno;
3301 lineno = OP_SYMBOL (func)->lineDef;
3302 /* create an entry label */
3303 geniCodeLabel (entryLabel);
3304 lineno = savelineno;
3306 /* create a proc icode */
3307 ic = newiCode (FUNCTION, func, NULL);
3308 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3312 /* for all parameters that are passed
3313 on registers add a "receive" */
3314 geniCodeReceive (tree->values.args);
3316 /* generate code for the body */
3317 ast2iCode (tree->right,lvl+1);
3319 /* create a label for return */
3320 geniCodeLabel (returnLabel);
3322 /* now generate the end proc */
3323 ic = newiCode (ENDFUNCTION, func, NULL);
3328 /*-----------------------------------------------------------------*/
3329 /* geniCodeReturn - gen icode for 'return' statement */
3330 /*-----------------------------------------------------------------*/
3332 geniCodeReturn (operand * op)
3336 /* if the operand is present force an rvalue */
3338 op = geniCodeRValue (op, FALSE);
3340 ic = newiCode (RETURN, op, NULL);
3344 /*-----------------------------------------------------------------*/
3345 /* geniCodeIfx - generates code for extended if statement */
3346 /*-----------------------------------------------------------------*/
3348 geniCodeIfx (ast * tree,int lvl)
3351 operand *condition = ast2iCode (tree->left,lvl+1);
3354 /* if condition is null then exit */
3358 condition = geniCodeRValue (condition, FALSE);
3360 cetype = getSpec (operandType (condition));
3361 /* if the condition is a literal */
3362 if (IS_LITERAL (cetype))
3364 if (floatFromVal (condition->operand.valOperand))
3366 if (tree->trueLabel)
3367 geniCodeGoto (tree->trueLabel);
3373 if (tree->falseLabel)
3374 geniCodeGoto (tree->falseLabel);
3381 if (tree->trueLabel)
3383 ic = newiCodeCondition (condition,
3388 if (tree->falseLabel)
3389 geniCodeGoto (tree->falseLabel);
3393 ic = newiCodeCondition (condition,
3400 ast2iCode (tree->right,lvl+1);
3403 /*-----------------------------------------------------------------*/
3404 /* geniCodeJumpTable - tries to create a jump table for switch */
3405 /*-----------------------------------------------------------------*/
3407 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3409 int min = 0, max = 0, t, cnt = 0;
3415 int needRangeCheck = !optimize.noJTabBoundary
3416 || tree->values.switchVals.swDefault;
3418 if (!tree || !caseVals)
3421 /* the criteria for creating a jump table is */
3422 /* all integer numbers between the maximum & minimum must */
3423 /* be present , the maximum value should not exceed 255 */
3424 min = max = (int) floatFromVal (vch = caseVals);
3425 SNPRINTF (buffer, sizeof(buffer),
3427 tree->values.switchVals.swNum,
3429 addSet (&labels, newiTempLabel (buffer));
3431 /* if there is only one case value then no need */
3432 if (!(vch = vch->next))
3437 if (((t = (int) floatFromVal (vch)) - max) != 1)
3439 SNPRINTF (buffer, sizeof(buffer),
3441 tree->values.switchVals.swNum,
3443 addSet (&labels, newiTempLabel (buffer));
3449 /* if the number of case statements <= 2 then */
3450 /* it is not economical to create the jump table */
3451 /* since two compares are needed for boundary conditions */
3452 if ((needRangeCheck && cnt <= 2) || max > (255 / 3))
3455 if (tree->values.switchVals.swDefault)
3457 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3461 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3465 falseLabel = newiTempLabel (buffer);
3467 /* so we can create a jumptable */
3468 /* first we rule out the boundary conditions */
3469 /* if only optimization says so */
3472 sym_link *cetype = getSpec (operandType (cond));
3473 /* no need to check the lower bound if
3474 the condition is unsigned & minimum value is zero */
3475 if (!(min == 0 && IS_UNSIGNED (cetype)))
3477 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3478 ic = newiCodeCondition (boundary, falseLabel, NULL);
3482 /* now for upper bounds */
3483 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3484 ic = newiCodeCondition (boundary, falseLabel, NULL);
3488 /* if the min is not zero then we no make it zero */
3491 cond = geniCodeSubtract (cond, operandFromLit (min));
3492 if (!IS_LITERAL(getSpec(operandType(cond))))
3493 setOperandType (cond, UCHARTYPE);
3496 /* now create the jumptable */
3497 ic = newiCode (JUMPTABLE, NULL, NULL);
3498 IC_JTCOND (ic) = cond;
3499 IC_JTLABELS (ic) = labels;
3504 /*-----------------------------------------------------------------*/
3505 /* geniCodeSwitch - changes a switch to a if statement */
3506 /*-----------------------------------------------------------------*/
3508 geniCodeSwitch (ast * tree,int lvl)
3511 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3512 value *caseVals = tree->values.switchVals.swVals;
3513 symbol *trueLabel, *falseLabel;
3515 /* If the condition is a literal, then just jump to the */
3516 /* appropriate case label. */
3517 if (IS_LITERAL(getSpec(operandType(cond))))
3519 int switchVal, caseVal;
3521 switchVal = (int) floatFromVal (cond->operand.valOperand);
3524 caseVal = (int) floatFromVal (caseVals);
3525 if (caseVal == switchVal)
3527 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3528 tree->values.switchVals.swNum, caseVal);
3529 trueLabel = newiTempLabel (buffer);
3530 geniCodeGoto (trueLabel);
3533 caseVals = caseVals->next;
3535 goto defaultOrBreak;
3538 /* if we can make this a jump table */
3539 if (geniCodeJumpTable (cond, caseVals, tree))
3540 goto jumpTable; /* no need for the comparison */
3542 /* for the cases defined do */
3546 operand *compare = geniCodeLogic (cond,
3547 operandFromValue (caseVals),
3550 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3551 tree->values.switchVals.swNum,
3552 (int) floatFromVal (caseVals));
3553 trueLabel = newiTempLabel (buffer);
3555 ic = newiCodeCondition (compare, trueLabel, NULL);
3557 caseVals = caseVals->next;
3562 /* if default is present then goto break else break */
3563 if (tree->values.switchVals.swDefault)
3565 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3569 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3572 falseLabel = newiTempLabel (buffer);
3573 geniCodeGoto (falseLabel);
3576 ast2iCode (tree->right,lvl+1);
3579 /*-----------------------------------------------------------------*/
3580 /* geniCodeInline - intermediate code for inline assembler */
3581 /*-----------------------------------------------------------------*/
3583 geniCodeInline (ast * tree)
3587 ic = newiCode (INLINEASM, NULL, NULL);
3588 IC_INLINE (ic) = tree->values.inlineasm;
3592 /*-----------------------------------------------------------------*/
3593 /* geniCodeArrayInit - intermediate code for array initializer */
3594 /*-----------------------------------------------------------------*/
3596 geniCodeArrayInit (ast * tree, operand *array)
3600 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3601 ic = newiCode (ARRAYINIT, array, NULL);
3602 IC_ARRAYILIST (ic) = tree->values.constlist;
3604 operand *left=newOperand(), *right=newOperand();
3605 left->type=right->type=SYMBOL;
3606 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3607 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3608 ic = newiCode (ARRAYINIT, left, right);
3613 /*-----------------------------------------------------------------*/
3614 /* geniCodeCritical - intermediate code for a critical statement */
3615 /*-----------------------------------------------------------------*/
3617 geniCodeCritical (ast *tree, int lvl)
3622 /* If op is NULL, the original interrupt state will saved on */
3623 /* the stack. Otherwise, it will be saved in op. */
3625 /* Generate a save of the current interrupt state & disabled */
3626 ic = newiCode (CRITICAL, NULL, NULL);
3627 IC_RESULT (ic) = op;
3630 /* Generate the critical code sequence */
3631 if (tree->left && tree->left->type == EX_VALUE)
3632 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3634 ast2iCode (tree->left,lvl+1);
3636 /* Generate a restore of the original interrupt state */
3637 ic = newiCode (ENDCRITICAL, NULL, op);
3641 /*-----------------------------------------------------------------*/
3642 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3643 /* particular case. Ie : assigning or dereferencing array or ptr */
3644 /*-----------------------------------------------------------------*/
3645 set * lvaluereqSet = NULL;
3646 typedef struct lvalItem
3653 /*-----------------------------------------------------------------*/
3654 /* addLvaluereq - add a flag for lvalreq for current ast level */
3655 /*-----------------------------------------------------------------*/
3656 void addLvaluereq(int lvl)
3658 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3661 addSetHead(&lvaluereqSet,lpItem);
3664 /*-----------------------------------------------------------------*/
3665 /* delLvaluereq - del a flag for lvalreq for current ast level */
3666 /*-----------------------------------------------------------------*/
3670 lpItem = getSet(&lvaluereqSet);
3671 if(lpItem) Safe_free(lpItem);
3673 /*-----------------------------------------------------------------*/
3674 /* clearLvaluereq - clear lvalreq flag */
3675 /*-----------------------------------------------------------------*/
3676 void clearLvaluereq()
3679 lpItem = peekSet(lvaluereqSet);
3680 if(lpItem) lpItem->req = 0;
3682 /*-----------------------------------------------------------------*/
3683 /* getLvaluereq - get the last lvalreq level */
3684 /*-----------------------------------------------------------------*/
3685 int getLvaluereqLvl()
3688 lpItem = peekSet(lvaluereqSet);
3689 if(lpItem) return lpItem->lvl;
3692 /*-----------------------------------------------------------------*/
3693 /* isLvaluereq - is lvalreq valid for this level ? */
3694 /*-----------------------------------------------------------------*/
3695 int isLvaluereq(int lvl)
3698 lpItem = peekSet(lvaluereqSet);
3699 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3703 /*-----------------------------------------------------------------*/
3704 /* ast2iCode - creates an icodeList from an ast */
3705 /*-----------------------------------------------------------------*/
3707 ast2iCode (ast * tree,int lvl)
3709 operand *left = NULL;
3710 operand *right = NULL;
3714 /* set the global variables for filename & line number */
3716 filename = tree->filename;
3718 lineno = tree->lineno;
3720 block = tree->block;
3722 scopeLevel = tree->level;
3724 seqPoint = tree->seqPoint;
3726 if (tree->type == EX_VALUE)
3727 return operandFromValue (tree->opval.val);
3729 if (tree->type == EX_LINK)
3730 return operandFromLink (tree->opval.lnk);
3732 /* if we find a nullop */
3733 if (tree->type == EX_OP &&
3734 (tree->opval.op == NULLOP ||
3735 tree->opval.op == BLOCK))
3737 if (tree->left && tree->left->type == EX_VALUE)
3738 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3740 ast2iCode (tree->left,lvl+1);
3741 if (tree->right && tree->right->type == EX_VALUE)
3742 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3744 ast2iCode (tree->right,lvl+1);
3748 /* special cases for not evaluating */
3749 if (tree->opval.op != ':' &&
3750 tree->opval.op != '?' &&
3751 tree->opval.op != CALL &&
3752 tree->opval.op != IFX &&
3753 tree->opval.op != LABEL &&
3754 tree->opval.op != GOTO &&
3755 tree->opval.op != SWITCH &&
3756 tree->opval.op != FUNCTION &&
3757 tree->opval.op != INLINEASM &&
3758 tree->opval.op != CRITICAL)
3761 if (IS_ASSIGN_OP (tree->opval.op) ||
3762 IS_DEREF_OP (tree) ||
3763 (tree->opval.op == '&' && !tree->right) ||
3764 tree->opval.op == PTR_OP)
3767 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3768 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3771 left = operandFromAst (tree->left,lvl);
3773 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3774 left = geniCodeRValue (left, TRUE);
3778 left = operandFromAst (tree->left,lvl);
3780 if (tree->opval.op == INC_OP ||
3781 tree->opval.op == DEC_OP)
3784 right = operandFromAst (tree->right,lvl);
3789 right = operandFromAst (tree->right,lvl);
3793 /* now depending on the type of operand */
3794 /* this will be a biggy */
3795 switch (tree->opval.op)
3798 case '[': /* array operation */
3800 //sym_link *ltype = operandType (left);
3801 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3802 left = geniCodeRValue (left, FALSE);
3803 right = geniCodeRValue (right, TRUE);
3806 return geniCodeArray (left, right,lvl);
3808 case '.': /* structure dereference */
3809 if (IS_PTR (operandType (left)))
3810 left = geniCodeRValue (left, TRUE);
3812 left = geniCodeRValue (left, FALSE);
3814 return geniCodeStruct (left, right, tree->lvalue);
3816 case PTR_OP: /* structure pointer dereference */
3819 pType = operandType (left);
3820 left = geniCodeRValue (left, TRUE);
3822 setOClass (pType, getSpec (operandType (left)));
3825 return geniCodeStruct (left, right, tree->lvalue);
3827 case INC_OP: /* increment operator */
3829 return geniCodePostInc (left);
3831 return geniCodePreInc (right, tree->lvalue);
3833 case DEC_OP: /* decrement operator */
3835 return geniCodePostDec (left);
3837 return geniCodePreDec (right, tree->lvalue);
3839 case '&': /* bitwise and or address of operator */
3841 { /* this is a bitwise operator */
3842 left = geniCodeRValue (left, FALSE);
3843 right = geniCodeRValue (right, FALSE);
3844 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3847 return geniCodeAddressOf (left);
3849 case '|': /* bitwise or & xor */
3851 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3852 geniCodeRValue (right, FALSE),
3857 return geniCodeDivision (geniCodeRValue (left, FALSE),
3858 geniCodeRValue (right, FALSE),
3859 IS_INT (tree->ftype));
3862 return geniCodeModulus (geniCodeRValue (left, FALSE),
3863 geniCodeRValue (right, FALSE),
3864 IS_INT (tree->ftype));
3867 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3868 geniCodeRValue (right, FALSE),
3869 IS_INT (tree->ftype));
3871 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3875 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3876 geniCodeRValue (right, FALSE));
3878 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3882 return geniCodeAdd (geniCodeRValue (left, FALSE),
3883 geniCodeRValue (right, FALSE),lvl);
3885 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3888 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3889 geniCodeRValue (right, FALSE));
3892 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3893 geniCodeRValue (right, FALSE));
3895 #if 0 // this indeed needs a second thought
3899 // let's keep this simple: get the rvalue we need
3900 op=geniCodeRValue (right, FALSE);
3901 // now cast it to whatever we want
3902 op=geniCodeCast (operandType(left), op, FALSE);
3903 // if this is going to be used as an lvalue, make it so
3909 #else // bug #604575, is it a bug ????
3910 return geniCodeCast (operandType (left),
3911 geniCodeRValue (right, FALSE), FALSE);
3918 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3923 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3924 setOperandType (op, UCHARTYPE);
3935 /* different compilers (even different gccs) evaluate
3936 the two calls in a different order. to get the same
3937 result on all machines we've to specify a clear sequence.
3938 return geniCodeLogic (geniCodeRValue (left, FALSE),
3939 geniCodeRValue (right, FALSE),
3943 operand *leftOp, *rightOp;
3945 rightOp = geniCodeRValue (right, FALSE);
3946 leftOp = geniCodeRValue (left , FALSE);
3948 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3951 return geniCodeConditional (tree,lvl);
3954 return operandFromLit (getSize (tree->right->ftype));
3958 sym_link *rtype = operandType (right);
3959 sym_link *ltype = operandType (left);
3960 if (IS_PTR (rtype) && IS_ITEMP (right)
3961 && right->isaddr && compareType (rtype->next, ltype) == 1)
3962 right = geniCodeRValue (right, TRUE);
3964 right = geniCodeRValue (right, FALSE);
3966 geniCodeAssign (left, right, 0);
3971 geniCodeAssign (left,
3972 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3974 geniCodeRValue (right, FALSE),FALSE), 0);
3978 geniCodeAssign (left,
3979 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3981 geniCodeRValue (right, FALSE),
3982 IS_INT (tree->ftype)),
3986 geniCodeAssign (left,
3987 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3989 geniCodeRValue (right, FALSE),
3990 IS_INT (tree->ftype)),
3994 sym_link *rtype = operandType (right);
3995 sym_link *ltype = operandType (left);
3996 if (IS_PTR (rtype) && IS_ITEMP (right)
3997 && right->isaddr && compareType (rtype->next, ltype) == 1)
3998 right = geniCodeRValue (right, TRUE);
4000 right = geniCodeRValue (right, FALSE);
4003 return geniCodeAssign (left,
4004 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4010 sym_link *rtype = operandType (right);
4011 sym_link *ltype = operandType (left);
4012 if (IS_PTR (rtype) && IS_ITEMP (right)
4013 && right->isaddr && compareType (rtype->next, ltype) == 1)
4015 right = geniCodeRValue (right, TRUE);
4019 right = geniCodeRValue (right, FALSE);
4022 geniCodeAssign (left,
4023 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4029 geniCodeAssign (left,
4030 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4032 geniCodeRValue (right, FALSE)), 0);
4035 geniCodeAssign (left,
4036 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4038 geniCodeRValue (right, FALSE)), 0);
4041 geniCodeAssign (left,
4042 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4044 geniCodeRValue (right, FALSE),
4046 operandType (left)), 0);
4049 geniCodeAssign (left,
4050 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4052 geniCodeRValue (right, FALSE),
4054 operandType (left)), 0);
4057 geniCodeAssign (left,
4058 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4060 geniCodeRValue (right, FALSE),
4062 operandType (left)), 0);
4064 return geniCodeRValue (right, FALSE);
4067 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4070 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4071 return ast2iCode (tree->right,lvl+1);
4074 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4075 return ast2iCode (tree->right,lvl+1);
4078 geniCodeFunctionBody (tree,lvl);
4082 geniCodeReturn (right);
4086 geniCodeIfx (tree,lvl);
4090 geniCodeSwitch (tree,lvl);
4094 geniCodeInline (tree);
4098 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4102 geniCodeCritical (tree, lvl);
4108 /*-----------------------------------------------------------------*/
4109 /* reverseICChain - gets from the list and creates a linkedlist */
4110 /*-----------------------------------------------------------------*/
4117 while ((loop = getSet (&iCodeChain)))
4129 /*-----------------------------------------------------------------*/
4130 /* iCodeFromAst - given an ast will convert it to iCode */
4131 /*-----------------------------------------------------------------*/
4133 iCodeFromAst (ast * tree)
4135 returnLabel = newiTempLabel ("_return");
4136 entryLabel = newiTempLabel ("_entry");
4138 return reverseiCChain ();
4141 static const char *opTypeToStr(OPTYPE op)
4145 case SYMBOL: return "symbol";
4146 case VALUE: return "value";
4147 case TYPE: return "type";
4149 return "undefined type";
4153 operand *validateOpType(operand *op,
4160 if (op && op->type == type)
4165 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4166 " expected %s, got %s\n",
4167 macro, args, file, line,
4168 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4170 return op; // never reached, makes compiler happy.