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 -------------------------------------------------------------------------*/
28 #include "dbuf_string.h"
30 /*-----------------------------------------------------------------*/
31 /* global variables */
33 set *iCodeChain = NULL;
38 char *filename; /* current file name */
39 int lineno = 1; /* current line number */
44 symbol *returnLabel; /* function return label */
45 symbol *entryLabel; /* function entry label */
47 /*-----------------------------------------------------------------*/
48 /* forward definition of some functions */
49 operand *geniCodeAssign (operand *, operand *, int, int);
50 static operand *geniCodeArray (operand *, operand *,int);
51 static operand *geniCodeArray2Ptr (operand *);
52 operand *geniCodeRValue (operand *, bool);
53 operand *geniCodeDerefPtr (operand *,int);
54 int isLvaluereq(int lvl);
55 void setOClass (sym_link * ptr, sym_link * spec);
56 static operand *geniCodeCast (sym_link *, operand *, bool);
58 #define PRINTFUNC(x) void x (struct dbuf_s *dbuf, iCode *ic, char *s)
59 /* forward definition of ic print functions */
60 PRINTFUNC (picGetValueAtAddr);
61 PRINTFUNC (picSetValueAtAddr);
62 PRINTFUNC (picAddrOf);
63 PRINTFUNC (picGeneric);
64 PRINTFUNC (picGenericOne);
66 PRINTFUNC (picAssign);
70 PRINTFUNC (picJumpTable);
71 PRINTFUNC (picInline);
72 PRINTFUNC (picReceive);
73 PRINTFUNC (picDummyRead);
74 PRINTFUNC (picCritical);
75 PRINTFUNC (picEndCritical);
77 iCodeTable codeTable[] =
79 {'!', "not", picGenericOne, NULL},
80 {'~', "~", picGenericOne, NULL},
81 {RRC, "rrc", picGenericOne, NULL},
82 {RLC, "rlc", picGenericOne, NULL},
83 {GETHBIT, "ghbit", picGenericOne, NULL},
84 {GETABIT, "gabit", picGenericOne, NULL},
85 {GETBYTE, "gbyte", picGenericOne, NULL},
86 {GETWORD, "gword", picGenericOne, NULL},
87 {UNARYMINUS, "-", picGenericOne, NULL},
88 {IPUSH, "push", picGenericOne, NULL},
89 {IPOP, "pop", picGenericOne, NULL},
90 {CALL, "call", picGenericOne, NULL},
91 {PCALL, "pcall", picGenericOne, NULL},
92 {FUNCTION, "proc", picGenericOne, NULL},
93 {ENDFUNCTION, "eproc", picGenericOne, NULL},
94 {RETURN, "ret", picGenericOne, NULL},
95 {'+', "+", picGeneric, NULL},
96 {'-', "-", picGeneric, NULL},
97 {'*', "*", picGeneric, NULL},
98 {'/', "/", picGeneric, NULL},
99 {'%', "%", picGeneric, NULL},
100 {'>', ">", picGeneric, NULL},
101 {'<', "<", picGeneric, NULL},
102 {LE_OP, "<=", picGeneric, NULL},
103 {GE_OP, ">=", picGeneric, NULL},
104 {EQ_OP, "==", picGeneric, NULL},
105 {NE_OP, "!=", picGeneric, NULL},
106 {AND_OP, "&&", picGeneric, NULL},
107 {OR_OP, "||", picGeneric, NULL},
108 {'^', "^", picGeneric, NULL},
109 {'|', "|", picGeneric, NULL},
110 {BITWISEAND, "&", picGeneric, NULL},
111 {LEFT_OP, "<<", picGeneric, NULL},
112 {RIGHT_OP, ">>", picGeneric, NULL},
113 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
114 {ADDRESS_OF, "&", picAddrOf, NULL},
115 {CAST, "<>", picCast, NULL},
116 {'=', ":=", picAssign, NULL},
117 {LABEL, "", picLabel, NULL},
118 {GOTO, "", picGoto, NULL},
119 {JUMPTABLE, "jtab", picJumpTable, NULL},
120 {IFX, "if", picIfx, NULL},
121 {INLINEASM, "", picInline, NULL},
122 {RECEIVE, "recv", picReceive, NULL},
123 {SEND, "send", picGenericOne, NULL},
124 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
125 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
126 {CRITICAL, "critical_start", picCritical, NULL},
127 {ENDCRITICAL, "critical_end", picEndCritical, NULL},
128 {SWAP, "swap", picGenericOne, NULL}
131 /*-----------------------------------------------------------------*/
132 /* operandName - returns the name of the operand */
133 /*-----------------------------------------------------------------*/
135 printOperand (operand * op, FILE * file)
146 dbuf_init (&dbuf, 1024);
147 ret = dbuf_printOperand(op, &dbuf);
148 dbuf_write_and_destroy (&dbuf, file);
157 dbuf_printOperand (operand * op, struct dbuf_s *dbuf)
168 opetype = getSpec (operandType (op));
169 if (IS_FLOAT (opetype))
170 dbuf_printf (dbuf, "%g {", SPEC_CVAL (opetype).v_float);
171 else if (IS_FIXED16X16 (opetype))
172 dbuf_printf (dbuf, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
174 dbuf_printf (dbuf, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
175 dbuf_printTypeChain (operandType (op), dbuf);
176 dbuf_append_char (dbuf, '}');
182 if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
183 dbuf_printf (dbuf, "%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}" , */
184 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
186 OP_LIVEFROM (op), OP_LIVETO (op),
187 OP_SYMBOL (op)->stack,
188 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
189 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
190 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
193 dbuf_append_char (dbuf, '{');
194 dbuf_printTypeChain (operandType (op), dbuf);
195 if (SPIL_LOC (op) && IS_ITEMP (op))
196 dbuf_printf (dbuf, "}{ sir@ %s", SPIL_LOC (op)->rname);
197 dbuf_append_char (dbuf, '}');
201 /* if assigned to registers */
202 if (OP_SYMBOL (op)->nRegs)
204 if (OP_SYMBOL (op)->isspilt)
206 if (!OP_SYMBOL (op)->remat)
207 if (OP_SYMBOL (op)->usl.spillLoc)
208 dbuf_printf (dbuf, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
209 OP_SYMBOL (op)->usl.spillLoc->rname :
210 OP_SYMBOL (op)->usl.spillLoc->name));
212 dbuf_append_str (dbuf, "[err]");
214 dbuf_append_str (dbuf, "[remat]");
219 dbuf_append_char (dbuf, '[');
220 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
221 dbuf_printf (dbuf, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
222 dbuf_append_char (dbuf, ']');
225 //#else /* } else { */
227 /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
228 dbuf_printf (dbuf, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
230 if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
232 dbuf_printf (dbuf, "[lr%d:%d so:%d]",
233 OP_LIVEFROM (op), OP_LIVETO (op),
234 OP_SYMBOL (op)->stack);
237 if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
239 dbuf_append_char (dbuf, '{');
240 dbuf_printTypeChain (operandType (op), dbuf);
241 if (SPIL_LOC (op) && IS_ITEMP (op))
242 dbuf_printf (dbuf, "}{ sir@ %s", SPIL_LOC (op)->rname);
243 dbuf_append_char (dbuf, '}');
246 /* if assigned to registers */
247 if (OP_SYMBOL (op)->nRegs)
249 if (OP_SYMBOL (op)->isspilt)
251 if (!OP_SYMBOL (op)->remat)
252 if (OP_SYMBOL (op)->usl.spillLoc)
253 dbuf_printf (dbuf, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
254 OP_SYMBOL (op)->usl.spillLoc->rname :
255 OP_SYMBOL (op)->usl.spillLoc->name));
257 dbuf_append_str (dbuf, "[err]");
259 dbuf_append_str (dbuf, "[remat]");
264 dbuf_append_char (dbuf, '[');
265 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
266 dbuf_printf (dbuf, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
267 dbuf_append_char (dbuf, ']');
275 dbuf_append_char (dbuf, '(');
276 dbuf_printTypeChain (op->operand.typeOperand, dbuf);
277 dbuf_append_char (dbuf, ')');
285 /*-----------------------------------------------------------------*/
286 /* print functions */
287 /*-----------------------------------------------------------------*/
288 PRINTFUNC (picGetValueAtAddr)
290 dbuf_append_char (dbuf, '\t');
291 dbuf_printOperand (IC_RESULT (ic), dbuf);
292 dbuf_append_str (dbuf, " = ");
293 dbuf_append_str (dbuf, "@[");
294 dbuf_printOperand (IC_LEFT (ic), dbuf);
295 dbuf_append_str (dbuf, "]\n");
298 PRINTFUNC (picSetValueAtAddr)
300 dbuf_append_char (dbuf, '\t');
301 dbuf_append_str (dbuf, "*[");
302 dbuf_printOperand (IC_LEFT (ic), dbuf);
303 dbuf_append_str (dbuf, "] = ");
304 dbuf_printOperand (IC_RIGHT (ic), dbuf);
305 dbuf_append_char (dbuf, '\n');
308 PRINTFUNC (picAddrOf)
310 dbuf_append_char (dbuf, '\t');
311 dbuf_printOperand (IC_RESULT (ic), dbuf);
312 if (IS_ITEMP (IC_LEFT (ic)))
313 dbuf_append_str (dbuf, " = ");
315 dbuf_append_str (dbuf, " = &[");
316 dbuf_printOperand (IC_LEFT (ic), dbuf);
319 if (IS_ITEMP (IC_LEFT (ic)))
320 dbuf_append_str (dbuf, " offsetAdd ");
322 dbuf_append_str (dbuf, " , ");
323 dbuf_printOperand (IC_RIGHT (ic), dbuf);
325 if (IS_ITEMP (IC_LEFT (ic)))
326 dbuf_append_char (dbuf, '\n');
328 dbuf_append_str (dbuf, "]\n");
331 PRINTFUNC (picJumpTable)
335 dbuf_append_char (dbuf, '\t');
336 dbuf_printf (dbuf, "%s\t", s);
337 dbuf_printOperand (IC_JTCOND (ic), dbuf);
338 dbuf_append_char (dbuf, '\n');
339 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
340 sym = setNextItem (IC_JTLABELS (ic)))
341 dbuf_printf (dbuf, "\t\t\t%s\n", sym->name);
344 PRINTFUNC (picGeneric)
346 dbuf_append_char (dbuf, '\t');
347 dbuf_printOperand (IC_RESULT (ic), dbuf);
348 dbuf_append_str (dbuf, " = ");
349 dbuf_printOperand (IC_LEFT (ic), dbuf);
350 dbuf_printf (dbuf, " %s ", s);
351 dbuf_printOperand (IC_RIGHT (ic), dbuf);
352 dbuf_append_char (dbuf, '\n');
355 PRINTFUNC (picGenericOne)
357 dbuf_append_char (dbuf, '\t');
360 dbuf_printOperand (IC_RESULT (ic), dbuf);
361 dbuf_append_str (dbuf, " = ");
366 dbuf_printf (dbuf, "%s ", s);
367 dbuf_printOperand (IC_LEFT (ic), dbuf);
370 if (!IC_RESULT (ic) && !IC_LEFT (ic))
371 dbuf_append_str (dbuf, s);
373 if (ic->op == SEND || ic->op == RECEIVE) {
374 dbuf_printf (dbuf,"{argreg = %d}",ic->argreg);
376 if (ic->op == IPUSH) {
377 dbuf_printf (dbuf,"{parmPush = %d}",ic->parmPush);
379 dbuf_append_char (dbuf, '\n');
384 dbuf_append_char (dbuf, '\t');
385 dbuf_printOperand (IC_RESULT (ic), dbuf);
386 dbuf_append_str (dbuf, " = ");
387 dbuf_printOperand (IC_LEFT (ic), dbuf);
388 dbuf_printOperand (IC_RIGHT (ic), dbuf);
389 dbuf_append_char (dbuf, '\n');
393 PRINTFUNC (picAssign)
395 dbuf_append_char (dbuf, '\t');
397 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
398 dbuf_append_str (dbuf, "*(");
400 dbuf_printOperand (IC_RESULT (ic), dbuf);
402 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
403 dbuf_append_char (dbuf, ')');
405 dbuf_printf (dbuf, " %s ", s);
406 dbuf_printOperand (IC_RIGHT (ic), dbuf);
408 dbuf_append_char (dbuf, '\n');
413 dbuf_printf (dbuf, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
418 dbuf_append_char (dbuf, '\t');
419 dbuf_printf (dbuf, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
424 dbuf_append_char (dbuf, '\t');
425 dbuf_append_str (dbuf, "if ");
426 dbuf_printOperand (IC_COND (ic), dbuf);
429 dbuf_printf (dbuf, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
432 dbuf_printf (dbuf, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
434 dbuf_printf (dbuf, "\tzzgoto %s\n", IC_FALSE (ic)->name);
438 PRINTFUNC (picInline)
440 dbuf_append_str (dbuf, IC_INLINE (ic));
443 PRINTFUNC (picReceive)
445 dbuf_printOperand (IC_RESULT (ic), dbuf);
446 dbuf_printf (dbuf, " = %s ", s);
447 dbuf_printOperand (IC_LEFT (ic), dbuf);
448 dbuf_append_char (dbuf, '\n');
451 PRINTFUNC (picDummyRead)
453 dbuf_append_char (dbuf, '\t');
454 dbuf_printf (dbuf, "%s ", s);
455 dbuf_printOperand (IC_RIGHT (ic), dbuf);
456 dbuf_append_char (dbuf, '\n');
459 PRINTFUNC (picCritical)
461 dbuf_append_char (dbuf, '\t');
463 dbuf_printOperand (IC_RESULT (ic), dbuf);
465 dbuf_append_str (dbuf, "(stack)");
466 dbuf_printf (dbuf, " = %s ", s);
467 dbuf_append_char (dbuf, '\n');
470 PRINTFUNC (picEndCritical)
472 dbuf_append_char (dbuf, '\t');
473 dbuf_printf (dbuf, "%s = ", s);
475 dbuf_printOperand (IC_RIGHT (ic), dbuf);
477 dbuf_append_str (dbuf, "(stack)");
478 dbuf_append_char (dbuf, '\n');
481 /*-----------------------------------------------------------------*/
482 /* piCode - prints one iCode */
483 /*-----------------------------------------------------------------*/
485 piCode (void *item, FILE * of)
494 icTab = getTableEntry (ic->op);
495 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
496 ic->filename, ic->lineno,
497 ic->seq, ic->key, ic->depth, ic->supportRtn);
498 dbuf_init (&dbuf, 1024);
499 icTab->iCodePrint (&dbuf, ic, icTab->printName);
500 dbuf_write_and_destroy (&dbuf, of);
506 printiCChain(ic,stdout);
508 /*-----------------------------------------------------------------*/
509 /* printiCChain - prints intermediate code for humans */
510 /*-----------------------------------------------------------------*/
512 printiCChain (iCode * icChain, FILE * of)
520 for (loop = icChain; loop; loop = loop->next)
522 if ((icTab = getTableEntry (loop->op)))
524 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
525 loop->filename, loop->lineno,
526 loop->seq, loop->key, loop->depth, loop->supportRtn);
528 dbuf_init(&dbuf, 1024);
529 icTab->iCodePrint (&dbuf, loop, icTab->printName);
530 dbuf_write_and_destroy (&dbuf, of);
536 /*-----------------------------------------------------------------*/
537 /* newOperand - allocate, init & return a new iCode */
538 /*-----------------------------------------------------------------*/
544 op = Safe_alloc ( sizeof (operand));
550 /*-----------------------------------------------------------------*/
551 /* newiCode - create and return a new iCode entry initialised */
552 /*-----------------------------------------------------------------*/
554 newiCode (int op, operand * left, operand * right)
558 ic = Safe_alloc ( sizeof (iCode));
560 ic->seqPoint = seqPoint;
562 ic->filename = filename;
564 ic->level = scopeLevel;
566 ic->key = iCodeKey++;
568 IC_RIGHT (ic) = right;
573 /*-----------------------------------------------------------------*/
574 /* newiCode for conditional statements */
575 /*-----------------------------------------------------------------*/
577 newiCodeCondition (operand * condition,
583 if (IS_VOID(operandType(condition))) {
584 werror(E_VOID_VALUE_USED);
587 ic = newiCode (IFX, NULL, NULL);
588 IC_COND (ic) = condition;
589 IC_TRUE (ic) = trueLabel;
590 IC_FALSE (ic) = falseLabel;
594 /*-----------------------------------------------------------------*/
595 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
596 /*-----------------------------------------------------------------*/
598 newiCodeLabelGoto (int op, symbol * label)
602 ic = newiCode (op, NULL, NULL);
606 IC_RIGHT (ic) = NULL;
607 IC_RESULT (ic) = NULL;
611 /*-----------------------------------------------------------------*/
612 /* newiTemp - allocate & return a newItemp Variable */
613 /*-----------------------------------------------------------------*/
621 SNPRINTF (buffer, sizeof(buffer), "%s", s);
625 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
628 itmp = newSymbol (buffer, 1);
629 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
635 /*-----------------------------------------------------------------*/
636 /* newiTempLabel - creates a temp variable label */
637 /*-----------------------------------------------------------------*/
639 newiTempLabel (char *s)
643 /* check if this already exists */
644 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
649 itmplbl = newSymbol (s, 1);
653 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
654 itmplbl = newSymbol (buffer, 1);
659 itmplbl->key = labelKey++;
660 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
664 /*-----------------------------------------------------------------*/
665 /* newiTempLoopHeaderLabel - creates a new loop header label */
666 /*-----------------------------------------------------------------*/
668 newiTempLoopHeaderLabel (bool pre)
672 SNPRINTF (buffer, sizeof(buffer), pre ? "preHeaderLbl%d" : LOOPEXITLBL "%d",
674 itmplbl = newSymbol (buffer, 1);
678 itmplbl->key = labelKey++;
679 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
684 /*-----------------------------------------------------------------*/
685 /* initiCode - initialises some iCode related stuff */
686 /*-----------------------------------------------------------------*/
693 /*-----------------------------------------------------------------*/
694 /* copyiCode - make a copy of the iCode given */
695 /*-----------------------------------------------------------------*/
697 copyiCode (iCode * ic)
699 iCode *nic = newiCode (ic->op, NULL, NULL);
701 nic->lineno = ic->lineno;
702 nic->filename = ic->filename;
703 nic->block = ic->block;
704 nic->level = ic->level;
705 nic->parmBytes = ic->parmBytes;
707 /* deal with the special cases first */
711 IC_COND (nic) = operandFromOperand (IC_COND (ic));
712 IC_TRUE (nic) = IC_TRUE (ic);
713 IC_FALSE (nic) = IC_FALSE (ic);
717 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
718 IC_JTLABELS (nic) = IC_JTLABELS (ic);
723 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
724 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
728 IC_INLINE (nic) = IC_INLINE (ic);
732 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
736 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
737 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
738 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
744 /*-----------------------------------------------------------------*/
745 /* getTableEntry - gets the table entry for the given operator */
746 /*-----------------------------------------------------------------*/
748 getTableEntry (int oper)
752 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
753 if (oper == codeTable[i].icode)
754 return &codeTable[i];
759 /*-----------------------------------------------------------------*/
760 /* newiTempOperand - new intermediate temp operand */
761 /*-----------------------------------------------------------------*/
763 newiTempOperand (sym_link * type, char throwType)
766 operand *op = newOperand ();
770 itmp = newiTemp (NULL);
772 etype = getSpec (type);
774 if (IS_LITERAL (etype))
777 /* copy the type information */
779 itmp->etype = getSpec (itmp->type = (throwType ? type :
780 copyLinkChain (type)));
781 if (IS_LITERAL (itmp->etype))
783 SPEC_SCLS (itmp->etype) = S_REGISTER;
784 SPEC_OCLS (itmp->etype) = reg;
787 op->operand.symOperand = itmp;
788 op->key = itmp->key = ++operandKey;
792 /*-----------------------------------------------------------------*/
793 /* operandType - returns the type chain for an operand */
794 /*-----------------------------------------------------------------*/
796 operandType (operand * op)
798 /* depending on type of operand */
803 return op->operand.valOperand->type;
806 return op->operand.symOperand->type;
809 return op->operand.typeOperand;
811 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
812 " operand type not known ");
813 assert (0); /* should never come here */
814 /* Just to keep the compiler happy */
815 return (sym_link *) 0;
819 /*-----------------------------------------------------------------*/
820 /* isParamterToCall - will return 1 if op is a parameter to args */
821 /*-----------------------------------------------------------------*/
823 isParameterToCall (value * args, operand * op)
827 wassert (IS_SYMOP(op));
832 isSymbolEqual (op->operand.symOperand, tval->sym))
839 /*-----------------------------------------------------------------*/
840 /* isOperandGlobal - return 1 if operand is a global variable */
841 /*-----------------------------------------------------------------*/
843 isOperandGlobal (operand * op)
852 (op->operand.symOperand->level == 0 ||
853 IS_STATIC (op->operand.symOperand->etype) ||
854 IS_EXTERN (op->operand.symOperand->etype))
861 /*-----------------------------------------------------------------*/
862 /* isOperandVolatile - return 1 if the operand is volatile */
863 /*-----------------------------------------------------------------*/
865 isOperandVolatile (operand * op, bool chkTemp)
870 if (IS_ITEMP (op) && !chkTemp)
873 opetype = getSpec (optype = operandType (op));
875 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
878 if (IS_VOLATILE (opetype))
883 /*-----------------------------------------------------------------*/
884 /* isOperandLiteral - returns 1 if an operand contains a literal */
885 /*-----------------------------------------------------------------*/
887 isOperandLiteral (operand * op)
894 opetype = getSpec (operandType (op));
896 if (IS_LITERAL (opetype))
902 /*-----------------------------------------------------------------*/
903 /* isOperandInFarSpace - will return true if operand is in farSpace */
904 /*-----------------------------------------------------------------*/
906 isOperandInFarSpace (operand * op)
916 if (!IS_TRUE_SYMOP (op))
919 etype = SPIL_LOC (op)->etype;
925 etype = getSpec (operandType (op));
927 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
930 /*-----------------------------------------------------------------*/
931 /* isOperandInPagedSpace - return true if operand is in pagedSpace */
932 /*-----------------------------------------------------------------*/
934 isOperandInPagedSpace (operand * op)
944 if (!IS_TRUE_SYMOP (op))
947 etype = SPIL_LOC (op)->etype;
953 etype = getSpec (operandType (op));
955 return (IN_PAGEDSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
958 /*------------------------------------------------------------------*/
959 /* isOperandInDirSpace - will return true if operand is in dirSpace */
960 /*------------------------------------------------------------------*/
962 isOperandInDirSpace (operand * op)
972 if (!IS_TRUE_SYMOP (op))
975 etype = SPIL_LOC (op)->etype;
981 etype = getSpec (operandType (op));
983 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
986 /*--------------------------------------------------------------------*/
987 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
988 /*--------------------------------------------------------------------*/
990 isOperandInCodeSpace (operand * op)
1000 etype = getSpec (operandType (op));
1002 if (!IS_TRUE_SYMOP (op))
1005 etype = SPIL_LOC (op)->etype;
1011 etype = getSpec (operandType (op));
1013 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1016 /*-----------------------------------------------------------------*/
1017 /* isOperandOnStack - will return true if operand is on stack */
1018 /*-----------------------------------------------------------------*/
1020 isOperandOnStack (operand * op)
1030 etype = getSpec (operandType (op));
1031 if (IN_STACK (etype) ||
1032 OP_SYMBOL(op)->onStack ||
1033 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1039 /*-----------------------------------------------------------------*/
1040 /* isOclsExpensive - will return true if accesses to an output */
1041 /* storage class are expensive */
1042 /*-----------------------------------------------------------------*/
1044 isOclsExpensive (struct memmap *oclass)
1046 if (port->oclsExpense)
1047 return port->oclsExpense (oclass) > 0;
1049 /* In the absence of port specific guidance, assume only */
1050 /* farspace is expensive. */
1051 return IN_FARSPACE (oclass);
1054 /*-----------------------------------------------------------------*/
1055 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1056 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1057 /*-----------------------------------------------------------------*/
1059 isiCodeInFunctionCall (iCode * ic)
1063 /* Find the next CALL/PCALL */
1066 if (lic->op == CALL || lic->op == PCALL)
1074 /* A function call was found. Scan backwards and see if an */
1075 /* IPUSH or SEND is encountered */
1078 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1080 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1088 /*-----------------------------------------------------------------*/
1089 /* operandLitValue - literal value of an operand */
1090 /*-----------------------------------------------------------------*/
1092 operandLitValue (operand * op)
1094 assert (isOperandLiteral (op));
1096 return floatFromVal (op->operand.valOperand);
1099 /*-----------------------------------------------------------------*/
1100 /* getBuiltInParms - returns parameters to a builtin functions */
1101 /*-----------------------------------------------------------------*/
1102 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1107 /* builtin functions uses only SEND for parameters */
1108 while (ic->op != CALL) {
1109 assert(ic->op == SEND && ic->builtinSEND);
1110 ic->generated = 1; /* mark the icode as generated */
1111 parms[*pcount] = IC_LEFT(ic);
1117 /* make sure this is a builtin function call */
1118 assert(IS_SYMOP(IC_LEFT(ic)));
1119 ftype = operandType(IC_LEFT(ic));
1120 assert(IFFUNC_ISBUILTIN(ftype));
1124 /*-----------------------------------------------------------------*/
1125 /* operandOperation - performs operations on operands */
1126 /*-----------------------------------------------------------------*/
1128 operandOperation (operand * left, operand * right,
1129 int op, sym_link * type)
1131 sym_link *let , *ret=NULL;
1132 operand *retval = (operand *) 0;
1134 assert (isOperandLiteral (left));
1135 let = getSpec(operandType(left));
1137 assert (isOperandLiteral (right));
1138 ret = getSpec(operandType(right));
1144 retval = operandFromValue (valCastLiteral (type,
1145 operandLitValue (left) +
1146 operandLitValue (right)));
1149 retval = operandFromValue (valCastLiteral (type,
1150 operandLitValue (left) -
1151 operandLitValue (right)));
1155 retval = operandFromValue (valCastLiteral (type,
1156 operandLitValue (left) *
1157 operandLitValue (right)));
1158 This could be all we've to do, but with gcc we've to take care about
1159 overflows. Two examples:
1160 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1161 significant bits are lost (52 in fraction, 63 bits would be
1162 necessary to keep full precision).
1163 If the resulting double value is greater than ULONG_MAX (resp.
1164 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1167 /* if it is not a specifier then we can assume that */
1168 /* it will be an unsigned long */
1169 if (IS_INT (type) ||
1172 /* long is handled here, because it can overflow with double */
1173 if (IS_LONG (type) ||
1175 /* signed and unsigned mul are the same, as long as the precision
1176 of the result isn't bigger than the precision of the operands. */
1177 retval = operandFromValue (valCastLiteral (type,
1178 (TYPE_TARGET_ULONG) operandLitValue (left) *
1179 (TYPE_TARGET_ULONG) operandLitValue (right)));
1180 else if (IS_UNSIGNED (type)) /* unsigned int */
1182 /* unsigned int is handled here in order to detect overflow */
1183 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) operandLitValue (left) *
1184 (TYPE_TARGET_UINT) operandLitValue (right);
1186 retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_UINT) ul));
1187 if (ul != (TYPE_TARGET_UINT) ul)
1190 else /* signed int */
1192 /* signed int is handled here in order to detect overflow */
1193 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) operandLitValue (left) *
1194 (TYPE_TARGET_INT) operandLitValue (right);
1196 retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_INT) l));
1197 if (l != (TYPE_TARGET_INT) l)
1202 /* all others go here: */
1203 retval = operandFromValue (valCastLiteral (type,
1204 operandLitValue (left) *
1205 operandLitValue (right)));
1208 if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
1210 werror (E_DIVIDE_BY_ZERO);
1216 if (IS_UNSIGNED (type))
1218 SPEC_USIGN (let) = 1;
1219 SPEC_USIGN (ret) = 1;
1220 retval = operandFromValue (valCastLiteral (type,
1221 (TYPE_TARGET_ULONG) operandLitValue (left) /
1222 (TYPE_TARGET_ULONG) operandLitValue (right)));
1226 retval = operandFromValue (valCastLiteral (type,
1227 operandLitValue (left) /
1228 operandLitValue (right)));
1233 if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
1235 werror (E_DIVIDE_BY_ZERO);
1240 if (IS_UNSIGNED (type))
1241 retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) %
1242 (TYPE_TARGET_ULONG) operandLitValue (right));
1244 retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) %
1245 (TYPE_TARGET_LONG) operandLitValue (right));
1249 /* The number of left shifts is always unsigned. Signed doesn't make
1250 sense here. Shifting by a negative number is impossible. */
1251 retval = operandFromValue (valCastLiteral (type,
1252 ((TYPE_TARGET_ULONG) operandLitValue (left) <<
1253 (TYPE_TARGET_ULONG) operandLitValue (right))));
1256 /* The number of right shifts is always unsigned. Signed doesn't make
1257 sense here. Shifting by a negative number is impossible. */
1258 if (IS_UNSIGNED(let))
1259 /* unsigned: logic shift right */
1260 retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) >>
1261 (TYPE_TARGET_ULONG) operandLitValue (right));
1263 /* signed: arithmetic shift right */
1264 retval = operandFromLit ((TYPE_TARGET_LONG ) operandLitValue (left) >>
1265 (TYPE_TARGET_ULONG) operandLitValue (right));
1268 if (IS_FLOAT (let) || IS_FLOAT (ret))
1270 retval = operandFromLit (operandLitValue (left) ==
1271 operandLitValue (right));
1273 else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
1275 retval = operandFromLit (operandLitValue (left) ==
1276 operandLitValue (right));
1280 /* this op doesn't care about signedness */
1281 TYPE_TARGET_ULONG l, r;
1283 l = (TYPE_TARGET_ULONG) operandLitValue (left);
1284 r = (TYPE_TARGET_ULONG) operandLitValue (right);
1285 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1286 neccessary to strip them to 16 bit.
1287 Literals are reduced to their cheapest type, therefore left and
1288 right might have different types. It's neccessary to find a
1289 common type: int (used for char too) or long */
1290 if (!IS_LONG (let) &&
1293 r = (TYPE_TARGET_UINT) r;
1294 l = (TYPE_TARGET_UINT) l;
1296 retval = operandFromLit (l == r);
1300 retval = operandFromLit (operandLitValue (left) <
1301 operandLitValue (right));
1304 retval = operandFromLit (operandLitValue (left) <=
1305 operandLitValue (right));
1308 retval = operandFromLit (operandLitValue (left) !=
1309 operandLitValue (right));
1312 retval = operandFromLit (operandLitValue (left) >
1313 operandLitValue (right));
1316 retval = operandFromLit (operandLitValue (left) >=
1317 operandLitValue (right));
1320 retval = operandFromValue (valCastLiteral (type,
1321 (TYPE_TARGET_ULONG)operandLitValue(left) &
1322 (TYPE_TARGET_ULONG)operandLitValue(right)));
1325 retval = operandFromValue (valCastLiteral (type,
1326 (TYPE_TARGET_ULONG)operandLitValue(left) |
1327 (TYPE_TARGET_ULONG)operandLitValue(right)));
1330 retval = operandFromValue (valCastLiteral (type,
1331 (TYPE_TARGET_ULONG)operandLitValue(left) ^
1332 (TYPE_TARGET_ULONG)operandLitValue(right)));
1335 retval = operandFromLit (operandLitValue (left) &&
1336 operandLitValue (right));
1339 retval = operandFromLit (operandLitValue (left) ||
1340 operandLitValue (right));
1344 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
1346 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1352 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
1354 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1359 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1360 (TYPE_TARGET_ULONG)operandLitValue(right)) & 1);
1363 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1364 (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFF);
1367 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1368 (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFFFF);
1372 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1373 ((getSize (let) * 8) - 1)) & 1);
1377 retval = operandFromValue (valCastLiteral (type,
1378 -1 * operandLitValue (left)));
1382 retval = operandFromValue (valCastLiteral (type,
1383 ~((TYPE_TARGET_ULONG)
1384 operandLitValue (left))));
1388 retval = operandFromLit (!operandLitValue (left));
1392 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1393 " operandOperation invalid operator ");
1401 /*-----------------------------------------------------------------*/
1402 /* isOperandEqual - compares two operand & return 1 if they r = */
1403 /*-----------------------------------------------------------------*/
1405 isOperandEqual (operand * left, operand * right)
1407 /* if the pointers are equal then they are equal */
1411 /* if either of them null then false */
1412 if (!left || !right)
1415 if (left->type != right->type)
1418 if (IS_SYMOP (left) && IS_SYMOP (right))
1419 return left->key == right->key;
1421 /* if types are the same */
1425 return isSymbolEqual (left->operand.symOperand,
1426 right->operand.symOperand);
1428 return (compareType (left->operand.valOperand->type,
1429 right->operand.valOperand->type) &&
1430 (floatFromVal (left->operand.valOperand) ==
1431 floatFromVal (right->operand.valOperand)));
1433 if (compareType (left->operand.typeOperand,
1434 right->operand.typeOperand) == 1)
1441 /*-------------------------------------------------------------------*/
1442 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1443 /*-------------------------------------------------------------------*/
1445 isiCodeEqual (iCode * left, iCode * right)
1447 /* if the same pointer */
1451 /* if either of them null */
1452 if (!left || !right)
1455 /* if operand are the same */
1456 if (left->op == right->op)
1459 /* compare all the elements depending on type */
1460 if (left->op != IFX)
1462 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1464 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1470 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1472 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1474 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1483 /*-----------------------------------------------------------------*/
1484 /* newiTempFromOp - create a temp Operand with same attributes */
1485 /*-----------------------------------------------------------------*/
1487 newiTempFromOp (operand * op)
1497 nop = newiTempOperand (operandType (op), TRUE);
1498 nop->isaddr = op->isaddr;
1499 nop->isvolatile = op->isvolatile;
1500 nop->isGlobal = op->isGlobal;
1501 nop->isLiteral = op->isLiteral;
1502 nop->usesDefs = op->usesDefs;
1503 nop->isParm = op->isParm;
1507 /*-----------------------------------------------------------------*/
1508 /* operand from operand - creates an operand holder for the type */
1509 /*-----------------------------------------------------------------*/
1511 operandFromOperand (operand * op)
1517 nop = newOperand ();
1518 nop->type = op->type;
1519 nop->isaddr = op->isaddr;
1521 nop->isvolatile = op->isvolatile;
1522 nop->isGlobal = op->isGlobal;
1523 nop->isLiteral = op->isLiteral;
1524 nop->usesDefs = op->usesDefs;
1525 nop->isParm = op->isParm;
1530 nop->operand.symOperand = op->operand.symOperand;
1533 nop->operand.valOperand = op->operand.valOperand;
1536 nop->operand.typeOperand = op->operand.typeOperand;
1543 /*-----------------------------------------------------------------*/
1544 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1545 /*-----------------------------------------------------------------*/
1547 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1549 operand *nop = operandFromOperand (op);
1551 if (nop->type == SYMBOL)
1553 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1554 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1560 /*-----------------------------------------------------------------*/
1561 /* operandFromSymbol - creates an operand from a symbol */
1562 /*-----------------------------------------------------------------*/
1564 operandFromSymbol (symbol * sym)
1569 /* if the symbol's type is a literal */
1570 /* then it is an enumerator type */
1571 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1572 return operandFromValue (valFromType (sym->etype));
1575 sym->key = ++operandKey;
1577 /* if this an implicit variable, means struct/union */
1578 /* member so just return it */
1579 if (sym->implicit || IS_FUNC (sym->type))
1583 op->operand.symOperand = sym;
1585 op->isvolatile = isOperandVolatile (op, TRUE);
1586 op->isGlobal = isOperandGlobal (op);
1590 /* under the following conditions create a
1591 register equivalent for a local symbol */
1592 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1593 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1595 (!(options.model == MODEL_FLAT24)) ) &&
1596 options.stackAuto == 0)
1599 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1600 !IS_FUNC (sym->type) && /* not a function */
1601 !sym->_isparm && /* not a parameter */
1602 IS_AUTO (sym) && /* is a local auto variable */
1603 !sym->addrtaken && /* whose address has not been taken */
1604 !sym->reqv && /* does not already have a reg equivalence */
1605 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1606 !sym->islbl && /* not a label */
1607 ok /* farspace check */
1611 /* we will use it after all optimizations
1612 and before liveRange calculation */
1613 sym->reqv = newiTempOperand (sym->type, 0);
1614 sym->reqv->key = sym->key;
1615 OP_SYMBOL (sym->reqv)->prereqv = sym;
1616 OP_SYMBOL (sym->reqv)->key = sym->key;
1617 OP_SYMBOL (sym->reqv)->isreqv = 1;
1618 OP_SYMBOL (sym->reqv)->islocal = 1;
1619 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1620 SPIL_LOC (sym->reqv) = sym;
1623 if (!IS_AGGREGATE (sym->type))
1627 op->operand.symOperand = sym;
1630 op->isvolatile = isOperandVolatile (op, TRUE);
1631 op->isGlobal = isOperandGlobal (op);
1632 op->isPtr = IS_PTR (operandType (op));
1633 op->isParm = sym->_isparm;
1638 /* itemp = &[_symbol] */
1640 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1641 IC_LEFT (ic)->type = SYMBOL;
1642 IC_LEFT (ic)->operand.symOperand = sym;
1643 IC_LEFT (ic)->key = sym->key;
1644 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1645 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1646 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1649 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1650 if (IS_ARRAY (sym->type))
1652 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1653 IC_RESULT (ic)->isaddr = 0;
1656 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1660 return IC_RESULT (ic);
1663 /*-----------------------------------------------------------------*/
1664 /* operandFromValue - creates an operand from value */
1665 /*-----------------------------------------------------------------*/
1667 operandFromValue (value * val)
1671 /* if this is a symbol then do the symbol thing */
1673 return operandFromSymbol (val->sym);
1675 /* this is not a symbol */
1678 op->operand.valOperand = val;
1679 op->isLiteral = isOperandLiteral (op);
1683 /*-----------------------------------------------------------------*/
1684 /* operandFromLink - operand from typeChain */
1685 /*-----------------------------------------------------------------*/
1687 operandFromLink (sym_link * type)
1691 /* operand from sym_link */
1697 op->operand.typeOperand = copyLinkChain (type);
1701 /*-----------------------------------------------------------------*/
1702 /* operandFromLit - makes an operand from a literal value */
1703 /*-----------------------------------------------------------------*/
1705 operandFromLit (double i)
1707 return operandFromValue (valueFromLit (i));
1710 /*-----------------------------------------------------------------*/
1711 /* operandFromAst - creates an operand from an ast */
1712 /*-----------------------------------------------------------------*/
1714 operandFromAst (ast * tree,int lvl)
1720 /* depending on type do */
1724 return ast2iCode (tree,lvl+1);
1728 return operandFromValue (tree->opval.val);
1732 return operandFromLink (tree->opval.lnk);
1739 /* Just to keep the compiler happy */
1740 return (operand *) 0;
1743 /*-----------------------------------------------------------------*/
1744 /* setOperandType - sets the operand's type to the given type */
1745 /*-----------------------------------------------------------------*/
1747 setOperandType (operand * op, sym_link * type)
1749 /* depending on the type of operand */
1754 op->operand.valOperand->etype =
1755 getSpec (op->operand.valOperand->type =
1756 copyLinkChain (type));
1760 if (op->operand.symOperand->isitmp)
1761 op->operand.symOperand->etype =
1762 getSpec (op->operand.symOperand->type =
1763 copyLinkChain (type));
1765 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1766 "attempt to modify type of source");
1770 op->operand.typeOperand = copyLinkChain (type);
1776 /*-----------------------------------------------------------------*/
1777 /* Get size in byte of ptr need to access an array */
1778 /*-----------------------------------------------------------------*/
1780 getArraySizePtr (operand * op)
1782 sym_link *ltype = operandType(op);
1786 int size = getSize(ltype);
1787 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1792 sym_link *letype = getSpec(ltype);
1793 switch (PTR_TYPE (SPEC_OCLS (letype)))
1805 if (GPTRSIZE > FPTRSIZE)
1806 return (GPTRSIZE-1);
1817 /*-----------------------------------------------------------------*/
1818 /* perform "usual unary conversions" */
1819 /*-----------------------------------------------------------------*/
1822 usualUnaryConversions (operand * op)
1824 if (IS_INTEGRAL (operandType (op)))
1826 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1829 return geniCodeCast (INTTYPE, op, TRUE);
1836 /*-----------------------------------------------------------------*/
1837 /* perform "usual binary conversions" */
1838 /*-----------------------------------------------------------------*/
1841 usualBinaryConversions (operand ** op1, operand ** op2,
1842 RESULT_TYPE resultType, int op)
1845 sym_link *rtype = operandType (*op2);
1846 sym_link *ltype = operandType (*op1);
1848 ctype = computeType (ltype, rtype, resultType, op);
1855 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1857 /* one byte operations: keep signedness for code generator */
1865 *op1 = geniCodeCast (ctype, *op1, TRUE);
1866 *op2 = geniCodeCast (ctype, *op2, TRUE);
1871 /*-----------------------------------------------------------------*/
1872 /* geniCodeValueAtAddress - generate intermeditate code for value */
1874 /*-----------------------------------------------------------------*/
1876 geniCodeRValue (operand * op, bool force)
1879 sym_link *type = operandType (op);
1880 sym_link *etype = getSpec (type);
1882 /* if this is an array & already */
1883 /* an address then return this */
1884 if (IS_AGGREGATE (type) ||
1885 (IS_PTR (type) && !force && !op->isaddr))
1886 return operandFromOperand (op);
1888 /* if this is not an address then must be */
1889 /* rvalue already so return this one */
1893 /* if this is not a temp symbol then */
1894 if (!IS_ITEMP (op) &&
1896 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1898 op = operandFromOperand (op);
1903 if (IS_SPEC (type) &&
1904 IS_TRUE_SYMOP (op) &&
1905 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1906 (options.model == MODEL_FLAT24) ))
1908 op = operandFromOperand (op);
1913 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1914 if (IS_PTR (type) && op->isaddr && force)
1917 type = copyLinkChain (type);
1919 IC_RESULT (ic) = newiTempOperand (type, 1);
1920 IC_RESULT (ic)->isaddr = 0;
1922 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1926 return IC_RESULT (ic);
1929 /*-----------------------------------------------------------------*/
1930 /* geniCodeCast - changes the value from one type to another */
1931 /*-----------------------------------------------------------------*/
1933 geniCodeCast (sym_link * type, operand * op, bool implicit)
1937 sym_link *opetype = getSpec (optype = operandType (op));
1941 /* one of them has size zero then error */
1942 if (IS_VOID (optype))
1944 werror (E_CAST_ZERO);
1948 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1950 geniCodeArray2Ptr (op);
1954 /* if the operand is already the desired type then do nothing */
1955 if (compareType (type, optype) == 1)
1958 /* if this is a literal then just change the type & return */
1959 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1961 return operandFromValue (valCastLiteral (type,
1962 operandLitValue (op)));
1965 /* if casting to/from pointers, do some checking */
1966 if (IS_PTR(type)) { // to a pointer
1967 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1968 if (IS_INTEGRAL(optype)) {
1969 // maybe this is NULL, than it's ok.
1970 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1971 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1972 // no way to set the storage
1973 if (IS_LITERAL(optype)) {
1974 werror(E_LITERAL_GENERIC);
1977 werror(E_NONPTR2_GENPTR);
1980 } else if (implicit) {
1981 werror(W_INTEGRAL2PTR_NOCAST);
1986 // shouldn't do that with float, array or structure unless to void
1987 if (!IS_VOID(getSpec(type)) &&
1988 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1989 werror(E_INCOMPAT_TYPES);
1993 } else { // from a pointer to a pointer
1994 if (IS_GENPTR(type) && IS_VOID(type->next))
1995 { // cast to void* is always allowed
1997 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
1998 { // cast from void* is always allowed
2000 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2001 // if not a pointer to a function
2002 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2003 if (implicit) { // if not to generic, they have to match
2004 if (!IS_GENPTR(type) &&
2005 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2006 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2010 werror(E_INCOMPAT_PTYPES);
2017 } else { // to a non pointer
2018 if (IS_PTR(optype)) { // from a pointer
2019 if (implicit) { // sneaky
2020 if (IS_INTEGRAL(type)) {
2021 werror(W_PTR2INTEGRAL_NOCAST);
2023 } else { // shouldn't do that with float, array or structure
2024 werror(E_INCOMPAT_TYPES);
2031 printFromToType (optype, type);
2034 /* if they are the same size create an assignment */
2036 /* This seems very dangerous to me, since there are several */
2037 /* optimizations (for example, gcse) that don't notice the */
2038 /* cast hidden in this assignement and may simplify an */
2039 /* iCode to use the original (uncasted) operand. */
2040 /* Unfortunately, other things break when this cast is */
2041 /* made explicit. Need to fix this someday. */
2042 /* -- EEP, 2004/01/21 */
2043 if (getSize (type) == getSize (optype) &&
2044 !IS_BITFIELD (type) &&
2046 !IS_FLOAT (optype) &&
2048 !IS_FIXED (optype) &&
2049 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2050 (!IS_SPEC (type) && !IS_SPEC (optype))))
2052 ic = newiCode ('=', NULL, op);
2053 IC_RESULT (ic) = newiTempOperand (type, 0);
2054 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2055 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2056 IC_RESULT (ic)->isaddr = 0;
2060 ic = newiCode (CAST, operandFromLink (type),
2061 geniCodeRValue (op, FALSE));
2063 IC_RESULT (ic) = newiTempOperand (type, 0);
2066 /* preserve the storage class & output class */
2067 /* of the original variable */
2068 restype = getSpec (operandType (IC_RESULT (ic)));
2069 if (!IS_LITERAL(opetype) &&
2072 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2073 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2076 return IC_RESULT (ic);
2079 /*-----------------------------------------------------------------*/
2080 /* geniCodeLabel - will create a Label */
2081 /*-----------------------------------------------------------------*/
2083 geniCodeLabel (symbol * label)
2087 ic = newiCodeLabelGoto (LABEL, label);
2091 /*-----------------------------------------------------------------*/
2092 /* geniCodeGoto - will create a Goto */
2093 /*-----------------------------------------------------------------*/
2095 geniCodeGoto (symbol * label)
2099 ic = newiCodeLabelGoto (GOTO, label);
2103 /*-----------------------------------------------------------------*/
2104 /* geniCodeMultiply - gen intermediate code for multiplication */
2105 /*-----------------------------------------------------------------*/
2107 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2114 /* if they are both literal then we know the result */
2115 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2116 return operandFromValue (valMult (left->operand.valOperand,
2117 right->operand.valOperand));
2119 if (IS_LITERAL(retype)) {
2120 p2 = powof2 ((TYPE_TARGET_ULONG) floatFromVal (right->operand.valOperand));
2123 resType = usualBinaryConversions (&left, &right, resultType, '*');
2125 rtype = operandType (right);
2126 retype = getSpec (rtype);
2127 ltype = operandType (left);
2128 letype = getSpec (ltype);
2131 /* if the right is a literal & power of 2 */
2132 /* then make it a left shift */
2133 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2134 efficient in most cases than 2 bytes result = 2 bytes << literal
2135 if port has 1 byte muldiv */
2136 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2137 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2138 && (port->support.muldiv == 1))
2139 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2140 && strcmp (port->target, "pic14") != 0)
2142 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2144 /* LEFT_OP need same size for left and result, */
2145 left = geniCodeCast (resType, left, TRUE);
2146 ltype = operandType (left);
2148 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2152 /* if the size left or right > 1 then support routine */
2153 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2155 if (IS_LITERAL (retype))
2156 ic = newiCode ('*', right, left); /* multiplication by support routine with one literal */
2158 ic = newiCode ('*', left, right); /* multiplication by support routine */
2163 ic = newiCode ('*', left, right); /* normal multiplication */
2166 IC_RESULT (ic) = newiTempOperand (resType, 1);
2169 return IC_RESULT (ic);
2172 /*-----------------------------------------------------------------*/
2173 /* geniCodeDivision - gen intermediate code for division */
2174 /*-----------------------------------------------------------------*/
2176 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2181 sym_link *rtype = operandType (right);
2182 sym_link *retype = getSpec (rtype);
2183 sym_link *ltype = operandType (left);
2184 sym_link *letype = getSpec (ltype);
2186 resType = usualBinaryConversions (&left, &right, resultType, '/');
2188 /* if the right is a literal & power of 2
2189 and left is unsigned then make it a
2191 if (IS_LITERAL (retype) &&
2192 !IS_FLOAT (letype) &&
2193 !IS_FIXED (letype) &&
2194 IS_UNSIGNED(letype) &&
2195 ((p2 = powof2 ((TYPE_TARGET_ULONG)
2196 floatFromVal (right->operand.valOperand))) > 0)) {
2197 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2201 ic = newiCode ('/', left, right); /* normal division */
2202 /* if the size left or right > 1 then support routine */
2203 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2206 IC_RESULT (ic) = newiTempOperand (resType, 0);
2209 return IC_RESULT (ic);
2211 /*-----------------------------------------------------------------*/
2212 /* geniCodeModulus - gen intermediate code for modulus */
2213 /*-----------------------------------------------------------------*/
2215 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2221 /* if they are both literal then we know the result */
2222 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2223 return operandFromValue (valMod (left->operand.valOperand,
2224 right->operand.valOperand));
2226 resType = usualBinaryConversions (&left, &right, resultType, '%');
2228 /* now they are the same size */
2229 ic = newiCode ('%', left, right);
2231 /* if the size left or right > 1 then support routine */
2232 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2234 IC_RESULT (ic) = newiTempOperand (resType, 0);
2237 return IC_RESULT (ic);
2240 /*-----------------------------------------------------------------*/
2241 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2242 /*-----------------------------------------------------------------*/
2244 geniCodePtrPtrSubtract (operand * left, operand * right)
2250 /* if they are both literals then */
2251 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2253 result = operandFromValue (valMinus (left->operand.valOperand,
2254 right->operand.valOperand));
2258 ic = newiCode ('-', left, right);
2260 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2264 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2268 // should we really do this? is this ANSI?
2269 return geniCodeDivision (result,
2270 operandFromLit (getSize (ltype->next)),
2274 /*-----------------------------------------------------------------*/
2275 /* geniCodeSubtract - generates code for subtraction */
2276 /*-----------------------------------------------------------------*/
2278 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2285 /* if they both pointers then */
2286 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2287 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2288 return geniCodePtrPtrSubtract (left, right);
2290 /* if they are both literal then we know the result */
2291 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2292 && left->isLiteral && right->isLiteral)
2293 return operandFromValue (valMinus (left->operand.valOperand,
2294 right->operand.valOperand));
2296 /* if left is an array or pointer */
2297 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2299 isarray = left->isaddr;
2300 right = geniCodeMultiply (right,
2301 operandFromLit (getSize (ltype->next)),
2302 (getArraySizePtr(left) >= INTSIZE) ?
2305 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2308 { /* make them the same size */
2309 resType = usualBinaryConversions (&left, &right, resultType, '-');
2312 ic = newiCode ('-', left, right);
2314 IC_RESULT (ic) = newiTempOperand (resType, 1);
2315 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2317 /* if left or right is a float */
2318 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2319 || IS_FIXED (ltype) || IS_FIXED (rtype))
2323 return IC_RESULT (ic);
2326 /*-----------------------------------------------------------------*/
2327 /* geniCodeAdd - generates iCode for addition */
2328 /*-----------------------------------------------------------------*/
2330 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2339 /* if the right side is LITERAL zero */
2340 /* return the left side */
2341 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2344 /* if left is literal zero return right */
2345 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2348 /* if left is a pointer then size */
2349 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2351 isarray = left->isaddr;
2352 // there is no need to multiply with 1
2353 if (getSize (ltype->next) != 1)
2355 size = operandFromLit (getSize (ltype->next));
2356 SPEC_USIGN (getSpec (operandType (size))) = 1;
2357 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2358 right = geniCodeMultiply (right, size, resultType);
2359 /* Even if right is a 'unsigned char',
2360 the result will be a 'signed int' due to the promotion rules.
2361 It doesn't make sense when accessing arrays, so let's fix it here: */
2363 SPEC_USIGN (getSpec (operandType (right))) = 1;
2365 resType = copyLinkChain (ltype);
2368 { // make them the same size
2369 resType = usualBinaryConversions (&left, &right, resultType, '+');
2372 /* if they are both literals then we know */
2373 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2374 && left->isLiteral && right->isLiteral)
2375 return operandFromValue (valPlus (valFromType (ltype),
2376 valFromType (rtype)));
2378 ic = newiCode ('+', left, right);
2380 IC_RESULT (ic) = newiTempOperand (resType, 1);
2381 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2383 /* if left or right is a float then support
2385 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2386 || IS_FIXED (ltype) || IS_FIXED (rtype))
2391 return IC_RESULT (ic);
2395 /*-----------------------------------------------------------------*/
2396 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2397 /*-----------------------------------------------------------------*/
2399 aggrToPtr (sym_link * type, bool force)
2404 if (IS_PTR (type) && !force)
2407 etype = getSpec (type);
2408 ptype = newLink (DECLARATOR);
2412 /* set the pointer depending on the storage class */
2413 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2417 /*------------------------------------------------------------------*/
2418 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2419 /*------------------------------------------------------------------*/
2421 aggrToPtrDclType (sym_link * type, bool force)
2423 if (IS_PTR (type) && !force)
2424 return DCL_TYPE (type);
2426 /* return the pointer depending on the storage class */
2427 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2430 /*-----------------------------------------------------------------*/
2431 /* geniCodeArray2Ptr - array to pointer */
2432 /*-----------------------------------------------------------------*/
2434 geniCodeArray2Ptr (operand * op)
2436 sym_link *optype = operandType (op);
2437 sym_link *opetype = getSpec (optype);
2439 /* set the pointer depending on the storage class */
2440 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2447 /*-----------------------------------------------------------------*/
2448 /* geniCodeArray - array access */
2449 /*-----------------------------------------------------------------*/
2451 geniCodeArray (operand * left, operand * right, int lvl)
2455 sym_link *ltype = operandType (left);
2457 RESULT_TYPE resultType;
2459 resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
2460 if (DCL_ELEM (ltype))
2462 if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
2463 resultType = RESULT_TYPE_CHAR;
2468 if (IS_PTR (ltype->next) && left->isaddr)
2470 left = geniCodeRValue (left, FALSE);
2473 return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
2476 size = operandFromLit (getSize (ltype->next));
2477 SPEC_USIGN (getSpec (operandType (size))) = 1;
2478 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2479 right = geniCodeMultiply (right, size, resultType);
2480 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2481 It doesn't make sense when accessing arrays, so let's fix it here: */
2483 SPEC_USIGN (getSpec (operandType (right))) = 1;
2484 /* we can check for limits here */
2485 /* already done in SDCCast.c
2486 if (isOperandLiteral (right) &&
2489 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2491 werror (W_IDX_OUT_OF_BOUNDS,
2492 (int) operandLitValue (right) / getSize (ltype->next),
2497 ic = newiCode ('+', left, right);
2499 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2500 !IS_AGGREGATE (ltype->next) &&
2501 !IS_PTR (ltype->next))
2502 ? ltype : ltype->next), 0);
2504 if (!IS_AGGREGATE (ltype->next))
2506 IC_RESULT (ic)->isaddr = 1;
2507 IC_RESULT (ic)->aggr2ptr = 1;
2511 return IC_RESULT (ic);
2514 /*-----------------------------------------------------------------*/
2515 /* geniCodeStruct - generates intermediate code for structures */
2516 /*-----------------------------------------------------------------*/
2518 geniCodeStruct (operand * left, operand * right, bool islval)
2521 sym_link *type = operandType (left);
2522 sym_link *etype = getSpec (type);
2524 symbol *element = getStructElement (SPEC_STRUCT (etype),
2525 right->operand.symOperand);
2527 wassert(IS_SYMOP(right));
2529 /* add the offset */
2530 ic = newiCode ('+', left, operandFromLit (element->offset));
2532 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2534 /* preserve the storage & output class of the struct */
2535 /* as well as the volatile attribute */
2536 retype = getSpec (operandType (IC_RESULT (ic)));
2537 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2538 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2539 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2540 SPEC_CONST (retype) |= SPEC_CONST (etype);
2542 if (IS_PTR (element->type))
2543 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2545 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2548 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2551 /*-----------------------------------------------------------------*/
2552 /* geniCodePostInc - generate int code for Post increment */
2553 /*-----------------------------------------------------------------*/
2555 geniCodePostInc (operand * op)
2559 sym_link *optype = operandType (op);
2561 operand *rv = (IS_ITEMP (op) ?
2562 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2564 sym_link *rvtype = operandType (rv);
2567 /* if this is not an address we have trouble */
2570 werror (E_LVALUE_REQUIRED, "++");
2574 rOp = newiTempOperand (rvtype, 0);
2575 OP_SYMBOL(rOp)->noSpilLoc = 1;
2578 OP_SYMBOL(rv)->noSpilLoc = 1;
2580 geniCodeAssign (rOp, rv, 0, 0);
2582 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2584 werror(W_SIZEOF_VOID);
2585 if (IS_FLOAT (rvtype))
2586 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2587 else if (IS_FIXED16X16 (rvtype))
2588 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2590 ic = newiCode ('+', rv, operandFromLit (size));
2592 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2595 geniCodeAssign (op, result, 0, 0);
2601 /*-----------------------------------------------------------------*/
2602 /* geniCodePreInc - generate code for preIncrement */
2603 /*-----------------------------------------------------------------*/
2605 geniCodePreInc (operand * op, bool lvalue)
2608 sym_link *optype = operandType (op);
2609 operand *rop = (IS_ITEMP (op) ?
2610 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2612 sym_link *roptype = operandType (rop);
2618 werror (E_LVALUE_REQUIRED, "++");
2622 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2624 werror(W_SIZEOF_VOID);
2625 if (IS_FLOAT (roptype))
2626 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2627 else if (IS_FIXED16X16 (roptype))
2628 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2630 ic = newiCode ('+', rop, operandFromLit (size));
2631 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2634 (void) geniCodeAssign (op, result, 0, 0);
2635 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2641 /*-----------------------------------------------------------------*/
2642 /* geniCodePostDec - generates code for Post decrement */
2643 /*-----------------------------------------------------------------*/
2645 geniCodePostDec (operand * op)
2649 sym_link *optype = operandType (op);
2651 operand *rv = (IS_ITEMP (op) ?
2652 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2654 sym_link *rvtype = operandType (rv);
2657 /* if this is not an address we have trouble */
2660 werror (E_LVALUE_REQUIRED, "--");
2664 rOp = newiTempOperand (rvtype, 0);
2665 OP_SYMBOL(rOp)->noSpilLoc = 1;
2668 OP_SYMBOL(rv)->noSpilLoc = 1;
2670 geniCodeAssign (rOp, rv, 0, 0);
2672 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2674 werror(W_SIZEOF_VOID);
2675 if (IS_FLOAT (rvtype))
2676 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2677 else if (IS_FIXED16X16 (rvtype))
2678 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2680 ic = newiCode ('-', rv, operandFromLit (size));
2682 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2685 geniCodeAssign (op, result, 0, 0);
2691 /*-----------------------------------------------------------------*/
2692 /* geniCodePreDec - generate code for pre decrement */
2693 /*-----------------------------------------------------------------*/
2695 geniCodePreDec (operand * op, bool lvalue)
2698 sym_link *optype = operandType (op);
2699 operand *rop = (IS_ITEMP (op) ?
2700 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2702 sym_link *roptype = operandType (rop);
2708 werror (E_LVALUE_REQUIRED, "--");
2712 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2714 werror(W_SIZEOF_VOID);
2715 if (IS_FLOAT (roptype))
2716 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2717 else if (IS_FIXED16X16 (roptype))
2718 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2720 ic = newiCode ('-', rop, operandFromLit (size));
2721 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2724 (void) geniCodeAssign (op, result, 0, 0);
2725 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2732 /*-----------------------------------------------------------------*/
2733 /* geniCodeBitwise - gen int code for bitWise operators */
2734 /*-----------------------------------------------------------------*/
2736 geniCodeBitwise (operand * left, operand * right,
2737 int oper, sym_link * resType)
2741 left = geniCodeCast (resType, left, TRUE);
2742 right = geniCodeCast (resType, right, TRUE);
2744 ic = newiCode (oper, left, right);
2745 IC_RESULT (ic) = newiTempOperand (resType, 0);
2748 return IC_RESULT (ic);
2751 /*-----------------------------------------------------------------*/
2752 /* geniCodeAddressOf - gens icode for '&' address of operator */
2753 /*-----------------------------------------------------------------*/
2755 geniCodeAddressOf (operand * op)
2759 sym_link *optype = operandType (op);
2760 sym_link *opetype = getSpec (optype);
2762 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2764 op = operandFromOperand (op);
2769 /* lvalue check already done in decorateType */
2770 /* this must be a lvalue */
2771 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2772 /* werror (E_LVALUE_REQUIRED,"&"); */
2776 p = newLink (DECLARATOR);
2778 /* set the pointer depending on the storage class */
2779 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2781 p->next = copyLinkChain (optype);
2783 /* if already a temp */
2786 setOperandType (op, p);
2791 /* otherwise make this of the type coming in */
2792 ic = newiCode (ADDRESS_OF, op, NULL);
2793 IC_RESULT (ic) = newiTempOperand (p, 1);
2794 IC_RESULT (ic)->isaddr = 0;
2796 return IC_RESULT (ic);
2799 /*-----------------------------------------------------------------*/
2800 /* setOClass - sets the output class depending on the pointer type */
2801 /*-----------------------------------------------------------------*/
2803 setOClass (sym_link * ptr, sym_link * spec)
2805 switch (DCL_TYPE (ptr))
2808 SPEC_OCLS (spec) = data;
2812 SPEC_OCLS (spec) = generic;
2816 SPEC_OCLS (spec) = xdata;
2820 SPEC_OCLS (spec) = code;
2824 SPEC_OCLS (spec) = idata;
2828 SPEC_OCLS (spec) = xstack;
2832 SPEC_OCLS (spec) = eeprom;
2841 /*-----------------------------------------------------------------*/
2842 /* geniCodeDerefPtr - dereference pointer with '*' */
2843 /*-----------------------------------------------------------------*/
2845 geniCodeDerefPtr (operand * op,int lvl)
2847 sym_link *rtype, *retype;
2848 sym_link *optype = operandType (op);
2850 // if this is an array then array access
2851 if (IS_ARRAY (optype)) {
2852 // don't worry, this will be optimized out later
2853 return geniCodeArray (op, operandFromLit (0), lvl);
2856 // just in case someone screws up
2857 wassert (IS_PTR (optype));
2859 if (IS_TRUE_SYMOP (op))
2862 op = geniCodeRValue (op, TRUE);
2865 /* now get rid of the pointer part */
2866 if (isLvaluereq(lvl) && IS_ITEMP (op))
2868 retype = getSpec (rtype = copyLinkChain (optype));
2872 retype = getSpec (rtype = copyLinkChain (optype->next));
2873 /* outputclass needs 2b updated */
2874 setOClass (optype, retype);
2877 op->isGptr = IS_GENPTR (optype);
2879 op->isaddr = (IS_PTR (rtype) ||
2880 IS_STRUCT (rtype) ||
2886 if (!isLvaluereq(lvl))
2887 op = geniCodeRValue (op, TRUE);
2889 setOperandType (op, rtype);
2894 /*-----------------------------------------------------------------*/
2895 /* geniCodeUnaryMinus - does a unary minus of the operand */
2896 /*-----------------------------------------------------------------*/
2898 geniCodeUnaryMinus (operand * op)
2901 sym_link *optype = operandType (op);
2903 if (IS_LITERAL (optype))
2904 return operandFromLit (-floatFromVal (op->operand.valOperand));
2906 ic = newiCode (UNARYMINUS, op, NULL);
2907 IC_RESULT (ic) = newiTempOperand (optype, 0);
2909 return IC_RESULT (ic);
2912 /*-----------------------------------------------------------------*/
2913 /* geniCodeLeftShift - gen i code for left shift */
2914 /*-----------------------------------------------------------------*/
2916 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2921 ic = newiCode (LEFT_OP, left, right);
2923 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2924 IC_RESULT (ic) = newiTempOperand (resType, 0);
2926 return IC_RESULT (ic);
2929 /*-----------------------------------------------------------------*/
2930 /* geniCodeRightShift - gen i code for right shift */
2931 /*-----------------------------------------------------------------*/
2933 geniCodeRightShift (operand * left, operand * right)
2937 ic = newiCode (RIGHT_OP, left, right);
2938 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2940 return IC_RESULT (ic);
2943 /*-----------------------------------------------------------------*/
2944 /* geniCodeLogic- logic code */
2945 /*-----------------------------------------------------------------*/
2947 geniCodeLogic (operand * left, operand * right, int op)
2951 sym_link *rtype = operandType (right);
2952 sym_link *ltype = operandType (left);
2954 /* left is integral type and right is literal then
2955 check if the literal value is within bounds */
2956 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2958 CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE);
2961 case CCR_ALWAYS_TRUE:
2962 case CCR_ALWAYS_FALSE:
2963 if (!options.lessPedantic)
2964 werror (W_COMP_RANGE, "true resp. false");
2965 return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0);
2971 /* if one operand is a pointer and the other is a literal generic void pointer,
2972 change the type of the literal generic void pointer to match the other pointer */
2973 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2974 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2976 /* find left's definition */
2977 ic = (iCode *) setFirstItem (iCodeChain);
2980 if (((ic->op == CAST) || (ic->op == '='))
2981 && isOperandEqual(left, IC_RESULT (ic)))
2984 ic = setNextItem (iCodeChain);
2986 /* if casting literal to generic pointer, then cast to rtype instead */
2987 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2989 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2990 ltype = operandType(left);
2993 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2994 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2996 /* find right's definition */
2997 ic = (iCode *) setFirstItem (iCodeChain);
3000 if (((ic->op == CAST) || (ic->op == '='))
3001 && isOperandEqual(right, IC_RESULT (ic)))
3004 ic = setNextItem (iCodeChain);
3006 /* if casting literal to generic pointer, then cast to rtype instead */
3007 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3009 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3010 rtype = operandType(right);
3014 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
3016 ic = newiCode (op, left, right);
3017 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3019 /* if comparing float
3020 and not a '==' || '!=' || '&&' || '||' (these
3022 if (IS_FLOAT(ctype) &&
3029 /* if comparing a fixed type use support functions */
3030 if (IS_FIXED(ctype))
3034 return IC_RESULT (ic);
3037 /*-----------------------------------------------------------------*/
3038 /* geniCodeLogicAndOr - && || operations */
3039 /*-----------------------------------------------------------------*/
3041 geniCodeLogicAndOr (ast *tree, int lvl)
3045 symbol *falseLabel = newiTempLabel (NULL);
3046 symbol *trueLabel = newiTempLabel (NULL);
3047 symbol *exitLabel = newiTempLabel (NULL);
3048 operand *op, *result, *condition;
3050 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3051 They can be reenabled by executing the following block. If you find
3052 a decent optimization you could start right here:
3057 operand *leftOp, *rightOp;
3059 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3060 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3062 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3066 /* generate two IFX for the '&&' or '||' op */
3068 /* evaluate left operand */
3069 condition = ast2iCode (tree->left, lvl + 1);
3070 op = geniCodeRValue (condition, FALSE);
3072 /* test left operand */
3073 if (tree->opval.op == AND_OP)
3074 ic = newiCodeCondition (op, NULL, falseLabel);
3076 ic = newiCodeCondition (op, trueLabel, NULL);
3079 /* evaluate right operand */
3080 condition = ast2iCode (tree->right, lvl + 1);
3081 op = geniCodeRValue (condition, FALSE);
3083 /* test right operand */
3084 ic = newiCodeCondition (op, trueLabel, NULL);
3087 /* store 0 or 1 in result */
3088 type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3089 result = newiTempOperand (type, 1);
3091 geniCodeLabel (falseLabel);
3092 geniCodeAssign (result, operandFromLit (0), 0, 0);
3093 /* generate an unconditional goto */
3094 geniCodeGoto (exitLabel);
3096 geniCodeLabel (trueLabel);
3097 geniCodeAssign (result, operandFromLit (1), 0, 0);
3099 geniCodeLabel (exitLabel);
3104 /*-----------------------------------------------------------------*/
3105 /* geniCodeUnary - for a generic unary operation */
3106 /*-----------------------------------------------------------------*/
3108 geniCodeUnary (operand * op, int oper)
3110 iCode *ic = newiCode (oper, op, NULL);
3112 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3114 return IC_RESULT (ic);
3117 /*-----------------------------------------------------------------*/
3118 /* geniCodeBinary - for a generic binary operation */
3119 /*-----------------------------------------------------------------*/
3121 geniCodeBinary (operand * left, operand * right, int oper)
3123 iCode *ic = newiCode (oper, left, right);
3125 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3127 return IC_RESULT (ic);
3130 /*-----------------------------------------------------------------*/
3131 /* geniCodeConditional - geniCode for '?' ':' operation */
3132 /*-----------------------------------------------------------------*/
3134 geniCodeConditional (ast * tree,int lvl)
3137 symbol *falseLabel = newiTempLabel (NULL);
3138 symbol *exitLabel = newiTempLabel (NULL);
3139 operand *cond = ast2iCode (tree->left,lvl+1);
3140 operand *true, *false, *result;
3142 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3146 true = ast2iCode (tree->right->left,lvl+1);
3148 /* move the value to a new Operand */
3149 result = newiTempOperand (tree->right->ftype, 0);
3150 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3152 /* generate an unconditional goto */
3153 geniCodeGoto (exitLabel);
3155 /* now for the right side */
3156 geniCodeLabel (falseLabel);
3158 false = ast2iCode (tree->right->right,lvl+1);
3159 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3161 /* create the exit label */
3162 geniCodeLabel (exitLabel);
3167 /*-----------------------------------------------------------------*/
3168 /* geniCodeAssign - generate code for assignment */
3169 /*-----------------------------------------------------------------*/
3171 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3174 sym_link *ltype = operandType (left);
3175 sym_link *rtype = operandType (right);
3177 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3179 werror (E_LVALUE_REQUIRED, "assignment");
3183 /* left is integral type and right is literal then
3184 check if the literal value is within bounds */
3185 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3186 checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3187 !options.lessPedantic)
3189 werror (W_LIT_OVERFLOW);
3192 /* if the left & right type don't exactly match */
3193 /* if pointer set then make sure the check is
3194 done with the type & not the pointer */
3195 /* then cast rights type to left */
3197 /* first check the type for pointer assignement */
3198 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3199 compareType (ltype, rtype) <= 0)
3201 if (compareType (ltype->next, rtype) < 0)
3202 right = geniCodeCast (ltype->next, right, TRUE);
3204 else if (compareType (ltype, rtype) < 0)
3205 right = geniCodeCast (ltype, right, TRUE);
3207 /* If left is a true symbol & ! volatile
3208 create an assignment to temporary for
3209 the right & then assign this temporary
3210 to the symbol. This is SSA (static single
3211 assignment). Isn't it simple and folks have
3212 published mountains of paper on it */
3213 if (IS_TRUE_SYMOP (left) &&
3214 !isOperandVolatile (left, FALSE) &&
3215 isOperandGlobal (left))
3220 if (IS_TRUE_SYMOP (right))
3221 sym = OP_SYMBOL (right);
3222 ic = newiCode ('=', NULL, right);
3223 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3224 /* avoid double fetch from volatile right, see bug 1369874 */
3225 if (!isOperandVolatile (right, FALSE))
3226 SPIL_LOC (newRight) = sym;
3231 ic = newiCode ('=', NULL, right);
3232 IC_RESULT (ic) = left;
3235 /* if left isgptr flag is set then support
3236 routine will be required */
3240 ic->nosupdate = nosupdate;
3241 /* left could be a pointer assignment,
3242 return the properly casted right instead */
3246 /*-----------------------------------------------------------------*/
3247 /* geniCodeDummyRead - generate code for dummy read */
3248 /*-----------------------------------------------------------------*/
3250 geniCodeDummyRead (operand * op)
3253 sym_link *type = operandType (op);
3255 if (!IS_VOLATILE(type))
3258 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3264 /*-----------------------------------------------------------------*/
3265 /* geniCodeSEParms - generate code for side effecting fcalls */
3266 /*-----------------------------------------------------------------*/
3268 geniCodeSEParms (ast * parms,int lvl)
3273 if (parms->type == EX_OP && parms->opval.op == PARAM)
3275 geniCodeSEParms (parms->left,lvl);
3276 geniCodeSEParms (parms->right,lvl);
3280 /* hack don't like this but too lazy to think of
3282 if (IS_ADDRESS_OF_OP (parms))
3283 parms->left->lvalue = 1;
3285 if (IS_CAST_OP (parms) &&
3286 IS_PTR (parms->ftype) &&
3287 IS_ADDRESS_OF_OP (parms->right))
3288 parms->right->left->lvalue = 1;
3290 parms->opval.oprnd =
3291 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3293 parms->type = EX_OPERAND;
3294 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3295 SPEC_ARGREG(parms->ftype);
3298 /*-----------------------------------------------------------------*/
3299 /* geniCodeParms - generates parameters */
3300 /*-----------------------------------------------------------------*/
3302 geniCodeParms (ast * parms, value *argVals, int *stack,
3303 sym_link * ftype, int lvl)
3311 if (argVals==NULL) {
3313 argVals = FUNC_ARGS (ftype);
3316 /* if this is a param node then do the left & right */
3317 if (parms->type == EX_OP && parms->opval.op == PARAM)
3319 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3320 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3324 /* get the parameter value */
3325 if (parms->type == EX_OPERAND)
3326 pval = parms->opval.oprnd;
3329 /* maybe this else should go away ?? */
3330 /* hack don't like this but too lazy to think of
3332 if (IS_ADDRESS_OF_OP (parms))
3333 parms->left->lvalue = 1;
3335 if (IS_CAST_OP (parms) &&
3336 IS_PTR (parms->ftype) &&
3337 IS_ADDRESS_OF_OP (parms->right))
3338 parms->right->left->lvalue = 1;
3340 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3343 /* if register parm then make it a send */
3344 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3345 IFFUNC_ISBUILTIN(ftype))
3347 ic = newiCode (SEND, pval, NULL);
3348 ic->argreg = SPEC_ARGREG(parms->etype);
3349 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3354 /* now decide whether to push or assign */
3355 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3359 operand *top = operandFromSymbol (argVals->sym);
3360 /* clear useDef and other bitVectors */
3361 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3362 geniCodeAssign (top, pval, 1, 0);
3366 sym_link *p = operandType (pval);
3368 ic = newiCode (IPUSH, pval, NULL);
3370 /* update the stack adjustment */
3371 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3376 argVals=argVals->next;
3380 /*-----------------------------------------------------------------*/
3381 /* geniCodeCall - generates temp code for calling */
3382 /*-----------------------------------------------------------------*/
3384 geniCodeCall (operand * left, ast * parms,int lvl)
3388 sym_link *type, *etype;
3392 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3393 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3394 werror (E_FUNCTION_EXPECTED);
3395 return operandFromValue(valueFromLit(0));
3398 /* take care of parameters with side-effecting
3399 function calls in them, this is required to take care
3400 of overlaying function parameters */
3401 geniCodeSEParms (parms,lvl);
3403 ftype = operandType (left);
3404 if (IS_FUNCPTR (ftype))
3405 ftype = ftype->next;
3407 /* first the parameters */
3408 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3410 /* now call : if symbol then pcall */
3411 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3412 ic = newiCode (PCALL, left, NULL);
3414 ic = newiCode (CALL, left, NULL);
3417 type = copyLinkChain (ftype->next);
3418 etype = getSpec (type);
3419 SPEC_EXTR (etype) = 0;
3420 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3424 /* stack adjustment after call */
3425 ic->parmBytes = stack;
3430 /*-----------------------------------------------------------------*/
3431 /* geniCodeReceive - generate intermediate code for "receive" */
3432 /*-----------------------------------------------------------------*/
3434 geniCodeReceive (value * args, operand * func)
3436 unsigned char paramByteCounter = 0;
3438 /* for all arguments that are passed in registers */
3441 if (IS_REGPARM (args->etype))
3443 operand *opr = operandFromValue (args);
3445 symbol *sym = OP_SYMBOL (opr);
3448 /* we will use it after all optimizations
3449 and before liveRange calculation */
3450 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3453 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3454 options.stackAuto == 0 &&
3455 (!(options.model == MODEL_FLAT24)) )
3460 opl = newiTempOperand (args->type, 0);
3462 sym->reqv->key = sym->key;
3463 OP_SYMBOL (sym->reqv)->key = sym->key;
3464 OP_SYMBOL (sym->reqv)->isreqv = 1;
3465 OP_SYMBOL (sym->reqv)->islocal = 0;
3466 SPIL_LOC (sym->reqv) = sym;
3470 ic = newiCode (RECEIVE, func, NULL);
3471 ic->argreg = SPEC_ARGREG(args->etype);
3472 if (ic->argreg == 1) {
3473 currFunc->recvSize = getSize (sym->type);
3475 IC_RESULT (ic) = opr;
3477 /* misuse of parmBytes (normally used for functions)
3478 * to save estimated stack position of this argument.
3479 * Normally this should be zero for RECEIVE iCodes.
3480 * No idea if this causes side effects on other ports. - dw
3482 ic->parmBytes = paramByteCounter;
3484 /* what stack position do we have? */
3485 paramByteCounter += getSize (sym->type);
3494 /*-----------------------------------------------------------------*/
3495 /* geniCodeFunctionBody - create the function body */
3496 /*-----------------------------------------------------------------*/
3498 geniCodeFunctionBody (ast * tree,int lvl)
3505 /* reset the auto generation */
3511 func = ast2iCode (tree->left,lvl+1);
3512 fetype = getSpec (operandType (func));
3514 savelineno = lineno;
3515 lineno = OP_SYMBOL (func)->lineDef;
3516 /* create an entry label */
3517 geniCodeLabel (entryLabel);
3518 lineno = savelineno;
3520 /* create a proc icode */
3521 ic = newiCode (FUNCTION, func, NULL);
3522 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3527 /* for all parameters that are passed
3528 on registers add a "receive" */
3529 geniCodeReceive (tree->values.args, func);
3531 /* generate code for the body */
3532 ast2iCode (tree->right,lvl+1);
3534 /* create a label for return */
3535 geniCodeLabel (returnLabel);
3537 /* now generate the end proc */
3538 ic = newiCode (ENDFUNCTION, func, NULL);
3544 /*-----------------------------------------------------------------*/
3545 /* geniCodeReturn - gen icode for 'return' statement */
3546 /*-----------------------------------------------------------------*/
3548 geniCodeReturn (operand * op)
3552 /* if the operand is present force an rvalue */
3554 op = geniCodeRValue (op, FALSE);
3556 ic = newiCode (RETURN, op, NULL);
3560 /*-----------------------------------------------------------------*/
3561 /* geniCodeIfx - generates code for extended if statement */
3562 /*-----------------------------------------------------------------*/
3564 geniCodeIfx (ast * tree,int lvl)
3567 operand *condition = ast2iCode (tree->left,lvl+1);
3570 /* if condition is null then exit */
3574 condition = geniCodeRValue (condition, FALSE);
3576 cetype = getSpec (operandType (condition));
3577 /* if the condition is a literal */
3578 if (IS_LITERAL (cetype))
3580 if (floatFromVal (condition->operand.valOperand))
3582 if (tree->trueLabel)
3583 geniCodeGoto (tree->trueLabel);
3589 if (tree->falseLabel)
3590 geniCodeGoto (tree->falseLabel);
3595 if (tree->trueLabel)
3597 ic = newiCodeCondition (condition,
3602 if (tree->falseLabel)
3603 geniCodeGoto (tree->falseLabel);
3607 ic = newiCodeCondition (condition,
3614 ast2iCode (tree->right,lvl+1);
3617 /*-----------------------------------------------------------------*/
3618 /* geniCodeJumpTable - tries to create a jump table for switch */
3619 /*-----------------------------------------------------------------*/
3621 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3623 int min, max, cnt = 1;
3630 int needRangeCheck = !optimize.noJTabBoundary
3631 || tree->values.switchVals.swDefault;
3632 sym_link *cetype = getSpec (operandType (cond));
3633 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3634 int sizeofMatchJump, sizeofJumpTable;
3637 if (!tree || !caseVals)
3640 /* the criteria for creating a jump table is */
3641 /* all integer numbers between the maximum & minimum must */
3642 /* be present , the maximum value should not exceed 255 */
3643 /* If not all integer numbers are present the algorithm */
3644 /* inserts jumps to the default label for the missing numbers */
3645 /* and decides later whether it is worth it */
3646 min = (int) floatFromVal (vch = caseVals);
3653 max = (int) floatFromVal (vch);
3655 /* Exit if the range is too large to handle with a jump table. */
3656 if (1 + max - min > port->jumptableCost.maxCount)
3659 switch (getSize (operandType (cond)))
3661 case 1: sizeIndex = 0; break;
3662 case 2: sizeIndex = 1; break;
3663 case 4: sizeIndex = 2; break;
3667 /* Compute the size cost of the range check and subtraction. */
3669 sizeofZeroMinCost = 0;
3673 if (!(min==0 && IS_UNSIGNED (cetype)))
3674 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3675 if (!IS_UNSIGNED (cetype))
3676 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3677 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3680 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3682 /* If the size cost of handling a non-zero minimum exceeds the */
3683 /* cost of extending the range down to zero, then it might be */
3684 /* better to extend the range to zero. */
3685 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3686 >= (min * port->jumptableCost.sizeofElement))
3688 /* Only extend the jump table if it would still be manageable. */
3689 if (1 + max <= port->jumptableCost.maxCount)
3692 if (IS_UNSIGNED (cetype))
3695 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3699 /* Compute the total size cost of a jump table. */
3700 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3701 + port->jumptableCost.sizeofDispatch
3702 + sizeofMinCost + sizeofMaxCost;
3704 /* Compute the total size cost of a match & jump sequence */
3705 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3707 /* If the size cost of the jump table is uneconomical then exit */
3708 if (sizeofMatchJump < sizeofJumpTable)
3711 /* The jump table is preferable. */
3713 /* First, a label for the default or missing cases. */
3714 if (tree->values.switchVals.swDefault)
3716 SNPRINTF (buffer, sizeof(buffer),
3718 tree->values.switchVals.swNum);
3722 SNPRINTF (buffer, sizeof(buffer),
3724 tree->values.switchVals.swNum);
3726 falseLabel = newiTempLabel (buffer);
3728 /* Build the list of labels for the jump table. */
3730 t = (int) floatFromVal (vch);
3731 for (i=min; i<=max; i++)
3735 /* Explicit case: make a new label for it. */
3736 SNPRINTF (buffer, sizeof(buffer),
3738 tree->values.switchVals.swNum,
3740 addSet (&labels, newiTempLabel (buffer));
3743 t = (int) floatFromVal (vch);
3747 /* Implicit case: use the default label. */
3748 addSet (&labels, falseLabel);
3752 /* first we rule out the boundary conditions */
3753 /* if only optimization says so */
3756 sym_link *cetype = getSpec (operandType (cond));
3757 /* no need to check the lower bound if
3758 the condition is unsigned & minimum value is zero */
3759 if (!(min == 0 && IS_UNSIGNED (cetype)))
3761 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3762 ic = newiCodeCondition (boundary, falseLabel, NULL);
3766 /* now for upper bounds */
3767 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3768 ic = newiCodeCondition (boundary, falseLabel, NULL);
3772 /* if the min is not zero then we no make it zero */
3775 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3776 if (!IS_LITERAL(getSpec(operandType(cond))))
3777 setOperandType (cond, UCHARTYPE);
3780 /* now create the jumptable */
3781 ic = newiCode (JUMPTABLE, NULL, NULL);
3782 IC_JTCOND (ic) = cond;
3783 IC_JTLABELS (ic) = labels;
3788 /*-----------------------------------------------------------------*/
3789 /* geniCodeSwitch - changes a switch to a if statement */
3790 /*-----------------------------------------------------------------*/
3792 geniCodeSwitch (ast * tree,int lvl)
3795 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3796 value *caseVals = tree->values.switchVals.swVals;
3797 symbol *trueLabel, *falseLabel;
3799 /* If the condition is a literal, then just jump to the */
3800 /* appropriate case label. */
3801 if (IS_LITERAL(getSpec(operandType(cond))))
3803 int switchVal, caseVal;
3805 switchVal = (int) floatFromVal (cond->operand.valOperand);
3808 caseVal = (int) floatFromVal (caseVals);
3809 if (caseVal == switchVal)
3811 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3812 tree->values.switchVals.swNum, caseVal);
3813 trueLabel = newiTempLabel (buffer);
3814 geniCodeGoto (trueLabel);
3817 caseVals = caseVals->next;
3819 goto defaultOrBreak;
3822 /* If cond is volatile, it might change while we are trying to */
3823 /* find the matching case. To avoid this possibility, make a */
3824 /* non-volatile copy to use instead. */
3825 if (IS_OP_VOLATILE (cond))
3830 newcond = newiTempOperand (operandType (cond), TRUE);
3831 newcond->isvolatile = 0;
3832 ic = newiCode ('=', NULL, cond);
3833 IC_RESULT (ic) = newcond;
3838 /* if we can make this a jump table */
3839 if (geniCodeJumpTable (cond, caseVals, tree))
3840 goto jumpTable; /* no need for the comparison */
3842 /* for the cases defined do */
3846 operand *compare = geniCodeLogic (cond,
3847 operandFromValue (caseVals),
3850 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3851 tree->values.switchVals.swNum,
3852 (int) floatFromVal (caseVals));
3853 trueLabel = newiTempLabel (buffer);
3855 ic = newiCodeCondition (compare, trueLabel, NULL);
3857 caseVals = caseVals->next;
3862 /* if default is present then goto break else break */
3863 if (tree->values.switchVals.swDefault)
3865 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3869 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3872 falseLabel = newiTempLabel (buffer);
3873 geniCodeGoto (falseLabel);
3876 ast2iCode (tree->right,lvl+1);
3879 /*-----------------------------------------------------------------*/
3880 /* geniCodeInline - intermediate code for inline assembler */
3881 /*-----------------------------------------------------------------*/
3883 geniCodeInline (ast * tree)
3887 ic = newiCode (INLINEASM, NULL, NULL);
3888 IC_INLINE (ic) = tree->values.inlineasm;
3892 /*-----------------------------------------------------------------*/
3893 /* geniCodeArrayInit - intermediate code for array initializer */
3894 /*-----------------------------------------------------------------*/
3896 geniCodeArrayInit (ast * tree, operand *array)
3900 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3901 ic = newiCode (ARRAYINIT, array, NULL);
3902 IC_ARRAYILIST (ic) = tree->values.constlist;
3904 operand *left=newOperand(), *right=newOperand();
3905 left->type=right->type=SYMBOL;
3906 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3907 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3908 ic = newiCode (ARRAYINIT, left, right);
3913 /*-----------------------------------------------------------------*/
3914 /* geniCodeCritical - intermediate code for a critical statement */
3915 /*-----------------------------------------------------------------*/
3917 geniCodeCritical (ast *tree, int lvl)
3923 if (!options.stackAuto)
3925 type = newLink(SPECIFIER);
3926 SPEC_VOLATILE(type) = 1;
3927 SPEC_NOUN(type) = V_BIT;
3928 SPEC_SCLS(type) = S_BIT;
3929 SPEC_BLEN(type) = 1;
3930 SPEC_BSTR(type) = 0;
3931 op = newiTempOperand(type, 1);
3934 /* If op is NULL, the original interrupt state will saved on */
3935 /* the stack. Otherwise, it will be saved in op. */
3937 /* Generate a save of the current interrupt state & disable */
3938 ic = newiCode (CRITICAL, NULL, NULL);
3939 IC_RESULT (ic) = op;
3942 /* Generate the critical code sequence */
3943 if (tree->left && tree->left->type == EX_VALUE)
3944 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3946 ast2iCode (tree->left,lvl+1);
3948 /* Generate a restore of the original interrupt state */
3949 ic = newiCode (ENDCRITICAL, NULL, op);
3953 /*-----------------------------------------------------------------*/
3954 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3955 /* particular case. Ie : assigning or dereferencing array or ptr */
3956 /*-----------------------------------------------------------------*/
3957 set * lvaluereqSet = NULL;
3958 typedef struct lvalItem
3965 /*-----------------------------------------------------------------*/
3966 /* addLvaluereq - add a flag for lvalreq for current ast level */
3967 /*-----------------------------------------------------------------*/
3968 void addLvaluereq(int lvl)
3970 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3973 addSetHead(&lvaluereqSet,lpItem);
3976 /*-----------------------------------------------------------------*/
3977 /* delLvaluereq - del a flag for lvalreq for current ast level */
3978 /*-----------------------------------------------------------------*/
3982 lpItem = getSet(&lvaluereqSet);
3983 if(lpItem) Safe_free(lpItem);
3985 /*-----------------------------------------------------------------*/
3986 /* clearLvaluereq - clear lvalreq flag */
3987 /*-----------------------------------------------------------------*/
3988 void clearLvaluereq()
3991 lpItem = peekSet(lvaluereqSet);
3992 if(lpItem) lpItem->req = 0;
3994 /*-----------------------------------------------------------------*/
3995 /* getLvaluereq - get the last lvalreq level */
3996 /*-----------------------------------------------------------------*/
3997 int getLvaluereqLvl()
4000 lpItem = peekSet(lvaluereqSet);
4001 if(lpItem) return lpItem->lvl;
4004 /*-----------------------------------------------------------------*/
4005 /* isLvaluereq - is lvalreq valid for this level ? */
4006 /*-----------------------------------------------------------------*/
4007 int isLvaluereq(int lvl)
4010 lpItem = peekSet(lvaluereqSet);
4011 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4015 /*-----------------------------------------------------------------*/
4016 /* ast2iCode - creates an icodeList from an ast */
4017 /*-----------------------------------------------------------------*/
4019 ast2iCode (ast * tree,int lvl)
4021 operand *left = NULL;
4022 operand *right = NULL;
4026 /* set the global variables for filename & line number */
4028 filename = tree->filename;
4030 lineno = tree->lineno;
4032 block = tree->block;
4034 scopeLevel = tree->level;
4036 seqPoint = tree->seqPoint;
4038 if (tree->type == EX_VALUE)
4039 return operandFromValue (tree->opval.val);
4041 if (tree->type == EX_LINK)
4042 return operandFromLink (tree->opval.lnk);
4044 /* if we find a nullop */
4045 if (tree->type == EX_OP &&
4046 (tree->opval.op == NULLOP ||
4047 tree->opval.op == BLOCK))
4049 if (tree->left && tree->left->type == EX_VALUE)
4050 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4052 ast2iCode (tree->left,lvl+1);
4053 if (tree->right && tree->right->type == EX_VALUE)
4054 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4056 ast2iCode (tree->right,lvl+1);
4060 /* special cases for not evaluating */
4061 if (tree->opval.op != ':' &&
4062 tree->opval.op != '?' &&
4063 tree->opval.op != CALL &&
4064 tree->opval.op != IFX &&
4065 tree->opval.op != AND_OP &&
4066 tree->opval.op != OR_OP &&
4067 tree->opval.op != LABEL &&
4068 tree->opval.op != GOTO &&
4069 tree->opval.op != SWITCH &&
4070 tree->opval.op != FUNCTION &&
4071 tree->opval.op != INLINEASM &&
4072 tree->opval.op != CRITICAL)
4075 if (IS_ASSIGN_OP (tree->opval.op) ||
4076 IS_DEREF_OP (tree) ||
4077 (tree->opval.op == '&' && !tree->right) ||
4078 tree->opval.op == PTR_OP)
4081 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4082 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4085 left = operandFromAst (tree->left,lvl);
4087 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4088 left = geniCodeRValue (left, TRUE);
4092 left = operandFromAst (tree->left,lvl);
4094 if (tree->opval.op == INC_OP ||
4095 tree->opval.op == DEC_OP)
4098 right = operandFromAst (tree->right,lvl);
4103 right = operandFromAst (tree->right,lvl);
4107 /* now depending on the type of operand */
4108 /* this will be a biggy */
4109 switch (tree->opval.op)
4112 case '[': /* array operation */
4114 //sym_link *ltype = operandType (left);
4115 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4116 left = geniCodeRValue (left, FALSE);
4117 right = geniCodeRValue (right, TRUE);
4120 return geniCodeArray (left, right,lvl);
4122 case '.': /* structure dereference */
4123 if (IS_PTR (operandType (left)))
4124 left = geniCodeRValue (left, TRUE);
4126 left = geniCodeRValue (left, FALSE);
4128 return geniCodeStruct (left, right, tree->lvalue);
4130 case PTR_OP: /* structure pointer dereference */
4133 pType = operandType (left);
4134 left = geniCodeRValue (left, TRUE);
4136 setOClass (pType, getSpec (operandType (left)));
4139 return geniCodeStruct (left, right, tree->lvalue);
4141 case INC_OP: /* increment operator */
4143 return geniCodePostInc (left);
4145 return geniCodePreInc (right, tree->lvalue);
4147 case DEC_OP: /* decrement operator */
4149 return geniCodePostDec (left);
4151 return geniCodePreDec (right, tree->lvalue);
4153 case '&': /* bitwise and or address of operator */
4155 { /* this is a bitwise operator */
4156 left = geniCodeRValue (left, FALSE);
4157 right = geniCodeRValue (right, FALSE);
4158 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4161 return geniCodeAddressOf (left);
4163 case '|': /* bitwise or & xor */
4165 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4166 geniCodeRValue (right, FALSE),
4171 return geniCodeDivision (geniCodeRValue (left, FALSE),
4172 geniCodeRValue (right, FALSE),
4173 getResultTypeFromType (tree->ftype));
4176 return geniCodeModulus (geniCodeRValue (left, FALSE),
4177 geniCodeRValue (right, FALSE),
4178 getResultTypeFromType (tree->ftype));
4181 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4182 geniCodeRValue (right, FALSE),
4183 getResultTypeFromType (tree->ftype));
4185 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4189 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4190 geniCodeRValue (right, FALSE),
4191 getResultTypeFromType (tree->ftype));
4193 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4197 return geniCodeAdd (geniCodeRValue (left, FALSE),
4198 geniCodeRValue (right, FALSE),
4199 getResultTypeFromType (tree->ftype),
4202 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4205 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4206 geniCodeRValue (right, FALSE),
4207 getResultTypeFromType (tree->ftype));
4210 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4211 geniCodeRValue (right, FALSE));
4213 #if 0 // this indeed needs a second thought
4217 // let's keep this simple: get the rvalue we need
4218 op=geniCodeRValue (right, FALSE);
4219 // now cast it to whatever we want
4220 op=geniCodeCast (operandType(left), op, FALSE);
4221 // if this is going to be used as an lvalue, make it so
4227 #else // bug #604575, is it a bug ????
4228 return geniCodeCast (operandType (left),
4229 geniCodeRValue (right, FALSE), FALSE);
4236 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4241 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4242 if (!IS_BIT (operandType (op)))
4243 setOperandType (op, UCHARTYPE);
4248 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4249 geniCodeRValue (right, FALSE),
4251 if (!IS_BIT (operandType (op)))
4252 setOperandType (op, UCHARTYPE);
4257 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4258 geniCodeRValue (right, FALSE),
4260 setOperandType (op, UCHARTYPE);
4265 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4266 geniCodeRValue (right, FALSE),
4268 setOperandType (op, UINTTYPE);
4273 return geniCodeLogicAndOr (tree, lvl);
4280 /* different compilers (even different gccs) evaluate
4281 the two calls in a different order. to get the same
4282 result on all machines we have to specify a clear sequence.
4283 return geniCodeLogic (geniCodeRValue (left, FALSE),
4284 geniCodeRValue (right, FALSE),
4288 operand *leftOp, *rightOp;
4290 leftOp = geniCodeRValue (left , FALSE);
4291 rightOp = geniCodeRValue (right, FALSE);
4293 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4296 return geniCodeConditional (tree,lvl);
4299 return operandFromLit (getSize (tree->right->ftype));
4303 sym_link *rtype = operandType (right);
4304 sym_link *ltype = operandType (left);
4305 if (IS_PTR (rtype) && IS_ITEMP (right)
4306 && right->isaddr && compareType (rtype->next, ltype) == 1)
4307 right = geniCodeRValue (right, TRUE);
4309 right = geniCodeRValue (right, FALSE);
4311 return geniCodeAssign (left, right, 0, 1);
4315 geniCodeAssign (left,
4316 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4318 geniCodeRValue (right, FALSE),
4319 getResultTypeFromType (tree->ftype)),
4324 geniCodeAssign (left,
4325 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4327 geniCodeRValue (right, FALSE),
4328 getResultTypeFromType (tree->ftype)),
4332 geniCodeAssign (left,
4333 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4335 geniCodeRValue (right, FALSE),
4336 getResultTypeFromType (tree->ftype)),
4340 sym_link *rtype = operandType (right);
4341 sym_link *ltype = operandType (left);
4342 if (IS_PTR (rtype) && IS_ITEMP (right)
4343 && right->isaddr && compareType (rtype->next, ltype) == 1)
4344 right = geniCodeRValue (right, TRUE);
4346 right = geniCodeRValue (right, FALSE);
4349 return geniCodeAssign (left,
4350 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4353 getResultTypeFromType (tree->ftype),
4359 sym_link *rtype = operandType (right);
4360 sym_link *ltype = operandType (left);
4361 if (IS_PTR (rtype) && IS_ITEMP (right)
4362 && right->isaddr && compareType (rtype->next, ltype) == 1)
4364 right = geniCodeRValue (right, TRUE);
4368 right = geniCodeRValue (right, FALSE);
4371 geniCodeAssign (left,
4372 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4375 getResultTypeFromType (tree->ftype)),
4380 geniCodeAssign (left,
4381 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4383 geniCodeRValue (right, FALSE),
4384 getResultTypeFromType (tree->ftype)),
4388 geniCodeAssign (left,
4389 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4391 geniCodeRValue (right, FALSE)), 0, 1);
4394 geniCodeAssign (left,
4395 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4397 geniCodeRValue (right, FALSE),
4399 operandType (left)), 0, 1);
4402 geniCodeAssign (left,
4403 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4405 geniCodeRValue (right, FALSE),
4407 operandType (left)), 0, 1);
4410 geniCodeAssign (left,
4411 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4413 geniCodeRValue (right, FALSE),
4415 operandType (left)), 0, 1);
4417 return geniCodeRValue (right, FALSE);
4420 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4423 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4424 return ast2iCode (tree->right,lvl+1);
4427 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4428 return ast2iCode (tree->right,lvl+1);
4431 geniCodeFunctionBody (tree,lvl);
4435 geniCodeReturn (right);
4439 geniCodeIfx (tree,lvl);
4443 geniCodeSwitch (tree,lvl);
4447 geniCodeInline (tree);
4451 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4455 geniCodeCritical (tree, lvl);
4461 /*-----------------------------------------------------------------*/
4462 /* reverseICChain - gets from the list and creates a linkedlist */
4463 /*-----------------------------------------------------------------*/
4470 while ((loop = getSet (&iCodeChain)))
4482 /*-----------------------------------------------------------------*/
4483 /* iCodeFromAst - given an ast will convert it to iCode */
4484 /*-----------------------------------------------------------------*/
4486 iCodeFromAst (ast * tree)
4488 returnLabel = newiTempLabel ("_return");
4489 entryLabel = newiTempLabel ("_entry");
4491 return reverseiCChain ();
4494 static const char *opTypeToStr(OPTYPE op)
4498 case SYMBOL: return "symbol";
4499 case VALUE: return "value";
4500 case TYPE: return "type";
4502 return "undefined type";
4506 operand *validateOpType(operand *op,
4513 if (op && op->type == type)
4518 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4519 " expected %s, got %s\n",
4520 macro, args, file, line,
4521 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4523 return op; // never reached, makes compiler happy.