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;
3244 /*-----------------------------------------------------------------*/
3245 /* geniCodeDummyRead - generate code for dummy read */
3246 /*-----------------------------------------------------------------*/
3248 geniCodeDummyRead (operand * op)
3251 sym_link *type = operandType (op);
3253 if (!IS_VOLATILE(type))
3256 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3262 /*-----------------------------------------------------------------*/
3263 /* geniCodeSEParms - generate code for side effecting fcalls */
3264 /*-----------------------------------------------------------------*/
3266 geniCodeSEParms (ast * parms,int lvl)
3271 if (parms->type == EX_OP && parms->opval.op == PARAM)
3273 geniCodeSEParms (parms->left,lvl);
3274 geniCodeSEParms (parms->right,lvl);
3278 /* hack don't like this but too lazy to think of
3280 if (IS_ADDRESS_OF_OP (parms))
3281 parms->left->lvalue = 1;
3283 if (IS_CAST_OP (parms) &&
3284 IS_PTR (parms->ftype) &&
3285 IS_ADDRESS_OF_OP (parms->right))
3286 parms->right->left->lvalue = 1;
3288 parms->opval.oprnd =
3289 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3291 parms->type = EX_OPERAND;
3292 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3293 SPEC_ARGREG(parms->ftype);
3296 /*-----------------------------------------------------------------*/
3297 /* geniCodeParms - generates parameters */
3298 /*-----------------------------------------------------------------*/
3300 geniCodeParms (ast * parms, value *argVals, int *stack,
3301 sym_link * ftype, int lvl)
3309 if (argVals==NULL) {
3311 argVals = FUNC_ARGS (ftype);
3314 /* if this is a param node then do the left & right */
3315 if (parms->type == EX_OP && parms->opval.op == PARAM)
3317 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3318 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3322 /* get the parameter value */
3323 if (parms->type == EX_OPERAND)
3324 pval = parms->opval.oprnd;
3327 /* maybe this else should go away ?? */
3328 /* hack don't like this but too lazy to think of
3330 if (IS_ADDRESS_OF_OP (parms))
3331 parms->left->lvalue = 1;
3333 if (IS_CAST_OP (parms) &&
3334 IS_PTR (parms->ftype) &&
3335 IS_ADDRESS_OF_OP (parms->right))
3336 parms->right->left->lvalue = 1;
3338 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3341 /* if register parm then make it a send */
3342 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3343 IFFUNC_ISBUILTIN(ftype))
3345 ic = newiCode (SEND, pval, NULL);
3346 ic->argreg = SPEC_ARGREG(parms->etype);
3347 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3352 /* now decide whether to push or assign */
3353 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3357 operand *top = operandFromSymbol (argVals->sym);
3358 /* clear useDef and other bitVectors */
3359 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3360 geniCodeAssign (top, pval, 1, 0);
3364 sym_link *p = operandType (pval);
3366 ic = newiCode (IPUSH, pval, NULL);
3368 /* update the stack adjustment */
3369 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3374 argVals=argVals->next;
3378 /*-----------------------------------------------------------------*/
3379 /* geniCodeCall - generates temp code for calling */
3380 /*-----------------------------------------------------------------*/
3382 geniCodeCall (operand * left, ast * parms,int lvl)
3386 sym_link *type, *etype;
3390 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3391 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3392 werror (E_FUNCTION_EXPECTED);
3393 return operandFromValue(valueFromLit(0));
3396 /* take care of parameters with side-effecting
3397 function calls in them, this is required to take care
3398 of overlaying function parameters */
3399 geniCodeSEParms (parms,lvl);
3401 ftype = operandType (left);
3402 if (IS_FUNCPTR (ftype))
3403 ftype = ftype->next;
3405 /* first the parameters */
3406 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3408 /* now call : if symbol then pcall */
3409 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3410 ic = newiCode (PCALL, left, NULL);
3412 ic = newiCode (CALL, left, NULL);
3415 type = copyLinkChain (ftype->next);
3416 etype = getSpec (type);
3417 SPEC_EXTR (etype) = 0;
3418 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3422 /* stack adjustment after call */
3423 ic->parmBytes = stack;
3428 /*-----------------------------------------------------------------*/
3429 /* geniCodeReceive - generate intermediate code for "receive" */
3430 /*-----------------------------------------------------------------*/
3432 geniCodeReceive (value * args, operand * func)
3434 unsigned char paramByteCounter = 0;
3436 /* for all arguments that are passed in registers */
3439 if (IS_REGPARM (args->etype))
3441 operand *opr = operandFromValue (args);
3443 symbol *sym = OP_SYMBOL (opr);
3446 /* we will use it after all optimizations
3447 and before liveRange calculation */
3448 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3451 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3452 options.stackAuto == 0 &&
3453 (!(options.model == MODEL_FLAT24)) )
3458 opl = newiTempOperand (args->type, 0);
3460 sym->reqv->key = sym->key;
3461 OP_SYMBOL (sym->reqv)->key = sym->key;
3462 OP_SYMBOL (sym->reqv)->isreqv = 1;
3463 OP_SYMBOL (sym->reqv)->islocal = 0;
3464 SPIL_LOC (sym->reqv) = sym;
3468 ic = newiCode (RECEIVE, func, NULL);
3469 ic->argreg = SPEC_ARGREG(args->etype);
3470 if (ic->argreg == 1) {
3471 currFunc->recvSize = getSize (sym->type);
3473 IC_RESULT (ic) = opr;
3475 /* misuse of parmBytes (normally used for functions)
3476 * to save estimated stack position of this argument.
3477 * Normally this should be zero for RECEIVE iCodes.
3478 * No idea if this causes side effects on other ports. - dw
3480 ic->parmBytes = paramByteCounter;
3482 /* what stack position do we have? */
3483 paramByteCounter += getSize (sym->type);
3492 /*-----------------------------------------------------------------*/
3493 /* geniCodeFunctionBody - create the function body */
3494 /*-----------------------------------------------------------------*/
3496 geniCodeFunctionBody (ast * tree,int lvl)
3503 /* reset the auto generation */
3509 func = ast2iCode (tree->left,lvl+1);
3510 fetype = getSpec (operandType (func));
3512 savelineno = lineno;
3513 lineno = OP_SYMBOL (func)->lineDef;
3514 /* create an entry label */
3515 geniCodeLabel (entryLabel);
3516 lineno = savelineno;
3518 /* create a proc icode */
3519 ic = newiCode (FUNCTION, func, NULL);
3520 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3525 /* for all parameters that are passed
3526 on registers add a "receive" */
3527 geniCodeReceive (tree->values.args, func);
3529 /* generate code for the body */
3530 ast2iCode (tree->right,lvl+1);
3532 /* create a label for return */
3533 geniCodeLabel (returnLabel);
3535 /* now generate the end proc */
3536 ic = newiCode (ENDFUNCTION, func, NULL);
3542 /*-----------------------------------------------------------------*/
3543 /* geniCodeReturn - gen icode for 'return' statement */
3544 /*-----------------------------------------------------------------*/
3546 geniCodeReturn (operand * op)
3550 /* if the operand is present force an rvalue */
3552 op = geniCodeRValue (op, FALSE);
3554 ic = newiCode (RETURN, op, NULL);
3558 /*-----------------------------------------------------------------*/
3559 /* geniCodeIfx - generates code for extended if statement */
3560 /*-----------------------------------------------------------------*/
3562 geniCodeIfx (ast * tree,int lvl)
3565 operand *condition = ast2iCode (tree->left,lvl+1);
3568 /* if condition is null then exit */
3572 condition = geniCodeRValue (condition, FALSE);
3574 cetype = getSpec (operandType (condition));
3575 /* if the condition is a literal */
3576 if (IS_LITERAL (cetype))
3578 if (floatFromVal (condition->operand.valOperand))
3580 if (tree->trueLabel)
3581 geniCodeGoto (tree->trueLabel);
3587 if (tree->falseLabel)
3588 geniCodeGoto (tree->falseLabel);
3593 if (tree->trueLabel)
3595 ic = newiCodeCondition (condition,
3600 if (tree->falseLabel)
3601 geniCodeGoto (tree->falseLabel);
3605 ic = newiCodeCondition (condition,
3612 ast2iCode (tree->right,lvl+1);
3615 /*-----------------------------------------------------------------*/
3616 /* geniCodeJumpTable - tries to create a jump table for switch */
3617 /*-----------------------------------------------------------------*/
3619 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3621 int min, max, cnt = 1;
3628 int needRangeCheck = !optimize.noJTabBoundary
3629 || tree->values.switchVals.swDefault;
3630 sym_link *cetype = getSpec (operandType (cond));
3631 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3632 int sizeofMatchJump, sizeofJumpTable;
3635 if (!tree || !caseVals)
3638 /* the criteria for creating a jump table is */
3639 /* all integer numbers between the maximum & minimum must */
3640 /* be present , the maximum value should not exceed 255 */
3641 /* If not all integer numbers are present the algorithm */
3642 /* inserts jumps to the default label for the missing numbers */
3643 /* and decides later whether it is worth it */
3644 min = (int) floatFromVal (vch = caseVals);
3651 max = (int) floatFromVal (vch);
3653 /* Exit if the range is too large to handle with a jump table. */
3654 if (1 + max - min > port->jumptableCost.maxCount)
3657 switch (getSize (operandType (cond)))
3659 case 1: sizeIndex = 0; break;
3660 case 2: sizeIndex = 1; break;
3661 case 4: sizeIndex = 2; break;
3665 /* Compute the size cost of the range check and subtraction. */
3667 sizeofZeroMinCost = 0;
3671 if (!(min==0 && IS_UNSIGNED (cetype)))
3672 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3673 if (!IS_UNSIGNED (cetype))
3674 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3675 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3678 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3680 /* If the size cost of handling a non-zero minimum exceeds the */
3681 /* cost of extending the range down to zero, then it might be */
3682 /* better to extend the range to zero. */
3683 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3684 >= (min * port->jumptableCost.sizeofElement))
3686 /* Only extend the jump table if it would still be manageable. */
3687 if (1 + max <= port->jumptableCost.maxCount)
3690 if (IS_UNSIGNED (cetype))
3693 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3697 /* Compute the total size cost of a jump table. */
3698 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3699 + port->jumptableCost.sizeofDispatch
3700 + sizeofMinCost + sizeofMaxCost;
3702 /* Compute the total size cost of a match & jump sequence */
3703 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3705 /* If the size cost of the jump table is uneconomical then exit */
3706 if (sizeofMatchJump < sizeofJumpTable)
3709 /* The jump table is preferable. */
3711 /* First, a label for the default or missing cases. */
3712 if (tree->values.switchVals.swDefault)
3714 SNPRINTF (buffer, sizeof(buffer),
3716 tree->values.switchVals.swNum);
3720 SNPRINTF (buffer, sizeof(buffer),
3722 tree->values.switchVals.swNum);
3724 falseLabel = newiTempLabel (buffer);
3726 /* Build the list of labels for the jump table. */
3728 t = (int) floatFromVal (vch);
3729 for (i=min; i<=max; i++)
3733 /* Explicit case: make a new label for it. */
3734 SNPRINTF (buffer, sizeof(buffer),
3736 tree->values.switchVals.swNum,
3738 addSet (&labels, newiTempLabel (buffer));
3741 t = (int) floatFromVal (vch);
3745 /* Implicit case: use the default label. */
3746 addSet (&labels, falseLabel);
3750 /* first we rule out the boundary conditions */
3751 /* if only optimization says so */
3754 sym_link *cetype = getSpec (operandType (cond));
3755 /* no need to check the lower bound if
3756 the condition is unsigned & minimum value is zero */
3757 if (!(min == 0 && IS_UNSIGNED (cetype)))
3759 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3760 ic = newiCodeCondition (boundary, falseLabel, NULL);
3764 /* now for upper bounds */
3765 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3766 ic = newiCodeCondition (boundary, falseLabel, NULL);
3770 /* if the min is not zero then we no make it zero */
3773 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3774 if (!IS_LITERAL(getSpec(operandType(cond))))
3775 setOperandType (cond, UCHARTYPE);
3778 /* now create the jumptable */
3779 ic = newiCode (JUMPTABLE, NULL, NULL);
3780 IC_JTCOND (ic) = cond;
3781 IC_JTLABELS (ic) = labels;
3786 /*-----------------------------------------------------------------*/
3787 /* geniCodeSwitch - changes a switch to a if statement */
3788 /*-----------------------------------------------------------------*/
3790 geniCodeSwitch (ast * tree,int lvl)
3793 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3794 value *caseVals = tree->values.switchVals.swVals;
3795 symbol *trueLabel, *falseLabel;
3797 /* If the condition is a literal, then just jump to the */
3798 /* appropriate case label. */
3799 if (IS_LITERAL(getSpec(operandType(cond))))
3801 int switchVal, caseVal;
3803 switchVal = (int) floatFromVal (cond->operand.valOperand);
3806 caseVal = (int) floatFromVal (caseVals);
3807 if (caseVal == switchVal)
3809 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3810 tree->values.switchVals.swNum, caseVal);
3811 trueLabel = newiTempLabel (buffer);
3812 geniCodeGoto (trueLabel);
3815 caseVals = caseVals->next;
3817 goto defaultOrBreak;
3820 /* If cond is volatile, it might change while we are trying to */
3821 /* find the matching case. To avoid this possibility, make a */
3822 /* non-volatile copy to use instead. */
3823 if (IS_OP_VOLATILE (cond))
3828 newcond = newiTempOperand (operandType (cond), TRUE);
3829 newcond->isvolatile = 0;
3830 ic = newiCode ('=', NULL, cond);
3831 IC_RESULT (ic) = newcond;
3836 /* if we can make this a jump table */
3837 if (geniCodeJumpTable (cond, caseVals, tree))
3838 goto jumpTable; /* no need for the comparison */
3840 /* for the cases defined do */
3844 operand *compare = geniCodeLogic (cond,
3845 operandFromValue (caseVals),
3848 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3849 tree->values.switchVals.swNum,
3850 (int) floatFromVal (caseVals));
3851 trueLabel = newiTempLabel (buffer);
3853 ic = newiCodeCondition (compare, trueLabel, NULL);
3855 caseVals = caseVals->next;
3860 /* if default is present then goto break else break */
3861 if (tree->values.switchVals.swDefault)
3863 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3867 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3870 falseLabel = newiTempLabel (buffer);
3871 geniCodeGoto (falseLabel);
3874 ast2iCode (tree->right,lvl+1);
3877 /*-----------------------------------------------------------------*/
3878 /* geniCodeInline - intermediate code for inline assembler */
3879 /*-----------------------------------------------------------------*/
3881 geniCodeInline (ast * tree)
3885 ic = newiCode (INLINEASM, NULL, NULL);
3886 IC_INLINE (ic) = tree->values.inlineasm;
3890 /*-----------------------------------------------------------------*/
3891 /* geniCodeArrayInit - intermediate code for array initializer */
3892 /*-----------------------------------------------------------------*/
3894 geniCodeArrayInit (ast * tree, operand *array)
3898 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3899 ic = newiCode (ARRAYINIT, array, NULL);
3900 IC_ARRAYILIST (ic) = tree->values.constlist;
3902 operand *left=newOperand(), *right=newOperand();
3903 left->type=right->type=SYMBOL;
3904 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3905 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3906 ic = newiCode (ARRAYINIT, left, right);
3911 /*-----------------------------------------------------------------*/
3912 /* geniCodeCritical - intermediate code for a critical statement */
3913 /*-----------------------------------------------------------------*/
3915 geniCodeCritical (ast *tree, int lvl)
3921 if (!options.stackAuto)
3923 type = newLink(SPECIFIER);
3924 SPEC_VOLATILE(type) = 1;
3925 SPEC_NOUN(type) = V_BIT;
3926 SPEC_SCLS(type) = S_BIT;
3927 SPEC_BLEN(type) = 1;
3928 SPEC_BSTR(type) = 0;
3929 op = newiTempOperand(type, 1);
3932 /* If op is NULL, the original interrupt state will saved on */
3933 /* the stack. Otherwise, it will be saved in op. */
3935 /* Generate a save of the current interrupt state & disable */
3936 ic = newiCode (CRITICAL, NULL, NULL);
3937 IC_RESULT (ic) = op;
3940 /* Generate the critical code sequence */
3941 if (tree->left && tree->left->type == EX_VALUE)
3942 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3944 ast2iCode (tree->left,lvl+1);
3946 /* Generate a restore of the original interrupt state */
3947 ic = newiCode (ENDCRITICAL, NULL, op);
3951 /*-----------------------------------------------------------------*/
3952 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3953 /* particular case. Ie : assigning or dereferencing array or ptr */
3954 /*-----------------------------------------------------------------*/
3955 set * lvaluereqSet = NULL;
3956 typedef struct lvalItem
3963 /*-----------------------------------------------------------------*/
3964 /* addLvaluereq - add a flag for lvalreq for current ast level */
3965 /*-----------------------------------------------------------------*/
3966 void addLvaluereq(int lvl)
3968 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3971 addSetHead(&lvaluereqSet,lpItem);
3974 /*-----------------------------------------------------------------*/
3975 /* delLvaluereq - del a flag for lvalreq for current ast level */
3976 /*-----------------------------------------------------------------*/
3980 lpItem = getSet(&lvaluereqSet);
3981 if(lpItem) Safe_free(lpItem);
3983 /*-----------------------------------------------------------------*/
3984 /* clearLvaluereq - clear lvalreq flag */
3985 /*-----------------------------------------------------------------*/
3986 void clearLvaluereq()
3989 lpItem = peekSet(lvaluereqSet);
3990 if(lpItem) lpItem->req = 0;
3992 /*-----------------------------------------------------------------*/
3993 /* getLvaluereq - get the last lvalreq level */
3994 /*-----------------------------------------------------------------*/
3995 int getLvaluereqLvl()
3998 lpItem = peekSet(lvaluereqSet);
3999 if(lpItem) return lpItem->lvl;
4002 /*-----------------------------------------------------------------*/
4003 /* isLvaluereq - is lvalreq valid for this level ? */
4004 /*-----------------------------------------------------------------*/
4005 int isLvaluereq(int lvl)
4008 lpItem = peekSet(lvaluereqSet);
4009 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4013 /*-----------------------------------------------------------------*/
4014 /* ast2iCode - creates an icodeList from an ast */
4015 /*-----------------------------------------------------------------*/
4017 ast2iCode (ast * tree,int lvl)
4019 operand *left = NULL;
4020 operand *right = NULL;
4024 /* set the global variables for filename & line number */
4026 filename = tree->filename;
4028 lineno = tree->lineno;
4030 block = tree->block;
4032 scopeLevel = tree->level;
4034 seqPoint = tree->seqPoint;
4036 if (tree->type == EX_VALUE)
4037 return operandFromValue (tree->opval.val);
4039 if (tree->type == EX_LINK)
4040 return operandFromLink (tree->opval.lnk);
4042 /* if we find a nullop */
4043 if (tree->type == EX_OP &&
4044 (tree->opval.op == NULLOP ||
4045 tree->opval.op == BLOCK))
4047 if (tree->left && tree->left->type == EX_VALUE)
4048 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4050 ast2iCode (tree->left,lvl+1);
4051 if (tree->right && tree->right->type == EX_VALUE)
4052 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4054 ast2iCode (tree->right,lvl+1);
4058 /* special cases for not evaluating */
4059 if (tree->opval.op != ':' &&
4060 tree->opval.op != '?' &&
4061 tree->opval.op != CALL &&
4062 tree->opval.op != IFX &&
4063 tree->opval.op != AND_OP &&
4064 tree->opval.op != OR_OP &&
4065 tree->opval.op != LABEL &&
4066 tree->opval.op != GOTO &&
4067 tree->opval.op != SWITCH &&
4068 tree->opval.op != FUNCTION &&
4069 tree->opval.op != INLINEASM &&
4070 tree->opval.op != CRITICAL)
4073 if (IS_ASSIGN_OP (tree->opval.op) ||
4074 IS_DEREF_OP (tree) ||
4075 (tree->opval.op == '&' && !tree->right) ||
4076 tree->opval.op == PTR_OP)
4079 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4080 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4083 left = operandFromAst (tree->left,lvl);
4085 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4086 left = geniCodeRValue (left, TRUE);
4090 left = operandFromAst (tree->left,lvl);
4092 if (tree->opval.op == INC_OP ||
4093 tree->opval.op == DEC_OP)
4096 right = operandFromAst (tree->right,lvl);
4101 right = operandFromAst (tree->right,lvl);
4105 /* now depending on the type of operand */
4106 /* this will be a biggy */
4107 switch (tree->opval.op)
4110 case '[': /* array operation */
4112 //sym_link *ltype = operandType (left);
4113 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4114 left = geniCodeRValue (left, FALSE);
4115 right = geniCodeRValue (right, TRUE);
4118 return geniCodeArray (left, right,lvl);
4120 case '.': /* structure dereference */
4121 if (IS_PTR (operandType (left)))
4122 left = geniCodeRValue (left, TRUE);
4124 left = geniCodeRValue (left, FALSE);
4126 return geniCodeStruct (left, right, tree->lvalue);
4128 case PTR_OP: /* structure pointer dereference */
4131 pType = operandType (left);
4132 left = geniCodeRValue (left, TRUE);
4134 setOClass (pType, getSpec (operandType (left)));
4137 return geniCodeStruct (left, right, tree->lvalue);
4139 case INC_OP: /* increment operator */
4141 return geniCodePostInc (left);
4143 return geniCodePreInc (right, tree->lvalue);
4145 case DEC_OP: /* decrement operator */
4147 return geniCodePostDec (left);
4149 return geniCodePreDec (right, tree->lvalue);
4151 case '&': /* bitwise and or address of operator */
4153 { /* this is a bitwise operator */
4154 left = geniCodeRValue (left, FALSE);
4155 right = geniCodeRValue (right, FALSE);
4156 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4159 return geniCodeAddressOf (left);
4161 case '|': /* bitwise or & xor */
4163 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4164 geniCodeRValue (right, FALSE),
4169 return geniCodeDivision (geniCodeRValue (left, FALSE),
4170 geniCodeRValue (right, FALSE),
4171 getResultTypeFromType (tree->ftype));
4174 return geniCodeModulus (geniCodeRValue (left, FALSE),
4175 geniCodeRValue (right, FALSE),
4176 getResultTypeFromType (tree->ftype));
4179 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4180 geniCodeRValue (right, FALSE),
4181 getResultTypeFromType (tree->ftype));
4183 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4187 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4188 geniCodeRValue (right, FALSE),
4189 getResultTypeFromType (tree->ftype));
4191 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4195 return geniCodeAdd (geniCodeRValue (left, FALSE),
4196 geniCodeRValue (right, FALSE),
4197 getResultTypeFromType (tree->ftype),
4200 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4203 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4204 geniCodeRValue (right, FALSE),
4205 getResultTypeFromType (tree->ftype));
4208 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4209 geniCodeRValue (right, FALSE));
4211 #if 0 // this indeed needs a second thought
4215 // let's keep this simple: get the rvalue we need
4216 op=geniCodeRValue (right, FALSE);
4217 // now cast it to whatever we want
4218 op=geniCodeCast (operandType(left), op, FALSE);
4219 // if this is going to be used as an lvalue, make it so
4225 #else // bug #604575, is it a bug ????
4226 return geniCodeCast (operandType (left),
4227 geniCodeRValue (right, FALSE), FALSE);
4234 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4239 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4240 setOperandType (op, UCHARTYPE);
4247 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4248 geniCodeRValue (right, FALSE),
4250 setOperandType (op, (tree->opval.op == GETWORD) ? UINTTYPE : UCHARTYPE);
4255 return geniCodeLogicAndOr (tree, lvl);
4262 /* different compilers (even different gccs) evaluate
4263 the two calls in a different order. to get the same
4264 result on all machines we've to specify a clear sequence.
4265 return geniCodeLogic (geniCodeRValue (left, FALSE),
4266 geniCodeRValue (right, FALSE),
4270 operand *leftOp, *rightOp;
4272 leftOp = geniCodeRValue (left , FALSE);
4273 rightOp = geniCodeRValue (right, FALSE);
4275 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4278 return geniCodeConditional (tree,lvl);
4281 return operandFromLit (getSize (tree->right->ftype));
4285 sym_link *rtype = operandType (right);
4286 sym_link *ltype = operandType (left);
4287 if (IS_PTR (rtype) && IS_ITEMP (right)
4288 && right->isaddr && compareType (rtype->next, ltype) == 1)
4289 right = geniCodeRValue (right, TRUE);
4291 right = geniCodeRValue (right, FALSE);
4293 geniCodeAssign (left, right, 0, 1);
4298 geniCodeAssign (left,
4299 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4301 geniCodeRValue (right, FALSE),
4302 getResultTypeFromType (tree->ftype)),
4307 geniCodeAssign (left,
4308 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4310 geniCodeRValue (right, FALSE),
4311 getResultTypeFromType (tree->ftype)),
4315 geniCodeAssign (left,
4316 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4318 geniCodeRValue (right, FALSE),
4319 getResultTypeFromType (tree->ftype)),
4323 sym_link *rtype = operandType (right);
4324 sym_link *ltype = operandType (left);
4325 if (IS_PTR (rtype) && IS_ITEMP (right)
4326 && right->isaddr && compareType (rtype->next, ltype) == 1)
4327 right = geniCodeRValue (right, TRUE);
4329 right = geniCodeRValue (right, FALSE);
4332 return geniCodeAssign (left,
4333 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4336 getResultTypeFromType (tree->ftype),
4342 sym_link *rtype = operandType (right);
4343 sym_link *ltype = operandType (left);
4344 if (IS_PTR (rtype) && IS_ITEMP (right)
4345 && right->isaddr && compareType (rtype->next, ltype) == 1)
4347 right = geniCodeRValue (right, TRUE);
4351 right = geniCodeRValue (right, FALSE);
4354 geniCodeAssign (left,
4355 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4358 getResultTypeFromType (tree->ftype)),
4363 geniCodeAssign (left,
4364 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4366 geniCodeRValue (right, FALSE),
4367 getResultTypeFromType (tree->ftype)),
4371 geniCodeAssign (left,
4372 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4374 geniCodeRValue (right, FALSE)), 0, 1);
4377 geniCodeAssign (left,
4378 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4380 geniCodeRValue (right, FALSE),
4382 operandType (left)), 0, 1);
4385 geniCodeAssign (left,
4386 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4388 geniCodeRValue (right, FALSE),
4390 operandType (left)), 0, 1);
4393 geniCodeAssign (left,
4394 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4396 geniCodeRValue (right, FALSE),
4398 operandType (left)), 0, 1);
4400 return geniCodeRValue (right, FALSE);
4403 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4406 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4407 return ast2iCode (tree->right,lvl+1);
4410 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4411 return ast2iCode (tree->right,lvl+1);
4414 geniCodeFunctionBody (tree,lvl);
4418 geniCodeReturn (right);
4422 geniCodeIfx (tree,lvl);
4426 geniCodeSwitch (tree,lvl);
4430 geniCodeInline (tree);
4434 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4438 geniCodeCritical (tree, lvl);
4444 /*-----------------------------------------------------------------*/
4445 /* reverseICChain - gets from the list and creates a linkedlist */
4446 /*-----------------------------------------------------------------*/
4453 while ((loop = getSet (&iCodeChain)))
4465 /*-----------------------------------------------------------------*/
4466 /* iCodeFromAst - given an ast will convert it to iCode */
4467 /*-----------------------------------------------------------------*/
4469 iCodeFromAst (ast * tree)
4471 returnLabel = newiTempLabel ("_return");
4472 entryLabel = newiTempLabel ("_entry");
4474 return reverseiCChain ();
4477 static const char *opTypeToStr(OPTYPE op)
4481 case SYMBOL: return "symbol";
4482 case VALUE: return "value";
4483 case TYPE: return "type";
4485 return "undefined type";
4489 operand *validateOpType(operand *op,
4496 if (op && op->type == type)
4501 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4502 " expected %s, got %s\n",
4503 macro, args, file, line,
4504 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4506 return op; // never reached, makes compiler happy.