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 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
339 sym = setNextItem (IC_JTLABELS (ic)))
340 dbuf_printf (dbuf, "; %s", sym->name);
341 dbuf_append_char (dbuf, '\n');
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)", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
434 dbuf_printf (dbuf, "; zzgoto %s\n", IC_FALSE (ic)->name);
435 dbuf_append_char (dbuf, '\n');
439 PRINTFUNC (picInline)
441 dbuf_append_str (dbuf, IC_INLINE (ic));
444 PRINTFUNC (picReceive)
446 dbuf_printOperand (IC_RESULT (ic), dbuf);
447 dbuf_printf (dbuf, " = %s ", s);
448 dbuf_printOperand (IC_LEFT (ic), dbuf);
449 dbuf_append_char (dbuf, '\n');
452 PRINTFUNC (picDummyRead)
454 dbuf_append_char (dbuf, '\t');
455 dbuf_printf (dbuf, "%s ", s);
456 dbuf_printOperand (IC_RIGHT (ic), dbuf);
457 dbuf_append_char (dbuf, '\n');
460 PRINTFUNC (picCritical)
462 dbuf_append_char (dbuf, '\t');
464 dbuf_printOperand (IC_RESULT (ic), dbuf);
466 dbuf_append_str (dbuf, "(stack)");
467 dbuf_printf (dbuf, " = %s ", s);
468 dbuf_append_char (dbuf, '\n');
471 PRINTFUNC (picEndCritical)
473 dbuf_append_char (dbuf, '\t');
474 dbuf_printf (dbuf, "%s = ", s);
476 dbuf_printOperand (IC_RIGHT (ic), dbuf);
478 dbuf_append_str (dbuf, "(stack)");
479 dbuf_append_char (dbuf, '\n');
482 /*-----------------------------------------------------------------*/
483 /* piCode - prints one iCode */
484 /*-----------------------------------------------------------------*/
486 piCode (void *item, FILE * of)
495 icTab = getTableEntry (ic->op);
496 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
497 ic->filename, ic->lineno,
498 ic->seq, ic->key, ic->depth, ic->supportRtn);
499 dbuf_init (&dbuf, 1024);
500 icTab->iCodePrint (&dbuf, ic, icTab->printName);
501 dbuf_write_and_destroy (&dbuf, of);
507 printiCChain(ic,stdout);
509 /*-----------------------------------------------------------------*/
510 /* printiCChain - prints intermediate code for humans */
511 /*-----------------------------------------------------------------*/
513 printiCChain (iCode * icChain, FILE * of)
521 for (loop = icChain; loop; loop = loop->next)
523 if ((icTab = getTableEntry (loop->op)))
525 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
526 loop->filename, loop->lineno,
527 loop->seq, loop->key, loop->depth, loop->supportRtn);
529 dbuf_init(&dbuf, 1024);
530 icTab->iCodePrint (&dbuf, loop, icTab->printName);
531 dbuf_write_and_destroy (&dbuf, of);
539 /*-----------------------------------------------------------------*/
540 /* newOperand - allocate, init & return a new iCode */
541 /*-----------------------------------------------------------------*/
547 op = Safe_alloc ( sizeof (operand));
553 /*-----------------------------------------------------------------*/
554 /* newiCode - create and return a new iCode entry initialised */
555 /*-----------------------------------------------------------------*/
557 newiCode (int op, operand * left, operand * right)
561 ic = Safe_alloc ( sizeof (iCode));
563 ic->seqPoint = seqPoint;
565 ic->filename = filename;
567 ic->level = scopeLevel;
569 ic->key = iCodeKey++;
571 IC_RIGHT (ic) = right;
576 /*-----------------------------------------------------------------*/
577 /* newiCode for conditional statements */
578 /*-----------------------------------------------------------------*/
580 newiCodeCondition (operand * condition,
586 if (IS_VOID(operandType(condition))) {
587 werror(E_VOID_VALUE_USED);
590 ic = newiCode (IFX, NULL, NULL);
591 IC_COND (ic) = condition;
592 IC_TRUE (ic) = trueLabel;
593 IC_FALSE (ic) = falseLabel;
597 /*-----------------------------------------------------------------*/
598 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
599 /*-----------------------------------------------------------------*/
601 newiCodeLabelGoto (int op, symbol * label)
605 ic = newiCode (op, NULL, NULL);
609 IC_RIGHT (ic) = NULL;
610 IC_RESULT (ic) = NULL;
614 /*-----------------------------------------------------------------*/
615 /* newiTemp - allocate & return a newItemp Variable */
616 /*-----------------------------------------------------------------*/
624 SNPRINTF (buffer, sizeof(buffer), "%s", s);
628 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
631 itmp = newSymbol (buffer, 1);
632 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
638 /*-----------------------------------------------------------------*/
639 /* newiTempLabel - creates a temp variable label */
640 /*-----------------------------------------------------------------*/
642 newiTempLabel (char *s)
646 /* check if this already exists */
647 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
652 itmplbl = newSymbol (s, 1);
656 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
657 itmplbl = newSymbol (buffer, 1);
662 itmplbl->key = labelKey++;
663 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
667 /*-----------------------------------------------------------------*/
668 /* newiTempLoopHeaderLabel - creates a new loop header label */
669 /*-----------------------------------------------------------------*/
671 newiTempLoopHeaderLabel (bool pre)
675 SNPRINTF (buffer, sizeof(buffer), pre ? "preHeaderLbl%d" : LOOPEXITLBL "%d",
677 itmplbl = newSymbol (buffer, 1);
681 itmplbl->key = labelKey++;
682 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
687 /*-----------------------------------------------------------------*/
688 /* initiCode - initialises some iCode related stuff */
689 /*-----------------------------------------------------------------*/
696 /*-----------------------------------------------------------------*/
697 /* copyiCode - make a copy of the iCode given */
698 /*-----------------------------------------------------------------*/
700 copyiCode (iCode * ic)
702 iCode *nic = newiCode (ic->op, NULL, NULL);
704 nic->lineno = ic->lineno;
705 nic->filename = ic->filename;
706 nic->block = ic->block;
707 nic->level = ic->level;
708 nic->parmBytes = ic->parmBytes;
710 /* deal with the special cases first */
714 IC_COND (nic) = operandFromOperand (IC_COND (ic));
715 IC_TRUE (nic) = IC_TRUE (ic);
716 IC_FALSE (nic) = IC_FALSE (ic);
720 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
721 IC_JTLABELS (nic) = IC_JTLABELS (ic);
726 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
727 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
731 IC_INLINE (nic) = IC_INLINE (ic);
735 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
739 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
740 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
741 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
747 /*-----------------------------------------------------------------*/
748 /* getTableEntry - gets the table entry for the given operator */
749 /*-----------------------------------------------------------------*/
751 getTableEntry (int oper)
755 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
756 if (oper == codeTable[i].icode)
757 return &codeTable[i];
762 /*-----------------------------------------------------------------*/
763 /* newiTempOperand - new intermediate temp operand */
764 /*-----------------------------------------------------------------*/
766 newiTempOperand (sym_link * type, char throwType)
769 operand *op = newOperand ();
773 itmp = newiTemp (NULL);
775 etype = getSpec (type);
777 if (IS_LITERAL (etype))
780 /* copy the type information */
782 itmp->etype = getSpec (itmp->type = (throwType ? type :
783 copyLinkChain (type)));
784 if (IS_LITERAL (itmp->etype))
786 SPEC_SCLS (itmp->etype) = S_REGISTER;
787 SPEC_OCLS (itmp->etype) = reg;
790 op->operand.symOperand = itmp;
791 op->key = itmp->key = ++operandKey;
795 /*-----------------------------------------------------------------*/
796 /* operandType - returns the type chain for an operand */
797 /*-----------------------------------------------------------------*/
799 operandType (operand * op)
801 /* depending on type of operand */
806 return op->operand.valOperand->type;
809 return op->operand.symOperand->type;
812 return op->operand.typeOperand;
814 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
815 " operand type not known ");
816 assert (0); /* should never come here */
817 /* Just to keep the compiler happy */
818 return (sym_link *) 0;
822 /*-----------------------------------------------------------------*/
823 /* isParamterToCall - will return 1 if op is a parameter to args */
824 /*-----------------------------------------------------------------*/
826 isParameterToCall (value * args, operand * op)
830 wassert (IS_SYMOP(op));
835 isSymbolEqual (op->operand.symOperand, tval->sym))
842 /*-----------------------------------------------------------------*/
843 /* isOperandGlobal - return 1 if operand is a global variable */
844 /*-----------------------------------------------------------------*/
846 isOperandGlobal (operand * op)
855 (op->operand.symOperand->level == 0 ||
856 IS_STATIC (op->operand.symOperand->etype) ||
857 IS_EXTERN (op->operand.symOperand->etype))
864 /*-----------------------------------------------------------------*/
865 /* isOperandVolatile - return 1 if the operand is volatile */
866 /*-----------------------------------------------------------------*/
868 isOperandVolatile (operand * op, bool chkTemp)
873 if (IS_ITEMP (op) && !chkTemp)
876 opetype = getSpec (optype = operandType (op));
878 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
881 if (IS_VOLATILE (opetype))
886 /*-----------------------------------------------------------------*/
887 /* isOperandLiteral - returns 1 if an operand contains a literal */
888 /*-----------------------------------------------------------------*/
890 isOperandLiteral (operand * op)
897 opetype = getSpec (operandType (op));
899 if (IS_LITERAL (opetype))
905 /*-----------------------------------------------------------------*/
906 /* isOperandInFarSpace - will return true if operand is in farSpace */
907 /*-----------------------------------------------------------------*/
909 isOperandInFarSpace (operand * op)
919 if (!IS_TRUE_SYMOP (op))
922 etype = SPIL_LOC (op)->etype;
928 etype = getSpec (operandType (op));
930 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
933 /*-----------------------------------------------------------------*/
934 /* isOperandInPagedSpace - return true if operand is in pagedSpace */
935 /*-----------------------------------------------------------------*/
937 isOperandInPagedSpace (operand * op)
947 if (!IS_TRUE_SYMOP (op))
950 etype = SPIL_LOC (op)->etype;
956 etype = getSpec (operandType (op));
958 return (IN_PAGEDSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
961 /*------------------------------------------------------------------*/
962 /* isOperandInDirSpace - will return true if operand is in dirSpace */
963 /*------------------------------------------------------------------*/
965 isOperandInDirSpace (operand * op)
975 if (!IS_TRUE_SYMOP (op))
978 etype = SPIL_LOC (op)->etype;
984 etype = getSpec (operandType (op));
986 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
989 /*--------------------------------------------------------------------*/
990 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
991 /*--------------------------------------------------------------------*/
993 isOperandInCodeSpace (operand * op)
1003 etype = getSpec (operandType (op));
1005 if (!IS_TRUE_SYMOP (op))
1008 etype = SPIL_LOC (op)->etype;
1014 etype = getSpec (operandType (op));
1016 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1019 /*-----------------------------------------------------------------*/
1020 /* isOperandOnStack - will return true if operand is on stack */
1021 /*-----------------------------------------------------------------*/
1023 isOperandOnStack (operand * op)
1033 etype = getSpec (operandType (op));
1034 if (IN_STACK (etype) ||
1035 OP_SYMBOL(op)->onStack ||
1036 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1042 /*-----------------------------------------------------------------*/
1043 /* isOclsExpensive - will return true if accesses to an output */
1044 /* storage class are expensive */
1045 /*-----------------------------------------------------------------*/
1047 isOclsExpensive (struct memmap *oclass)
1049 if (port->oclsExpense)
1050 return port->oclsExpense (oclass) > 0;
1052 /* In the absence of port specific guidance, assume only */
1053 /* farspace is expensive. */
1054 return IN_FARSPACE (oclass);
1057 /*-----------------------------------------------------------------*/
1058 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1059 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1060 /*-----------------------------------------------------------------*/
1062 isiCodeInFunctionCall (iCode * ic)
1066 /* Find the next CALL/PCALL */
1069 if (lic->op == CALL || lic->op == PCALL)
1077 /* A function call was found. Scan backwards and see if an */
1078 /* IPUSH or SEND is encountered */
1081 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1083 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1091 /*-----------------------------------------------------------------*/
1092 /* operandLitValue - literal value of an operand */
1093 /*-----------------------------------------------------------------*/
1095 operandLitValue (operand * op)
1097 assert (isOperandLiteral (op));
1099 return floatFromVal (op->operand.valOperand);
1102 /*-----------------------------------------------------------------*/
1103 /* getBuiltInParms - returns parameters to a builtin functions */
1104 /*-----------------------------------------------------------------*/
1105 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1110 /* builtin functions uses only SEND for parameters */
1111 while (ic->op != CALL) {
1112 assert(ic->op == SEND && ic->builtinSEND);
1113 ic->generated = 1; /* mark the icode as generated */
1114 parms[*pcount] = IC_LEFT(ic);
1120 /* make sure this is a builtin function call */
1121 assert(IS_SYMOP(IC_LEFT(ic)));
1122 ftype = operandType(IC_LEFT(ic));
1123 assert(IFFUNC_ISBUILTIN(ftype));
1127 /*-----------------------------------------------------------------*/
1128 /* operandOperation - performs operations on operands */
1129 /*-----------------------------------------------------------------*/
1131 operandOperation (operand * left, operand * right,
1132 int op, sym_link * type)
1134 sym_link *let , *ret=NULL;
1135 operand *retval = (operand *) 0;
1137 assert (isOperandLiteral (left));
1138 let = getSpec(operandType(left));
1140 assert (isOperandLiteral (right));
1141 ret = getSpec(operandType(right));
1147 retval = operandFromValue (valCastLiteral (type,
1148 operandLitValue (left) +
1149 operandLitValue (right)));
1152 retval = operandFromValue (valCastLiteral (type,
1153 operandLitValue (left) -
1154 operandLitValue (right)));
1158 retval = operandFromValue (valCastLiteral (type,
1159 operandLitValue (left) *
1160 operandLitValue (right)));
1161 This could be all we've to do, but with gcc we've to take care about
1162 overflows. Two examples:
1163 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1164 significant bits are lost (52 in fraction, 63 bits would be
1165 necessary to keep full precision).
1166 If the resulting double value is greater than ULONG_MAX (resp.
1167 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1170 /* if it is not a specifier then we can assume that */
1171 /* it will be an unsigned long */
1172 if (IS_INT (type) ||
1175 /* long is handled here, because it can overflow with double */
1176 if (IS_LONG (type) ||
1178 /* signed and unsigned mul are the same, as long as the precision
1179 of the result isn't bigger than the precision of the operands. */
1180 retval = operandFromValue (valCastLiteral (type,
1181 (TYPE_TARGET_ULONG) operandLitValue (left) *
1182 (TYPE_TARGET_ULONG) operandLitValue (right)));
1183 else if (IS_UNSIGNED (type)) /* unsigned int */
1185 /* unsigned int is handled here in order to detect overflow */
1186 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) operandLitValue (left) *
1187 (TYPE_TARGET_UINT) operandLitValue (right);
1189 retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_UINT) ul));
1190 if (ul != (TYPE_TARGET_UINT) ul)
1193 else /* signed int */
1195 /* signed int is handled here in order to detect overflow */
1196 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) operandLitValue (left) *
1197 (TYPE_TARGET_INT) operandLitValue (right);
1199 retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_INT) l));
1200 if (l != (TYPE_TARGET_INT) l)
1205 /* all others go here: */
1206 retval = operandFromValue (valCastLiteral (type,
1207 operandLitValue (left) *
1208 operandLitValue (right)));
1211 if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
1213 werror (E_DIVIDE_BY_ZERO);
1219 if (IS_UNSIGNED (type))
1221 SPEC_USIGN (let) = 1;
1222 SPEC_USIGN (ret) = 1;
1223 retval = operandFromValue (valCastLiteral (type,
1224 (TYPE_TARGET_ULONG) operandLitValue (left) /
1225 (TYPE_TARGET_ULONG) operandLitValue (right)));
1229 retval = operandFromValue (valCastLiteral (type,
1230 operandLitValue (left) /
1231 operandLitValue (right)));
1236 if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
1238 werror (E_DIVIDE_BY_ZERO);
1243 if (IS_UNSIGNED (type))
1244 retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) %
1245 (TYPE_TARGET_ULONG) operandLitValue (right));
1247 retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) %
1248 (TYPE_TARGET_LONG) operandLitValue (right));
1252 /* The number of left shifts is always unsigned. Signed doesn't make
1253 sense here. Shifting by a negative number is impossible. */
1254 retval = operandFromValue (valCastLiteral (type,
1255 ((TYPE_TARGET_ULONG) operandLitValue (left) <<
1256 (TYPE_TARGET_ULONG) operandLitValue (right))));
1259 /* The number of right shifts is always unsigned. Signed doesn't make
1260 sense here. Shifting by a negative number is impossible. */
1261 if (IS_UNSIGNED(let))
1262 /* unsigned: logic shift right */
1263 retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) >>
1264 (TYPE_TARGET_ULONG) operandLitValue (right));
1266 /* signed: arithmetic shift right */
1267 retval = operandFromLit ((TYPE_TARGET_LONG ) operandLitValue (left) >>
1268 (TYPE_TARGET_ULONG) operandLitValue (right));
1271 if (IS_FLOAT (let) || IS_FLOAT (ret))
1273 retval = operandFromLit (operandLitValue (left) ==
1274 operandLitValue (right));
1276 else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
1278 retval = operandFromLit (operandLitValue (left) ==
1279 operandLitValue (right));
1283 /* this op doesn't care about signedness */
1284 TYPE_TARGET_ULONG l, r;
1286 l = (TYPE_TARGET_ULONG) operandLitValue (left);
1287 r = (TYPE_TARGET_ULONG) operandLitValue (right);
1288 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1289 neccessary to strip them to 16 bit.
1290 Literals are reduced to their cheapest type, therefore left and
1291 right might have different types. It's neccessary to find a
1292 common type: int (used for char too) or long */
1293 if (!IS_LONG (let) &&
1296 r = (TYPE_TARGET_UINT) r;
1297 l = (TYPE_TARGET_UINT) l;
1299 retval = operandFromLit (l == r);
1303 retval = operandFromLit (operandLitValue (left) <
1304 operandLitValue (right));
1307 retval = operandFromLit (operandLitValue (left) <=
1308 operandLitValue (right));
1311 retval = operandFromLit (operandLitValue (left) !=
1312 operandLitValue (right));
1315 retval = operandFromLit (operandLitValue (left) >
1316 operandLitValue (right));
1319 retval = operandFromLit (operandLitValue (left) >=
1320 operandLitValue (right));
1323 retval = operandFromValue (valCastLiteral (type,
1324 (TYPE_TARGET_ULONG)operandLitValue(left) &
1325 (TYPE_TARGET_ULONG)operandLitValue(right)));
1328 retval = operandFromValue (valCastLiteral (type,
1329 (TYPE_TARGET_ULONG)operandLitValue(left) |
1330 (TYPE_TARGET_ULONG)operandLitValue(right)));
1333 retval = operandFromValue (valCastLiteral (type,
1334 (TYPE_TARGET_ULONG)operandLitValue(left) ^
1335 (TYPE_TARGET_ULONG)operandLitValue(right)));
1338 retval = operandFromLit (operandLitValue (left) &&
1339 operandLitValue (right));
1342 retval = operandFromLit (operandLitValue (left) ||
1343 operandLitValue (right));
1347 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
1349 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1355 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
1357 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1362 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1363 (TYPE_TARGET_ULONG)operandLitValue(right)) & 1);
1366 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1367 (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFF);
1370 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1371 (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFFFF);
1375 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1376 ((getSize (let) * 8) - 1)) & 1);
1380 retval = operandFromValue (valCastLiteral (type,
1381 -1 * operandLitValue (left)));
1385 retval = operandFromValue (valCastLiteral (type,
1386 ~((TYPE_TARGET_ULONG)
1387 operandLitValue (left))));
1391 retval = operandFromLit (!operandLitValue (left));
1395 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1396 " operandOperation invalid operator ");
1404 /*-----------------------------------------------------------------*/
1405 /* isOperandEqual - compares two operand & return 1 if they r = */
1406 /*-----------------------------------------------------------------*/
1408 isOperandEqual (operand * left, operand * right)
1410 /* if the pointers are equal then they are equal */
1414 /* if either of them null then false */
1415 if (!left || !right)
1418 if (left->type != right->type)
1421 if (IS_SYMOP (left) && IS_SYMOP (right))
1422 return left->key == right->key;
1424 /* if types are the same */
1428 return isSymbolEqual (left->operand.symOperand,
1429 right->operand.symOperand);
1431 return (compareType (left->operand.valOperand->type,
1432 right->operand.valOperand->type) &&
1433 (floatFromVal (left->operand.valOperand) ==
1434 floatFromVal (right->operand.valOperand)));
1436 if (compareType (left->operand.typeOperand,
1437 right->operand.typeOperand) == 1)
1444 /*-------------------------------------------------------------------*/
1445 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1446 /*-------------------------------------------------------------------*/
1448 isiCodeEqual (iCode * left, iCode * right)
1450 /* if the same pointer */
1454 /* if either of them null */
1455 if (!left || !right)
1458 /* if operand are the same */
1459 if (left->op == right->op)
1462 /* compare all the elements depending on type */
1463 if (left->op != IFX)
1465 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1467 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1473 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1475 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1477 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1486 /*-----------------------------------------------------------------*/
1487 /* newiTempFromOp - create a temp Operand with same attributes */
1488 /*-----------------------------------------------------------------*/
1490 newiTempFromOp (operand * op)
1500 nop = newiTempOperand (operandType (op), TRUE);
1501 nop->isaddr = op->isaddr;
1502 nop->isvolatile = op->isvolatile;
1503 nop->isGlobal = op->isGlobal;
1504 nop->isLiteral = op->isLiteral;
1505 nop->usesDefs = op->usesDefs;
1506 nop->isParm = op->isParm;
1510 /*-----------------------------------------------------------------*/
1511 /* operand from operand - creates an operand holder for the type */
1512 /*-----------------------------------------------------------------*/
1514 operandFromOperand (operand * op)
1520 nop = newOperand ();
1521 nop->type = op->type;
1522 nop->isaddr = op->isaddr;
1524 nop->isvolatile = op->isvolatile;
1525 nop->isGlobal = op->isGlobal;
1526 nop->isLiteral = op->isLiteral;
1527 nop->usesDefs = op->usesDefs;
1528 nop->isParm = op->isParm;
1533 nop->operand.symOperand = op->operand.symOperand;
1536 nop->operand.valOperand = op->operand.valOperand;
1539 nop->operand.typeOperand = op->operand.typeOperand;
1546 /*-----------------------------------------------------------------*/
1547 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1548 /*-----------------------------------------------------------------*/
1550 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1552 operand *nop = operandFromOperand (op);
1554 if (nop->type == SYMBOL)
1556 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1557 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1563 /*-----------------------------------------------------------------*/
1564 /* operandFromSymbol - creates an operand from a symbol */
1565 /*-----------------------------------------------------------------*/
1567 operandFromSymbol (symbol * sym)
1572 /* if the symbol's type is a literal */
1573 /* then it is an enumerator type */
1574 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1575 return operandFromValue (valFromType (sym->etype));
1578 sym->key = ++operandKey;
1580 /* if this an implicit variable, means struct/union */
1581 /* member so just return it */
1582 if (sym->implicit || IS_FUNC (sym->type))
1586 op->operand.symOperand = sym;
1588 op->isvolatile = isOperandVolatile (op, TRUE);
1589 op->isGlobal = isOperandGlobal (op);
1593 /* under the following conditions create a
1594 register equivalent for a local symbol */
1595 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1596 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1598 (!(options.model == MODEL_FLAT24)) ) &&
1599 options.stackAuto == 0)
1602 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1603 !IS_FUNC (sym->type) && /* not a function */
1604 !sym->_isparm && /* not a parameter */
1605 IS_AUTO (sym) && /* is a local auto variable */
1606 !sym->addrtaken && /* whose address has not been taken */
1607 !sym->reqv && /* does not already have a reg equivalence */
1608 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1609 !sym->islbl && /* not a label */
1610 ok /* farspace check */
1614 /* we will use it after all optimizations
1615 and before liveRange calculation */
1616 sym->reqv = newiTempOperand (sym->type, 0);
1617 sym->reqv->key = sym->key;
1618 OP_SYMBOL (sym->reqv)->prereqv = sym;
1619 OP_SYMBOL (sym->reqv)->key = sym->key;
1620 OP_SYMBOL (sym->reqv)->isreqv = 1;
1621 OP_SYMBOL (sym->reqv)->islocal = 1;
1622 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1623 SPIL_LOC (sym->reqv) = sym;
1626 if (!IS_AGGREGATE (sym->type))
1630 op->operand.symOperand = sym;
1633 op->isvolatile = isOperandVolatile (op, TRUE);
1634 op->isGlobal = isOperandGlobal (op);
1635 op->isPtr = IS_PTR (operandType (op));
1636 op->isParm = sym->_isparm;
1641 /* itemp = &[_symbol] */
1643 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1644 IC_LEFT (ic)->type = SYMBOL;
1645 IC_LEFT (ic)->operand.symOperand = sym;
1646 IC_LEFT (ic)->key = sym->key;
1647 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1648 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1649 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1652 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1653 if (IS_ARRAY (sym->type))
1655 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1656 IC_RESULT (ic)->isaddr = 0;
1659 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1663 return IC_RESULT (ic);
1666 /*-----------------------------------------------------------------*/
1667 /* operandFromValue - creates an operand from value */
1668 /*-----------------------------------------------------------------*/
1670 operandFromValue (value * val)
1674 /* if this is a symbol then do the symbol thing */
1676 return operandFromSymbol (val->sym);
1678 /* this is not a symbol */
1681 op->operand.valOperand = val;
1682 op->isLiteral = isOperandLiteral (op);
1686 /*-----------------------------------------------------------------*/
1687 /* operandFromLink - operand from typeChain */
1688 /*-----------------------------------------------------------------*/
1690 operandFromLink (sym_link * type)
1694 /* operand from sym_link */
1700 op->operand.typeOperand = copyLinkChain (type);
1704 /*-----------------------------------------------------------------*/
1705 /* operandFromLit - makes an operand from a literal value */
1706 /*-----------------------------------------------------------------*/
1708 operandFromLit (double i)
1710 return operandFromValue (valueFromLit (i));
1713 /*-----------------------------------------------------------------*/
1714 /* operandFromAst - creates an operand from an ast */
1715 /*-----------------------------------------------------------------*/
1717 operandFromAst (ast * tree,int lvl)
1723 /* depending on type do */
1727 return ast2iCode (tree,lvl+1);
1731 return operandFromValue (tree->opval.val);
1735 return operandFromLink (tree->opval.lnk);
1742 /* Just to keep the compiler happy */
1743 return (operand *) 0;
1746 /*-----------------------------------------------------------------*/
1747 /* setOperandType - sets the operand's type to the given type */
1748 /*-----------------------------------------------------------------*/
1750 setOperandType (operand * op, sym_link * type)
1752 /* depending on the type of operand */
1757 op->operand.valOperand->etype =
1758 getSpec (op->operand.valOperand->type =
1759 copyLinkChain (type));
1763 if (op->operand.symOperand->isitmp)
1764 op->operand.symOperand->etype =
1765 getSpec (op->operand.symOperand->type =
1766 copyLinkChain (type));
1768 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1769 "attempt to modify type of source");
1773 op->operand.typeOperand = copyLinkChain (type);
1779 /*-----------------------------------------------------------------*/
1780 /* Get size in byte of ptr need to access an array */
1781 /*-----------------------------------------------------------------*/
1783 getArraySizePtr (operand * op)
1785 sym_link *ltype = operandType(op);
1789 int size = getSize(ltype);
1790 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1795 sym_link *letype = getSpec(ltype);
1796 switch (PTR_TYPE (SPEC_OCLS (letype)))
1808 if (GPTRSIZE > FPTRSIZE)
1809 return (GPTRSIZE-1);
1820 /*-----------------------------------------------------------------*/
1821 /* perform "usual unary conversions" */
1822 /*-----------------------------------------------------------------*/
1825 usualUnaryConversions (operand * op)
1827 if (IS_INTEGRAL (operandType (op)))
1829 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1832 return geniCodeCast (INTTYPE, op, TRUE);
1839 /*-----------------------------------------------------------------*/
1840 /* perform "usual binary conversions" */
1841 /*-----------------------------------------------------------------*/
1844 usualBinaryConversions (operand ** op1, operand ** op2,
1845 RESULT_TYPE resultType, int op)
1848 sym_link *rtype = operandType (*op2);
1849 sym_link *ltype = operandType (*op1);
1851 ctype = computeType (ltype, rtype, resultType, op);
1858 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1860 /* one byte operations: keep signedness for code generator */
1868 *op1 = geniCodeCast (ctype, *op1, TRUE);
1869 *op2 = geniCodeCast (ctype, *op2, TRUE);
1874 /*-----------------------------------------------------------------*/
1875 /* geniCodeValueAtAddress - generate intermeditate code for value */
1877 /*-----------------------------------------------------------------*/
1879 geniCodeRValue (operand * op, bool force)
1882 sym_link *type = operandType (op);
1883 sym_link *etype = getSpec (type);
1885 /* if this is an array & already */
1886 /* an address then return this */
1887 if (IS_AGGREGATE (type) ||
1888 (IS_PTR (type) && !force && !op->isaddr))
1889 return operandFromOperand (op);
1891 /* if this is not an address then must be */
1892 /* rvalue already so return this one */
1896 /* if this is not a temp symbol then */
1897 if (!IS_ITEMP (op) &&
1899 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1901 op = operandFromOperand (op);
1906 if (IS_SPEC (type) &&
1907 IS_TRUE_SYMOP (op) &&
1908 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1909 (options.model == MODEL_FLAT24) ))
1911 op = operandFromOperand (op);
1916 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1917 if (IS_PTR (type) && op->isaddr && force)
1920 type = copyLinkChain (type);
1922 IC_RESULT (ic) = newiTempOperand (type, 1);
1923 IC_RESULT (ic)->isaddr = 0;
1925 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1929 return IC_RESULT (ic);
1932 /*-----------------------------------------------------------------*/
1933 /* geniCodeCast - changes the value from one type to another */
1934 /*-----------------------------------------------------------------*/
1936 geniCodeCast (sym_link * type, operand * op, bool implicit)
1940 sym_link *opetype = getSpec (optype = operandType (op));
1944 /* one of them has size zero then error */
1945 if (IS_VOID (optype))
1947 werror (E_CAST_ZERO);
1951 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1953 geniCodeArray2Ptr (op);
1957 /* if the operand is already the desired type then do nothing */
1958 if (compareType (type, optype) == 1)
1961 /* if this is a literal then just change the type & return */
1962 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1964 return operandFromValue (valCastLiteral (type,
1965 operandLitValue (op)));
1968 /* if casting to/from pointers, do some checking */
1969 if (IS_PTR(type)) { // to a pointer
1970 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1971 if (IS_INTEGRAL(optype)) {
1972 // maybe this is NULL, than it's ok.
1973 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1974 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1975 // no way to set the storage
1976 if (IS_LITERAL(optype)) {
1977 werror(E_LITERAL_GENERIC);
1980 werror(E_NONPTR2_GENPTR);
1983 } else if (implicit) {
1984 werror(W_INTEGRAL2PTR_NOCAST);
1989 // shouldn't do that with float, array or structure unless to void
1990 if (!IS_VOID(getSpec(type)) &&
1991 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1992 werror(E_INCOMPAT_TYPES);
1996 } else { // from a pointer to a pointer
1997 if (IS_GENPTR(type) && IS_VOID(type->next))
1998 { // cast to void* is always allowed
2000 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2001 { // cast from void* is always allowed
2003 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2004 // if not a pointer to a function
2005 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2006 if (implicit) { // if not to generic, they have to match
2007 if (!IS_GENPTR(type) &&
2008 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2009 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2013 werror(E_INCOMPAT_PTYPES);
2020 } else { // to a non pointer
2021 if (IS_PTR(optype)) { // from a pointer
2022 if (implicit) { // sneaky
2023 if (IS_INTEGRAL(type)) {
2024 werror(W_PTR2INTEGRAL_NOCAST);
2026 } else { // shouldn't do that with float, array or structure
2027 werror(E_INCOMPAT_TYPES);
2034 printFromToType (optype, type);
2037 /* if they are the same size create an assignment */
2039 /* This seems very dangerous to me, since there are several */
2040 /* optimizations (for example, gcse) that don't notice the */
2041 /* cast hidden in this assignment and may simplify an */
2042 /* iCode to use the original (uncasted) operand. */
2043 /* Unfortunately, other things break when this cast is */
2044 /* made explicit. Need to fix this someday. */
2045 /* -- EEP, 2004/01/21 */
2046 if (getSize (type) == getSize (optype) &&
2047 !IS_BITFIELD (type) &&
2049 !IS_FLOAT (optype) &&
2051 !IS_FIXED (optype) &&
2052 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2053 (!IS_SPEC (type) && !IS_SPEC (optype))))
2055 ic = newiCode ('=', NULL, op);
2056 IC_RESULT (ic) = newiTempOperand (type, 0);
2057 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2058 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2059 IC_RESULT (ic)->isaddr = 0;
2063 ic = newiCode (CAST, operandFromLink (type),
2064 geniCodeRValue (op, FALSE));
2066 IC_RESULT (ic) = newiTempOperand (type, 0);
2069 /* preserve the storage class & output class */
2070 /* of the original variable */
2071 restype = getSpec (operandType (IC_RESULT (ic)));
2072 if (!IS_LITERAL(opetype) &&
2075 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2076 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2079 return IC_RESULT (ic);
2082 /*-----------------------------------------------------------------*/
2083 /* geniCodeLabel - will create a Label */
2084 /*-----------------------------------------------------------------*/
2086 geniCodeLabel (symbol * label)
2090 ic = newiCodeLabelGoto (LABEL, label);
2094 /*-----------------------------------------------------------------*/
2095 /* geniCodeGoto - will create a Goto */
2096 /*-----------------------------------------------------------------*/
2098 geniCodeGoto (symbol * label)
2102 ic = newiCodeLabelGoto (GOTO, label);
2106 /*-----------------------------------------------------------------*/
2107 /* geniCodeMultiply - gen intermediate code for multiplication */
2108 /*-----------------------------------------------------------------*/
2110 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2117 /* if they are both literal then we know the result */
2118 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2119 return operandFromValue (valMult (left->operand.valOperand,
2120 right->operand.valOperand));
2122 if (IS_LITERAL(retype)) {
2123 p2 = powof2 ((TYPE_TARGET_ULONG) floatFromVal (right->operand.valOperand));
2126 resType = usualBinaryConversions (&left, &right, resultType, '*');
2128 rtype = operandType (right);
2129 retype = getSpec (rtype);
2130 ltype = operandType (left);
2131 letype = getSpec (ltype);
2134 /* if the right is a literal & power of 2 */
2135 /* then make it a left shift */
2136 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2137 efficient in most cases than 2 bytes result = 2 bytes << literal
2138 if port has 1 byte muldiv */
2139 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2140 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2141 && (port->support.muldiv == 1))
2142 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2143 && strcmp (port->target, "pic14") != 0)
2145 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2147 /* LEFT_OP need same size for left and result, */
2148 left = geniCodeCast (resType, left, TRUE);
2149 ltype = operandType (left);
2151 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2155 /* if the size left or right > 1 then support routine */
2156 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2158 if (IS_LITERAL (retype))
2159 ic = newiCode ('*', right, left); /* multiplication by support routine with one literal */
2161 ic = newiCode ('*', left, right); /* multiplication by support routine */
2166 ic = newiCode ('*', left, right); /* normal multiplication */
2169 IC_RESULT (ic) = newiTempOperand (resType, 1);
2172 return IC_RESULT (ic);
2175 /*-----------------------------------------------------------------*/
2176 /* geniCodeDivision - gen intermediate code for division */
2177 /*-----------------------------------------------------------------*/
2179 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2184 sym_link *rtype = operandType (right);
2185 sym_link *retype = getSpec (rtype);
2186 sym_link *ltype = operandType (left);
2187 sym_link *letype = getSpec (ltype);
2189 resType = usualBinaryConversions (&left, &right, resultType, '/');
2191 /* if the right is a literal & power of 2
2192 and left is unsigned then make it a
2194 if (IS_LITERAL (retype) &&
2195 !IS_FLOAT (letype) &&
2196 !IS_FIXED (letype) &&
2197 IS_UNSIGNED(letype) &&
2198 ((p2 = powof2 ((TYPE_TARGET_ULONG)
2199 floatFromVal (right->operand.valOperand))) > 0)) {
2200 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2204 ic = newiCode ('/', left, right); /* normal division */
2205 /* if the size left or right > 1 then support routine */
2206 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2209 IC_RESULT (ic) = newiTempOperand (resType, 0);
2212 return IC_RESULT (ic);
2214 /*-----------------------------------------------------------------*/
2215 /* geniCodeModulus - gen intermediate code for modulus */
2216 /*-----------------------------------------------------------------*/
2218 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2224 /* if they are both literal then we know the result */
2225 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2226 return operandFromValue (valMod (left->operand.valOperand,
2227 right->operand.valOperand));
2229 resType = usualBinaryConversions (&left, &right, resultType, '%');
2231 /* now they are the same size */
2232 ic = newiCode ('%', left, right);
2234 /* if the size left or right > 1 then support routine */
2235 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2237 IC_RESULT (ic) = newiTempOperand (resType, 0);
2240 return IC_RESULT (ic);
2243 /*-----------------------------------------------------------------*/
2244 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2245 /*-----------------------------------------------------------------*/
2247 geniCodePtrPtrSubtract (operand * left, operand * right)
2253 /* if they are both literals then */
2254 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2256 result = operandFromValue (valMinus (left->operand.valOperand,
2257 right->operand.valOperand));
2261 ic = newiCode ('-', left, right);
2263 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2267 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2271 // should we really do this? is this ANSI?
2272 return geniCodeDivision (result,
2273 operandFromLit (getSize (ltype->next)),
2277 /*-----------------------------------------------------------------*/
2278 /* geniCodeSubtract - generates code for subtraction */
2279 /*-----------------------------------------------------------------*/
2281 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2288 /* if they both pointers then */
2289 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2290 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2291 return geniCodePtrPtrSubtract (left, right);
2293 /* if they are both literal then we know the result */
2294 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2295 && left->isLiteral && right->isLiteral)
2296 return operandFromValue (valMinus (left->operand.valOperand,
2297 right->operand.valOperand));
2299 /* if left is an array or pointer */
2300 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2302 isarray = left->isaddr;
2303 right = geniCodeMultiply (right,
2304 operandFromLit (getSize (ltype->next)),
2305 (getArraySizePtr(left) >= INTSIZE) ?
2308 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2311 { /* make them the same size */
2312 resType = usualBinaryConversions (&left, &right, resultType, '-');
2315 ic = newiCode ('-', left, right);
2317 IC_RESULT (ic) = newiTempOperand (resType, 1);
2318 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2320 /* if left or right is a float */
2321 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2322 || IS_FIXED (ltype) || IS_FIXED (rtype))
2326 return IC_RESULT (ic);
2329 /*-----------------------------------------------------------------*/
2330 /* geniCodeAdd - generates iCode for addition */
2331 /*-----------------------------------------------------------------*/
2333 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2342 /* if the right side is LITERAL zero */
2343 /* return the left side */
2344 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2347 /* if left is literal zero return right */
2348 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2351 /* if left is a pointer then size */
2352 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2354 isarray = left->isaddr;
2355 // there is no need to multiply with 1
2356 if (getSize (ltype->next) != 1)
2358 size = operandFromLit (getSize (ltype->next));
2359 SPEC_USIGN (getSpec (operandType (size))) = 1;
2360 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2361 right = geniCodeMultiply (right, size, resultType);
2362 /* Even if right is a 'unsigned char',
2363 the result will be a 'signed int' due to the promotion rules.
2364 It doesn't make sense when accessing arrays, so let's fix it here: */
2366 SPEC_USIGN (getSpec (operandType (right))) = 1;
2368 resType = copyLinkChain (ltype);
2371 { // make them the same size
2372 resType = usualBinaryConversions (&left, &right, resultType, '+');
2375 /* if they are both literals then we know */
2376 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2377 && left->isLiteral && right->isLiteral)
2378 return operandFromValue (valPlus (valFromType (ltype),
2379 valFromType (rtype)));
2381 ic = newiCode ('+', left, right);
2383 IC_RESULT (ic) = newiTempOperand (resType, 1);
2384 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2386 /* if left or right is a float then support
2388 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2389 || IS_FIXED (ltype) || IS_FIXED (rtype))
2394 return IC_RESULT (ic);
2398 /*-----------------------------------------------------------------*/
2399 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2400 /*-----------------------------------------------------------------*/
2402 aggrToPtr (sym_link * type, bool force)
2407 if (IS_PTR (type) && !force)
2410 etype = getSpec (type);
2411 ptype = newLink (DECLARATOR);
2415 /* set the pointer depending on the storage class */
2416 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2420 /*------------------------------------------------------------------*/
2421 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2422 /*------------------------------------------------------------------*/
2424 aggrToPtrDclType (sym_link * type, bool force)
2426 if (IS_PTR (type) && !force)
2427 return DCL_TYPE (type);
2429 /* return the pointer depending on the storage class */
2430 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2433 /*-----------------------------------------------------------------*/
2434 /* geniCodeArray2Ptr - array to pointer */
2435 /*-----------------------------------------------------------------*/
2437 geniCodeArray2Ptr (operand * op)
2439 sym_link *optype = operandType (op);
2440 sym_link *opetype = getSpec (optype);
2442 /* set the pointer depending on the storage class */
2443 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2450 /*-----------------------------------------------------------------*/
2451 /* geniCodeArray - array access */
2452 /*-----------------------------------------------------------------*/
2454 geniCodeArray (operand * left, operand * right, int lvl)
2458 sym_link *ltype = operandType (left);
2460 RESULT_TYPE resultType;
2462 resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
2463 if (DCL_ELEM (ltype))
2465 if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
2466 resultType = RESULT_TYPE_CHAR;
2471 if (IS_PTR (ltype->next) && left->isaddr)
2473 left = geniCodeRValue (left, FALSE);
2476 return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
2479 size = operandFromLit (getSize (ltype->next));
2480 SPEC_USIGN (getSpec (operandType (size))) = 1;
2481 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2482 right = geniCodeMultiply (right, size, resultType);
2483 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2484 It doesn't make sense when accessing arrays, so let's fix it here: */
2486 SPEC_USIGN (getSpec (operandType (right))) = 1;
2487 /* we can check for limits here */
2488 /* already done in SDCCast.c
2489 if (isOperandLiteral (right) &&
2492 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2494 werror (W_IDX_OUT_OF_BOUNDS,
2495 (int) operandLitValue (right) / getSize (ltype->next),
2500 ic = newiCode ('+', left, right);
2502 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2503 !IS_AGGREGATE (ltype->next) &&
2504 !IS_PTR (ltype->next))
2505 ? ltype : ltype->next), 0);
2507 if (!IS_AGGREGATE (ltype->next))
2509 IC_RESULT (ic)->isaddr = 1;
2510 IC_RESULT (ic)->aggr2ptr = 1;
2514 return IC_RESULT (ic);
2517 /*-----------------------------------------------------------------*/
2518 /* geniCodeStruct - generates intermediate code for structures */
2519 /*-----------------------------------------------------------------*/
2521 geniCodeStruct (operand * left, operand * right, bool islval)
2524 sym_link *type = operandType (left);
2525 sym_link *etype = getSpec (type);
2527 symbol *element = getStructElement (SPEC_STRUCT (etype),
2528 right->operand.symOperand);
2530 wassert(IS_SYMOP(right));
2532 /* add the offset */
2533 ic = newiCode ('+', left, operandFromLit (element->offset));
2535 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2537 /* preserve the storage & output class of the struct */
2538 /* as well as the volatile attribute */
2539 retype = getSpec (operandType (IC_RESULT (ic)));
2540 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2541 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2542 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2543 SPEC_CONST (retype) |= SPEC_CONST (etype);
2545 if (IS_PTR (element->type))
2546 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2548 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2551 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2554 /*-----------------------------------------------------------------*/
2555 /* geniCodePostInc - generate int code for Post increment */
2556 /*-----------------------------------------------------------------*/
2558 geniCodePostInc (operand * op)
2562 sym_link *optype = operandType (op);
2564 operand *rv = (IS_ITEMP (op) ?
2565 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2567 sym_link *rvtype = operandType (rv);
2570 /* if this is not an address we have trouble */
2573 werror (E_LVALUE_REQUIRED, "++");
2577 rOp = newiTempOperand (rvtype, 0);
2578 OP_SYMBOL(rOp)->noSpilLoc = 1;
2581 OP_SYMBOL(rv)->noSpilLoc = 1;
2583 geniCodeAssign (rOp, rv, 0, 0);
2585 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2587 werror(W_SIZEOF_VOID);
2588 if (IS_FLOAT (rvtype))
2589 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2590 else if (IS_FIXED16X16 (rvtype))
2591 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2593 ic = newiCode ('+', rv, operandFromLit (size));
2595 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2598 geniCodeAssign (op, result, 0, 0);
2604 /*-----------------------------------------------------------------*/
2605 /* geniCodePreInc - generate code for preIncrement */
2606 /*-----------------------------------------------------------------*/
2608 geniCodePreInc (operand * op, bool lvalue)
2611 sym_link *optype = operandType (op);
2612 operand *rop = (IS_ITEMP (op) ?
2613 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2615 sym_link *roptype = operandType (rop);
2621 werror (E_LVALUE_REQUIRED, "++");
2625 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2627 werror(W_SIZEOF_VOID);
2628 if (IS_FLOAT (roptype))
2629 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2630 else if (IS_FIXED16X16 (roptype))
2631 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2633 ic = newiCode ('+', rop, operandFromLit (size));
2634 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2637 (void) geniCodeAssign (op, result, 0, 0);
2638 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2644 /*-----------------------------------------------------------------*/
2645 /* geniCodePostDec - generates code for Post decrement */
2646 /*-----------------------------------------------------------------*/
2648 geniCodePostDec (operand * op)
2652 sym_link *optype = operandType (op);
2654 operand *rv = (IS_ITEMP (op) ?
2655 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2657 sym_link *rvtype = operandType (rv);
2660 /* if this is not an address we have trouble */
2663 werror (E_LVALUE_REQUIRED, "--");
2667 rOp = newiTempOperand (rvtype, 0);
2668 OP_SYMBOL(rOp)->noSpilLoc = 1;
2671 OP_SYMBOL(rv)->noSpilLoc = 1;
2673 geniCodeAssign (rOp, rv, 0, 0);
2675 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2677 werror(W_SIZEOF_VOID);
2678 if (IS_FLOAT (rvtype))
2679 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2680 else if (IS_FIXED16X16 (rvtype))
2681 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2683 ic = newiCode ('-', rv, operandFromLit (size));
2685 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2688 geniCodeAssign (op, result, 0, 0);
2694 /*-----------------------------------------------------------------*/
2695 /* geniCodePreDec - generate code for pre decrement */
2696 /*-----------------------------------------------------------------*/
2698 geniCodePreDec (operand * op, bool lvalue)
2701 sym_link *optype = operandType (op);
2702 operand *rop = (IS_ITEMP (op) ?
2703 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2705 sym_link *roptype = operandType (rop);
2711 werror (E_LVALUE_REQUIRED, "--");
2715 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2717 werror(W_SIZEOF_VOID);
2718 if (IS_FLOAT (roptype))
2719 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2720 else if (IS_FIXED16X16 (roptype))
2721 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2723 ic = newiCode ('-', rop, operandFromLit (size));
2724 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2727 (void) geniCodeAssign (op, result, 0, 0);
2728 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2735 /*-----------------------------------------------------------------*/
2736 /* geniCodeBitwise - gen int code for bitWise operators */
2737 /*-----------------------------------------------------------------*/
2739 geniCodeBitwise (operand * left, operand * right,
2740 int oper, sym_link * resType)
2744 left = geniCodeCast (resType, left, TRUE);
2745 right = geniCodeCast (resType, right, TRUE);
2747 ic = newiCode (oper, left, right);
2748 IC_RESULT (ic) = newiTempOperand (resType, 0);
2751 return IC_RESULT (ic);
2754 /*-----------------------------------------------------------------*/
2755 /* geniCodeAddressOf - gens icode for '&' address of operator */
2756 /*-----------------------------------------------------------------*/
2758 geniCodeAddressOf (operand * op)
2762 sym_link *optype = operandType (op);
2763 sym_link *opetype = getSpec (optype);
2765 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2767 op = operandFromOperand (op);
2772 /* lvalue check already done in decorateType */
2773 /* this must be a lvalue */
2774 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2775 /* werror (E_LVALUE_REQUIRED,"&"); */
2779 p = newLink (DECLARATOR);
2781 /* set the pointer depending on the storage class */
2782 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2784 p->next = copyLinkChain (optype);
2786 /* if already a temp */
2789 setOperandType (op, p);
2794 /* otherwise make this of the type coming in */
2795 ic = newiCode (ADDRESS_OF, op, NULL);
2796 IC_RESULT (ic) = newiTempOperand (p, 1);
2797 IC_RESULT (ic)->isaddr = 0;
2799 return IC_RESULT (ic);
2802 /*-----------------------------------------------------------------*/
2803 /* setOClass - sets the output class depending on the pointer type */
2804 /*-----------------------------------------------------------------*/
2806 setOClass (sym_link * ptr, sym_link * spec)
2808 switch (DCL_TYPE (ptr))
2811 SPEC_OCLS (spec) = data;
2815 SPEC_OCLS (spec) = generic;
2819 SPEC_OCLS (spec) = xdata;
2823 SPEC_OCLS (spec) = code;
2827 SPEC_OCLS (spec) = idata;
2831 SPEC_OCLS (spec) = xstack;
2835 SPEC_OCLS (spec) = eeprom;
2844 /*-----------------------------------------------------------------*/
2845 /* geniCodeDerefPtr - dereference pointer with '*' */
2846 /*-----------------------------------------------------------------*/
2848 geniCodeDerefPtr (operand * op,int lvl)
2850 sym_link *rtype, *retype;
2851 sym_link *optype = operandType (op);
2853 // if this is an array then array access
2854 if (IS_ARRAY (optype)) {
2855 // don't worry, this will be optimized out later
2856 return geniCodeArray (op, operandFromLit (0), lvl);
2859 // just in case someone screws up
2860 wassert (IS_PTR (optype));
2862 if (IS_TRUE_SYMOP (op))
2865 op = geniCodeRValue (op, TRUE);
2868 /* now get rid of the pointer part */
2869 if (isLvaluereq(lvl) && IS_ITEMP (op))
2871 retype = getSpec (rtype = copyLinkChain (optype));
2875 retype = getSpec (rtype = copyLinkChain (optype->next));
2876 /* outputclass needs 2b updated */
2877 setOClass (optype, retype);
2880 op->isGptr = IS_GENPTR (optype);
2882 op->isaddr = (IS_PTR (rtype) ||
2883 IS_STRUCT (rtype) ||
2889 if (!isLvaluereq(lvl))
2890 op = geniCodeRValue (op, TRUE);
2892 setOperandType (op, rtype);
2897 /*-----------------------------------------------------------------*/
2898 /* geniCodeUnaryMinus - does a unary minus of the operand */
2899 /*-----------------------------------------------------------------*/
2901 geniCodeUnaryMinus (operand * op)
2904 sym_link *optype = operandType (op);
2906 if (IS_LITERAL (optype))
2907 return operandFromLit (-floatFromVal (op->operand.valOperand));
2909 ic = newiCode (UNARYMINUS, op, NULL);
2910 IC_RESULT (ic) = newiTempOperand (optype, 0);
2912 return IC_RESULT (ic);
2915 /*-----------------------------------------------------------------*/
2916 /* geniCodeLeftShift - gen i code for left shift */
2917 /*-----------------------------------------------------------------*/
2919 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2924 ic = newiCode (LEFT_OP, left, right);
2926 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2927 IC_RESULT (ic) = newiTempOperand (resType, 0);
2929 return IC_RESULT (ic);
2932 /*-----------------------------------------------------------------*/
2933 /* geniCodeRightShift - gen i code for right shift */
2934 /*-----------------------------------------------------------------*/
2936 geniCodeRightShift (operand * left, operand * right)
2940 ic = newiCode (RIGHT_OP, left, right);
2941 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2943 return IC_RESULT (ic);
2946 /*-----------------------------------------------------------------*/
2947 /* geniCodeLogic- logic code */
2948 /*-----------------------------------------------------------------*/
2950 geniCodeLogic (operand * left, operand * right, int op, ast *tree)
2953 sym_link *ctype, *ttype;
2954 sym_link *rtype = operandType (right);
2955 sym_link *ltype = operandType (left);
2957 /* left is integral type and right is literal then
2958 check if the literal value is within bounds */
2959 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2961 CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE);
2964 case CCR_ALWAYS_TRUE:
2965 case CCR_ALWAYS_FALSE:
2966 if (!options.lessPedantic)
2967 werror (W_COMP_RANGE, "true resp. false");
2968 return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0);
2974 /* if one operand is a pointer and the other is a literal generic void pointer,
2975 change the type of the literal generic void pointer to match the other pointer */
2976 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2977 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2979 /* find left's definition */
2980 ic = (iCode *) setFirstItem (iCodeChain);
2983 if (((ic->op == CAST) || (ic->op == '='))
2984 && isOperandEqual(left, IC_RESULT (ic)))
2987 ic = setNextItem (iCodeChain);
2989 /* if casting literal to generic pointer, then cast to rtype instead */
2990 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2992 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2993 ltype = operandType(left);
2996 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2997 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2999 /* find right's definition */
3000 ic = (iCode *) setFirstItem (iCodeChain);
3003 if (((ic->op == CAST) || (ic->op == '='))
3004 && isOperandEqual(right, IC_RESULT (ic)))
3007 ic = setNextItem (iCodeChain);
3009 /* if casting literal to generic pointer, then cast to rtype instead */
3010 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3012 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3013 rtype = operandType(right);
3017 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
3019 ic = newiCode (op, left, right);
3020 /* store 0 or 1 in result */
3021 ttype = (tree && IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3022 IC_RESULT (ic) = newiTempOperand (ttype, 1);
3024 /* if comparing float
3025 and not a '==' || '!=' || '&&' || '||' (these
3027 if (IS_FLOAT(ctype) &&
3034 /* if comparing a fixed type use support functions */
3035 if (IS_FIXED(ctype))
3039 return IC_RESULT (ic);
3042 /*-----------------------------------------------------------------*/
3043 /* geniCodeLogicAndOr - && || operations */
3044 /*-----------------------------------------------------------------*/
3046 geniCodeLogicAndOr (ast *tree, int lvl)
3050 symbol *falseLabel = newiTempLabel (NULL);
3051 symbol *trueLabel = newiTempLabel (NULL);
3052 symbol *exitLabel = newiTempLabel (NULL);
3053 operand *op, *result, *condition;
3055 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3056 They can be reenabled by executing the following block. If you find
3057 a decent optimization you could start right here:
3062 operand *leftOp, *rightOp;
3064 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3065 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3067 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3071 /* generate two IFX for the '&&' or '||' op */
3073 /* evaluate left operand */
3074 condition = ast2iCode (tree->left, lvl + 1);
3075 op = geniCodeRValue (condition, FALSE);
3077 /* test left operand */
3078 if (tree->opval.op == AND_OP)
3079 ic = newiCodeCondition (op, NULL, falseLabel);
3081 ic = newiCodeCondition (op, trueLabel, NULL);
3084 /* evaluate right operand */
3085 condition = ast2iCode (tree->right, lvl + 1);
3086 op = geniCodeRValue (condition, FALSE);
3088 /* test right operand */
3089 ic = newiCodeCondition (op, trueLabel, NULL);
3092 /* store 0 or 1 in result */
3093 type = (IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3094 result = newiTempOperand (type, 1);
3096 geniCodeLabel (falseLabel);
3097 geniCodeAssign (result, operandFromLit (0), 0, 0);
3098 /* generate an unconditional goto */
3099 geniCodeGoto (exitLabel);
3101 geniCodeLabel (trueLabel);
3102 geniCodeAssign (result, operandFromLit (1), 0, 0);
3104 geniCodeLabel (exitLabel);
3109 /*-----------------------------------------------------------------*/
3110 /* geniCodeUnary - for a generic unary operation */
3111 /*-----------------------------------------------------------------*/
3113 geniCodeUnary (operand * op, int oper)
3115 iCode *ic = newiCode (oper, op, NULL);
3117 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3119 return IC_RESULT (ic);
3122 /*-----------------------------------------------------------------*/
3123 /* geniCodeBinary - for a generic binary operation */
3124 /*-----------------------------------------------------------------*/
3126 geniCodeBinary (operand * left, operand * right, int oper)
3128 iCode *ic = newiCode (oper, left, right);
3130 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3132 return IC_RESULT (ic);
3135 /*-----------------------------------------------------------------*/
3136 /* geniCodeConditional - geniCode for '?' ':' operation */
3137 /*-----------------------------------------------------------------*/
3139 geniCodeConditional (ast * tree,int lvl)
3142 symbol *falseLabel = newiTempLabel (NULL);
3143 symbol *exitLabel = newiTempLabel (NULL);
3144 operand *cond = ast2iCode (tree->left,lvl+1);
3145 operand *true, *false, *result;
3147 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3151 true = ast2iCode (tree->right->left,lvl+1);
3153 /* move the value to a new Operand */
3154 result = newiTempOperand (tree->right->ftype, 0);
3155 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3157 /* generate an unconditional goto */
3158 geniCodeGoto (exitLabel);
3160 /* now for the right side */
3161 geniCodeLabel (falseLabel);
3163 false = ast2iCode (tree->right->right,lvl+1);
3164 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3166 /* create the exit label */
3167 geniCodeLabel (exitLabel);
3172 /*-----------------------------------------------------------------*/
3173 /* geniCodeAssign - generate code for assignment */
3174 /*-----------------------------------------------------------------*/
3176 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3179 sym_link *ltype = operandType (left);
3180 sym_link *rtype = operandType (right);
3182 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3184 werror (E_LVALUE_REQUIRED, "assignment");
3188 /* left is integral type and right is literal then
3189 check if the literal value is within bounds */
3190 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3191 checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3192 !options.lessPedantic)
3194 werror (W_LIT_OVERFLOW);
3197 /* if the left & right type don't exactly match */
3198 /* if pointer set then make sure the check is
3199 done with the type & not the pointer */
3200 /* then cast rights type to left */
3202 /* first check the type for pointer assignement */
3203 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3204 compareType (ltype, rtype) <= 0)
3206 if (compareType (ltype->next, rtype) < 0)
3207 right = geniCodeCast (ltype->next, right, TRUE);
3209 else if (compareType (ltype, rtype) < 0)
3210 right = geniCodeCast (ltype, right, TRUE);
3212 /* If left is a true symbol & ! volatile
3213 create an assignment to temporary for
3214 the right & then assign this temporary
3215 to the symbol. This is SSA (static single
3216 assignment). Isn't it simple and folks have
3217 published mountains of paper on it */
3218 if (IS_TRUE_SYMOP (left) &&
3219 !isOperandVolatile (left, FALSE) &&
3220 isOperandGlobal (left))
3225 if (IS_TRUE_SYMOP (right))
3226 sym = OP_SYMBOL (right);
3227 ic = newiCode ('=', NULL, right);
3228 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3229 /* avoid double fetch from volatile right, see bug 1369874 */
3230 if (!isOperandVolatile (right, FALSE))
3231 SPIL_LOC (newRight) = sym;
3236 ic = newiCode ('=', NULL, right);
3237 IC_RESULT (ic) = left;
3240 /* if left isgptr flag is set then support
3241 routine will be required */
3245 ic->nosupdate = nosupdate;
3246 /* left could be a pointer assignment,
3247 return the properly casted right instead */
3251 /*-----------------------------------------------------------------*/
3252 /* geniCodeDummyRead - generate code for dummy read */
3253 /*-----------------------------------------------------------------*/
3255 geniCodeDummyRead (operand * op)
3258 sym_link *type = operandType (op);
3260 if (!IS_VOLATILE(type))
3263 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3269 /*-----------------------------------------------------------------*/
3270 /* geniCodeSEParms - generate code for side effecting fcalls */
3271 /*-----------------------------------------------------------------*/
3273 geniCodeSEParms (ast * parms,int lvl)
3278 if (parms->type == EX_OP && parms->opval.op == PARAM)
3280 geniCodeSEParms (parms->left,lvl);
3281 geniCodeSEParms (parms->right,lvl);
3285 /* hack don't like this but too lazy to think of
3287 if (IS_ADDRESS_OF_OP (parms))
3288 parms->left->lvalue = 1;
3290 if (IS_CAST_OP (parms) &&
3291 IS_PTR (parms->ftype) &&
3292 IS_ADDRESS_OF_OP (parms->right))
3293 parms->right->left->lvalue = 1;
3295 parms->opval.oprnd =
3296 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3298 parms->type = EX_OPERAND;
3299 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3300 SPEC_ARGREG(parms->ftype);
3303 /*-----------------------------------------------------------------*/
3304 /* geniCodeParms - generates parameters */
3305 /*-----------------------------------------------------------------*/
3307 geniCodeParms (ast * parms, value *argVals, int *stack,
3308 sym_link * ftype, int lvl)
3316 if (argVals==NULL) {
3318 argVals = FUNC_ARGS (ftype);
3321 /* if this is a param node then do the left & right */
3322 if (parms->type == EX_OP && parms->opval.op == PARAM)
3324 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3325 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3329 /* get the parameter value */
3330 if (parms->type == EX_OPERAND)
3331 pval = parms->opval.oprnd;
3334 /* maybe this else should go away ?? */
3335 /* hack don't like this but too lazy to think of
3337 if (IS_ADDRESS_OF_OP (parms))
3338 parms->left->lvalue = 1;
3340 if (IS_CAST_OP (parms) &&
3341 IS_PTR (parms->ftype) &&
3342 IS_ADDRESS_OF_OP (parms->right))
3343 parms->right->left->lvalue = 1;
3345 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3348 /* if register parm then make it a send */
3349 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3350 IFFUNC_ISBUILTIN(ftype))
3352 ic = newiCode (SEND, pval, NULL);
3353 ic->argreg = SPEC_ARGREG(parms->etype);
3354 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3359 /* now decide whether to push or assign */
3360 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3364 operand *top = operandFromSymbol (argVals->sym);
3365 /* clear useDef and other bitVectors */
3366 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3367 geniCodeAssign (top, pval, 1, 0);
3371 sym_link *p = operandType (pval);
3373 ic = newiCode (IPUSH, pval, NULL);
3375 /* update the stack adjustment */
3376 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3381 argVals=argVals->next;
3385 /*-----------------------------------------------------------------*/
3386 /* geniCodeCall - generates temp code for calling */
3387 /*-----------------------------------------------------------------*/
3389 geniCodeCall (operand * left, ast * parms,int lvl)
3393 sym_link *type, *etype;
3397 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3398 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3399 werror (E_FUNCTION_EXPECTED);
3400 return operandFromValue(valueFromLit(0));
3403 /* take care of parameters with side-effecting
3404 function calls in them, this is required to take care
3405 of overlaying function parameters */
3406 geniCodeSEParms (parms,lvl);
3408 ftype = operandType (left);
3409 if (IS_FUNCPTR (ftype))
3410 ftype = ftype->next;
3412 /* first the parameters */
3413 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3415 /* now call : if symbol then pcall */
3416 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3417 ic = newiCode (PCALL, left, NULL);
3419 ic = newiCode (CALL, left, NULL);
3422 type = copyLinkChain (ftype->next);
3423 etype = getSpec (type);
3424 SPEC_EXTR (etype) = 0;
3425 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3429 /* stack adjustment after call */
3430 ic->parmBytes = stack;
3435 /*-----------------------------------------------------------------*/
3436 /* geniCodeReceive - generate intermediate code for "receive" */
3437 /*-----------------------------------------------------------------*/
3439 geniCodeReceive (value * args, operand * func)
3441 unsigned char paramByteCounter = 0;
3443 /* for all arguments that are passed in registers */
3446 if (IS_REGPARM (args->etype))
3448 operand *opr = operandFromValue (args);
3450 symbol *sym = OP_SYMBOL (opr);
3453 /* we will use it after all optimizations
3454 and before liveRange calculation */
3455 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3458 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3459 options.stackAuto == 0 &&
3460 (!(options.model == MODEL_FLAT24)) )
3465 opl = newiTempOperand (args->type, 0);
3467 sym->reqv->key = sym->key;
3468 OP_SYMBOL (sym->reqv)->key = sym->key;
3469 OP_SYMBOL (sym->reqv)->isreqv = 1;
3470 OP_SYMBOL (sym->reqv)->islocal = 0;
3471 SPIL_LOC (sym->reqv) = sym;
3475 ic = newiCode (RECEIVE, func, NULL);
3476 ic->argreg = SPEC_ARGREG(args->etype);
3477 if (ic->argreg == 1) {
3478 currFunc->recvSize = getSize (sym->type);
3480 IC_RESULT (ic) = opr;
3482 /* misuse of parmBytes (normally used for functions)
3483 * to save estimated stack position of this argument.
3484 * Normally this should be zero for RECEIVE iCodes.
3485 * No idea if this causes side effects on other ports. - dw
3487 ic->parmBytes = paramByteCounter;
3489 /* what stack position do we have? */
3490 paramByteCounter += getSize (sym->type);
3499 /*-----------------------------------------------------------------*/
3500 /* geniCodeFunctionBody - create the function body */
3501 /*-----------------------------------------------------------------*/
3503 geniCodeFunctionBody (ast * tree,int lvl)
3510 /* reset the auto generation */
3516 func = ast2iCode (tree->left,lvl+1);
3517 fetype = getSpec (operandType (func));
3519 savelineno = lineno;
3520 lineno = OP_SYMBOL (func)->lineDef;
3521 /* create an entry label */
3522 geniCodeLabel (entryLabel);
3523 lineno = savelineno;
3525 /* create a proc icode */
3526 ic = newiCode (FUNCTION, func, NULL);
3527 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3532 /* for all parameters that are passed
3533 on registers add a "receive" */
3534 geniCodeReceive (tree->values.args, func);
3536 /* generate code for the body */
3537 ast2iCode (tree->right,lvl+1);
3539 /* create a label for return */
3540 geniCodeLabel (returnLabel);
3542 /* now generate the end proc */
3543 ic = newiCode (ENDFUNCTION, func, NULL);
3549 /*-----------------------------------------------------------------*/
3550 /* geniCodeReturn - gen icode for 'return' statement */
3551 /*-----------------------------------------------------------------*/
3553 geniCodeReturn (operand * op)
3557 /* if the operand is present force an rvalue */
3559 op = geniCodeRValue (op, FALSE);
3561 ic = newiCode (RETURN, op, NULL);
3565 /*-----------------------------------------------------------------*/
3566 /* geniCodeIfx - generates code for extended if statement */
3567 /*-----------------------------------------------------------------*/
3569 geniCodeIfx (ast * tree,int lvl)
3572 operand *condition = ast2iCode (tree->left,lvl+1);
3575 /* if condition is null then exit */
3579 condition = geniCodeRValue (condition, FALSE);
3581 cetype = getSpec (operandType (condition));
3582 /* if the condition is a literal */
3583 if (IS_LITERAL (cetype))
3585 if (floatFromVal (condition->operand.valOperand))
3587 if (tree->trueLabel)
3588 geniCodeGoto (tree->trueLabel);
3594 if (tree->falseLabel)
3595 geniCodeGoto (tree->falseLabel);
3600 if (tree->trueLabel)
3602 ic = newiCodeCondition (condition,
3607 if (tree->falseLabel)
3608 geniCodeGoto (tree->falseLabel);
3612 ic = newiCodeCondition (condition,
3619 ast2iCode (tree->right,lvl+1);
3622 /*-----------------------------------------------------------------*/
3623 /* geniCodeJumpTable - tries to create a jump table for switch */
3624 /*-----------------------------------------------------------------*/
3626 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3628 int min, max, cnt = 1;
3635 int needRangeCheck = !optimize.noJTabBoundary
3636 || tree->values.switchVals.swDefault;
3637 sym_link *cetype = getSpec (operandType (cond));
3638 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3639 int sizeofMatchJump, sizeofJumpTable;
3642 if (!tree || !caseVals)
3645 /* the criteria for creating a jump table is */
3646 /* all integer numbers between the maximum & minimum must */
3647 /* be present , the maximum value should not exceed 255 */
3648 /* If not all integer numbers are present the algorithm */
3649 /* inserts jumps to the default label for the missing numbers */
3650 /* and decides later whether it is worth it */
3651 min = (int) floatFromVal (vch = caseVals);
3658 max = (int) floatFromVal (vch);
3660 /* Exit if the range is too large to handle with a jump table. */
3661 if (1 + max - min > port->jumptableCost.maxCount)
3664 switch (getSize (operandType (cond)))
3666 case 1: sizeIndex = 0; break;
3667 case 2: sizeIndex = 1; break;
3668 case 4: sizeIndex = 2; break;
3672 /* Compute the size cost of the range check and subtraction. */
3674 sizeofZeroMinCost = 0;
3678 if (!(min==0 && IS_UNSIGNED (cetype)))
3679 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3680 if (!IS_UNSIGNED (cetype))
3681 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3682 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3685 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3687 /* If the size cost of handling a non-zero minimum exceeds the */
3688 /* cost of extending the range down to zero, then it might be */
3689 /* better to extend the range to zero. */
3690 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3691 >= (min * port->jumptableCost.sizeofElement))
3693 /* Only extend the jump table if it would still be manageable. */
3694 if (1 + max <= port->jumptableCost.maxCount)
3697 if (IS_UNSIGNED (cetype))
3700 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3704 /* Compute the total size cost of a jump table. */
3705 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3706 + port->jumptableCost.sizeofDispatch
3707 + sizeofMinCost + sizeofMaxCost;
3709 /* Compute the total size cost of a match & jump sequence */
3710 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3712 /* If the size cost of the jump table is uneconomical then exit */
3713 if (sizeofMatchJump < sizeofJumpTable)
3716 /* The jump table is preferable. */
3718 /* First, a label for the default or missing cases. */
3719 if (tree->values.switchVals.swDefault)
3721 SNPRINTF (buffer, sizeof(buffer),
3723 tree->values.switchVals.swNum);
3727 SNPRINTF (buffer, sizeof(buffer),
3729 tree->values.switchVals.swNum);
3731 falseLabel = newiTempLabel (buffer);
3733 /* Build the list of labels for the jump table. */
3735 t = (int) floatFromVal (vch);
3736 for (i=min; i<=max; i++)
3740 /* Explicit case: make a new label for it. */
3741 SNPRINTF (buffer, sizeof(buffer),
3743 tree->values.switchVals.swNum,
3745 addSet (&labels, newiTempLabel (buffer));
3748 t = (int) floatFromVal (vch);
3752 /* Implicit case: use the default label. */
3753 addSet (&labels, falseLabel);
3757 /* first we rule out the boundary conditions */
3758 /* if only optimization says so */
3761 sym_link *cetype = getSpec (operandType (cond));
3762 /* no need to check the lower bound if
3763 the condition is unsigned & minimum value is zero */
3764 if (!(min == 0 && IS_UNSIGNED (cetype)))
3766 boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL);
3767 ic = newiCodeCondition (boundary, falseLabel, NULL);
3771 /* now for upper bounds */
3772 boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL);
3773 ic = newiCodeCondition (boundary, falseLabel, NULL);
3777 /* if the min is not zero then we no make it zero */
3780 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3781 if (!IS_LITERAL(getSpec(operandType(cond))))
3782 setOperandType (cond, UCHARTYPE);
3785 /* now create the jumptable */
3786 ic = newiCode (JUMPTABLE, NULL, NULL);
3787 IC_JTCOND (ic) = cond;
3788 IC_JTLABELS (ic) = labels;
3793 /*-----------------------------------------------------------------*/
3794 /* geniCodeSwitch - changes a switch to a if statement */
3795 /*-----------------------------------------------------------------*/
3797 geniCodeSwitch (ast * tree,int lvl)
3800 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3801 value *caseVals = tree->values.switchVals.swVals;
3802 symbol *trueLabel, *falseLabel;
3804 /* If the condition is a literal, then just jump to the */
3805 /* appropriate case label. */
3806 if (IS_LITERAL(getSpec(operandType(cond))))
3808 int switchVal, caseVal;
3810 switchVal = (int) floatFromVal (cond->operand.valOperand);
3813 caseVal = (int) floatFromVal (caseVals);
3814 if (caseVal == switchVal)
3816 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3817 tree->values.switchVals.swNum, caseVal);
3818 trueLabel = newiTempLabel (buffer);
3819 geniCodeGoto (trueLabel);
3822 caseVals = caseVals->next;
3824 goto defaultOrBreak;
3827 /* If cond is volatile, it might change while we are trying to */
3828 /* find the matching case. To avoid this possibility, make a */
3829 /* non-volatile copy to use instead. */
3830 if (IS_OP_VOLATILE (cond))
3835 newcond = newiTempOperand (operandType (cond), TRUE);
3836 newcond->isvolatile = 0;
3837 ic = newiCode ('=', NULL, cond);
3838 IC_RESULT (ic) = newcond;
3843 /* if we can make this a jump table */
3844 if (geniCodeJumpTable (cond, caseVals, tree))
3845 goto jumpTable; /* no need for the comparison */
3847 /* for the cases defined do */
3851 operand *compare = geniCodeLogic (cond,
3852 operandFromValue (caseVals),
3855 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3856 tree->values.switchVals.swNum,
3857 (int) floatFromVal (caseVals));
3858 trueLabel = newiTempLabel (buffer);
3860 ic = newiCodeCondition (compare, trueLabel, NULL);
3862 caseVals = caseVals->next;
3867 /* if default is present then goto break else break */
3868 if (tree->values.switchVals.swDefault)
3870 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3874 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3877 falseLabel = newiTempLabel (buffer);
3878 geniCodeGoto (falseLabel);
3881 ast2iCode (tree->right,lvl+1);
3884 /*-----------------------------------------------------------------*/
3885 /* geniCodeInline - intermediate code for inline assembler */
3886 /*-----------------------------------------------------------------*/
3888 geniCodeInline (ast * tree)
3892 ic = newiCode (INLINEASM, NULL, NULL);
3893 IC_INLINE (ic) = tree->values.inlineasm;
3897 /*-----------------------------------------------------------------*/
3898 /* geniCodeArrayInit - intermediate code for array initializer */
3899 /*-----------------------------------------------------------------*/
3901 geniCodeArrayInit (ast * tree, operand *array)
3905 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3906 ic = newiCode (ARRAYINIT, array, NULL);
3907 IC_ARRAYILIST (ic) = tree->values.constlist;
3909 operand *left=newOperand(), *right=newOperand();
3910 left->type=right->type=SYMBOL;
3911 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3912 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3913 ic = newiCode (ARRAYINIT, left, right);
3918 /*-----------------------------------------------------------------*/
3919 /* geniCodeCritical - intermediate code for a critical statement */
3920 /*-----------------------------------------------------------------*/
3922 geniCodeCritical (ast *tree, int lvl)
3928 if (!options.stackAuto)
3930 type = newLink(SPECIFIER);
3931 SPEC_VOLATILE(type) = 1;
3932 SPEC_NOUN(type) = V_BIT;
3933 SPEC_SCLS(type) = S_BIT;
3934 SPEC_BLEN(type) = 1;
3935 SPEC_BSTR(type) = 0;
3936 op = newiTempOperand(type, 1);
3939 /* If op is NULL, the original interrupt state will saved on */
3940 /* the stack. Otherwise, it will be saved in op. */
3942 /* Generate a save of the current interrupt state & disable */
3943 ic = newiCode (CRITICAL, NULL, NULL);
3944 IC_RESULT (ic) = op;
3947 /* Generate the critical code sequence */
3948 if (tree->left && tree->left->type == EX_VALUE)
3949 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3951 ast2iCode (tree->left,lvl+1);
3953 /* Generate a restore of the original interrupt state */
3954 ic = newiCode (ENDCRITICAL, NULL, op);
3958 /*-----------------------------------------------------------------*/
3959 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3960 /* particular case. Ie : assigning or dereferencing array or ptr */
3961 /*-----------------------------------------------------------------*/
3962 set * lvaluereqSet = NULL;
3963 typedef struct lvalItem
3970 /*-----------------------------------------------------------------*/
3971 /* addLvaluereq - add a flag for lvalreq for current ast level */
3972 /*-----------------------------------------------------------------*/
3973 void addLvaluereq(int lvl)
3975 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3978 addSetHead(&lvaluereqSet,lpItem);
3981 /*-----------------------------------------------------------------*/
3982 /* delLvaluereq - del a flag for lvalreq for current ast level */
3983 /*-----------------------------------------------------------------*/
3987 lpItem = getSet(&lvaluereqSet);
3988 if(lpItem) Safe_free(lpItem);
3990 /*-----------------------------------------------------------------*/
3991 /* clearLvaluereq - clear lvalreq flag */
3992 /*-----------------------------------------------------------------*/
3993 void clearLvaluereq()
3996 lpItem = peekSet(lvaluereqSet);
3997 if(lpItem) lpItem->req = 0;
3999 /*-----------------------------------------------------------------*/
4000 /* getLvaluereq - get the last lvalreq level */
4001 /*-----------------------------------------------------------------*/
4002 int getLvaluereqLvl()
4005 lpItem = peekSet(lvaluereqSet);
4006 if(lpItem) return lpItem->lvl;
4009 /*-----------------------------------------------------------------*/
4010 /* isLvaluereq - is lvalreq valid for this level ? */
4011 /*-----------------------------------------------------------------*/
4012 int isLvaluereq(int lvl)
4015 lpItem = peekSet(lvaluereqSet);
4016 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4020 /*-----------------------------------------------------------------*/
4021 /* ast2iCode - creates an icodeList from an ast */
4022 /*-----------------------------------------------------------------*/
4024 ast2iCode (ast * tree,int lvl)
4026 operand *left = NULL;
4027 operand *right = NULL;
4031 /* set the global variables for filename & line number */
4033 filename = tree->filename;
4035 lineno = tree->lineno;
4037 block = tree->block;
4039 scopeLevel = tree->level;
4041 seqPoint = tree->seqPoint;
4043 if (tree->type == EX_VALUE)
4044 return operandFromValue (tree->opval.val);
4046 if (tree->type == EX_LINK)
4047 return operandFromLink (tree->opval.lnk);
4049 /* if we find a nullop */
4050 if (tree->type == EX_OP &&
4051 (tree->opval.op == NULLOP ||
4052 tree->opval.op == BLOCK))
4054 if (tree->left && tree->left->type == EX_VALUE)
4055 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4057 ast2iCode (tree->left,lvl+1);
4058 if (tree->right && tree->right->type == EX_VALUE)
4059 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4061 ast2iCode (tree->right,lvl+1);
4065 /* special cases for not evaluating */
4066 if (tree->opval.op != ':' &&
4067 tree->opval.op != '?' &&
4068 tree->opval.op != CALL &&
4069 tree->opval.op != IFX &&
4070 tree->opval.op != AND_OP &&
4071 tree->opval.op != OR_OP &&
4072 tree->opval.op != LABEL &&
4073 tree->opval.op != GOTO &&
4074 tree->opval.op != SWITCH &&
4075 tree->opval.op != FUNCTION &&
4076 tree->opval.op != INLINEASM &&
4077 tree->opval.op != CRITICAL)
4080 if (IS_ASSIGN_OP (tree->opval.op) ||
4081 IS_DEREF_OP (tree) ||
4082 (tree->opval.op == '&' && !tree->right) ||
4083 tree->opval.op == PTR_OP)
4086 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4087 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4090 left = operandFromAst (tree->left,lvl);
4092 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4093 left = geniCodeRValue (left, TRUE);
4097 left = operandFromAst (tree->left,lvl);
4099 if (tree->opval.op == INC_OP ||
4100 tree->opval.op == DEC_OP)
4103 right = operandFromAst (tree->right,lvl);
4108 right = operandFromAst (tree->right,lvl);
4112 /* now depending on the type of operand */
4113 /* this will be a biggy */
4114 switch (tree->opval.op)
4117 case '[': /* array operation */
4119 //sym_link *ltype = operandType (left);
4120 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4121 left = geniCodeRValue (left, FALSE);
4122 right = geniCodeRValue (right, TRUE);
4125 return geniCodeArray (left, right,lvl);
4127 case '.': /* structure dereference */
4128 if (IS_PTR (operandType (left)))
4129 left = geniCodeRValue (left, TRUE);
4131 left = geniCodeRValue (left, FALSE);
4133 return geniCodeStruct (left, right, tree->lvalue);
4135 case PTR_OP: /* structure pointer dereference */
4138 pType = operandType (left);
4139 left = geniCodeRValue (left, TRUE);
4141 setOClass (pType, getSpec (operandType (left)));
4144 return geniCodeStruct (left, right, tree->lvalue);
4146 case INC_OP: /* increment operator */
4148 return geniCodePostInc (left);
4150 return geniCodePreInc (right, tree->lvalue);
4152 case DEC_OP: /* decrement operator */
4154 return geniCodePostDec (left);
4156 return geniCodePreDec (right, tree->lvalue);
4158 case '&': /* bitwise and or address of operator */
4160 { /* this is a bitwise operator */
4161 left = geniCodeRValue (left, FALSE);
4162 right = geniCodeRValue (right, FALSE);
4163 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4166 return geniCodeAddressOf (left);
4168 case '|': /* bitwise or & xor */
4170 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4171 geniCodeRValue (right, FALSE),
4176 return geniCodeDivision (geniCodeRValue (left, FALSE),
4177 geniCodeRValue (right, FALSE),
4178 getResultTypeFromType (tree->ftype));
4181 return geniCodeModulus (geniCodeRValue (left, FALSE),
4182 geniCodeRValue (right, FALSE),
4183 getResultTypeFromType (tree->ftype));
4186 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4187 geniCodeRValue (right, FALSE),
4188 getResultTypeFromType (tree->ftype));
4190 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4194 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4195 geniCodeRValue (right, FALSE),
4196 getResultTypeFromType (tree->ftype));
4198 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4202 return geniCodeAdd (geniCodeRValue (left, FALSE),
4203 geniCodeRValue (right, FALSE),
4204 getResultTypeFromType (tree->ftype),
4207 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4210 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4211 geniCodeRValue (right, FALSE),
4212 getResultTypeFromType (tree->ftype));
4215 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4216 geniCodeRValue (right, FALSE));
4218 #if 0 // this indeed needs a second thought
4222 // let's keep this simple: get the rvalue we need
4223 op=geniCodeRValue (right, FALSE);
4224 // now cast it to whatever we want
4225 op=geniCodeCast (operandType(left), op, FALSE);
4226 // if this is going to be used as an lvalue, make it so
4232 #else // bug #604575, is it a bug ????
4233 return geniCodeCast (operandType (left),
4234 geniCodeRValue (right, FALSE), FALSE);
4241 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4246 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4247 if (!IS_BIT (operandType (op)))
4248 setOperandType (op, UCHARTYPE);
4253 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4254 geniCodeRValue (right, FALSE),
4256 if (!IS_BIT (operandType (op)))
4257 setOperandType (op, UCHARTYPE);
4262 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4263 geniCodeRValue (right, FALSE),
4265 setOperandType (op, UCHARTYPE);
4270 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4271 geniCodeRValue (right, FALSE),
4273 setOperandType (op, UINTTYPE);
4278 return geniCodeLogicAndOr (tree, lvl);
4285 /* different compilers (even different gccs) evaluate
4286 the two calls in a different order. to get the same
4287 result on all machines we have to specify a clear sequence.
4288 return geniCodeLogic (geniCodeRValue (left, FALSE),
4289 geniCodeRValue (right, FALSE),
4293 operand *leftOp, *rightOp;
4295 leftOp = geniCodeRValue (left , FALSE);
4296 rightOp = geniCodeRValue (right, FALSE);
4298 return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree);
4301 return geniCodeConditional (tree,lvl);
4304 return operandFromLit (getSize (tree->right->ftype));
4308 sym_link *rtype = operandType (right);
4309 sym_link *ltype = operandType (left);
4310 if (IS_PTR (rtype) && IS_ITEMP (right)
4311 && right->isaddr && compareType (rtype->next, ltype) == 1)
4312 right = geniCodeRValue (right, TRUE);
4314 right = geniCodeRValue (right, FALSE);
4316 return geniCodeAssign (left, right, 0, 1);
4320 geniCodeAssign (left,
4321 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4323 geniCodeRValue (right, FALSE),
4324 getResultTypeFromType (tree->ftype)),
4329 geniCodeAssign (left,
4330 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4332 geniCodeRValue (right, FALSE),
4333 getResultTypeFromType (tree->ftype)),
4337 geniCodeAssign (left,
4338 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4340 geniCodeRValue (right, FALSE),
4341 getResultTypeFromType (tree->ftype)),
4345 sym_link *rtype = operandType (right);
4346 sym_link *ltype = operandType (left);
4347 if (IS_PTR (rtype) && IS_ITEMP (right)
4348 && right->isaddr && compareType (rtype->next, ltype) == 1)
4349 right = geniCodeRValue (right, TRUE);
4351 right = geniCodeRValue (right, FALSE);
4354 return geniCodeAssign (left,
4355 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4358 getResultTypeFromType (tree->ftype),
4364 sym_link *rtype = operandType (right);
4365 sym_link *ltype = operandType (left);
4366 if (IS_PTR (rtype) && IS_ITEMP (right)
4367 && right->isaddr && compareType (rtype->next, ltype) == 1)
4369 right = geniCodeRValue (right, TRUE);
4373 right = geniCodeRValue (right, FALSE);
4376 geniCodeAssign (left,
4377 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4380 getResultTypeFromType (tree->ftype)),
4385 geniCodeAssign (left,
4386 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4388 geniCodeRValue (right, FALSE),
4389 getResultTypeFromType (tree->ftype)),
4393 geniCodeAssign (left,
4394 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4396 geniCodeRValue (right, FALSE)), 0, 1);
4399 geniCodeAssign (left,
4400 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4402 geniCodeRValue (right, FALSE),
4404 operandType (left)), 0, 1);
4407 geniCodeAssign (left,
4408 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4410 geniCodeRValue (right, FALSE),
4412 operandType (left)), 0, 1);
4415 geniCodeAssign (left,
4416 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4418 geniCodeRValue (right, FALSE),
4420 operandType (left)), 0, 1);
4422 return geniCodeRValue (right, FALSE);
4425 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4428 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4429 return ast2iCode (tree->right,lvl+1);
4432 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4433 return ast2iCode (tree->right,lvl+1);
4436 geniCodeFunctionBody (tree,lvl);
4440 geniCodeReturn (right);
4444 geniCodeIfx (tree,lvl);
4448 geniCodeSwitch (tree,lvl);
4452 geniCodeInline (tree);
4456 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4460 geniCodeCritical (tree, lvl);
4466 /*-----------------------------------------------------------------*/
4467 /* reverseICChain - gets from the list and creates a linkedlist */
4468 /*-----------------------------------------------------------------*/
4475 while ((loop = getSet (&iCodeChain)))
4487 /*-----------------------------------------------------------------*/
4488 /* iCodeFromAst - given an ast will convert it to iCode */
4489 /*-----------------------------------------------------------------*/
4491 iCodeFromAst (ast * tree)
4493 returnLabel = newiTempLabel ("_return");
4494 entryLabel = newiTempLabel ("_entry");
4496 return reverseiCChain ();
4499 static const char *opTypeToStr(OPTYPE op)
4503 case SYMBOL: return "symbol";
4504 case VALUE: return "value";
4505 case TYPE: return "type";
4507 return "undefined type";
4511 operand *validateOpType(operand *op,
4518 if (op && op->type == type)
4523 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4524 " expected %s, got %s\n",
4525 macro, args, file, line,
4526 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4528 return op; // never reached, makes compiler happy.