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 ast *astTrue = tree->right->left;
3145 ast *astFalse = tree->right->right;
3146 operand *cond = ast2iCode (tree->left, lvl+1);
3147 operand *result = newiTempOperand (tree->right->ftype, 0);
3148 operand *opTrue, *opFalse;
3150 ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel);
3153 opTrue = ast2iCode (astTrue, lvl+1);
3155 /* move the value to the new operand */
3156 geniCodeAssign (result, geniCodeRValue (opTrue, FALSE), 0, 0);
3158 /* generate an unconditional goto */
3159 geniCodeGoto (exitLabel);
3161 /* now for the right side */
3162 geniCodeLabel (falseLabel);
3164 opFalse = ast2iCode (astFalse, lvl+1);
3165 geniCodeAssign (result, geniCodeRValue (opFalse, FALSE), 0, 0);
3167 /* create the exit label */
3168 geniCodeLabel (exitLabel);
3173 /*-----------------------------------------------------------------*/
3174 /* geniCodeAssign - generate code for assignment */
3175 /*-----------------------------------------------------------------*/
3177 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3180 sym_link *ltype = operandType (left);
3181 sym_link *rtype = operandType (right);
3183 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3185 werror (E_LVALUE_REQUIRED, "assignment");
3189 /* left is integral type and right is literal then
3190 check if the literal value is within bounds */
3191 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3192 checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3193 !options.lessPedantic)
3195 werror (W_LIT_OVERFLOW);
3198 /* if the left & right type don't exactly match */
3199 /* if pointer set then make sure the check is
3200 done with the type & not the pointer */
3201 /* then cast rights type to left */
3203 /* first check the type for pointer assignement */
3204 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3205 compareType (ltype, rtype) <= 0)
3207 if (compareType (ltype->next, rtype) < 0)
3208 right = geniCodeCast (ltype->next, right, TRUE);
3210 else if (compareType (ltype, rtype) < 0)
3211 right = geniCodeCast (ltype, right, TRUE);
3213 /* If left is a true symbol & ! volatile
3214 create an assignment to temporary for
3215 the right & then assign this temporary
3216 to the symbol. This is SSA (static single
3217 assignment). Isn't it simple and folks have
3218 published mountains of paper on it */
3219 if (IS_TRUE_SYMOP (left) &&
3220 !isOperandVolatile (left, FALSE) &&
3221 isOperandGlobal (left))
3226 if (IS_TRUE_SYMOP (right))
3227 sym = OP_SYMBOL (right);
3228 ic = newiCode ('=', NULL, right);
3229 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3230 /* avoid double fetch from volatile right, see bug 1369874 */
3231 if (!isOperandVolatile (right, FALSE))
3232 SPIL_LOC (newRight) = sym;
3237 ic = newiCode ('=', NULL, right);
3238 IC_RESULT (ic) = left;
3241 /* if left isgptr flag is set then support
3242 routine will be required */
3246 ic->nosupdate = nosupdate;
3247 /* left could be a pointer assignment,
3248 return the properly casted right instead */
3252 /*-----------------------------------------------------------------*/
3253 /* geniCodeDummyRead - generate code for dummy read */
3254 /*-----------------------------------------------------------------*/
3256 geniCodeDummyRead (operand * op)
3259 sym_link *type = operandType (op);
3261 if (!IS_VOLATILE(type))
3264 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3270 /*-----------------------------------------------------------------*/
3271 /* geniCodeSEParms - generate code for side effecting fcalls */
3272 /*-----------------------------------------------------------------*/
3274 geniCodeSEParms (ast * parms,int lvl)
3279 if (parms->type == EX_OP && parms->opval.op == PARAM)
3281 geniCodeSEParms (parms->left,lvl);
3282 geniCodeSEParms (parms->right,lvl);
3286 /* hack don't like this but too lazy to think of
3288 if (IS_ADDRESS_OF_OP (parms))
3289 parms->left->lvalue = 1;
3291 if (IS_CAST_OP (parms) &&
3292 IS_PTR (parms->ftype) &&
3293 IS_ADDRESS_OF_OP (parms->right))
3294 parms->right->left->lvalue = 1;
3296 parms->opval.oprnd =
3297 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3299 parms->type = EX_OPERAND;
3300 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3301 SPEC_ARGREG(parms->ftype);
3304 /*-----------------------------------------------------------------*/
3305 /* geniCodeParms - generates parameters */
3306 /*-----------------------------------------------------------------*/
3308 geniCodeParms (ast * parms, value *argVals, int *stack,
3309 sym_link * ftype, int lvl)
3317 if (argVals==NULL) {
3319 argVals = FUNC_ARGS (ftype);
3322 /* if this is a param node then do the left & right */
3323 if (parms->type == EX_OP && parms->opval.op == PARAM)
3325 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3326 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3330 /* get the parameter value */
3331 if (parms->type == EX_OPERAND)
3332 pval = parms->opval.oprnd;
3335 /* maybe this else should go away ?? */
3336 /* hack don't like this but too lazy to think of
3338 if (IS_ADDRESS_OF_OP (parms))
3339 parms->left->lvalue = 1;
3341 if (IS_CAST_OP (parms) &&
3342 IS_PTR (parms->ftype) &&
3343 IS_ADDRESS_OF_OP (parms->right))
3344 parms->right->left->lvalue = 1;
3346 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3349 /* if register parm then make it a send */
3350 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3351 IFFUNC_ISBUILTIN(ftype))
3353 ic = newiCode (SEND, pval, NULL);
3354 ic->argreg = SPEC_ARGREG(parms->etype);
3355 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3360 /* now decide whether to push or assign */
3361 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3365 operand *top = operandFromSymbol (argVals->sym);
3366 /* clear useDef and other bitVectors */
3367 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3368 geniCodeAssign (top, pval, 1, 0);
3372 sym_link *p = operandType (pval);
3374 ic = newiCode (IPUSH, pval, NULL);
3376 /* update the stack adjustment */
3377 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3382 argVals=argVals->next;
3386 /*-----------------------------------------------------------------*/
3387 /* geniCodeCall - generates temp code for calling */
3388 /*-----------------------------------------------------------------*/
3390 geniCodeCall (operand * left, ast * parms,int lvl)
3394 sym_link *type, *etype;
3398 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3399 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3400 werror (E_FUNCTION_EXPECTED);
3401 return operandFromValue(valueFromLit(0));
3404 /* take care of parameters with side-effecting
3405 function calls in them, this is required to take care
3406 of overlaying function parameters */
3407 geniCodeSEParms (parms,lvl);
3409 ftype = operandType (left);
3410 if (IS_FUNCPTR (ftype))
3411 ftype = ftype->next;
3413 /* first the parameters */
3414 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3416 /* now call : if symbol then pcall */
3417 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3418 ic = newiCode (PCALL, left, NULL);
3420 ic = newiCode (CALL, left, NULL);
3423 type = copyLinkChain (ftype->next);
3424 etype = getSpec (type);
3425 SPEC_EXTR (etype) = 0;
3426 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3430 /* stack adjustment after call */
3431 ic->parmBytes = stack;
3436 /*-----------------------------------------------------------------*/
3437 /* geniCodeReceive - generate intermediate code for "receive" */
3438 /*-----------------------------------------------------------------*/
3440 geniCodeReceive (value * args, operand * func)
3442 unsigned char paramByteCounter = 0;
3444 /* for all arguments that are passed in registers */
3447 if (IS_REGPARM (args->etype))
3449 operand *opr = operandFromValue (args);
3451 symbol *sym = OP_SYMBOL (opr);
3454 /* we will use it after all optimizations
3455 and before liveRange calculation */
3456 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3459 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3460 options.stackAuto == 0 &&
3461 (!(options.model == MODEL_FLAT24)) )
3466 opl = newiTempOperand (args->type, 0);
3468 sym->reqv->key = sym->key;
3469 OP_SYMBOL (sym->reqv)->key = sym->key;
3470 OP_SYMBOL (sym->reqv)->isreqv = 1;
3471 OP_SYMBOL (sym->reqv)->islocal = 0;
3472 SPIL_LOC (sym->reqv) = sym;
3476 ic = newiCode (RECEIVE, func, NULL);
3477 ic->argreg = SPEC_ARGREG(args->etype);
3478 if (ic->argreg == 1) {
3479 currFunc->recvSize = getSize (sym->type);
3481 IC_RESULT (ic) = opr;
3483 /* misuse of parmBytes (normally used for functions)
3484 * to save estimated stack position of this argument.
3485 * Normally this should be zero for RECEIVE iCodes.
3486 * No idea if this causes side effects on other ports. - dw
3488 ic->parmBytes = paramByteCounter;
3490 /* what stack position do we have? */
3491 paramByteCounter += getSize (sym->type);
3500 /*-----------------------------------------------------------------*/
3501 /* geniCodeFunctionBody - create the function body */
3502 /*-----------------------------------------------------------------*/
3504 geniCodeFunctionBody (ast * tree,int lvl)
3511 /* reset the auto generation */
3517 func = ast2iCode (tree->left,lvl+1);
3518 fetype = getSpec (operandType (func));
3520 savelineno = lineno;
3521 lineno = OP_SYMBOL (func)->lineDef;
3522 /* create an entry label */
3523 geniCodeLabel (entryLabel);
3524 lineno = savelineno;
3526 /* create a proc icode */
3527 ic = newiCode (FUNCTION, func, NULL);
3528 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3533 /* for all parameters that are passed
3534 on registers add a "receive" */
3535 geniCodeReceive (tree->values.args, func);
3537 /* generate code for the body */
3538 ast2iCode (tree->right,lvl+1);
3540 /* create a label for return */
3541 geniCodeLabel (returnLabel);
3543 /* now generate the end proc */
3544 ic = newiCode (ENDFUNCTION, func, NULL);
3550 /*-----------------------------------------------------------------*/
3551 /* geniCodeReturn - gen icode for 'return' statement */
3552 /*-----------------------------------------------------------------*/
3554 geniCodeReturn (operand * op)
3558 /* if the operand is present force an rvalue */
3560 op = geniCodeRValue (op, FALSE);
3562 ic = newiCode (RETURN, op, NULL);
3566 /*-----------------------------------------------------------------*/
3567 /* geniCodeIfx - generates code for extended if statement */
3568 /*-----------------------------------------------------------------*/
3570 geniCodeIfx (ast * tree,int lvl)
3573 operand *condition = ast2iCode (tree->left,lvl+1);
3576 /* if condition is null then exit */
3580 condition = geniCodeRValue (condition, FALSE);
3582 cetype = getSpec (operandType (condition));
3583 /* if the condition is a literal */
3584 if (IS_LITERAL (cetype))
3586 if (floatFromVal (condition->operand.valOperand))
3588 if (tree->trueLabel)
3589 geniCodeGoto (tree->trueLabel);
3595 if (tree->falseLabel)
3596 geniCodeGoto (tree->falseLabel);
3601 if (tree->trueLabel)
3603 ic = newiCodeCondition (condition,
3608 if (tree->falseLabel)
3609 geniCodeGoto (tree->falseLabel);
3613 ic = newiCodeCondition (condition,
3620 ast2iCode (tree->right,lvl+1);
3623 /*-----------------------------------------------------------------*/
3624 /* geniCodeJumpTable - tries to create a jump table for switch */
3625 /*-----------------------------------------------------------------*/
3627 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3629 int min, max, cnt = 1;
3636 int needRangeCheck = !optimize.noJTabBoundary
3637 || tree->values.switchVals.swDefault;
3638 sym_link *cetype = getSpec (operandType (cond));
3639 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3640 int sizeofMatchJump, sizeofJumpTable;
3643 if (!tree || !caseVals)
3646 /* the criteria for creating a jump table is */
3647 /* all integer numbers between the maximum & minimum must */
3648 /* be present , the maximum value should not exceed 255 */
3649 /* If not all integer numbers are present the algorithm */
3650 /* inserts jumps to the default label for the missing numbers */
3651 /* and decides later whether it is worth it */
3652 min = (int) floatFromVal (vch = caseVals);
3659 max = (int) floatFromVal (vch);
3661 /* Exit if the range is too large to handle with a jump table. */
3662 if (1 + max - min > port->jumptableCost.maxCount)
3665 switch (getSize (operandType (cond)))
3667 case 1: sizeIndex = 0; break;
3668 case 2: sizeIndex = 1; break;
3669 case 4: sizeIndex = 2; break;
3673 /* Compute the size cost of the range check and subtraction. */
3675 sizeofZeroMinCost = 0;
3679 if (!(min==0 && IS_UNSIGNED (cetype)))
3680 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3681 if (!IS_UNSIGNED (cetype))
3682 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3683 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3686 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3688 /* If the size cost of handling a non-zero minimum exceeds the */
3689 /* cost of extending the range down to zero, then it might be */
3690 /* better to extend the range to zero. */
3691 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3692 >= (min * port->jumptableCost.sizeofElement))
3694 /* Only extend the jump table if it would still be manageable. */
3695 if (1 + max <= port->jumptableCost.maxCount)
3698 if (IS_UNSIGNED (cetype))
3701 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3705 /* Compute the total size cost of a jump table. */
3706 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3707 + port->jumptableCost.sizeofDispatch
3708 + sizeofMinCost + sizeofMaxCost;
3710 /* Compute the total size cost of a match & jump sequence */
3711 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3713 /* If the size cost of the jump table is uneconomical then exit */
3714 if (sizeofMatchJump < sizeofJumpTable)
3717 /* The jump table is preferable. */
3719 /* First, a label for the default or missing cases. */
3720 if (tree->values.switchVals.swDefault)
3722 SNPRINTF (buffer, sizeof(buffer),
3724 tree->values.switchVals.swNum);
3728 SNPRINTF (buffer, sizeof(buffer),
3730 tree->values.switchVals.swNum);
3732 falseLabel = newiTempLabel (buffer);
3734 /* Build the list of labels for the jump table. */
3736 t = (int) floatFromVal (vch);
3737 for (i=min; i<=max; i++)
3741 /* Explicit case: make a new label for it. */
3742 SNPRINTF (buffer, sizeof(buffer),
3744 tree->values.switchVals.swNum,
3746 addSet (&labels, newiTempLabel (buffer));
3749 t = (int) floatFromVal (vch);
3753 /* Implicit case: use the default label. */
3754 addSet (&labels, falseLabel);
3758 /* first we rule out the boundary conditions */
3759 /* if only optimization says so */
3762 sym_link *cetype = getSpec (operandType (cond));
3763 /* no need to check the lower bound if
3764 the condition is unsigned & minimum value is zero */
3765 if (!(min == 0 && IS_UNSIGNED (cetype)))
3767 boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL);
3768 ic = newiCodeCondition (boundary, falseLabel, NULL);
3772 /* now for upper bounds */
3773 boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL);
3774 ic = newiCodeCondition (boundary, falseLabel, NULL);
3778 /* if the min is not zero then we no make it zero */
3781 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3782 if (!IS_LITERAL(getSpec(operandType(cond))))
3783 setOperandType (cond, UCHARTYPE);
3786 /* now create the jumptable */
3787 ic = newiCode (JUMPTABLE, NULL, NULL);
3788 IC_JTCOND (ic) = cond;
3789 IC_JTLABELS (ic) = labels;
3794 /*-----------------------------------------------------------------*/
3795 /* geniCodeSwitch - changes a switch to a if statement */
3796 /*-----------------------------------------------------------------*/
3798 geniCodeSwitch (ast * tree,int lvl)
3801 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3802 value *caseVals = tree->values.switchVals.swVals;
3803 symbol *trueLabel, *falseLabel;
3805 /* If the condition is a literal, then just jump to the */
3806 /* appropriate case label. */
3807 if (IS_LITERAL(getSpec(operandType(cond))))
3809 int switchVal, caseVal;
3811 switchVal = (int) floatFromVal (cond->operand.valOperand);
3814 caseVal = (int) floatFromVal (caseVals);
3815 if (caseVal == switchVal)
3817 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3818 tree->values.switchVals.swNum, caseVal);
3819 trueLabel = newiTempLabel (buffer);
3820 geniCodeGoto (trueLabel);
3823 caseVals = caseVals->next;
3825 goto defaultOrBreak;
3828 /* If cond is volatile, it might change while we are trying to */
3829 /* find the matching case. To avoid this possibility, make a */
3830 /* non-volatile copy to use instead. */
3831 if (IS_OP_VOLATILE (cond))
3836 newcond = newiTempOperand (operandType (cond), TRUE);
3837 newcond->isvolatile = 0;
3838 ic = newiCode ('=', NULL, cond);
3839 IC_RESULT (ic) = newcond;
3844 /* if we can make this a jump table */
3845 if (geniCodeJumpTable (cond, caseVals, tree))
3846 goto jumpTable; /* no need for the comparison */
3848 /* for the cases defined do */
3852 operand *compare = geniCodeLogic (cond,
3853 operandFromValue (caseVals),
3856 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3857 tree->values.switchVals.swNum,
3858 (int) floatFromVal (caseVals));
3859 trueLabel = newiTempLabel (buffer);
3861 ic = newiCodeCondition (compare, trueLabel, NULL);
3863 caseVals = caseVals->next;
3868 /* if default is present then goto break else break */
3869 if (tree->values.switchVals.swDefault)
3871 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3875 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3878 falseLabel = newiTempLabel (buffer);
3879 geniCodeGoto (falseLabel);
3882 ast2iCode (tree->right,lvl+1);
3885 /*-----------------------------------------------------------------*/
3886 /* geniCodeInline - intermediate code for inline assembler */
3887 /*-----------------------------------------------------------------*/
3889 geniCodeInline (ast * tree)
3893 ic = newiCode (INLINEASM, NULL, NULL);
3894 IC_INLINE (ic) = tree->values.inlineasm;
3898 /*-----------------------------------------------------------------*/
3899 /* geniCodeArrayInit - intermediate code for array initializer */
3900 /*-----------------------------------------------------------------*/
3902 geniCodeArrayInit (ast * tree, operand *array)
3906 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3907 ic = newiCode (ARRAYINIT, array, NULL);
3908 IC_ARRAYILIST (ic) = tree->values.constlist;
3910 operand *left=newOperand(), *right=newOperand();
3911 left->type=right->type=SYMBOL;
3912 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3913 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3914 ic = newiCode (ARRAYINIT, left, right);
3919 /*-----------------------------------------------------------------*/
3920 /* geniCodeCritical - intermediate code for a critical statement */
3921 /*-----------------------------------------------------------------*/
3923 geniCodeCritical (ast *tree, int lvl)
3929 if (!options.stackAuto)
3931 type = newLink(SPECIFIER);
3932 SPEC_VOLATILE(type) = 1;
3933 SPEC_NOUN(type) = V_BIT;
3934 SPEC_SCLS(type) = S_BIT;
3935 SPEC_BLEN(type) = 1;
3936 SPEC_BSTR(type) = 0;
3937 op = newiTempOperand(type, 1);
3940 /* If op is NULL, the original interrupt state will saved on */
3941 /* the stack. Otherwise, it will be saved in op. */
3943 /* Generate a save of the current interrupt state & disable */
3944 ic = newiCode (CRITICAL, NULL, NULL);
3945 IC_RESULT (ic) = op;
3948 /* Generate the critical code sequence */
3949 if (tree->left && tree->left->type == EX_VALUE)
3950 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3952 ast2iCode (tree->left,lvl+1);
3954 /* Generate a restore of the original interrupt state */
3955 ic = newiCode (ENDCRITICAL, NULL, op);
3959 /*-----------------------------------------------------------------*/
3960 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3961 /* particular case. Ie : assigning or dereferencing array or ptr */
3962 /*-----------------------------------------------------------------*/
3963 set * lvaluereqSet = NULL;
3964 typedef struct lvalItem
3971 /*-----------------------------------------------------------------*/
3972 /* addLvaluereq - add a flag for lvalreq for current ast level */
3973 /*-----------------------------------------------------------------*/
3974 void addLvaluereq(int lvl)
3976 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3979 addSetHead(&lvaluereqSet,lpItem);
3982 /*-----------------------------------------------------------------*/
3983 /* delLvaluereq - del a flag for lvalreq for current ast level */
3984 /*-----------------------------------------------------------------*/
3988 lpItem = getSet(&lvaluereqSet);
3989 if(lpItem) Safe_free(lpItem);
3991 /*-----------------------------------------------------------------*/
3992 /* clearLvaluereq - clear lvalreq flag */
3993 /*-----------------------------------------------------------------*/
3994 void clearLvaluereq()
3997 lpItem = peekSet(lvaluereqSet);
3998 if(lpItem) lpItem->req = 0;
4000 /*-----------------------------------------------------------------*/
4001 /* getLvaluereq - get the last lvalreq level */
4002 /*-----------------------------------------------------------------*/
4003 int getLvaluereqLvl()
4006 lpItem = peekSet(lvaluereqSet);
4007 if(lpItem) return lpItem->lvl;
4010 /*-----------------------------------------------------------------*/
4011 /* isLvaluereq - is lvalreq valid for this level ? */
4012 /*-----------------------------------------------------------------*/
4013 int isLvaluereq(int lvl)
4016 lpItem = peekSet(lvaluereqSet);
4017 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4021 /*-----------------------------------------------------------------*/
4022 /* ast2iCode - creates an icodeList from an ast */
4023 /*-----------------------------------------------------------------*/
4025 ast2iCode (ast * tree,int lvl)
4027 operand *left = NULL;
4028 operand *right = NULL;
4032 /* set the global variables for filename & line number */
4034 filename = tree->filename;
4036 lineno = tree->lineno;
4038 block = tree->block;
4040 scopeLevel = tree->level;
4042 seqPoint = tree->seqPoint;
4044 if (tree->type == EX_VALUE)
4045 return operandFromValue (tree->opval.val);
4047 if (tree->type == EX_LINK)
4048 return operandFromLink (tree->opval.lnk);
4050 /* if we find a nullop */
4051 if (tree->type == EX_OP &&
4052 (tree->opval.op == NULLOP ||
4053 tree->opval.op == BLOCK))
4055 if (tree->left && tree->left->type == EX_VALUE)
4056 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4058 ast2iCode (tree->left,lvl+1);
4059 if (tree->right && tree->right->type == EX_VALUE)
4060 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4062 ast2iCode (tree->right,lvl+1);
4066 /* special cases for not evaluating */
4067 if (tree->opval.op != ':' &&
4068 tree->opval.op != '?' &&
4069 tree->opval.op != CALL &&
4070 tree->opval.op != IFX &&
4071 tree->opval.op != AND_OP &&
4072 tree->opval.op != OR_OP &&
4073 tree->opval.op != LABEL &&
4074 tree->opval.op != GOTO &&
4075 tree->opval.op != SWITCH &&
4076 tree->opval.op != FUNCTION &&
4077 tree->opval.op != INLINEASM &&
4078 tree->opval.op != CRITICAL)
4081 if (IS_ASSIGN_OP (tree->opval.op) ||
4082 IS_DEREF_OP (tree) ||
4083 (tree->opval.op == '&' && !tree->right) ||
4084 tree->opval.op == PTR_OP)
4087 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4088 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4091 left = operandFromAst (tree->left,lvl);
4093 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4094 left = geniCodeRValue (left, TRUE);
4098 left = operandFromAst (tree->left,lvl);
4100 if (tree->opval.op == INC_OP ||
4101 tree->opval.op == DEC_OP)
4104 right = operandFromAst (tree->right,lvl);
4109 right = operandFromAst (tree->right,lvl);
4113 /* now depending on the type of operand */
4114 /* this will be a biggy */
4115 switch (tree->opval.op)
4118 case '[': /* array operation */
4120 //sym_link *ltype = operandType (left);
4121 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4122 left = geniCodeRValue (left, FALSE);
4123 right = geniCodeRValue (right, TRUE);
4126 return geniCodeArray (left, right,lvl);
4128 case '.': /* structure dereference */
4129 if (IS_PTR (operandType (left)))
4130 left = geniCodeRValue (left, TRUE);
4132 left = geniCodeRValue (left, FALSE);
4134 return geniCodeStruct (left, right, tree->lvalue);
4136 case PTR_OP: /* structure pointer dereference */
4139 pType = operandType (left);
4140 left = geniCodeRValue (left, TRUE);
4142 setOClass (pType, getSpec (operandType (left)));
4145 return geniCodeStruct (left, right, tree->lvalue);
4147 case INC_OP: /* increment operator */
4149 return geniCodePostInc (left);
4151 return geniCodePreInc (right, tree->lvalue);
4153 case DEC_OP: /* decrement operator */
4155 return geniCodePostDec (left);
4157 return geniCodePreDec (right, tree->lvalue);
4159 case '&': /* bitwise and or address of operator */
4161 { /* this is a bitwise operator */
4162 left = geniCodeRValue (left, FALSE);
4163 right = geniCodeRValue (right, FALSE);
4164 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4167 return geniCodeAddressOf (left);
4169 case '|': /* bitwise or & xor */
4171 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4172 geniCodeRValue (right, FALSE),
4177 return geniCodeDivision (geniCodeRValue (left, FALSE),
4178 geniCodeRValue (right, FALSE),
4179 getResultTypeFromType (tree->ftype));
4182 return geniCodeModulus (geniCodeRValue (left, FALSE),
4183 geniCodeRValue (right, FALSE),
4184 getResultTypeFromType (tree->ftype));
4187 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4188 geniCodeRValue (right, FALSE),
4189 getResultTypeFromType (tree->ftype));
4191 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4195 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4196 geniCodeRValue (right, FALSE),
4197 getResultTypeFromType (tree->ftype));
4199 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4203 return geniCodeAdd (geniCodeRValue (left, FALSE),
4204 geniCodeRValue (right, FALSE),
4205 getResultTypeFromType (tree->ftype),
4208 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4211 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4212 geniCodeRValue (right, FALSE),
4213 getResultTypeFromType (tree->ftype));
4216 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4217 geniCodeRValue (right, FALSE));
4219 #if 0 // this indeed needs a second thought
4223 // let's keep this simple: get the rvalue we need
4224 op=geniCodeRValue (right, FALSE);
4225 // now cast it to whatever we want
4226 op=geniCodeCast (operandType(left), op, FALSE);
4227 // if this is going to be used as an lvalue, make it so
4233 #else // bug #604575, is it a bug ????
4234 return geniCodeCast (operandType (left),
4235 geniCodeRValue (right, FALSE), FALSE);
4242 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4247 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4248 if (!IS_BIT (operandType (op)))
4249 setOperandType (op, UCHARTYPE);
4254 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4255 geniCodeRValue (right, FALSE),
4257 if (!IS_BIT (operandType (op)))
4258 setOperandType (op, UCHARTYPE);
4263 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4264 geniCodeRValue (right, FALSE),
4266 setOperandType (op, UCHARTYPE);
4271 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4272 geniCodeRValue (right, FALSE),
4274 setOperandType (op, UINTTYPE);
4279 return geniCodeLogicAndOr (tree, lvl);
4286 /* different compilers (even different gccs) evaluate
4287 the two calls in a different order. to get the same
4288 result on all machines we have to specify a clear sequence.
4289 return geniCodeLogic (geniCodeRValue (left, FALSE),
4290 geniCodeRValue (right, FALSE),
4294 operand *leftOp, *rightOp;
4296 leftOp = geniCodeRValue (left , FALSE);
4297 rightOp = geniCodeRValue (right, FALSE);
4299 return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree);
4302 return geniCodeConditional (tree,lvl);
4305 return operandFromLit (getSize (tree->right->ftype));
4309 sym_link *rtype = operandType (right);
4310 sym_link *ltype = operandType (left);
4311 if (IS_PTR (rtype) && IS_ITEMP (right)
4312 && right->isaddr && compareType (rtype->next, ltype) == 1)
4313 right = geniCodeRValue (right, TRUE);
4315 right = geniCodeRValue (right, FALSE);
4317 return geniCodeAssign (left, right, 0, 1);
4321 geniCodeAssign (left,
4322 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4324 geniCodeRValue (right, FALSE),
4325 getResultTypeFromType (tree->ftype)),
4330 geniCodeAssign (left,
4331 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4333 geniCodeRValue (right, FALSE),
4334 getResultTypeFromType (tree->ftype)),
4338 geniCodeAssign (left,
4339 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4341 geniCodeRValue (right, FALSE),
4342 getResultTypeFromType (tree->ftype)),
4346 sym_link *rtype = operandType (right);
4347 sym_link *ltype = operandType (left);
4348 if (IS_PTR (rtype) && IS_ITEMP (right)
4349 && right->isaddr && compareType (rtype->next, ltype) == 1)
4350 right = geniCodeRValue (right, TRUE);
4352 right = geniCodeRValue (right, FALSE);
4355 return geniCodeAssign (left,
4356 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4359 getResultTypeFromType (tree->ftype),
4365 sym_link *rtype = operandType (right);
4366 sym_link *ltype = operandType (left);
4367 if (IS_PTR (rtype) && IS_ITEMP (right)
4368 && right->isaddr && compareType (rtype->next, ltype) == 1)
4370 right = geniCodeRValue (right, TRUE);
4374 right = geniCodeRValue (right, FALSE);
4377 geniCodeAssign (left,
4378 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4381 getResultTypeFromType (tree->ftype)),
4386 geniCodeAssign (left,
4387 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4389 geniCodeRValue (right, FALSE),
4390 getResultTypeFromType (tree->ftype)),
4394 geniCodeAssign (left,
4395 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4397 geniCodeRValue (right, FALSE)), 0, 1);
4400 geniCodeAssign (left,
4401 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4403 geniCodeRValue (right, FALSE),
4405 operandType (left)), 0, 1);
4408 geniCodeAssign (left,
4409 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4411 geniCodeRValue (right, FALSE),
4413 operandType (left)), 0, 1);
4416 geniCodeAssign (left,
4417 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4419 geniCodeRValue (right, FALSE),
4421 operandType (left)), 0, 1);
4423 return geniCodeRValue (right, FALSE);
4426 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4429 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4430 return ast2iCode (tree->right,lvl+1);
4433 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4434 return ast2iCode (tree->right,lvl+1);
4437 geniCodeFunctionBody (tree,lvl);
4441 geniCodeReturn (right);
4445 geniCodeIfx (tree,lvl);
4449 geniCodeSwitch (tree,lvl);
4453 geniCodeInline (tree);
4457 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4461 geniCodeCritical (tree, lvl);
4467 /*-----------------------------------------------------------------*/
4468 /* reverseICChain - gets from the list and creates a linkedlist */
4469 /*-----------------------------------------------------------------*/
4476 while ((loop = getSet (&iCodeChain)))
4488 /*-----------------------------------------------------------------*/
4489 /* iCodeFromAst - given an ast will convert it to iCode */
4490 /*-----------------------------------------------------------------*/
4492 iCodeFromAst (ast * tree)
4494 returnLabel = newiTempLabel ("_return");
4495 entryLabel = newiTempLabel ("_entry");
4497 return reverseiCChain ();
4500 static const char *opTypeToStr(OPTYPE op)
4504 case SYMBOL: return "symbol";
4505 case VALUE: return "value";
4506 case TYPE: return "type";
4508 return "undefined type";
4512 operand *validateOpType(operand *op,
4519 if (op && op->type == type)
4524 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4525 " expected %s, got %s\n",
4526 macro, args, file, line,
4527 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4529 return op; // never reached, makes compiler happy.