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 *geniCodeAssign (operand *, operand *, int, int);
49 static operand *geniCodeArray (operand *, operand *,int);
50 static operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
54 void setOClass (sym_link * ptr, sym_link * spec);
55 static operand *geniCodeCast (sym_link *, operand *, bool);
57 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
58 /* forward definition of ic print functions */
59 PRINTFUNC (picGetValueAtAddr);
60 PRINTFUNC (picSetValueAtAddr);
61 PRINTFUNC (picAddrOf);
62 PRINTFUNC (picGeneric);
63 PRINTFUNC (picGenericOne);
65 PRINTFUNC (picAssign);
69 PRINTFUNC (picJumpTable);
70 PRINTFUNC (picInline);
71 PRINTFUNC (picReceive);
72 PRINTFUNC (picDummyRead);
73 PRINTFUNC (picCritical);
74 PRINTFUNC (picEndCritical);
76 iCodeTable codeTable[] =
78 {'!', "not", picGenericOne, NULL},
79 {'~', "~", picGenericOne, NULL},
80 {RRC, "rrc", picGenericOne, NULL},
81 {RLC, "rlc", picGenericOne, NULL},
82 {GETHBIT, "ghbit", picGenericOne, NULL},
83 {UNARYMINUS, "-", picGenericOne, NULL},
84 {IPUSH, "push", picGenericOne, NULL},
85 {IPOP, "pop", picGenericOne, NULL},
86 {CALL, "call", picGenericOne, NULL},
87 {PCALL, "pcall", picGenericOne, NULL},
88 {FUNCTION, "proc", picGenericOne, NULL},
89 {ENDFUNCTION, "eproc", picGenericOne, NULL},
90 {RETURN, "ret", picGenericOne, NULL},
91 {'+', "+", picGeneric, NULL},
92 {'-', "-", picGeneric, NULL},
93 {'*', "*", picGeneric, NULL},
94 {'/', "/", picGeneric, NULL},
95 {'%', "%", picGeneric, NULL},
96 {'>', ">", picGeneric, NULL},
97 {'<', "<", picGeneric, NULL},
98 {LE_OP, "<=", picGeneric, NULL},
99 {GE_OP, ">=", picGeneric, NULL},
100 {EQ_OP, "==", picGeneric, NULL},
101 {NE_OP, "!=", picGeneric, NULL},
102 {AND_OP, "&&", picGeneric, NULL},
103 {OR_OP, "||", picGeneric, NULL},
104 {'^', "^", picGeneric, NULL},
105 {'|', "|", picGeneric, NULL},
106 {BITWISEAND, "&", picGeneric, NULL},
107 {LEFT_OP, "<<", picGeneric, NULL},
108 {RIGHT_OP, ">>", picGeneric, NULL},
109 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
110 {ADDRESS_OF, "&", picAddrOf, NULL},
111 {CAST, "<>", picCast, NULL},
112 {'=', ":=", picAssign, NULL},
113 {LABEL, "", picLabel, NULL},
114 {GOTO, "", picGoto, NULL},
115 {JUMPTABLE, "jtab", picJumpTable, NULL},
116 {IFX, "if", picIfx, NULL},
117 {INLINEASM, "", picInline, NULL},
118 {RECEIVE, "recv", picReceive, NULL},
119 {SEND, "send", picGenericOne, NULL},
120 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
121 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
122 {CRITICAL, "critical_start", picCritical, NULL},
123 {ENDCRITICAL, "critical_end", picEndCritical, NULL},
124 {SWAP, "swap", picGenericOne, 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 a2p%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->aggr2ptr, OP_SYMBOL (op)->isreqv,
243 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
244 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
248 printTypeChain (operandType (op), file);
249 if (SPIL_LOC (op) && IS_ITEMP (op))
250 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
255 /* if assigned to registers */
256 if (OP_SYMBOL (op)->nRegs)
258 if (OP_SYMBOL (op)->isspilt)
260 if (!OP_SYMBOL (op)->remat)
261 if (OP_SYMBOL (op)->usl.spillLoc)
262 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
263 OP_SYMBOL (op)->usl.spillLoc->rname :
264 OP_SYMBOL (op)->usl.spillLoc->name));
266 fprintf (file, "[err]");
268 fprintf (file, "[remat]");
274 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
275 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
280 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
281 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
282 /* if assigned to registers */
283 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
287 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
288 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
289 OP_SYMBOL (op)->regs[i]->name :
298 printTypeChain (op->operand.typeOperand, file);
304 fprintf (file, "\n");
309 /*-----------------------------------------------------------------*/
310 /* print functions */
311 /*-----------------------------------------------------------------*/
312 PRINTFUNC (picGetValueAtAddr)
315 printOperand (IC_RESULT (ic), of);
318 printOperand (IC_LEFT (ic), of);
324 PRINTFUNC (picSetValueAtAddr)
328 printOperand (IC_LEFT (ic), of);
329 fprintf (of, "] = ");
330 printOperand (IC_RIGHT (ic), of);
334 PRINTFUNC (picAddrOf)
337 printOperand (IC_RESULT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
341 fprintf (of, " = &[");
342 printOperand (IC_LEFT (ic), of);
345 if (IS_ITEMP (IC_LEFT (ic)))
346 fprintf (of, " offsetAdd ");
349 printOperand (IC_RIGHT (ic), of);
351 if (IS_ITEMP (IC_LEFT (ic)))
357 PRINTFUNC (picJumpTable)
362 fprintf (of, "%s\t", s);
363 printOperand (IC_JTCOND (ic), of);
365 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
366 sym = setNextItem (IC_JTLABELS (ic)))
367 fprintf (of, "\t\t\t%s\n", sym->name);
370 PRINTFUNC (picGeneric)
373 printOperand (IC_RESULT (ic), of);
375 printOperand (IC_LEFT (ic), of);
376 fprintf (of, " %s ", s);
377 printOperand (IC_RIGHT (ic), of);
381 PRINTFUNC (picGenericOne)
386 printOperand (IC_RESULT (ic), of);
392 fprintf (of, "%s ", s);
393 printOperand (IC_LEFT (ic), of);
396 if (!IC_RESULT (ic) && !IC_LEFT (ic))
399 if (ic->op == SEND || ic->op == RECEIVE) {
400 fprintf(of,"{argreg = %d}",ic->argreg);
408 printOperand (IC_RESULT (ic), of);
410 printOperand (IC_LEFT (ic), of);
411 printOperand (IC_RIGHT (ic), of);
416 PRINTFUNC (picAssign)
420 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
423 printOperand (IC_RESULT (ic), of);
425 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
428 fprintf (of, " %s ", s);
429 printOperand (IC_RIGHT (ic), of);
436 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
442 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
449 printOperand (IC_COND (ic), of);
452 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
455 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
457 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
461 PRINTFUNC (picInline)
463 fprintf (of, "%s", IC_INLINE (ic));
466 PRINTFUNC (picReceive)
468 printOperand (IC_RESULT (ic), of);
469 fprintf (of, " = %s ", s);
470 printOperand (IC_LEFT (ic), of);
474 PRINTFUNC (picDummyRead)
477 fprintf (of, "%s ", s);
478 printOperand (IC_RIGHT (ic), of);
482 PRINTFUNC (picCritical)
486 printOperand (IC_RESULT (ic), of);
488 fprintf (of, "(stack)");
489 fprintf (of, " = %s ", s);
493 PRINTFUNC (picEndCritical)
496 fprintf (of, "%s = ", s);
498 printOperand (IC_RIGHT (ic), of);
500 fprintf (of, "(stack)");
504 /*-----------------------------------------------------------------*/
505 /* piCode - prints one iCode */
506 /*-----------------------------------------------------------------*/
508 piCode (void *item, FILE * of)
516 icTab = getTableEntry (ic->op);
517 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
518 ic->filename, ic->lineno,
519 ic->seq, ic->key, ic->depth, ic->supportRtn);
520 icTab->iCodePrint (of, ic, icTab->printName);
526 printiCChain(ic,stdout);
528 /*-----------------------------------------------------------------*/
529 /* printiCChain - prints intermediate code for humans */
530 /*-----------------------------------------------------------------*/
532 printiCChain (iCode * icChain, FILE * of)
539 for (loop = icChain; loop; loop = loop->next)
541 if ((icTab = getTableEntry (loop->op)))
543 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
544 loop->filename, loop->lineno,
545 loop->seq, loop->key, loop->depth, loop->supportRtn);
547 icTab->iCodePrint (of, loop, icTab->printName);
553 /*-----------------------------------------------------------------*/
554 /* newOperand - allocate, init & return a new iCode */
555 /*-----------------------------------------------------------------*/
561 op = Safe_alloc ( sizeof (operand));
567 /*-----------------------------------------------------------------*/
568 /* newiCode - create and return a new iCode entry initialised */
569 /*-----------------------------------------------------------------*/
571 newiCode (int op, operand * left, operand * right)
575 ic = Safe_alloc ( sizeof (iCode));
577 ic->seqPoint = seqPoint;
579 ic->filename = filename;
581 ic->level = scopeLevel;
583 ic->key = iCodeKey++;
585 IC_RIGHT (ic) = right;
590 /*-----------------------------------------------------------------*/
591 /* newiCode for conditional statements */
592 /*-----------------------------------------------------------------*/
594 newiCodeCondition (operand * condition,
600 if (IS_VOID(operandType(condition))) {
601 werror(E_VOID_VALUE_USED);
604 ic = newiCode (IFX, NULL, NULL);
605 IC_COND (ic) = condition;
606 IC_TRUE (ic) = trueLabel;
607 IC_FALSE (ic) = falseLabel;
611 /*-----------------------------------------------------------------*/
612 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
613 /*-----------------------------------------------------------------*/
615 newiCodeLabelGoto (int op, symbol * label)
619 ic = newiCode (op, NULL, NULL);
623 IC_RIGHT (ic) = NULL;
624 IC_RESULT (ic) = NULL;
628 /*-----------------------------------------------------------------*/
629 /* newiTemp - allocate & return a newItemp Variable */
630 /*-----------------------------------------------------------------*/
638 SNPRINTF (buffer, sizeof(buffer), "%s", s);
642 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
645 itmp = newSymbol (buffer, 1);
646 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
652 /*-----------------------------------------------------------------*/
653 /* newiTempLabel - creates a temp variable label */
654 /*-----------------------------------------------------------------*/
656 newiTempLabel (char *s)
660 /* check if this alredy exists */
661 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
666 itmplbl = newSymbol (s, 1);
670 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
671 itmplbl = newSymbol (buffer, 1);
676 itmplbl->key = labelKey++;
677 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
681 /*-----------------------------------------------------------------*/
682 /* newiTempPreheaderLabel - creates a new preheader label */
683 /*-----------------------------------------------------------------*/
685 newiTempPreheaderLabel ()
689 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
690 itmplbl = newSymbol (buffer, 1);
694 itmplbl->key = labelKey++;
695 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
700 /*-----------------------------------------------------------------*/
701 /* initiCode - initialises some iCode related stuff */
702 /*-----------------------------------------------------------------*/
709 /*-----------------------------------------------------------------*/
710 /* copyiCode - make a copy of the iCode given */
711 /*-----------------------------------------------------------------*/
713 copyiCode (iCode * ic)
715 iCode *nic = newiCode (ic->op, NULL, NULL);
717 nic->lineno = ic->lineno;
718 nic->filename = ic->filename;
719 nic->block = ic->block;
720 nic->level = ic->level;
721 nic->parmBytes = ic->parmBytes;
723 /* deal with the special cases first */
727 IC_COND (nic) = operandFromOperand (IC_COND (ic));
728 IC_TRUE (nic) = IC_TRUE (ic);
729 IC_FALSE (nic) = IC_FALSE (ic);
733 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
734 IC_JTLABELS (nic) = IC_JTLABELS (ic);
739 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
740 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
744 IC_INLINE (nic) = IC_INLINE (ic);
748 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
752 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
753 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
754 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
760 /*-----------------------------------------------------------------*/
761 /* getTableEntry - gets the table entry for the given operator */
762 /*-----------------------------------------------------------------*/
764 getTableEntry (int oper)
768 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
769 if (oper == codeTable[i].icode)
770 return &codeTable[i];
775 /*-----------------------------------------------------------------*/
776 /* newiTempOperand - new intermediate temp operand */
777 /*-----------------------------------------------------------------*/
779 newiTempOperand (sym_link * type, char throwType)
782 operand *op = newOperand ();
786 itmp = newiTemp (NULL);
788 etype = getSpec (type);
790 if (IS_LITERAL (etype))
793 /* copy the type information */
795 itmp->etype = getSpec (itmp->type = (throwType ? type :
796 copyLinkChain (type)));
797 if (IS_LITERAL (itmp->etype))
799 SPEC_SCLS (itmp->etype) = S_REGISTER;
800 SPEC_OCLS (itmp->etype) = reg;
803 op->operand.symOperand = itmp;
804 op->key = itmp->key = ++operandKey;
808 /*-----------------------------------------------------------------*/
809 /* operandType - returns the type chain for an operand */
810 /*-----------------------------------------------------------------*/
812 operandType (operand * op)
814 /* depending on type of operand */
819 return op->operand.valOperand->type;
822 return op->operand.symOperand->type;
825 return op->operand.typeOperand;
827 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
828 " operand type not known ");
829 assert (0); /* should never come here */
830 /* Just to keep the compiler happy */
831 return (sym_link *) 0;
835 /*-----------------------------------------------------------------*/
836 /* isParamterToCall - will return 1 if op is a parameter to args */
837 /*-----------------------------------------------------------------*/
839 isParameterToCall (value * args, operand * op)
843 wassert (IS_SYMOP(op));
848 isSymbolEqual (op->operand.symOperand, tval->sym))
855 /*-----------------------------------------------------------------*/
856 /* isOperandGlobal - return 1 if operand is a global variable */
857 /*-----------------------------------------------------------------*/
859 isOperandGlobal (operand * op)
868 (op->operand.symOperand->level == 0 ||
869 IS_STATIC (op->operand.symOperand->etype) ||
870 IS_EXTERN (op->operand.symOperand->etype))
877 /*-----------------------------------------------------------------*/
878 /* isOperandVolatile - return 1 if the operand is volatile */
879 /*-----------------------------------------------------------------*/
881 isOperandVolatile (operand * op, bool chkTemp)
886 if (IS_ITEMP (op) && !chkTemp)
889 opetype = getSpec (optype = operandType (op));
891 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
894 if (IS_VOLATILE (opetype))
899 /*-----------------------------------------------------------------*/
900 /* isOperandLiteral - returns 1 if an operand contains a literal */
901 /*-----------------------------------------------------------------*/
903 isOperandLiteral (operand * op)
910 opetype = getSpec (operandType (op));
912 if (IS_LITERAL (opetype))
918 /*-----------------------------------------------------------------*/
919 /* isOperandInFarSpace - will return true if operand is in farSpace */
920 /*-----------------------------------------------------------------*/
922 isOperandInFarSpace (operand * op)
932 if (!IS_TRUE_SYMOP (op))
935 etype = SPIL_LOC (op)->etype;
941 etype = getSpec (operandType (op));
943 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
946 /*------------------------------------------------------------------*/
947 /* isOperandInDirSpace - will return true if operand is in dirSpace */
948 /*------------------------------------------------------------------*/
950 isOperandInDirSpace (operand * op)
960 if (!IS_TRUE_SYMOP (op))
963 etype = SPIL_LOC (op)->etype;
969 etype = getSpec (operandType (op));
971 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
974 /*--------------------------------------------------------------------*/
975 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
976 /*--------------------------------------------------------------------*/
978 isOperandInCodeSpace (operand * op)
988 etype = getSpec (operandType (op));
990 if (!IS_TRUE_SYMOP (op))
993 etype = SPIL_LOC (op)->etype;
999 etype = getSpec (operandType (op));
1001 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1004 /*-----------------------------------------------------------------*/
1005 /* isOperandOnStack - will return true if operand is on stack */
1006 /*-----------------------------------------------------------------*/
1008 isOperandOnStack (operand * op)
1018 etype = getSpec (operandType (op));
1019 if (IN_STACK (etype) ||
1020 OP_SYMBOL(op)->onStack ||
1021 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1027 /*-----------------------------------------------------------------*/
1028 /* isOclsExpensive - will return true if accesses to an output */
1029 /* storage class are expensive */
1030 /*-----------------------------------------------------------------*/
1032 isOclsExpensive (struct memmap *oclass)
1034 if (port->oclsExpense)
1035 return port->oclsExpense (oclass) > 0;
1037 /* In the absence of port specific guidance, assume only */
1038 /* farspace is expensive. */
1039 return IN_FARSPACE (oclass);
1042 /*-----------------------------------------------------------------*/
1043 /* operandLitValue - literal value of an operand */
1044 /*-----------------------------------------------------------------*/
1046 operandLitValue (operand * op)
1048 assert (isOperandLiteral (op));
1050 return floatFromVal (op->operand.valOperand);
1053 /*-----------------------------------------------------------------*/
1054 /* getBuiltInParms - returns parameters to a builtin functions */
1055 /*-----------------------------------------------------------------*/
1056 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1061 /* builtin functions uses only SEND for parameters */
1062 while (ic->op != CALL) {
1063 assert(ic->op == SEND && ic->builtinSEND);
1064 ic->generated = 1; /* mark the icode as generated */
1065 parms[*pcount] = IC_LEFT(ic);
1071 /* make sure this is a builtin function call */
1072 assert(IS_SYMOP(IC_LEFT(ic)));
1073 ftype = operandType(IC_LEFT(ic));
1074 assert(IFFUNC_ISBUILTIN(ftype));
1078 /*-----------------------------------------------------------------*/
1079 /* operandOperation - performs operations on operands */
1080 /*-----------------------------------------------------------------*/
1082 operandOperation (operand * left, operand * right,
1083 int op, sym_link * type)
1085 sym_link *let , *ret=NULL;
1086 operand *retval = (operand *) 0;
1088 assert (isOperandLiteral (left));
1089 let = getSpec(operandType(left));
1091 assert (isOperandLiteral (right));
1092 ret = getSpec(operandType(right));
1098 retval = operandFromValue (valCastLiteral (type,
1099 operandLitValue (left) +
1100 operandLitValue (right)));
1103 retval = operandFromValue (valCastLiteral (type,
1104 operandLitValue (left) -
1105 operandLitValue (right)));
1109 retval = operandFromValue (valCastLiteral (type,
1110 operandLitValue (left) *
1111 operandLitValue (right)));
1112 This could be all we've to do, but with gcc we've to take care about
1113 overflows. Two examples:
1114 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1115 significant bits are lost (52 in fraction, 63 bits would be
1116 necessary to keep full precision).
1117 If the resulting double value is greater than ULONG_MAX (resp.
1118 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1121 /* if it is not a specifier then we can assume that */
1122 /* it will be an unsigned long */
1123 if (IS_INT (type) ||
1126 /* long is handled here, because it can overflow with double */
1127 if (IS_LONG (type) ||
1129 /* signed and unsigned mul are the same, as long as the precision
1130 of the result isn't bigger than the precision of the operands. */
1131 retval = operandFromValue (valCastLiteral (type,
1132 (TYPE_UDWORD) operandLitValue (left) *
1133 (TYPE_UDWORD) operandLitValue (right)));
1134 else if (IS_UNSIGNED (type)) /* unsigned int */
1136 /* unsigned int is handled here in order to detect overflow */
1137 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1138 (TYPE_UWORD) operandLitValue (right);
1140 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1141 if (ul != (TYPE_UWORD) ul)
1144 else /* signed int */
1146 /* signed int is handled here in order to detect overflow */
1147 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1148 (TYPE_WORD) operandLitValue (right);
1150 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1151 if (l != (TYPE_WORD) l)
1156 /* all others go here: */
1157 retval = operandFromValue (valCastLiteral (type,
1158 operandLitValue (left) *
1159 operandLitValue (right)));
1162 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1164 werror (E_DIVIDE_BY_ZERO);
1170 if (IS_UNSIGNED (type))
1172 SPEC_USIGN (let) = 1;
1173 SPEC_USIGN (ret) = 1;
1174 retval = operandFromValue (valCastLiteral (type,
1175 (TYPE_UDWORD) operandLitValue (left) /
1176 (TYPE_UDWORD) operandLitValue (right)));
1180 retval = operandFromValue (valCastLiteral (type,
1181 operandLitValue (left) /
1182 operandLitValue (right)));
1187 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1189 werror (E_DIVIDE_BY_ZERO);
1194 if (IS_UNSIGNED (type))
1195 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1196 (TYPE_UDWORD) operandLitValue (right));
1198 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1199 (TYPE_DWORD) operandLitValue (right));
1203 /* The number of left shifts is always unsigned. Signed doesn't make
1204 sense here. Shifting by a negative number is impossible. */
1205 retval = operandFromValue (valCastLiteral (type,
1206 ((TYPE_UDWORD) operandLitValue (left) <<
1207 (TYPE_UDWORD) operandLitValue (right))));
1210 /* The number of right shifts is always unsigned. Signed doesn't make
1211 sense here. Shifting by a negative number is impossible. */
1212 if (IS_UNSIGNED(let))
1213 /* unsigned: logic shift right */
1214 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1215 (TYPE_UDWORD) operandLitValue (right));
1217 /* signed: arithmetic shift right */
1218 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1219 (TYPE_UDWORD) operandLitValue (right));
1222 if (IS_FLOAT (let) ||
1225 retval = operandFromLit (operandLitValue (left) ==
1226 operandLitValue (right));
1230 /* this op doesn't care about signedness */
1233 l = (TYPE_UDWORD) operandLitValue (left);
1234 r = (TYPE_UDWORD) operandLitValue (right);
1235 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1236 neccessary to strip them to 16 bit.
1237 Literals are reduced to their cheapest type, therefore left and
1238 right might have different types. It's neccessary to find a
1239 common type: int (used for char too) or long */
1240 if (!IS_LONG (let) &&
1246 retval = operandFromLit (l == r);
1250 retval = operandFromLit (operandLitValue (left) <
1251 operandLitValue (right));
1254 retval = operandFromLit (operandLitValue (left) <=
1255 operandLitValue (right));
1258 retval = operandFromLit (operandLitValue (left) !=
1259 operandLitValue (right));
1262 retval = operandFromLit (operandLitValue (left) >
1263 operandLitValue (right));
1266 retval = operandFromLit (operandLitValue (left) >=
1267 operandLitValue (right));
1270 retval = operandFromValue (valCastLiteral (type,
1271 (TYPE_UDWORD)operandLitValue(left) &
1272 (TYPE_UDWORD)operandLitValue(right)));
1275 retval = operandFromValue (valCastLiteral (type,
1276 (TYPE_UDWORD)operandLitValue(left) |
1277 (TYPE_UDWORD)operandLitValue(right)));
1280 retval = operandFromValue (valCastLiteral (type,
1281 (TYPE_UDWORD)operandLitValue(left) ^
1282 (TYPE_UDWORD)operandLitValue(right)));
1285 retval = operandFromLit (operandLitValue (left) &&
1286 operandLitValue (right));
1289 retval = operandFromLit (operandLitValue (left) ||
1290 operandLitValue (right));
1294 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1296 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1302 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1304 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1310 retval = operandFromValue (valCastLiteral (type,
1311 -1 * operandLitValue (left)));
1315 retval = operandFromValue (valCastLiteral (type,
1317 operandLitValue (left))));
1321 retval = operandFromLit (!operandLitValue (left));
1325 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1326 " operandOperation invalid operator ");
1334 /*-----------------------------------------------------------------*/
1335 /* isOperandEqual - compares two operand & return 1 if they r = */
1336 /*-----------------------------------------------------------------*/
1338 isOperandEqual (operand * left, operand * right)
1340 /* if the pointers are equal then they are equal */
1344 /* if either of them null then false */
1345 if (!left || !right)
1348 if (left->type != right->type)
1351 if (IS_SYMOP (left) && IS_SYMOP (right))
1352 return left->key == right->key;
1354 /* if types are the same */
1358 return isSymbolEqual (left->operand.symOperand,
1359 right->operand.symOperand);
1361 return (floatFromVal (left->operand.valOperand) ==
1362 floatFromVal (right->operand.valOperand));
1364 if (compareType (left->operand.typeOperand,
1365 right->operand.typeOperand) == 1)
1372 /*-------------------------------------------------------------------*/
1373 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1374 /*-------------------------------------------------------------------*/
1376 isiCodeEqual (iCode * left, iCode * right)
1378 /* if the same pointer */
1382 /* if either of them null */
1383 if (!left || !right)
1386 /* if operand are the same */
1387 if (left->op == right->op)
1390 /* compare all the elements depending on type */
1391 if (left->op != IFX)
1393 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1395 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1401 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1403 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1405 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1414 /*-----------------------------------------------------------------*/
1415 /* newiTempFromOp - create a temp Operand with same attributes */
1416 /*-----------------------------------------------------------------*/
1418 newiTempFromOp (operand * op)
1428 nop = newiTempOperand (operandType (op), TRUE);
1429 nop->isaddr = op->isaddr;
1430 nop->isvolatile = op->isvolatile;
1431 nop->isGlobal = op->isGlobal;
1432 nop->isLiteral = op->isLiteral;
1433 nop->usesDefs = op->usesDefs;
1434 nop->isParm = op->isParm;
1438 /*-----------------------------------------------------------------*/
1439 /* operand from operand - creates an operand holder for the type */
1440 /*-----------------------------------------------------------------*/
1442 operandFromOperand (operand * op)
1448 nop = newOperand ();
1449 nop->type = op->type;
1450 nop->isaddr = op->isaddr;
1452 nop->isvolatile = op->isvolatile;
1453 nop->isGlobal = op->isGlobal;
1454 nop->isLiteral = op->isLiteral;
1455 nop->usesDefs = op->usesDefs;
1456 nop->isParm = op->isParm;
1461 nop->operand.symOperand = op->operand.symOperand;
1464 nop->operand.valOperand = op->operand.valOperand;
1467 nop->operand.typeOperand = op->operand.typeOperand;
1474 /*-----------------------------------------------------------------*/
1475 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1476 /*-----------------------------------------------------------------*/
1478 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1480 operand *nop = operandFromOperand (op);
1482 if (nop->type == SYMBOL)
1484 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1485 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1491 /*-----------------------------------------------------------------*/
1492 /* operandFromSymbol - creates an operand from a symbol */
1493 /*-----------------------------------------------------------------*/
1495 operandFromSymbol (symbol * sym)
1500 /* if the symbol's type is a literal */
1501 /* then it is an enumerator type */
1502 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1503 return operandFromValue (valFromType (sym->etype));
1506 sym->key = ++operandKey;
1508 /* if this an implicit variable, means struct/union */
1509 /* member so just return it */
1510 if (sym->implicit || IS_FUNC (sym->type))
1514 op->operand.symOperand = sym;
1516 op->isvolatile = isOperandVolatile (op, TRUE);
1517 op->isGlobal = isOperandGlobal (op);
1521 /* under the following conditions create a
1522 register equivalent for a local symbol */
1523 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1524 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1526 (!(options.model == MODEL_FLAT24)) ) &&
1527 options.stackAuto == 0)
1530 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1531 !IS_FUNC (sym->type) && /* not a function */
1532 !sym->_isparm && /* not a parameter */
1533 IS_AUTO (sym) && /* is a local auto variable */
1534 !sym->addrtaken && /* whose address has not been taken */
1535 !sym->reqv && /* does not already have a reg equivalence */
1536 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1537 !sym->islbl && /* not a label */
1538 ok && /* farspace check */
1539 !IS_BITVAR (sym->etype) /* not a bit variable */
1543 /* we will use it after all optimizations
1544 and before liveRange calculation */
1545 sym->reqv = newiTempOperand (sym->type, 0);
1546 sym->reqv->key = sym->key;
1547 OP_SYMBOL (sym->reqv)->prereqv = sym;
1548 OP_SYMBOL (sym->reqv)->key = sym->key;
1549 OP_SYMBOL (sym->reqv)->isreqv = 1;
1550 OP_SYMBOL (sym->reqv)->islocal = 1;
1551 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1552 SPIL_LOC (sym->reqv) = sym;
1555 if (!IS_AGGREGATE (sym->type))
1559 op->operand.symOperand = sym;
1562 op->isvolatile = isOperandVolatile (op, TRUE);
1563 op->isGlobal = isOperandGlobal (op);
1564 op->isPtr = IS_PTR (operandType (op));
1565 op->isParm = sym->_isparm;
1570 /* itemp = &[_symbol] */
1572 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1573 IC_LEFT (ic)->type = SYMBOL;
1574 IC_LEFT (ic)->operand.symOperand = sym;
1575 IC_LEFT (ic)->key = sym->key;
1576 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1577 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1578 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1581 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1582 if (IS_ARRAY (sym->type))
1584 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1585 IC_RESULT (ic)->isaddr = 0;
1588 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1592 return IC_RESULT (ic);
1595 /*-----------------------------------------------------------------*/
1596 /* operandFromValue - creates an operand from value */
1597 /*-----------------------------------------------------------------*/
1599 operandFromValue (value * val)
1603 /* if this is a symbol then do the symbol thing */
1605 return operandFromSymbol (val->sym);
1607 /* this is not a symbol */
1610 op->operand.valOperand = val;
1611 op->isLiteral = isOperandLiteral (op);
1615 /*-----------------------------------------------------------------*/
1616 /* operandFromLink - operand from typeChain */
1617 /*-----------------------------------------------------------------*/
1619 operandFromLink (sym_link * type)
1623 /* operand from sym_link */
1629 op->operand.typeOperand = copyLinkChain (type);
1633 /*-----------------------------------------------------------------*/
1634 /* operandFromLit - makes an operand from a literal value */
1635 /*-----------------------------------------------------------------*/
1637 operandFromLit (double i)
1639 return operandFromValue (valueFromLit (i));
1642 /*-----------------------------------------------------------------*/
1643 /* operandFromAst - creates an operand from an ast */
1644 /*-----------------------------------------------------------------*/
1646 operandFromAst (ast * tree,int lvl)
1652 /* depending on type do */
1656 return ast2iCode (tree,lvl+1);
1660 return operandFromValue (tree->opval.val);
1664 return operandFromLink (tree->opval.lnk);
1671 /* Just to keep the compiler happy */
1672 return (operand *) 0;
1675 /*-----------------------------------------------------------------*/
1676 /* setOperandType - sets the operand's type to the given type */
1677 /*-----------------------------------------------------------------*/
1679 setOperandType (operand * op, sym_link * type)
1681 /* depending on the type of operand */
1686 op->operand.valOperand->etype =
1687 getSpec (op->operand.valOperand->type =
1688 copyLinkChain (type));
1692 if (op->operand.symOperand->isitmp)
1693 op->operand.symOperand->etype =
1694 getSpec (op->operand.symOperand->type =
1695 copyLinkChain (type));
1697 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1698 "attempt to modify type of source");
1702 op->operand.typeOperand = copyLinkChain (type);
1708 /*-----------------------------------------------------------------*/
1709 /* Get size in byte of ptr need to access an array */
1710 /*-----------------------------------------------------------------*/
1712 getArraySizePtr (operand * op)
1714 sym_link *ltype = operandType(op);
1718 int size = getSize(ltype);
1719 return(IS_GENPTR(ltype)?(size-1):size);
1724 sym_link *letype = getSpec(ltype);
1725 switch (PTR_TYPE (SPEC_OCLS (letype)))
1737 return (GPTRSIZE-1);
1746 /*-----------------------------------------------------------------*/
1747 /* perform "usual unary conversions" */
1748 /*-----------------------------------------------------------------*/
1751 usualUnaryConversions (operand * op)
1753 if (IS_INTEGRAL (operandType (op)))
1755 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1758 return geniCodeCast (INTTYPE, op, TRUE);
1765 /*-----------------------------------------------------------------*/
1766 /* perform "usual binary conversions" */
1767 /*-----------------------------------------------------------------*/
1770 usualBinaryConversions (operand ** op1, operand ** op2,
1771 RESULT_TYPE resultType, int op)
1774 sym_link *rtype = operandType (*op2);
1775 sym_link *ltype = operandType (*op1);
1777 ctype = computeType (ltype, rtype, resultType, op);
1784 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1786 /* one byte operations: keep signedness for code generator */
1794 *op1 = geniCodeCast (ctype, *op1, TRUE);
1795 *op2 = geniCodeCast (ctype, *op2, TRUE);
1800 /*-----------------------------------------------------------------*/
1801 /* geniCodeValueAtAddress - generate intermeditate code for value */
1803 /*-----------------------------------------------------------------*/
1805 geniCodeRValue (operand * op, bool force)
1808 sym_link *type = operandType (op);
1809 sym_link *etype = getSpec (type);
1811 /* if this is an array & already */
1812 /* an address then return this */
1813 if (IS_AGGREGATE (type) ||
1814 (IS_PTR (type) && !force && !op->isaddr))
1815 return operandFromOperand (op);
1817 /* if this is not an address then must be */
1818 /* rvalue already so return this one */
1822 /* if this is not a temp symbol then */
1823 if (!IS_ITEMP (op) &&
1825 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1827 op = operandFromOperand (op);
1832 if (IS_SPEC (type) &&
1833 IS_TRUE_SYMOP (op) &&
1834 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1835 (options.model == MODEL_FLAT24) ))
1837 op = operandFromOperand (op);
1842 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1843 if (IS_PTR (type) && op->isaddr && force)
1846 type = copyLinkChain (type);
1848 IC_RESULT (ic) = newiTempOperand (type, 1);
1849 IC_RESULT (ic)->isaddr = 0;
1851 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1855 return IC_RESULT (ic);
1858 /*-----------------------------------------------------------------*/
1859 /* geniCodeCast - changes the value from one type to another */
1860 /*-----------------------------------------------------------------*/
1862 geniCodeCast (sym_link * type, operand * op, bool implicit)
1866 sym_link *opetype = getSpec (optype = operandType (op));
1870 /* one of them has size zero then error */
1871 if (IS_VOID (optype))
1873 werror (E_CAST_ZERO);
1877 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1879 geniCodeArray2Ptr (op);
1883 /* if the operand is already the desired type then do nothing */
1884 if (compareType (type, optype) == 1)
1887 /* if this is a literal then just change the type & return */
1888 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1890 return operandFromValue (valCastLiteral (type,
1891 operandLitValue (op)));
1894 /* if casting to/from pointers, do some checking */
1895 if (IS_PTR(type)) { // to a pointer
1896 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1897 if (IS_INTEGRAL(optype)) {
1898 // maybe this is NULL, than it's ok.
1899 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1900 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1901 // no way to set the storage
1902 if (IS_LITERAL(optype)) {
1903 werror(E_LITERAL_GENERIC);
1906 werror(E_NONPTR2_GENPTR);
1909 } else if (implicit) {
1910 werror(W_INTEGRAL2PTR_NOCAST);
1915 // shouldn't do that with float, array or structure unless to void
1916 if (!IS_VOID(getSpec(type)) &&
1917 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1918 werror(E_INCOMPAT_TYPES);
1922 } else { // from a pointer to a pointer
1923 if (IS_GENPTR(type) && IS_VOID(type->next))
1924 { // cast to void* is always allowed
1926 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
1927 { // cast from void* is always allowed
1929 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
1930 // if not a pointer to a function
1931 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1932 if (implicit) { // if not to generic, they have to match
1933 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1934 werror(E_INCOMPAT_PTYPES);
1941 } else { // to a non pointer
1942 if (IS_PTR(optype)) { // from a pointer
1943 if (implicit) { // sneaky
1944 if (IS_INTEGRAL(type)) {
1945 werror(W_PTR2INTEGRAL_NOCAST);
1947 } else { // shouldn't do that with float, array or structure
1948 werror(E_INCOMPAT_TYPES);
1955 printFromToType (optype, type);
1958 /* if they are the same size create an assignment */
1960 /* This seems very dangerous to me, since there are several */
1961 /* optimizations (for example, gcse) that don't notice the */
1962 /* cast hidden in this assignement and may simplify an */
1963 /* iCode to use the original (uncasted) operand. */
1964 /* Unfortunately, other things break when this cast is */
1965 /* made explicit. Need to fix this someday. */
1966 /* -- EEP, 2004/01/21 */
1967 if (getSize (type) == getSize (optype) &&
1968 !IS_BITFIELD (type) &&
1970 !IS_FLOAT (optype) &&
1971 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1972 (!IS_SPEC (type) && !IS_SPEC (optype))))
1974 ic = newiCode ('=', NULL, op);
1975 IC_RESULT (ic) = newiTempOperand (type, 0);
1976 SPIL_LOC (IC_RESULT (ic)) =
1977 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1978 IC_RESULT (ic)->isaddr = 0;
1982 ic = newiCode (CAST, operandFromLink (type),
1983 geniCodeRValue (op, FALSE));
1985 IC_RESULT (ic) = newiTempOperand (type, 0);
1988 /* preserve the storage class & output class */
1989 /* of the original variable */
1990 restype = getSpec (operandType (IC_RESULT (ic)));
1991 if (!IS_LITERAL(opetype) &&
1993 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1994 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1997 return IC_RESULT (ic);
2000 /*-----------------------------------------------------------------*/
2001 /* geniCodeLabel - will create a Label */
2002 /*-----------------------------------------------------------------*/
2004 geniCodeLabel (symbol * label)
2008 ic = newiCodeLabelGoto (LABEL, label);
2012 /*-----------------------------------------------------------------*/
2013 /* geniCodeGoto - will create a Goto */
2014 /*-----------------------------------------------------------------*/
2016 geniCodeGoto (symbol * label)
2020 ic = newiCodeLabelGoto (GOTO, label);
2024 /*-----------------------------------------------------------------*/
2025 /* geniCodeMultiply - gen intermediate code for multiplication */
2026 /*-----------------------------------------------------------------*/
2028 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2035 /* if they are both literal then we know the result */
2036 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2037 return operandFromValue (valMult (left->operand.valOperand,
2038 right->operand.valOperand));
2040 if (IS_LITERAL(retype)) {
2041 p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand));
2044 resType = usualBinaryConversions (&left, &right, resultType, '*');
2046 rtype = operandType (right);
2047 retype = getSpec (rtype);
2048 ltype = operandType (left);
2049 letype = getSpec (ltype);
2052 /* if the right is a literal & power of 2 */
2053 /* then make it a left shift */
2054 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2055 efficient in most cases than 2 bytes result = 2 bytes << literal
2056 if port has 1 byte muldiv */
2057 if (p2 && !IS_FLOAT (letype)
2058 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2059 && (port->support.muldiv == 1))
2060 && strcmp (port->target, "pic14") != 0 /* don't shift for pic */
2061 && strcmp (port->target, "pic16") != 0)
2063 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2065 /* LEFT_OP need same size for left and result, */
2066 left = geniCodeCast (resType, left, TRUE);
2067 ltype = operandType (left);
2069 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2073 ic = newiCode ('*', left, right); /* normal multiplication */
2074 /* if the size left or right > 1 then support routine */
2075 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2079 IC_RESULT (ic) = newiTempOperand (resType, 1);
2082 return IC_RESULT (ic);
2085 /*-----------------------------------------------------------------*/
2086 /* geniCodeDivision - gen intermediate code for division */
2087 /*-----------------------------------------------------------------*/
2089 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2094 sym_link *rtype = operandType (right);
2095 sym_link *retype = getSpec (rtype);
2096 sym_link *ltype = operandType (left);
2097 sym_link *letype = getSpec (ltype);
2099 resType = usualBinaryConversions (&left, &right, resultType, '/');
2101 /* if the right is a literal & power of 2
2102 and left is unsigned then make it a
2104 if (IS_LITERAL (retype) &&
2105 !IS_FLOAT (letype) &&
2106 IS_UNSIGNED(letype) &&
2107 (p2 = powof2 ((TYPE_UDWORD)
2108 floatFromVal (right->operand.valOperand)))) {
2109 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2113 ic = newiCode ('/', left, right); /* normal division */
2114 /* if the size left or right > 1 then support routine */
2115 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2118 IC_RESULT (ic) = newiTempOperand (resType, 0);
2121 return IC_RESULT (ic);
2123 /*-----------------------------------------------------------------*/
2124 /* geniCodeModulus - gen intermediate code for modulus */
2125 /*-----------------------------------------------------------------*/
2127 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2133 /* if they are both literal then we know the result */
2134 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2135 return operandFromValue (valMod (left->operand.valOperand,
2136 right->operand.valOperand));
2138 resType = usualBinaryConversions (&left, &right, resultType, '%');
2140 /* now they are the same size */
2141 ic = newiCode ('%', left, right);
2143 /* if the size left or right > 1 then support routine */
2144 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2146 IC_RESULT (ic) = newiTempOperand (resType, 0);
2149 return IC_RESULT (ic);
2152 /*-----------------------------------------------------------------*/
2153 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2154 /*-----------------------------------------------------------------*/
2156 geniCodePtrPtrSubtract (operand * left, operand * right)
2162 /* if they are both literals then */
2163 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2165 result = operandFromValue (valMinus (left->operand.valOperand,
2166 right->operand.valOperand));
2170 ic = newiCode ('-', left, right);
2172 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2176 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2180 // should we really do this? is this ANSI?
2181 return geniCodeDivision (result,
2182 operandFromLit (getSize (ltype->next)),
2186 /*-----------------------------------------------------------------*/
2187 /* geniCodeSubtract - generates code for subtraction */
2188 /*-----------------------------------------------------------------*/
2190 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2197 /* if they both pointers then */
2198 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2199 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2200 return geniCodePtrPtrSubtract (left, right);
2202 /* if they are both literal then we know the result */
2203 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2204 && left->isLiteral && right->isLiteral)
2205 return operandFromValue (valMinus (left->operand.valOperand,
2206 right->operand.valOperand));
2208 /* if left is an array or pointer */
2209 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2211 isarray = left->isaddr;
2212 right = geniCodeMultiply (right,
2213 operandFromLit (getSize (ltype->next)),
2214 (getArraySizePtr(left) >= INTSIZE) ?
2217 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2220 { /* make them the same size */
2221 resType = usualBinaryConversions (&left, &right, resultType, '-');
2224 ic = newiCode ('-', left, right);
2226 IC_RESULT (ic) = newiTempOperand (resType, 1);
2227 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2229 /* if left or right is a float */
2230 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2234 return IC_RESULT (ic);
2237 /*-----------------------------------------------------------------*/
2238 /* geniCodeAdd - generates iCode for addition */
2239 /*-----------------------------------------------------------------*/
2241 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2250 /* if the right side is LITERAL zero */
2251 /* return the left side */
2252 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2255 /* if left is literal zero return right */
2256 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2259 /* if left is a pointer then size */
2260 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2262 isarray = left->isaddr;
2263 // there is no need to multiply with 1
2264 if (getSize (ltype->next) != 1)
2266 size = operandFromLit (getSize (ltype->next));
2267 SPEC_USIGN (getSpec (operandType (size))) = 1;
2268 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2269 right = geniCodeMultiply (right,
2271 (getArraySizePtr(left) >= INTSIZE) ?
2274 /* Even if right is a 'unsigned char',
2275 the result will be a 'signed int' due to the promotion rules.
2276 It doesn't make sense when accessing arrays, so let's fix it here: */
2278 SPEC_USIGN (getSpec (operandType (right))) = 1;
2280 resType = copyLinkChain (ltype);
2283 { // make them the same size
2284 resType = usualBinaryConversions (&left, &right, resultType, '+');
2287 /* if they are both literals then we know */
2288 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2289 && left->isLiteral && right->isLiteral)
2290 return operandFromValue (valPlus (valFromType (ltype),
2291 valFromType (rtype)));
2293 ic = newiCode ('+', left, right);
2295 IC_RESULT (ic) = newiTempOperand (resType, 1);
2296 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2298 /* if left or right is a float then support
2300 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2305 return IC_RESULT (ic);
2309 /*-----------------------------------------------------------------*/
2310 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2311 /*-----------------------------------------------------------------*/
2313 aggrToPtr (sym_link * type, bool force)
2318 if (IS_PTR (type) && !force)
2321 etype = getSpec (type);
2322 ptype = newLink (DECLARATOR);
2326 /* set the pointer depending on the storage class */
2327 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2331 /*------------------------------------------------------------------*/
2332 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2333 /*------------------------------------------------------------------*/
2335 aggrToPtrDclType (sym_link * type, bool force)
2337 if (IS_PTR (type) && !force)
2338 return DCL_TYPE (type);
2340 /* return the pointer depending on the storage class */
2341 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2344 /*-----------------------------------------------------------------*/
2345 /* geniCodeArray2Ptr - array to pointer */
2346 /*-----------------------------------------------------------------*/
2348 geniCodeArray2Ptr (operand * op)
2350 sym_link *optype = operandType (op);
2351 sym_link *opetype = getSpec (optype);
2353 /* set the pointer depending on the storage class */
2354 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2361 /*-----------------------------------------------------------------*/
2362 /* geniCodeArray - array access */
2363 /*-----------------------------------------------------------------*/
2365 geniCodeArray (operand * left, operand * right, int lvl)
2369 sym_link *ltype = operandType (left);
2374 if (IS_PTR (ltype->next) && left->isaddr)
2376 left = geniCodeRValue (left, FALSE);
2379 return geniCodeDerefPtr (geniCodeAdd (left,
2381 (getArraySizePtr(left) >= INTSIZE) ?
2387 size = operandFromLit (getSize (ltype->next));
2388 SPEC_USIGN (getSpec (operandType (size))) = 1;
2389 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2390 right = geniCodeMultiply (right,
2392 (getArraySizePtr(left) >= INTSIZE) ?
2395 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2396 It doesn't make sense when accessing arrays, so let's fix it here: */
2398 SPEC_USIGN (getSpec (operandType (right))) = 1;
2399 /* we can check for limits here */
2400 /* already done in SDCCast.c
2401 if (isOperandLiteral (right) &&
2404 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2406 werror (W_IDX_OUT_OF_BOUNDS,
2407 (int) operandLitValue (right) / getSize (ltype->next),
2412 ic = newiCode ('+', left, right);
2414 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2415 !IS_AGGREGATE (ltype->next) &&
2416 !IS_PTR (ltype->next))
2417 ? ltype : ltype->next), 0);
2419 if (!IS_AGGREGATE (ltype->next))
2421 IC_RESULT (ic)->isaddr = 1;
2422 IC_RESULT (ic)->aggr2ptr = 1;
2426 return IC_RESULT (ic);
2429 /*-----------------------------------------------------------------*/
2430 /* geniCodeStruct - generates intermediate code for structures */
2431 /*-----------------------------------------------------------------*/
2433 geniCodeStruct (operand * left, operand * right, bool islval)
2436 sym_link *type = operandType (left);
2437 sym_link *etype = getSpec (type);
2439 symbol *element = getStructElement (SPEC_STRUCT (etype),
2440 right->operand.symOperand);
2442 wassert(IS_SYMOP(right));
2444 /* add the offset */
2445 ic = newiCode ('+', left, operandFromLit (element->offset));
2447 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2449 /* preserve the storage & output class of the struct */
2450 /* as well as the volatile attribute */
2451 retype = getSpec (operandType (IC_RESULT (ic)));
2452 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2453 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2454 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2455 SPEC_CONST (retype) |= SPEC_CONST (etype);
2457 if (IS_PTR (element->type))
2458 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2460 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2463 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2466 /*-----------------------------------------------------------------*/
2467 /* geniCodePostInc - generate int code for Post increment */
2468 /*-----------------------------------------------------------------*/
2470 geniCodePostInc (operand * op)
2474 sym_link *optype = operandType (op);
2476 operand *rv = (IS_ITEMP (op) ?
2477 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2479 sym_link *rvtype = operandType (rv);
2482 /* if this is not an address we have trouble */
2485 werror (E_LVALUE_REQUIRED, "++");
2489 rOp = newiTempOperand (rvtype, 0);
2490 OP_SYMBOL(rOp)->noSpilLoc = 1;
2493 OP_SYMBOL(rv)->noSpilLoc = 1;
2495 geniCodeAssign (rOp, rv, 0, 0);
2497 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2498 if (IS_FLOAT (rvtype))
2499 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2501 ic = newiCode ('+', rv, operandFromLit (size));
2503 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2506 geniCodeAssign (op, result, 0, 0);
2512 /*-----------------------------------------------------------------*/
2513 /* geniCodePreInc - generate code for preIncrement */
2514 /*-----------------------------------------------------------------*/
2516 geniCodePreInc (operand * op, bool lvalue)
2519 sym_link *optype = operandType (op);
2520 operand *rop = (IS_ITEMP (op) ?
2521 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2523 sym_link *roptype = operandType (rop);
2529 werror (E_LVALUE_REQUIRED, "++");
2534 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2535 if (IS_FLOAT (roptype))
2536 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2538 ic = newiCode ('+', rop, operandFromLit (size));
2539 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2542 (void) geniCodeAssign (op, result, 0, 0);
2543 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2549 /*-----------------------------------------------------------------*/
2550 /* geniCodePostDec - generates code for Post decrement */
2551 /*-----------------------------------------------------------------*/
2553 geniCodePostDec (operand * op)
2557 sym_link *optype = operandType (op);
2559 operand *rv = (IS_ITEMP (op) ?
2560 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2562 sym_link *rvtype = operandType (rv);
2565 /* if this is not an address we have trouble */
2568 werror (E_LVALUE_REQUIRED, "--");
2572 rOp = newiTempOperand (rvtype, 0);
2573 OP_SYMBOL(rOp)->noSpilLoc = 1;
2576 OP_SYMBOL(rv)->noSpilLoc = 1;
2578 geniCodeAssign (rOp, rv, 0, 0);
2580 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2581 if (IS_FLOAT (rvtype))
2582 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2584 ic = newiCode ('-', rv, operandFromLit (size));
2586 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2589 geniCodeAssign (op, result, 0, 0);
2595 /*-----------------------------------------------------------------*/
2596 /* geniCodePreDec - generate code for pre decrement */
2597 /*-----------------------------------------------------------------*/
2599 geniCodePreDec (operand * op, bool lvalue)
2602 sym_link *optype = operandType (op);
2603 operand *rop = (IS_ITEMP (op) ?
2604 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2606 sym_link *roptype = operandType (rop);
2612 werror (E_LVALUE_REQUIRED, "--");
2617 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2618 if (IS_FLOAT (roptype))
2619 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2621 ic = newiCode ('-', rop, operandFromLit (size));
2622 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2625 (void) geniCodeAssign (op, result, 0, 0);
2626 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2633 /*-----------------------------------------------------------------*/
2634 /* geniCodeBitwise - gen int code for bitWise operators */
2635 /*-----------------------------------------------------------------*/
2637 geniCodeBitwise (operand * left, operand * right,
2638 int oper, sym_link * resType)
2642 left = geniCodeCast (resType, left, TRUE);
2643 right = geniCodeCast (resType, right, TRUE);
2645 ic = newiCode (oper, left, right);
2646 IC_RESULT (ic) = newiTempOperand (resType, 0);
2649 return IC_RESULT (ic);
2652 /*-----------------------------------------------------------------*/
2653 /* geniCodeAddressOf - gens icode for '&' address of operator */
2654 /*-----------------------------------------------------------------*/
2656 geniCodeAddressOf (operand * op)
2660 sym_link *optype = operandType (op);
2661 sym_link *opetype = getSpec (optype);
2663 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2665 op = operandFromOperand (op);
2670 /* lvalue check already done in decorateType */
2671 /* this must be a lvalue */
2672 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2673 /* werror (E_LVALUE_REQUIRED,"&"); */
2677 p = newLink (DECLARATOR);
2679 /* set the pointer depending on the storage class */
2680 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2682 p->next = copyLinkChain (optype);
2684 /* if already a temp */
2687 setOperandType (op, p);
2692 /* other wise make this of the type coming in */
2693 ic = newiCode (ADDRESS_OF, op, NULL);
2694 IC_RESULT (ic) = newiTempOperand (p, 1);
2695 IC_RESULT (ic)->isaddr = 0;
2697 return IC_RESULT (ic);
2699 /*-----------------------------------------------------------------*/
2700 /* setOClass - sets the output class depending on the pointer type */
2701 /*-----------------------------------------------------------------*/
2703 setOClass (sym_link * ptr, sym_link * spec)
2705 switch (DCL_TYPE (ptr))
2708 SPEC_OCLS (spec) = data;
2712 SPEC_OCLS (spec) = generic;
2716 SPEC_OCLS (spec) = xdata;
2720 SPEC_OCLS (spec) = code;
2724 SPEC_OCLS (spec) = idata;
2728 SPEC_OCLS (spec) = xstack;
2732 SPEC_OCLS (spec) = eeprom;
2741 /*-----------------------------------------------------------------*/
2742 /* geniCodeDerefPtr - dereference pointer with '*' */
2743 /*-----------------------------------------------------------------*/
2745 geniCodeDerefPtr (operand * op,int lvl)
2747 sym_link *rtype, *retype;
2748 sym_link *optype = operandType (op);
2750 // if this is an array then array access
2751 if (IS_ARRAY (optype)) {
2752 // don't worry, this will be optimized out later
2753 return geniCodeArray (op, operandFromLit (0), lvl);
2756 // just in case someone screws up
2757 wassert (IS_PTR (optype));
2759 if (IS_TRUE_SYMOP (op))
2762 op = geniCodeRValue (op, TRUE);
2765 /* now get rid of the pointer part */
2766 if (isLvaluereq(lvl) && IS_ITEMP (op))
2768 retype = getSpec (rtype = copyLinkChain (optype));
2772 retype = getSpec (rtype = copyLinkChain (optype->next));
2773 /* outputclass needs 2b updated */
2774 setOClass (optype, retype);
2777 op->isGptr = IS_GENPTR (optype);
2779 op->isaddr = (IS_PTR (rtype) ||
2780 IS_STRUCT (rtype) ||
2785 if (!isLvaluereq(lvl))
2786 op = geniCodeRValue (op, TRUE);
2788 setOperandType (op, rtype);
2793 /*-----------------------------------------------------------------*/
2794 /* geniCodeUnaryMinus - does a unary minus of the operand */
2795 /*-----------------------------------------------------------------*/
2797 geniCodeUnaryMinus (operand * op)
2800 sym_link *optype = operandType (op);
2802 if (IS_LITERAL (optype))
2803 return operandFromLit (-floatFromVal (op->operand.valOperand));
2805 ic = newiCode (UNARYMINUS, op, NULL);
2806 IC_RESULT (ic) = newiTempOperand (optype, 0);
2808 return IC_RESULT (ic);
2811 /*-----------------------------------------------------------------*/
2812 /* geniCodeLeftShift - gen i code for left shift */
2813 /*-----------------------------------------------------------------*/
2815 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2820 ic = newiCode (LEFT_OP, left, right);
2822 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2823 IC_RESULT (ic) = newiTempOperand (resType, 0);
2825 return IC_RESULT (ic);
2828 /*-----------------------------------------------------------------*/
2829 /* geniCodeRightShift - gen i code for right shift */
2830 /*-----------------------------------------------------------------*/
2832 geniCodeRightShift (operand * left, operand * right)
2836 ic = newiCode (RIGHT_OP, left, right);
2837 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2839 return IC_RESULT (ic);
2842 /*-----------------------------------------------------------------*/
2843 /* geniCodeLogic- logic code */
2844 /*-----------------------------------------------------------------*/
2846 geniCodeLogic (operand * left, operand * right, int op)
2850 sym_link *rtype = operandType (right);
2851 sym_link *ltype = operandType (left);
2853 /* left is integral type and right is literal then
2854 check if the literal value is within bounds */
2855 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2857 checkConstantRange(ltype,
2858 OP_VALUE(right), "compare operation", 1);
2861 /* if one operand is a pointer and the other is a literal generic void pointer,
2862 change the type of the literal generic void pointer to match the other pointer */
2863 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2864 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2866 /* find left's definition */
2867 ic = (iCode *) setFirstItem (iCodeChain);
2870 if (((ic->op == CAST) || (ic->op == '='))
2871 && isOperandEqual(left, IC_RESULT (ic)))
2874 ic = setNextItem (iCodeChain);
2876 /* if casting literal to generic pointer, then cast to rtype instead */
2877 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2879 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2880 ltype = operandType(left);
2883 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2884 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2886 /* find right's definition */
2887 ic = (iCode *) setFirstItem (iCodeChain);
2890 if (((ic->op == CAST) || (ic->op == '='))
2891 && isOperandEqual(right, IC_RESULT (ic)))
2894 ic = setNextItem (iCodeChain);
2896 /* if casting literal to generic pointer, then cast to rtype instead */
2897 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2899 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2900 rtype = operandType(right);
2904 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_NONE, 0);
2906 ic = newiCode (op, left, right);
2907 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2909 /* if comparing float
2910 and not a '==' || '!=' || '&&' || '||' (these
2912 if (IS_FLOAT(ctype) &&
2920 return IC_RESULT (ic);
2923 /*-----------------------------------------------------------------*/
2924 /* geniCodeLogicAndOr - && || operations */
2925 /*-----------------------------------------------------------------*/
2927 geniCodeLogicAndOr (ast *tree, int lvl)
2930 symbol *falseLabel = newiTempLabel (NULL);
2931 symbol *trueLabel = newiTempLabel (NULL);
2932 symbol *exitLabel = newiTempLabel (NULL);
2933 operand *op, *result, *condition;
2935 /* AND_OP and OR_OP are no longer generated because of bug-905492.
2936 They can be reenabled by executing the following block. If you find
2937 a decent optimization you could start right here:
2942 operand *leftOp, *rightOp;
2944 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
2945 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
2947 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
2951 /* generate two IFX for the '&&' or '||' op */
2953 /* evaluate left operand */
2954 condition = ast2iCode (tree->left, lvl + 1);
2955 op = geniCodeRValue (condition, FALSE);
2957 /* test left operand */
2958 if (tree->opval.op == AND_OP)
2959 ic = newiCodeCondition (op, NULL, falseLabel);
2961 ic = newiCodeCondition (op, trueLabel, NULL);
2964 /* evaluate right operand */
2965 condition = ast2iCode (tree->right, lvl + 1);
2966 op = geniCodeRValue (condition, FALSE);
2968 /* test right operand */
2969 ic = newiCodeCondition (op, trueLabel, NULL);
2972 /* store 0 or 1 in result */
2973 result = newiTempOperand (newCharLink(), 1);
2975 geniCodeLabel (falseLabel);
2976 geniCodeAssign (result, operandFromLit (0), 0, 0);
2977 /* generate an unconditional goto */
2978 geniCodeGoto (exitLabel);
2980 geniCodeLabel (trueLabel);
2981 geniCodeAssign (result, operandFromLit (1), 0, 0);
2983 geniCodeLabel (exitLabel);
2988 /*-----------------------------------------------------------------*/
2989 /* geniCodeUnary - for a a generic unary operation */
2990 /*-----------------------------------------------------------------*/
2992 geniCodeUnary (operand * op, int oper)
2994 iCode *ic = newiCode (oper, op, NULL);
2996 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2998 return IC_RESULT (ic);
3001 /*-----------------------------------------------------------------*/
3002 /* geniCodeConditional - geniCode for '?' ':' operation */
3003 /*-----------------------------------------------------------------*/
3005 geniCodeConditional (ast * tree,int lvl)
3008 symbol *falseLabel = newiTempLabel (NULL);
3009 symbol *exitLabel = newiTempLabel (NULL);
3010 operand *cond = ast2iCode (tree->left,lvl+1);
3011 operand *true, *false, *result;
3013 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3017 true = ast2iCode (tree->right->left,lvl+1);
3019 /* move the value to a new Operand */
3020 result = newiTempOperand (tree->right->ftype, 0);
3021 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3023 /* generate an unconditional goto */
3024 geniCodeGoto (exitLabel);
3026 /* now for the right side */
3027 geniCodeLabel (falseLabel);
3029 false = ast2iCode (tree->right->right,lvl+1);
3030 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3032 /* create the exit label */
3033 geniCodeLabel (exitLabel);
3038 /*-----------------------------------------------------------------*/
3039 /* geniCodeAssign - generate code for assignment */
3040 /*-----------------------------------------------------------------*/
3042 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3045 sym_link *ltype = operandType (left);
3046 sym_link *rtype = operandType (right);
3048 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3050 werror (E_LVALUE_REQUIRED, "assignment");
3054 /* left is integral type and right is literal then
3055 check if the literal value is within bounds */
3056 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
3058 checkConstantRange(ltype,
3059 OP_VALUE(right), "= operation", 0);
3062 /* if the left & right type don't exactly match */
3063 /* if pointer set then make sure the check is
3064 done with the type & not the pointer */
3065 /* then cast rights type to left */
3067 /* first check the type for pointer assignement */
3068 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3069 compareType (ltype, rtype) <= 0)
3071 if (compareType (ltype->next, rtype) < 0)
3072 right = geniCodeCast (ltype->next, right, TRUE);
3074 else if (compareType (ltype, rtype) < 0)
3075 right = geniCodeCast (ltype, right, TRUE);
3077 /* If left is a true symbol & ! volatile
3078 create an assignment to temporary for
3079 the right & then assign this temporary
3080 to the symbol. This is SSA (static single
3081 assignment). Isn't it simple and folks have
3082 published mountains of paper on it */
3083 if (IS_TRUE_SYMOP (left) &&
3084 !isOperandVolatile (left, FALSE) &&
3085 isOperandGlobal (left))
3089 if (IS_TRUE_SYMOP (right))
3090 sym = OP_SYMBOL (right);
3091 ic = newiCode ('=', NULL, right);
3092 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
3093 SPIL_LOC (right) = sym;
3097 ic = newiCode ('=', NULL, right);
3098 IC_RESULT (ic) = left;
3101 /* if left isgptr flag is set then support
3102 routine will be required */
3106 ic->nosupdate = nosupdate;
3110 /*-----------------------------------------------------------------*/
3111 /* geniCodeDummyRead - generate code for dummy read */
3112 /*-----------------------------------------------------------------*/
3114 geniCodeDummyRead (operand * op)
3117 sym_link *type = operandType (op);
3119 if (!IS_VOLATILE(type))
3122 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3128 /*-----------------------------------------------------------------*/
3129 /* geniCodeSEParms - generate code for side effecting fcalls */
3130 /*-----------------------------------------------------------------*/
3132 geniCodeSEParms (ast * parms,int lvl)
3137 if (parms->type == EX_OP && parms->opval.op == PARAM)
3139 geniCodeSEParms (parms->left,lvl);
3140 geniCodeSEParms (parms->right,lvl);
3144 /* hack don't like this but too lazy to think of
3146 if (IS_ADDRESS_OF_OP (parms))
3147 parms->left->lvalue = 1;
3149 if (IS_CAST_OP (parms) &&
3150 IS_PTR (parms->ftype) &&
3151 IS_ADDRESS_OF_OP (parms->right))
3152 parms->right->left->lvalue = 1;
3154 parms->opval.oprnd =
3155 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3157 parms->type = EX_OPERAND;
3158 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3159 SPEC_ARGREG(parms->ftype);
3162 /*-----------------------------------------------------------------*/
3163 /* geniCodeParms - generates parameters */
3164 /*-----------------------------------------------------------------*/
3166 geniCodeParms (ast * parms, value *argVals, int *stack,
3167 sym_link * ftype, int lvl)
3175 if (argVals==NULL) {
3177 argVals = FUNC_ARGS (ftype);
3180 /* if this is a param node then do the left & right */
3181 if (parms->type == EX_OP && parms->opval.op == PARAM)
3183 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3184 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3188 /* get the parameter value */
3189 if (parms->type == EX_OPERAND)
3190 pval = parms->opval.oprnd;
3193 /* maybe this else should go away ?? */
3194 /* hack don't like this but too lazy to think of
3196 if (IS_ADDRESS_OF_OP (parms))
3197 parms->left->lvalue = 1;
3199 if (IS_CAST_OP (parms) &&
3200 IS_PTR (parms->ftype) &&
3201 IS_ADDRESS_OF_OP (parms->right))
3202 parms->right->left->lvalue = 1;
3204 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3207 /* if register parm then make it a send */
3208 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3209 IFFUNC_ISBUILTIN(ftype))
3211 ic = newiCode (SEND, pval, NULL);
3212 ic->argreg = SPEC_ARGREG(parms->etype);
3213 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3218 /* now decide whether to push or assign */
3219 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3223 operand *top = operandFromSymbol (argVals->sym);
3224 /* clear useDef and other bitVectors */
3225 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3226 geniCodeAssign (top, pval, 1, 0);
3230 sym_link *p = operandType (pval);
3232 ic = newiCode (IPUSH, pval, NULL);
3234 /* update the stack adjustment */
3235 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3240 argVals=argVals->next;
3244 /*-----------------------------------------------------------------*/
3245 /* geniCodeCall - generates temp code for calling */
3246 /*-----------------------------------------------------------------*/
3248 geniCodeCall (operand * left, ast * parms,int lvl)
3252 sym_link *type, *etype;
3256 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3257 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
3258 werror (E_FUNCTION_EXPECTED);
3259 return operandFromValue(valueFromLit(0));
3262 /* take care of parameters with side-effecting
3263 function calls in them, this is required to take care
3264 of overlaying function parameters */
3265 geniCodeSEParms (parms,lvl);
3267 ftype = operandType (left);
3268 if (IS_CODEPTR (ftype))
3269 ftype = ftype->next;
3271 /* first the parameters */
3272 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3274 /* now call : if symbol then pcall */
3275 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3276 ic = newiCode (PCALL, left, NULL);
3278 ic = newiCode (CALL, left, NULL);
3281 type = copyLinkChain (ftype->next);
3282 etype = getSpec (type);
3283 SPEC_EXTR (etype) = 0;
3284 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3288 /* stack adjustment after call */
3289 ic->parmBytes = stack;
3294 /*-----------------------------------------------------------------*/
3295 /* geniCodeReceive - generate intermediate code for "receive" */
3296 /*-----------------------------------------------------------------*/
3298 geniCodeReceive (value * args)
3300 /* for all arguments that are passed in registers */
3304 if (IS_REGPARM (args->etype))
3306 operand *opr = operandFromValue (args);
3308 symbol *sym = OP_SYMBOL (opr);
3311 /* we will use it after all optimizations
3312 and before liveRange calculation */
3313 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3316 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3317 options.stackAuto == 0 &&
3318 (!(options.model == MODEL_FLAT24)) )
3323 opl = newiTempOperand (args->type, 0);
3325 sym->reqv->key = sym->key;
3326 OP_SYMBOL (sym->reqv)->key = sym->key;
3327 OP_SYMBOL (sym->reqv)->isreqv = 1;
3328 OP_SYMBOL (sym->reqv)->islocal = 0;
3329 SPIL_LOC (sym->reqv) = sym;
3333 ic = newiCode (RECEIVE, NULL, NULL);
3334 ic->argreg = SPEC_ARGREG(args->etype);
3336 currFunc->recvSize = getSize (sym->type);
3339 IC_RESULT (ic) = opr;
3347 /*-----------------------------------------------------------------*/
3348 /* geniCodeFunctionBody - create the function body */
3349 /*-----------------------------------------------------------------*/
3351 geniCodeFunctionBody (ast * tree,int lvl)
3358 /* reset the auto generation */
3364 func = ast2iCode (tree->left,lvl+1);
3365 fetype = getSpec (operandType (func));
3367 savelineno = lineno;
3368 lineno = OP_SYMBOL (func)->lineDef;
3369 /* create an entry label */
3370 geniCodeLabel (entryLabel);
3371 lineno = savelineno;
3373 /* create a proc icode */
3374 ic = newiCode (FUNCTION, func, NULL);
3375 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3380 /* for all parameters that are passed
3381 on registers add a "receive" */
3382 geniCodeReceive (tree->values.args);
3384 /* generate code for the body */
3385 ast2iCode (tree->right,lvl+1);
3387 /* create a label for return */
3388 geniCodeLabel (returnLabel);
3390 /* now generate the end proc */
3391 ic = newiCode (ENDFUNCTION, func, NULL);
3397 /*-----------------------------------------------------------------*/
3398 /* geniCodeReturn - gen icode for 'return' statement */
3399 /*-----------------------------------------------------------------*/
3401 geniCodeReturn (operand * op)
3405 /* if the operand is present force an rvalue */
3407 op = geniCodeRValue (op, FALSE);
3409 ic = newiCode (RETURN, op, NULL);
3413 /*-----------------------------------------------------------------*/
3414 /* geniCodeIfx - generates code for extended if statement */
3415 /*-----------------------------------------------------------------*/
3417 geniCodeIfx (ast * tree,int lvl)
3420 operand *condition = ast2iCode (tree->left,lvl+1);
3423 /* if condition is null then exit */
3427 condition = geniCodeRValue (condition, FALSE);
3429 cetype = getSpec (operandType (condition));
3430 /* if the condition is a literal */
3431 if (IS_LITERAL (cetype))
3433 if (floatFromVal (condition->operand.valOperand))
3435 if (tree->trueLabel)
3436 geniCodeGoto (tree->trueLabel);
3442 if (tree->falseLabel)
3443 geniCodeGoto (tree->falseLabel);
3450 if (tree->trueLabel)
3452 ic = newiCodeCondition (condition,
3457 if (tree->falseLabel)
3458 geniCodeGoto (tree->falseLabel);
3462 ic = newiCodeCondition (condition,
3469 ast2iCode (tree->right,lvl+1);
3472 /*-----------------------------------------------------------------*/
3473 /* geniCodeJumpTable - tries to create a jump table for switch */
3474 /*-----------------------------------------------------------------*/
3476 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3478 int min, max, cnt = 1;
3485 int needRangeCheck = !optimize.noJTabBoundary
3486 || tree->values.switchVals.swDefault;
3487 sym_link *cetype = getSpec (operandType (cond));
3488 int sizeofMinCost, sizeofMaxCost;
3489 int sizeofMatchJump, sizeofJumpTable;
3492 if (!tree || !caseVals)
3495 /* the criteria for creating a jump table is */
3496 /* all integer numbers between the maximum & minimum must */
3497 /* be present , the maximum value should not exceed 255 */
3498 /* If not all integer numbers are present the algorithm */
3499 /* inserts jumps to the default label for the missing numbers */
3500 /* and decides later whether it is worth it */
3501 min = (int) floatFromVal (vch = caseVals);
3508 max = (int) floatFromVal (vch);
3510 /* Exit if the range is too large to handle with a jump table. */
3511 if (1 + max - min > port->jumptableCost.maxCount)
3514 switch (getSize (operandType (cond)))
3516 case 1: sizeIndex = 0; break;
3517 case 2: sizeIndex = 1; break;
3518 case 4: sizeIndex = 2; break;
3522 /* Compute the size cost of the range check and subtraction. */
3527 if (!(min==0 && IS_UNSIGNED (cetype)))
3528 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3529 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3532 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3534 /* If the size cost of handling a non-zero minimum exceeds the */
3535 /* cost of extending the range down to zero, then it might be */
3536 /* better to extend the range to zero. */
3537 if (min > 0 && sizeofMinCost >= (min * port->jumptableCost.sizeofElement))
3539 /* Only extend the jump table if it would still be manageable. */
3540 if (1 + max <= port->jumptableCost.maxCount)
3544 /* Compute the total size cost of a jump table. */
3545 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3546 + port->jumptableCost.sizeofDispatch
3547 + sizeofMinCost + sizeofMaxCost;
3549 /* Compute the total size cost of a match & jump sequence */
3550 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3552 /* If the size cost of the jump table is uneconomical then exit */
3553 if (sizeofMatchJump < sizeofJumpTable)
3556 /* The jump table is preferable. */
3558 /* First, a label for the default or missing cases. */
3559 if (tree->values.switchVals.swDefault)
3561 SNPRINTF (buffer, sizeof(buffer),
3563 tree->values.switchVals.swNum);
3567 SNPRINTF (buffer, sizeof(buffer),
3569 tree->values.switchVals.swNum);
3571 falseLabel = newiTempLabel (buffer);
3573 /* Build the list of labels for the jump table. */
3575 t = (int) floatFromVal (vch);
3576 for (i=min; i<=max; i++)
3580 /* Explicit case: make a new label for it. */
3581 SNPRINTF (buffer, sizeof(buffer),
3583 tree->values.switchVals.swNum,
3585 addSet (&labels, newiTempLabel (buffer));
3588 t = (int) floatFromVal (vch);
3592 /* Implicit case: use the default label. */
3593 addSet (&labels, falseLabel);
3597 /* If cond is volatile, it might change after the boundary */
3598 /* conditions are tested to an out of bounds value, causing */
3599 /* a jump to a location outside of the jump table. To avoid */
3600 /* this possibility, use a non-volatile copy of it instead. */
3601 if (IS_OP_VOLATILE (cond))
3606 newcond = newiTempOperand (operandType (cond), TRUE);
3607 newcond->isvolatile = 0;
3608 ic = newiCode ('=', NULL, cond);
3609 IC_RESULT (ic) = newcond;
3614 /* first we rule out the boundary conditions */
3615 /* if only optimization says so */
3618 sym_link *cetype = getSpec (operandType (cond));
3619 /* no need to check the lower bound if
3620 the condition is unsigned & minimum value is zero */
3621 if (!(min == 0 && IS_UNSIGNED (cetype)))
3623 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3624 ic = newiCodeCondition (boundary, falseLabel, NULL);
3628 /* now for upper bounds */
3629 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3630 ic = newiCodeCondition (boundary, falseLabel, NULL);
3634 /* if the min is not zero then we no make it zero */
3637 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3638 if (!IS_LITERAL(getSpec(operandType(cond))))
3639 setOperandType (cond, UCHARTYPE);
3642 /* now create the jumptable */
3643 ic = newiCode (JUMPTABLE, NULL, NULL);
3644 IC_JTCOND (ic) = cond;
3645 IC_JTLABELS (ic) = labels;
3650 /*-----------------------------------------------------------------*/
3651 /* geniCodeSwitch - changes a switch to a if statement */
3652 /*-----------------------------------------------------------------*/
3654 geniCodeSwitch (ast * tree,int lvl)
3657 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3658 value *caseVals = tree->values.switchVals.swVals;
3659 symbol *trueLabel, *falseLabel;
3661 /* If the condition is a literal, then just jump to the */
3662 /* appropriate case label. */
3663 if (IS_LITERAL(getSpec(operandType(cond))))
3665 int switchVal, caseVal;
3667 switchVal = (int) floatFromVal (cond->operand.valOperand);
3670 caseVal = (int) floatFromVal (caseVals);
3671 if (caseVal == switchVal)
3673 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3674 tree->values.switchVals.swNum, caseVal);
3675 trueLabel = newiTempLabel (buffer);
3676 geniCodeGoto (trueLabel);
3679 caseVals = caseVals->next;
3681 goto defaultOrBreak;
3684 /* if we can make this a jump table */
3685 if (geniCodeJumpTable (cond, caseVals, tree))
3686 goto jumpTable; /* no need for the comparison */
3688 /* for the cases defined do */
3692 operand *compare = geniCodeLogic (cond,
3693 operandFromValue (caseVals),
3696 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3697 tree->values.switchVals.swNum,
3698 (int) floatFromVal (caseVals));
3699 trueLabel = newiTempLabel (buffer);
3701 ic = newiCodeCondition (compare, trueLabel, NULL);
3703 caseVals = caseVals->next;
3708 /* if default is present then goto break else break */
3709 if (tree->values.switchVals.swDefault)
3711 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3715 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3718 falseLabel = newiTempLabel (buffer);
3719 geniCodeGoto (falseLabel);
3722 ast2iCode (tree->right,lvl+1);
3725 /*-----------------------------------------------------------------*/
3726 /* geniCodeInline - intermediate code for inline assembler */
3727 /*-----------------------------------------------------------------*/
3729 geniCodeInline (ast * tree)
3733 ic = newiCode (INLINEASM, NULL, NULL);
3734 IC_INLINE (ic) = tree->values.inlineasm;
3738 /*-----------------------------------------------------------------*/
3739 /* geniCodeArrayInit - intermediate code for array initializer */
3740 /*-----------------------------------------------------------------*/
3742 geniCodeArrayInit (ast * tree, operand *array)
3746 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3747 ic = newiCode (ARRAYINIT, array, NULL);
3748 IC_ARRAYILIST (ic) = tree->values.constlist;
3750 operand *left=newOperand(), *right=newOperand();
3751 left->type=right->type=SYMBOL;
3752 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3753 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3754 ic = newiCode (ARRAYINIT, left, right);
3759 /*-----------------------------------------------------------------*/
3760 /* geniCodeCritical - intermediate code for a critical statement */
3761 /*-----------------------------------------------------------------*/
3763 geniCodeCritical (ast *tree, int lvl)
3768 /* If op is NULL, the original interrupt state will saved on */
3769 /* the stack. Otherwise, it will be saved in op. */
3771 /* Generate a save of the current interrupt state & disabled */
3772 ic = newiCode (CRITICAL, NULL, NULL);
3773 IC_RESULT (ic) = op;
3776 /* Generate the critical code sequence */
3777 if (tree->left && tree->left->type == EX_VALUE)
3778 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3780 ast2iCode (tree->left,lvl+1);
3782 /* Generate a restore of the original interrupt state */
3783 ic = newiCode (ENDCRITICAL, NULL, op);
3787 /*-----------------------------------------------------------------*/
3788 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3789 /* particular case. Ie : assigning or dereferencing array or ptr */
3790 /*-----------------------------------------------------------------*/
3791 set * lvaluereqSet = NULL;
3792 typedef struct lvalItem
3799 /*-----------------------------------------------------------------*/
3800 /* addLvaluereq - add a flag for lvalreq for current ast level */
3801 /*-----------------------------------------------------------------*/
3802 void addLvaluereq(int lvl)
3804 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3807 addSetHead(&lvaluereqSet,lpItem);
3810 /*-----------------------------------------------------------------*/
3811 /* delLvaluereq - del a flag for lvalreq for current ast level */
3812 /*-----------------------------------------------------------------*/
3816 lpItem = getSet(&lvaluereqSet);
3817 if(lpItem) Safe_free(lpItem);
3819 /*-----------------------------------------------------------------*/
3820 /* clearLvaluereq - clear lvalreq flag */
3821 /*-----------------------------------------------------------------*/
3822 void clearLvaluereq()
3825 lpItem = peekSet(lvaluereqSet);
3826 if(lpItem) lpItem->req = 0;
3828 /*-----------------------------------------------------------------*/
3829 /* getLvaluereq - get the last lvalreq level */
3830 /*-----------------------------------------------------------------*/
3831 int getLvaluereqLvl()
3834 lpItem = peekSet(lvaluereqSet);
3835 if(lpItem) return lpItem->lvl;
3838 /*-----------------------------------------------------------------*/
3839 /* isLvaluereq - is lvalreq valid for this level ? */
3840 /*-----------------------------------------------------------------*/
3841 int isLvaluereq(int lvl)
3844 lpItem = peekSet(lvaluereqSet);
3845 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3849 /*-----------------------------------------------------------------*/
3850 /* ast2iCode - creates an icodeList from an ast */
3851 /*-----------------------------------------------------------------*/
3853 ast2iCode (ast * tree,int lvl)
3855 operand *left = NULL;
3856 operand *right = NULL;
3860 /* set the global variables for filename & line number */
3862 filename = tree->filename;
3864 lineno = tree->lineno;
3866 block = tree->block;
3868 scopeLevel = tree->level;
3870 seqPoint = tree->seqPoint;
3872 if (tree->type == EX_VALUE)
3873 return operandFromValue (tree->opval.val);
3875 if (tree->type == EX_LINK)
3876 return operandFromLink (tree->opval.lnk);
3878 /* if we find a nullop */
3879 if (tree->type == EX_OP &&
3880 (tree->opval.op == NULLOP ||
3881 tree->opval.op == BLOCK))
3883 if (tree->left && tree->left->type == EX_VALUE)
3884 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3886 ast2iCode (tree->left,lvl+1);
3887 if (tree->right && tree->right->type == EX_VALUE)
3888 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
3890 ast2iCode (tree->right,lvl+1);
3894 /* special cases for not evaluating */
3895 if (tree->opval.op != ':' &&
3896 tree->opval.op != '?' &&
3897 tree->opval.op != CALL &&
3898 tree->opval.op != IFX &&
3899 tree->opval.op != AND_OP &&
3900 tree->opval.op != OR_OP &&
3901 tree->opval.op != LABEL &&
3902 tree->opval.op != GOTO &&
3903 tree->opval.op != SWITCH &&
3904 tree->opval.op != FUNCTION &&
3905 tree->opval.op != INLINEASM &&
3906 tree->opval.op != CRITICAL)
3909 if (IS_ASSIGN_OP (tree->opval.op) ||
3910 IS_DEREF_OP (tree) ||
3911 (tree->opval.op == '&' && !tree->right) ||
3912 tree->opval.op == PTR_OP)
3915 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3916 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3919 left = operandFromAst (tree->left,lvl);
3921 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3922 left = geniCodeRValue (left, TRUE);
3926 left = operandFromAst (tree->left,lvl);
3928 if (tree->opval.op == INC_OP ||
3929 tree->opval.op == DEC_OP)
3932 right = operandFromAst (tree->right,lvl);
3937 right = operandFromAst (tree->right,lvl);
3941 /* now depending on the type of operand */
3942 /* this will be a biggy */
3943 switch (tree->opval.op)
3946 case '[': /* array operation */
3948 //sym_link *ltype = operandType (left);
3949 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3950 left = geniCodeRValue (left, FALSE);
3951 right = geniCodeRValue (right, TRUE);
3954 return geniCodeArray (left, right,lvl);
3956 case '.': /* structure dereference */
3957 if (IS_PTR (operandType (left)))
3958 left = geniCodeRValue (left, TRUE);
3960 left = geniCodeRValue (left, FALSE);
3962 return geniCodeStruct (left, right, tree->lvalue);
3964 case PTR_OP: /* structure pointer dereference */
3967 pType = operandType (left);
3968 left = geniCodeRValue (left, TRUE);
3970 setOClass (pType, getSpec (operandType (left)));
3973 return geniCodeStruct (left, right, tree->lvalue);
3975 case INC_OP: /* increment operator */
3977 return geniCodePostInc (left);
3979 return geniCodePreInc (right, tree->lvalue);
3981 case DEC_OP: /* decrement operator */
3983 return geniCodePostDec (left);
3985 return geniCodePreDec (right, tree->lvalue);
3987 case '&': /* bitwise and or address of operator */
3989 { /* this is a bitwise operator */
3990 left = geniCodeRValue (left, FALSE);
3991 right = geniCodeRValue (right, FALSE);
3992 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3995 return geniCodeAddressOf (left);
3997 case '|': /* bitwise or & xor */
3999 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4000 geniCodeRValue (right, FALSE),
4005 return geniCodeDivision (geniCodeRValue (left, FALSE),
4006 geniCodeRValue (right, FALSE),
4007 getResultTypeFromType (tree->ftype));
4010 return geniCodeModulus (geniCodeRValue (left, FALSE),
4011 geniCodeRValue (right, FALSE),
4012 getResultTypeFromType (tree->ftype));
4015 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4016 geniCodeRValue (right, FALSE),
4017 getResultTypeFromType (tree->ftype));
4019 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4023 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4024 geniCodeRValue (right, FALSE),
4025 getResultTypeFromType (tree->ftype));
4027 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4031 return geniCodeAdd (geniCodeRValue (left, FALSE),
4032 geniCodeRValue (right, FALSE),
4033 getResultTypeFromType (tree->ftype),
4036 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4039 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4040 geniCodeRValue (right, FALSE),
4041 getResultTypeFromType (tree->ftype));
4044 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4045 geniCodeRValue (right, FALSE));
4047 #if 0 // this indeed needs a second thought
4051 // let's keep this simple: get the rvalue we need
4052 op=geniCodeRValue (right, FALSE);
4053 // now cast it to whatever we want
4054 op=geniCodeCast (operandType(left), op, FALSE);
4055 // if this is going to be used as an lvalue, make it so
4061 #else // bug #604575, is it a bug ????
4062 return geniCodeCast (operandType (left),
4063 geniCodeRValue (right, FALSE), FALSE);
4070 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4075 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4076 setOperandType (op, UCHARTYPE);
4081 return geniCodeLogicAndOr (tree, lvl);
4088 /* different compilers (even different gccs) evaluate
4089 the two calls in a different order. to get the same
4090 result on all machines we've to specify a clear sequence.
4091 return geniCodeLogic (geniCodeRValue (left, FALSE),
4092 geniCodeRValue (right, FALSE),
4096 operand *leftOp, *rightOp;
4098 leftOp = geniCodeRValue (left , FALSE);
4099 rightOp = geniCodeRValue (right, FALSE);
4101 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4104 return geniCodeConditional (tree,lvl);
4107 return operandFromLit (getSize (tree->right->ftype));
4111 sym_link *rtype = operandType (right);
4112 sym_link *ltype = operandType (left);
4113 if (IS_PTR (rtype) && IS_ITEMP (right)
4114 && right->isaddr && compareType (rtype->next, ltype) == 1)
4115 right = geniCodeRValue (right, TRUE);
4117 right = geniCodeRValue (right, FALSE);
4119 geniCodeAssign (left, right, 0, 1);
4124 geniCodeAssign (left,
4125 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4127 geniCodeRValue (right, FALSE),
4128 getResultTypeFromType (tree->ftype)),
4133 geniCodeAssign (left,
4134 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4136 geniCodeRValue (right, FALSE),
4137 getResultTypeFromType (tree->ftype)),
4141 geniCodeAssign (left,
4142 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4144 geniCodeRValue (right, FALSE),
4145 getResultTypeFromType (tree->ftype)),
4149 sym_link *rtype = operandType (right);
4150 sym_link *ltype = operandType (left);
4151 if (IS_PTR (rtype) && IS_ITEMP (right)
4152 && right->isaddr && compareType (rtype->next, ltype) == 1)
4153 right = geniCodeRValue (right, TRUE);
4155 right = geniCodeRValue (right, FALSE);
4158 return geniCodeAssign (left,
4159 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4162 getResultTypeFromType (tree->ftype),
4168 sym_link *rtype = operandType (right);
4169 sym_link *ltype = operandType (left);
4170 if (IS_PTR (rtype) && IS_ITEMP (right)
4171 && right->isaddr && compareType (rtype->next, ltype) == 1)
4173 right = geniCodeRValue (right, TRUE);
4177 right = geniCodeRValue (right, FALSE);
4180 geniCodeAssign (left,
4181 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4184 getResultTypeFromType (tree->ftype)),
4189 geniCodeAssign (left,
4190 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4192 geniCodeRValue (right, FALSE),
4193 getResultTypeFromType (tree->ftype)),
4197 geniCodeAssign (left,
4198 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4200 geniCodeRValue (right, FALSE)), 0, 1);
4203 geniCodeAssign (left,
4204 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4206 geniCodeRValue (right, FALSE),
4208 operandType (left)), 0, 1);
4211 geniCodeAssign (left,
4212 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4214 geniCodeRValue (right, FALSE),
4216 operandType (left)), 0, 1);
4219 geniCodeAssign (left,
4220 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4222 geniCodeRValue (right, FALSE),
4224 operandType (left)), 0, 1);
4226 return geniCodeRValue (right, FALSE);
4229 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4232 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4233 return ast2iCode (tree->right,lvl+1);
4236 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4237 return ast2iCode (tree->right,lvl+1);
4240 geniCodeFunctionBody (tree,lvl);
4244 geniCodeReturn (right);
4248 geniCodeIfx (tree,lvl);
4252 geniCodeSwitch (tree,lvl);
4256 geniCodeInline (tree);
4260 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4264 geniCodeCritical (tree, lvl);
4270 /*-----------------------------------------------------------------*/
4271 /* reverseICChain - gets from the list and creates a linkedlist */
4272 /*-----------------------------------------------------------------*/
4279 while ((loop = getSet (&iCodeChain)))
4291 /*-----------------------------------------------------------------*/
4292 /* iCodeFromAst - given an ast will convert it to iCode */
4293 /*-----------------------------------------------------------------*/
4295 iCodeFromAst (ast * tree)
4297 returnLabel = newiTempLabel ("_return");
4298 entryLabel = newiTempLabel ("_entry");
4300 return reverseiCChain ();
4303 static const char *opTypeToStr(OPTYPE op)
4307 case SYMBOL: return "symbol";
4308 case VALUE: return "value";
4309 case TYPE: return "type";
4311 return "undefined type";
4315 operand *validateOpType(operand *op,
4322 if (op && op->type == type)
4327 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4328 " expected %s, got %s\n",
4329 macro, args, file, line,
4330 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4332 return op; // never reached, makes compiler happy.