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 assignement 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)
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 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
3022 /* if comparing float
3023 and not a '==' || '!=' || '&&' || '||' (these
3025 if (IS_FLOAT(ctype) &&
3032 /* if comparing a fixed type use support functions */
3033 if (IS_FIXED(ctype))
3037 return IC_RESULT (ic);
3040 /*-----------------------------------------------------------------*/
3041 /* geniCodeLogicAndOr - && || operations */
3042 /*-----------------------------------------------------------------*/
3044 geniCodeLogicAndOr (ast *tree, int lvl)
3048 symbol *falseLabel = newiTempLabel (NULL);
3049 symbol *trueLabel = newiTempLabel (NULL);
3050 symbol *exitLabel = newiTempLabel (NULL);
3051 operand *op, *result, *condition;
3053 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3054 They can be reenabled by executing the following block. If you find
3055 a decent optimization you could start right here:
3060 operand *leftOp, *rightOp;
3062 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3063 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3065 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3069 /* generate two IFX for the '&&' or '||' op */
3071 /* evaluate left operand */
3072 condition = ast2iCode (tree->left, lvl + 1);
3073 op = geniCodeRValue (condition, FALSE);
3075 /* test left operand */
3076 if (tree->opval.op == AND_OP)
3077 ic = newiCodeCondition (op, NULL, falseLabel);
3079 ic = newiCodeCondition (op, trueLabel, NULL);
3082 /* evaluate right operand */
3083 condition = ast2iCode (tree->right, lvl + 1);
3084 op = geniCodeRValue (condition, FALSE);
3086 /* test right operand */
3087 ic = newiCodeCondition (op, trueLabel, NULL);
3090 /* store 0 or 1 in result */
3091 type = (SPEC_NOUN(tree->ftype) == V_BIT) ? newBoolLink() : newCharLink();
3092 result = newiTempOperand (type, 1);
3094 geniCodeLabel (falseLabel);
3095 geniCodeAssign (result, operandFromLit (0), 0, 0);
3096 /* generate an unconditional goto */
3097 geniCodeGoto (exitLabel);
3099 geniCodeLabel (trueLabel);
3100 geniCodeAssign (result, operandFromLit (1), 0, 0);
3102 geniCodeLabel (exitLabel);
3107 /*-----------------------------------------------------------------*/
3108 /* geniCodeUnary - for a generic unary operation */
3109 /*-----------------------------------------------------------------*/
3111 geniCodeUnary (operand * op, int oper)
3113 iCode *ic = newiCode (oper, op, NULL);
3115 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3117 return IC_RESULT (ic);
3120 /*-----------------------------------------------------------------*/
3121 /* geniCodeBinary - for a generic binary operation */
3122 /*-----------------------------------------------------------------*/
3124 geniCodeBinary (operand * left, operand * right, int oper)
3126 iCode *ic = newiCode (oper, left, right);
3128 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3130 return IC_RESULT (ic);
3133 /*-----------------------------------------------------------------*/
3134 /* geniCodeConditional - geniCode for '?' ':' operation */
3135 /*-----------------------------------------------------------------*/
3137 geniCodeConditional (ast * tree,int lvl)
3140 symbol *falseLabel = newiTempLabel (NULL);
3141 symbol *exitLabel = newiTempLabel (NULL);
3142 operand *cond = ast2iCode (tree->left,lvl+1);
3143 operand *true, *false, *result;
3145 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
3149 true = ast2iCode (tree->right->left,lvl+1);
3151 /* move the value to a new Operand */
3152 result = newiTempOperand (tree->right->ftype, 0);
3153 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0, 0);
3155 /* generate an unconditional goto */
3156 geniCodeGoto (exitLabel);
3158 /* now for the right side */
3159 geniCodeLabel (falseLabel);
3161 false = ast2iCode (tree->right->right,lvl+1);
3162 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0, 0);
3164 /* create the exit label */
3165 geniCodeLabel (exitLabel);
3170 /*-----------------------------------------------------------------*/
3171 /* geniCodeAssign - generate code for assignment */
3172 /*-----------------------------------------------------------------*/
3174 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3177 sym_link *ltype = operandType (left);
3178 sym_link *rtype = operandType (right);
3180 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3182 werror (E_LVALUE_REQUIRED, "assignment");
3186 /* left is integral type and right is literal then
3187 check if the literal value is within bounds */
3188 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3189 checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3190 !options.lessPedantic)
3192 werror (W_LIT_OVERFLOW);
3195 /* if the left & right type don't exactly match */
3196 /* if pointer set then make sure the check is
3197 done with the type & not the pointer */
3198 /* then cast rights type to left */
3200 /* first check the type for pointer assignement */
3201 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3202 compareType (ltype, rtype) <= 0)
3204 if (compareType (ltype->next, rtype) < 0)
3205 right = geniCodeCast (ltype->next, right, TRUE);
3207 else if (compareType (ltype, rtype) < 0)
3208 right = geniCodeCast (ltype, right, TRUE);
3210 /* If left is a true symbol & ! volatile
3211 create an assignment to temporary for
3212 the right & then assign this temporary
3213 to the symbol. This is SSA (static single
3214 assignment). Isn't it simple and folks have
3215 published mountains of paper on it */
3216 if (IS_TRUE_SYMOP (left) &&
3217 !isOperandVolatile (left, FALSE) &&
3218 isOperandGlobal (left))
3223 if (IS_TRUE_SYMOP (right))
3224 sym = OP_SYMBOL (right);
3225 ic = newiCode ('=', NULL, right);
3226 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3227 /* avoid double fetch from volatile right, see bug 1369874 */
3228 if (!isOperandVolatile (right, FALSE))
3229 SPIL_LOC (newRight) = sym;
3234 ic = newiCode ('=', NULL, right);
3235 IC_RESULT (ic) = left;
3238 /* if left isgptr flag is set then support
3239 routine will be required */
3243 ic->nosupdate = nosupdate;
3244 /* left could be a pointer assignment,
3245 return the properly casted right instead */
3249 /*-----------------------------------------------------------------*/
3250 /* geniCodeDummyRead - generate code for dummy read */
3251 /*-----------------------------------------------------------------*/
3253 geniCodeDummyRead (operand * op)
3256 sym_link *type = operandType (op);
3258 if (!IS_VOLATILE(type))
3261 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3267 /*-----------------------------------------------------------------*/
3268 /* geniCodeSEParms - generate code for side effecting fcalls */
3269 /*-----------------------------------------------------------------*/
3271 geniCodeSEParms (ast * parms,int lvl)
3276 if (parms->type == EX_OP && parms->opval.op == PARAM)
3278 geniCodeSEParms (parms->left,lvl);
3279 geniCodeSEParms (parms->right,lvl);
3283 /* hack don't like this but too lazy to think of
3285 if (IS_ADDRESS_OF_OP (parms))
3286 parms->left->lvalue = 1;
3288 if (IS_CAST_OP (parms) &&
3289 IS_PTR (parms->ftype) &&
3290 IS_ADDRESS_OF_OP (parms->right))
3291 parms->right->left->lvalue = 1;
3293 parms->opval.oprnd =
3294 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3296 parms->type = EX_OPERAND;
3297 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3298 SPEC_ARGREG(parms->ftype);
3301 /*-----------------------------------------------------------------*/
3302 /* geniCodeParms - generates parameters */
3303 /*-----------------------------------------------------------------*/
3305 geniCodeParms (ast * parms, value *argVals, int *stack,
3306 sym_link * ftype, int lvl)
3314 if (argVals==NULL) {
3316 argVals = FUNC_ARGS (ftype);
3319 /* if this is a param node then do the left & right */
3320 if (parms->type == EX_OP && parms->opval.op == PARAM)
3322 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3323 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3327 /* get the parameter value */
3328 if (parms->type == EX_OPERAND)
3329 pval = parms->opval.oprnd;
3332 /* maybe this else should go away ?? */
3333 /* hack don't like this but too lazy to think of
3335 if (IS_ADDRESS_OF_OP (parms))
3336 parms->left->lvalue = 1;
3338 if (IS_CAST_OP (parms) &&
3339 IS_PTR (parms->ftype) &&
3340 IS_ADDRESS_OF_OP (parms->right))
3341 parms->right->left->lvalue = 1;
3343 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3346 /* if register parm then make it a send */
3347 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3348 IFFUNC_ISBUILTIN(ftype))
3350 ic = newiCode (SEND, pval, NULL);
3351 ic->argreg = SPEC_ARGREG(parms->etype);
3352 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3357 /* now decide whether to push or assign */
3358 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3362 operand *top = operandFromSymbol (argVals->sym);
3363 /* clear useDef and other bitVectors */
3364 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3365 geniCodeAssign (top, pval, 1, 0);
3369 sym_link *p = operandType (pval);
3371 ic = newiCode (IPUSH, pval, NULL);
3373 /* update the stack adjustment */
3374 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3379 argVals=argVals->next;
3383 /*-----------------------------------------------------------------*/
3384 /* geniCodeCall - generates temp code for calling */
3385 /*-----------------------------------------------------------------*/
3387 geniCodeCall (operand * left, ast * parms,int lvl)
3391 sym_link *type, *etype;
3395 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3396 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3397 werror (E_FUNCTION_EXPECTED);
3398 return operandFromValue(valueFromLit(0));
3401 /* take care of parameters with side-effecting
3402 function calls in them, this is required to take care
3403 of overlaying function parameters */
3404 geniCodeSEParms (parms,lvl);
3406 ftype = operandType (left);
3407 if (IS_FUNCPTR (ftype))
3408 ftype = ftype->next;
3410 /* first the parameters */
3411 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3413 /* now call : if symbol then pcall */
3414 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3415 ic = newiCode (PCALL, left, NULL);
3417 ic = newiCode (CALL, left, NULL);
3420 type = copyLinkChain (ftype->next);
3421 etype = getSpec (type);
3422 SPEC_EXTR (etype) = 0;
3423 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3427 /* stack adjustment after call */
3428 ic->parmBytes = stack;
3433 /*-----------------------------------------------------------------*/
3434 /* geniCodeReceive - generate intermediate code for "receive" */
3435 /*-----------------------------------------------------------------*/
3437 geniCodeReceive (value * args, operand * func)
3439 unsigned char paramByteCounter = 0;
3441 /* for all arguments that are passed in registers */
3444 if (IS_REGPARM (args->etype))
3446 operand *opr = operandFromValue (args);
3448 symbol *sym = OP_SYMBOL (opr);
3451 /* we will use it after all optimizations
3452 and before liveRange calculation */
3453 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3456 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3457 options.stackAuto == 0 &&
3458 (!(options.model == MODEL_FLAT24)) )
3463 opl = newiTempOperand (args->type, 0);
3465 sym->reqv->key = sym->key;
3466 OP_SYMBOL (sym->reqv)->key = sym->key;
3467 OP_SYMBOL (sym->reqv)->isreqv = 1;
3468 OP_SYMBOL (sym->reqv)->islocal = 0;
3469 SPIL_LOC (sym->reqv) = sym;
3473 ic = newiCode (RECEIVE, func, NULL);
3474 ic->argreg = SPEC_ARGREG(args->etype);
3475 if (ic->argreg == 1) {
3476 currFunc->recvSize = getSize (sym->type);
3478 IC_RESULT (ic) = opr;
3480 /* misuse of parmBytes (normally used for functions)
3481 * to save estimated stack position of this argument.
3482 * Normally this should be zero for RECEIVE iCodes.
3483 * No idea if this causes side effects on other ports. - dw
3485 ic->parmBytes = paramByteCounter;
3487 /* what stack position do we have? */
3488 paramByteCounter += getSize (sym->type);
3497 /*-----------------------------------------------------------------*/
3498 /* geniCodeFunctionBody - create the function body */
3499 /*-----------------------------------------------------------------*/
3501 geniCodeFunctionBody (ast * tree,int lvl)
3508 /* reset the auto generation */
3514 func = ast2iCode (tree->left,lvl+1);
3515 fetype = getSpec (operandType (func));
3517 savelineno = lineno;
3518 lineno = OP_SYMBOL (func)->lineDef;
3519 /* create an entry label */
3520 geniCodeLabel (entryLabel);
3521 lineno = savelineno;
3523 /* create a proc icode */
3524 ic = newiCode (FUNCTION, func, NULL);
3525 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3530 /* for all parameters that are passed
3531 on registers add a "receive" */
3532 geniCodeReceive (tree->values.args, func);
3534 /* generate code for the body */
3535 ast2iCode (tree->right,lvl+1);
3537 /* create a label for return */
3538 geniCodeLabel (returnLabel);
3540 /* now generate the end proc */
3541 ic = newiCode (ENDFUNCTION, func, NULL);
3547 /*-----------------------------------------------------------------*/
3548 /* geniCodeReturn - gen icode for 'return' statement */
3549 /*-----------------------------------------------------------------*/
3551 geniCodeReturn (operand * op)
3555 /* if the operand is present force an rvalue */
3557 op = geniCodeRValue (op, FALSE);
3559 ic = newiCode (RETURN, op, NULL);
3563 /*-----------------------------------------------------------------*/
3564 /* geniCodeIfx - generates code for extended if statement */
3565 /*-----------------------------------------------------------------*/
3567 geniCodeIfx (ast * tree,int lvl)
3570 operand *condition = ast2iCode (tree->left,lvl+1);
3573 /* if condition is null then exit */
3577 condition = geniCodeRValue (condition, FALSE);
3579 cetype = getSpec (operandType (condition));
3580 /* if the condition is a literal */
3581 if (IS_LITERAL (cetype))
3583 if (floatFromVal (condition->operand.valOperand))
3585 if (tree->trueLabel)
3586 geniCodeGoto (tree->trueLabel);
3592 if (tree->falseLabel)
3593 geniCodeGoto (tree->falseLabel);
3598 if (tree->trueLabel)
3600 ic = newiCodeCondition (condition,
3605 if (tree->falseLabel)
3606 geniCodeGoto (tree->falseLabel);
3610 ic = newiCodeCondition (condition,
3617 ast2iCode (tree->right,lvl+1);
3620 /*-----------------------------------------------------------------*/
3621 /* geniCodeJumpTable - tries to create a jump table for switch */
3622 /*-----------------------------------------------------------------*/
3624 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3626 int min, max, cnt = 1;
3633 int needRangeCheck = !optimize.noJTabBoundary
3634 || tree->values.switchVals.swDefault;
3635 sym_link *cetype = getSpec (operandType (cond));
3636 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3637 int sizeofMatchJump, sizeofJumpTable;
3640 if (!tree || !caseVals)
3643 /* the criteria for creating a jump table is */
3644 /* all integer numbers between the maximum & minimum must */
3645 /* be present , the maximum value should not exceed 255 */
3646 /* If not all integer numbers are present the algorithm */
3647 /* inserts jumps to the default label for the missing numbers */
3648 /* and decides later whether it is worth it */
3649 min = (int) floatFromVal (vch = caseVals);
3656 max = (int) floatFromVal (vch);
3658 /* Exit if the range is too large to handle with a jump table. */
3659 if (1 + max - min > port->jumptableCost.maxCount)
3662 switch (getSize (operandType (cond)))
3664 case 1: sizeIndex = 0; break;
3665 case 2: sizeIndex = 1; break;
3666 case 4: sizeIndex = 2; break;
3670 /* Compute the size cost of the range check and subtraction. */
3672 sizeofZeroMinCost = 0;
3676 if (!(min==0 && IS_UNSIGNED (cetype)))
3677 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3678 if (!IS_UNSIGNED (cetype))
3679 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3680 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3683 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3685 /* If the size cost of handling a non-zero minimum exceeds the */
3686 /* cost of extending the range down to zero, then it might be */
3687 /* better to extend the range to zero. */
3688 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3689 >= (min * port->jumptableCost.sizeofElement))
3691 /* Only extend the jump table if it would still be manageable. */
3692 if (1 + max <= port->jumptableCost.maxCount)
3695 if (IS_UNSIGNED (cetype))
3698 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3702 /* Compute the total size cost of a jump table. */
3703 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3704 + port->jumptableCost.sizeofDispatch
3705 + sizeofMinCost + sizeofMaxCost;
3707 /* Compute the total size cost of a match & jump sequence */
3708 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3710 /* If the size cost of the jump table is uneconomical then exit */
3711 if (sizeofMatchJump < sizeofJumpTable)
3714 /* The jump table is preferable. */
3716 /* First, a label for the default or missing cases. */
3717 if (tree->values.switchVals.swDefault)
3719 SNPRINTF (buffer, sizeof(buffer),
3721 tree->values.switchVals.swNum);
3725 SNPRINTF (buffer, sizeof(buffer),
3727 tree->values.switchVals.swNum);
3729 falseLabel = newiTempLabel (buffer);
3731 /* Build the list of labels for the jump table. */
3733 t = (int) floatFromVal (vch);
3734 for (i=min; i<=max; i++)
3738 /* Explicit case: make a new label for it. */
3739 SNPRINTF (buffer, sizeof(buffer),
3741 tree->values.switchVals.swNum,
3743 addSet (&labels, newiTempLabel (buffer));
3746 t = (int) floatFromVal (vch);
3750 /* Implicit case: use the default label. */
3751 addSet (&labels, falseLabel);
3755 /* first we rule out the boundary conditions */
3756 /* if only optimization says so */
3759 sym_link *cetype = getSpec (operandType (cond));
3760 /* no need to check the lower bound if
3761 the condition is unsigned & minimum value is zero */
3762 if (!(min == 0 && IS_UNSIGNED (cetype)))
3764 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3765 ic = newiCodeCondition (boundary, falseLabel, NULL);
3769 /* now for upper bounds */
3770 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3771 ic = newiCodeCondition (boundary, falseLabel, NULL);
3775 /* if the min is not zero then we no make it zero */
3778 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3779 if (!IS_LITERAL(getSpec(operandType(cond))))
3780 setOperandType (cond, UCHARTYPE);
3783 /* now create the jumptable */
3784 ic = newiCode (JUMPTABLE, NULL, NULL);
3785 IC_JTCOND (ic) = cond;
3786 IC_JTLABELS (ic) = labels;
3791 /*-----------------------------------------------------------------*/
3792 /* geniCodeSwitch - changes a switch to a if statement */
3793 /*-----------------------------------------------------------------*/
3795 geniCodeSwitch (ast * tree,int lvl)
3798 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3799 value *caseVals = tree->values.switchVals.swVals;
3800 symbol *trueLabel, *falseLabel;
3802 /* If the condition is a literal, then just jump to the */
3803 /* appropriate case label. */
3804 if (IS_LITERAL(getSpec(operandType(cond))))
3806 int switchVal, caseVal;
3808 switchVal = (int) floatFromVal (cond->operand.valOperand);
3811 caseVal = (int) floatFromVal (caseVals);
3812 if (caseVal == switchVal)
3814 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3815 tree->values.switchVals.swNum, caseVal);
3816 trueLabel = newiTempLabel (buffer);
3817 geniCodeGoto (trueLabel);
3820 caseVals = caseVals->next;
3822 goto defaultOrBreak;
3825 /* If cond is volatile, it might change while we are trying to */
3826 /* find the matching case. To avoid this possibility, make a */
3827 /* non-volatile copy to use instead. */
3828 if (IS_OP_VOLATILE (cond))
3833 newcond = newiTempOperand (operandType (cond), TRUE);
3834 newcond->isvolatile = 0;
3835 ic = newiCode ('=', NULL, cond);
3836 IC_RESULT (ic) = newcond;
3841 /* if we can make this a jump table */
3842 if (geniCodeJumpTable (cond, caseVals, tree))
3843 goto jumpTable; /* no need for the comparison */
3845 /* for the cases defined do */
3849 operand *compare = geniCodeLogic (cond,
3850 operandFromValue (caseVals),
3853 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3854 tree->values.switchVals.swNum,
3855 (int) floatFromVal (caseVals));
3856 trueLabel = newiTempLabel (buffer);
3858 ic = newiCodeCondition (compare, trueLabel, NULL);
3860 caseVals = caseVals->next;
3865 /* if default is present then goto break else break */
3866 if (tree->values.switchVals.swDefault)
3868 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3872 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3875 falseLabel = newiTempLabel (buffer);
3876 geniCodeGoto (falseLabel);
3879 ast2iCode (tree->right,lvl+1);
3882 /*-----------------------------------------------------------------*/
3883 /* geniCodeInline - intermediate code for inline assembler */
3884 /*-----------------------------------------------------------------*/
3886 geniCodeInline (ast * tree)
3890 ic = newiCode (INLINEASM, NULL, NULL);
3891 IC_INLINE (ic) = tree->values.inlineasm;
3895 /*-----------------------------------------------------------------*/
3896 /* geniCodeArrayInit - intermediate code for array initializer */
3897 /*-----------------------------------------------------------------*/
3899 geniCodeArrayInit (ast * tree, operand *array)
3903 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3904 ic = newiCode (ARRAYINIT, array, NULL);
3905 IC_ARRAYILIST (ic) = tree->values.constlist;
3907 operand *left=newOperand(), *right=newOperand();
3908 left->type=right->type=SYMBOL;
3909 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3910 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3911 ic = newiCode (ARRAYINIT, left, right);
3916 /*-----------------------------------------------------------------*/
3917 /* geniCodeCritical - intermediate code for a critical statement */
3918 /*-----------------------------------------------------------------*/
3920 geniCodeCritical (ast *tree, int lvl)
3926 if (!options.stackAuto)
3928 type = newLink(SPECIFIER);
3929 SPEC_VOLATILE(type) = 1;
3930 SPEC_NOUN(type) = V_BIT;
3931 SPEC_SCLS(type) = S_BIT;
3932 SPEC_BLEN(type) = 1;
3933 SPEC_BSTR(type) = 0;
3934 op = newiTempOperand(type, 1);
3937 /* If op is NULL, the original interrupt state will saved on */
3938 /* the stack. Otherwise, it will be saved in op. */
3940 /* Generate a save of the current interrupt state & disable */
3941 ic = newiCode (CRITICAL, NULL, NULL);
3942 IC_RESULT (ic) = op;
3945 /* Generate the critical code sequence */
3946 if (tree->left && tree->left->type == EX_VALUE)
3947 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3949 ast2iCode (tree->left,lvl+1);
3951 /* Generate a restore of the original interrupt state */
3952 ic = newiCode (ENDCRITICAL, NULL, op);
3956 /*-----------------------------------------------------------------*/
3957 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3958 /* particular case. Ie : assigning or dereferencing array or ptr */
3959 /*-----------------------------------------------------------------*/
3960 set * lvaluereqSet = NULL;
3961 typedef struct lvalItem
3968 /*-----------------------------------------------------------------*/
3969 /* addLvaluereq - add a flag for lvalreq for current ast level */
3970 /*-----------------------------------------------------------------*/
3971 void addLvaluereq(int lvl)
3973 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3976 addSetHead(&lvaluereqSet,lpItem);
3979 /*-----------------------------------------------------------------*/
3980 /* delLvaluereq - del a flag for lvalreq for current ast level */
3981 /*-----------------------------------------------------------------*/
3985 lpItem = getSet(&lvaluereqSet);
3986 if(lpItem) Safe_free(lpItem);
3988 /*-----------------------------------------------------------------*/
3989 /* clearLvaluereq - clear lvalreq flag */
3990 /*-----------------------------------------------------------------*/
3991 void clearLvaluereq()
3994 lpItem = peekSet(lvaluereqSet);
3995 if(lpItem) lpItem->req = 0;
3997 /*-----------------------------------------------------------------*/
3998 /* getLvaluereq - get the last lvalreq level */
3999 /*-----------------------------------------------------------------*/
4000 int getLvaluereqLvl()
4003 lpItem = peekSet(lvaluereqSet);
4004 if(lpItem) return lpItem->lvl;
4007 /*-----------------------------------------------------------------*/
4008 /* isLvaluereq - is lvalreq valid for this level ? */
4009 /*-----------------------------------------------------------------*/
4010 int isLvaluereq(int lvl)
4013 lpItem = peekSet(lvaluereqSet);
4014 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4018 /*-----------------------------------------------------------------*/
4019 /* ast2iCode - creates an icodeList from an ast */
4020 /*-----------------------------------------------------------------*/
4022 ast2iCode (ast * tree,int lvl)
4024 operand *left = NULL;
4025 operand *right = NULL;
4029 /* set the global variables for filename & line number */
4031 filename = tree->filename;
4033 lineno = tree->lineno;
4035 block = tree->block;
4037 scopeLevel = tree->level;
4039 seqPoint = tree->seqPoint;
4041 if (tree->type == EX_VALUE)
4042 return operandFromValue (tree->opval.val);
4044 if (tree->type == EX_LINK)
4045 return operandFromLink (tree->opval.lnk);
4047 /* if we find a nullop */
4048 if (tree->type == EX_OP &&
4049 (tree->opval.op == NULLOP ||
4050 tree->opval.op == BLOCK))
4052 if (tree->left && tree->left->type == EX_VALUE)
4053 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4055 ast2iCode (tree->left,lvl+1);
4056 if (tree->right && tree->right->type == EX_VALUE)
4057 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4059 ast2iCode (tree->right,lvl+1);
4063 /* special cases for not evaluating */
4064 if (tree->opval.op != ':' &&
4065 tree->opval.op != '?' &&
4066 tree->opval.op != CALL &&
4067 tree->opval.op != IFX &&
4068 tree->opval.op != AND_OP &&
4069 tree->opval.op != OR_OP &&
4070 tree->opval.op != LABEL &&
4071 tree->opval.op != GOTO &&
4072 tree->opval.op != SWITCH &&
4073 tree->opval.op != FUNCTION &&
4074 tree->opval.op != INLINEASM &&
4075 tree->opval.op != CRITICAL)
4078 if (IS_ASSIGN_OP (tree->opval.op) ||
4079 IS_DEREF_OP (tree) ||
4080 (tree->opval.op == '&' && !tree->right) ||
4081 tree->opval.op == PTR_OP)
4084 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4085 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4088 left = operandFromAst (tree->left,lvl);
4090 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4091 left = geniCodeRValue (left, TRUE);
4095 left = operandFromAst (tree->left,lvl);
4097 if (tree->opval.op == INC_OP ||
4098 tree->opval.op == DEC_OP)
4101 right = operandFromAst (tree->right,lvl);
4106 right = operandFromAst (tree->right,lvl);
4110 /* now depending on the type of operand */
4111 /* this will be a biggy */
4112 switch (tree->opval.op)
4115 case '[': /* array operation */
4117 //sym_link *ltype = operandType (left);
4118 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4119 left = geniCodeRValue (left, FALSE);
4120 right = geniCodeRValue (right, TRUE);
4123 return geniCodeArray (left, right,lvl);
4125 case '.': /* structure dereference */
4126 if (IS_PTR (operandType (left)))
4127 left = geniCodeRValue (left, TRUE);
4129 left = geniCodeRValue (left, FALSE);
4131 return geniCodeStruct (left, right, tree->lvalue);
4133 case PTR_OP: /* structure pointer dereference */
4136 pType = operandType (left);
4137 left = geniCodeRValue (left, TRUE);
4139 setOClass (pType, getSpec (operandType (left)));
4142 return geniCodeStruct (left, right, tree->lvalue);
4144 case INC_OP: /* increment operator */
4146 return geniCodePostInc (left);
4148 return geniCodePreInc (right, tree->lvalue);
4150 case DEC_OP: /* decrement operator */
4152 return geniCodePostDec (left);
4154 return geniCodePreDec (right, tree->lvalue);
4156 case '&': /* bitwise and or address of operator */
4158 { /* this is a bitwise operator */
4159 left = geniCodeRValue (left, FALSE);
4160 right = geniCodeRValue (right, FALSE);
4161 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4164 return geniCodeAddressOf (left);
4166 case '|': /* bitwise or & xor */
4168 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4169 geniCodeRValue (right, FALSE),
4174 return geniCodeDivision (geniCodeRValue (left, FALSE),
4175 geniCodeRValue (right, FALSE),
4176 getResultTypeFromType (tree->ftype));
4179 return geniCodeModulus (geniCodeRValue (left, FALSE),
4180 geniCodeRValue (right, FALSE),
4181 getResultTypeFromType (tree->ftype));
4184 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4185 geniCodeRValue (right, FALSE),
4186 getResultTypeFromType (tree->ftype));
4188 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4192 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4193 geniCodeRValue (right, FALSE),
4194 getResultTypeFromType (tree->ftype));
4196 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4200 return geniCodeAdd (geniCodeRValue (left, FALSE),
4201 geniCodeRValue (right, FALSE),
4202 getResultTypeFromType (tree->ftype),
4205 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4208 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4209 geniCodeRValue (right, FALSE),
4210 getResultTypeFromType (tree->ftype));
4213 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4214 geniCodeRValue (right, FALSE));
4216 #if 0 // this indeed needs a second thought
4220 // let's keep this simple: get the rvalue we need
4221 op=geniCodeRValue (right, FALSE);
4222 // now cast it to whatever we want
4223 op=geniCodeCast (operandType(left), op, FALSE);
4224 // if this is going to be used as an lvalue, make it so
4230 #else // bug #604575, is it a bug ????
4231 return geniCodeCast (operandType (left),
4232 geniCodeRValue (right, FALSE), FALSE);
4239 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4244 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4245 if (!IS_BIT (operandType (op)))
4246 setOperandType (op, UCHARTYPE);
4251 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4252 geniCodeRValue (right, FALSE),
4254 if (!IS_BIT (operandType (op)))
4255 setOperandType (op, UCHARTYPE);
4260 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4261 geniCodeRValue (right, FALSE),
4263 setOperandType (op, UCHARTYPE);
4268 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4269 geniCodeRValue (right, FALSE),
4271 setOperandType (op, UINTTYPE);
4276 return geniCodeLogicAndOr (tree, lvl);
4283 /* different compilers (even different gccs) evaluate
4284 the two calls in a different order. to get the same
4285 result on all machines we have to specify a clear sequence.
4286 return geniCodeLogic (geniCodeRValue (left, FALSE),
4287 geniCodeRValue (right, FALSE),
4291 operand *leftOp, *rightOp;
4293 leftOp = geniCodeRValue (left , FALSE);
4294 rightOp = geniCodeRValue (right, FALSE);
4296 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
4299 return geniCodeConditional (tree,lvl);
4302 return operandFromLit (getSize (tree->right->ftype));
4306 sym_link *rtype = operandType (right);
4307 sym_link *ltype = operandType (left);
4308 if (IS_PTR (rtype) && IS_ITEMP (right)
4309 && right->isaddr && compareType (rtype->next, ltype) == 1)
4310 right = geniCodeRValue (right, TRUE);
4312 right = geniCodeRValue (right, FALSE);
4314 return geniCodeAssign (left, right, 0, 1);
4318 geniCodeAssign (left,
4319 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4321 geniCodeRValue (right, FALSE),
4322 getResultTypeFromType (tree->ftype)),
4327 geniCodeAssign (left,
4328 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4330 geniCodeRValue (right, FALSE),
4331 getResultTypeFromType (tree->ftype)),
4335 geniCodeAssign (left,
4336 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4338 geniCodeRValue (right, FALSE),
4339 getResultTypeFromType (tree->ftype)),
4343 sym_link *rtype = operandType (right);
4344 sym_link *ltype = operandType (left);
4345 if (IS_PTR (rtype) && IS_ITEMP (right)
4346 && right->isaddr && compareType (rtype->next, ltype) == 1)
4347 right = geniCodeRValue (right, TRUE);
4349 right = geniCodeRValue (right, FALSE);
4352 return geniCodeAssign (left,
4353 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4356 getResultTypeFromType (tree->ftype),
4362 sym_link *rtype = operandType (right);
4363 sym_link *ltype = operandType (left);
4364 if (IS_PTR (rtype) && IS_ITEMP (right)
4365 && right->isaddr && compareType (rtype->next, ltype) == 1)
4367 right = geniCodeRValue (right, TRUE);
4371 right = geniCodeRValue (right, FALSE);
4374 geniCodeAssign (left,
4375 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4378 getResultTypeFromType (tree->ftype)),
4383 geniCodeAssign (left,
4384 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4386 geniCodeRValue (right, FALSE),
4387 getResultTypeFromType (tree->ftype)),
4391 geniCodeAssign (left,
4392 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4394 geniCodeRValue (right, FALSE)), 0, 1);
4397 geniCodeAssign (left,
4398 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4400 geniCodeRValue (right, FALSE),
4402 operandType (left)), 0, 1);
4405 geniCodeAssign (left,
4406 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4408 geniCodeRValue (right, FALSE),
4410 operandType (left)), 0, 1);
4413 geniCodeAssign (left,
4414 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4416 geniCodeRValue (right, FALSE),
4418 operandType (left)), 0, 1);
4420 return geniCodeRValue (right, FALSE);
4423 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4426 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4427 return ast2iCode (tree->right,lvl+1);
4430 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4431 return ast2iCode (tree->right,lvl+1);
4434 geniCodeFunctionBody (tree,lvl);
4438 geniCodeReturn (right);
4442 geniCodeIfx (tree,lvl);
4446 geniCodeSwitch (tree,lvl);
4450 geniCodeInline (tree);
4454 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4458 geniCodeCritical (tree, lvl);
4464 /*-----------------------------------------------------------------*/
4465 /* reverseICChain - gets from the list and creates a linkedlist */
4466 /*-----------------------------------------------------------------*/
4473 while ((loop = getSet (&iCodeChain)))
4485 /*-----------------------------------------------------------------*/
4486 /* iCodeFromAst - given an ast will convert it to iCode */
4487 /*-----------------------------------------------------------------*/
4489 iCodeFromAst (ast * tree)
4491 returnLabel = newiTempLabel ("_return");
4492 entryLabel = newiTempLabel ("_entry");
4494 return reverseiCChain ();
4497 static const char *opTypeToStr(OPTYPE op)
4501 case SYMBOL: return "symbol";
4502 case VALUE: return "value";
4503 case TYPE: return "type";
4505 return "undefined type";
4509 operand *validateOpType(operand *op,
4516 if (op && op->type == type)
4521 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4522 " expected %s, got %s\n",
4523 macro, args, file, line,
4524 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4526 return op; // never reached, makes compiler happy.