1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
28 #include "dbuf_string.h"
30 /*-----------------------------------------------------------------*/
31 /* global variables */
33 set *iCodeChain = NULL;
38 char *filename; /* current file name */
39 int lineno = 1; /* current line number */
44 symbol *returnLabel; /* function return label */
45 symbol *entryLabel; /* function entry label */
47 /*-----------------------------------------------------------------*/
48 /* forward definition of some functions */
49 operand *geniCodeAssign (operand *, operand *, int, int);
50 static operand *geniCodeArray (operand *, operand *,int);
51 static operand *geniCodeArray2Ptr (operand *);
52 operand *geniCodeRValue (operand *, bool);
53 operand *geniCodeDerefPtr (operand *,int);
54 int isLvaluereq(int lvl);
55 void setOClass (sym_link * ptr, sym_link * spec);
56 static operand *geniCodeCast (sym_link *, operand *, bool);
58 #define PRINTFUNC(x) void x (struct dbuf_s *dbuf, iCode *ic, char *s)
59 /* forward definition of ic print functions */
60 PRINTFUNC (picGetValueAtAddr);
61 PRINTFUNC (picSetValueAtAddr);
62 PRINTFUNC (picAddrOf);
63 PRINTFUNC (picGeneric);
64 PRINTFUNC (picGenericOne);
66 PRINTFUNC (picAssign);
70 PRINTFUNC (picJumpTable);
71 PRINTFUNC (picInline);
72 PRINTFUNC (picReceive);
73 PRINTFUNC (picDummyRead);
74 PRINTFUNC (picCritical);
75 PRINTFUNC (picEndCritical);
77 iCodeTable codeTable[] =
79 {'!', "not", picGenericOne, NULL},
80 {'~', "~", picGenericOne, NULL},
81 {RRC, "rrc", picGenericOne, NULL},
82 {RLC, "rlc", picGenericOne, NULL},
83 {GETHBIT, "ghbit", picGenericOne, NULL},
84 {GETABIT, "gabit", picGenericOne, NULL},
85 {GETBYTE, "gbyte", picGenericOne, NULL},
86 {GETWORD, "gword", picGenericOne, NULL},
87 {UNARYMINUS, "-", picGenericOne, NULL},
88 {IPUSH, "push", picGenericOne, NULL},
89 {IPOP, "pop", picGenericOne, NULL},
90 {CALL, "call", picGenericOne, NULL},
91 {PCALL, "pcall", picGenericOne, NULL},
92 {FUNCTION, "proc", picGenericOne, NULL},
93 {ENDFUNCTION, "eproc", picGenericOne, NULL},
94 {RETURN, "ret", picGenericOne, NULL},
95 {'+', "+", picGeneric, NULL},
96 {'-', "-", picGeneric, NULL},
97 {'*', "*", picGeneric, NULL},
98 {'/', "/", picGeneric, NULL},
99 {'%', "%", picGeneric, NULL},
100 {'>', ">", picGeneric, NULL},
101 {'<', "<", picGeneric, NULL},
102 {LE_OP, "<=", picGeneric, NULL},
103 {GE_OP, ">=", picGeneric, NULL},
104 {EQ_OP, "==", picGeneric, NULL},
105 {NE_OP, "!=", picGeneric, NULL},
106 {AND_OP, "&&", picGeneric, NULL},
107 {OR_OP, "||", picGeneric, NULL},
108 {'^', "^", picGeneric, NULL},
109 {'|', "|", picGeneric, NULL},
110 {BITWISEAND, "&", picGeneric, NULL},
111 {LEFT_OP, "<<", picGeneric, NULL},
112 {RIGHT_OP, ">>", picGeneric, NULL},
113 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
114 {ADDRESS_OF, "&", picAddrOf, NULL},
115 {CAST, "<>", picCast, NULL},
116 {'=', ":=", picAssign, NULL},
117 {LABEL, "", picLabel, NULL},
118 {GOTO, "", picGoto, NULL},
119 {JUMPTABLE, "jtab", picJumpTable, NULL},
120 {IFX, "if", picIfx, NULL},
121 {INLINEASM, "", picInline, NULL},
122 {RECEIVE, "recv", picReceive, NULL},
123 {SEND, "send", picGenericOne, NULL},
124 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
125 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
126 {CRITICAL, "critical_start", picCritical, NULL},
127 {ENDCRITICAL, "critical_end", picEndCritical, NULL},
128 {SWAP, "swap", picGenericOne, NULL}
131 /*-----------------------------------------------------------------*/
132 /* operandName - returns the name of the operand */
133 /*-----------------------------------------------------------------*/
135 printOperand (operand * op, FILE * file)
146 dbuf_init (&dbuf, 1024);
147 ret = dbuf_printOperand(op, &dbuf);
148 dbuf_write_and_destroy (&dbuf, file);
157 dbuf_printOperand (operand * op, struct dbuf_s *dbuf)
168 opetype = getSpec (operandType (op));
169 if (IS_FLOAT (opetype))
170 dbuf_printf (dbuf, "%g {", SPEC_CVAL (opetype).v_float);
171 else if (IS_FIXED16X16 (opetype))
172 dbuf_printf (dbuf, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
174 dbuf_printf (dbuf, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
175 dbuf_printTypeChain (operandType (op), dbuf);
176 dbuf_append_char (dbuf, '}');
182 if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
183 dbuf_printf (dbuf, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
184 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
186 OP_LIVEFROM (op), OP_LIVETO (op),
187 OP_SYMBOL (op)->stack,
188 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
189 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
190 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
193 dbuf_append_char (dbuf, '{');
194 dbuf_printTypeChain (operandType (op), dbuf);
195 if (SPIL_LOC (op) && IS_ITEMP (op))
196 dbuf_printf (dbuf, "}{ sir@ %s", SPIL_LOC (op)->rname);
197 dbuf_append_char (dbuf, '}');
201 /* if assigned to registers */
202 if (OP_SYMBOL (op)->nRegs)
204 if (OP_SYMBOL (op)->isspilt)
206 if (!OP_SYMBOL (op)->remat)
207 if (OP_SYMBOL (op)->usl.spillLoc)
208 dbuf_printf (dbuf, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
209 OP_SYMBOL (op)->usl.spillLoc->rname :
210 OP_SYMBOL (op)->usl.spillLoc->name));
212 dbuf_append_str (dbuf, "[err]");
214 dbuf_append_str (dbuf, "[remat]");
219 dbuf_append_char (dbuf, '[');
220 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
221 dbuf_printf (dbuf, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
222 dbuf_append_char (dbuf, ']');
225 //#else /* } else { */
227 /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
228 dbuf_printf (dbuf, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
230 if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
232 dbuf_printf (dbuf, "[lr%d:%d so:%d]",
233 OP_LIVEFROM (op), OP_LIVETO (op),
234 OP_SYMBOL (op)->stack);
237 if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
239 dbuf_append_char (dbuf, '{');
240 dbuf_printTypeChain (operandType (op), dbuf);
241 if (SPIL_LOC (op) && IS_ITEMP (op))
242 dbuf_printf (dbuf, "}{ sir@ %s", SPIL_LOC (op)->rname);
243 dbuf_append_char (dbuf, '}');
246 /* if assigned to registers */
247 if (OP_SYMBOL (op)->nRegs)
249 if (OP_SYMBOL (op)->isspilt)
251 if (!OP_SYMBOL (op)->remat)
252 if (OP_SYMBOL (op)->usl.spillLoc)
253 dbuf_printf (dbuf, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
254 OP_SYMBOL (op)->usl.spillLoc->rname :
255 OP_SYMBOL (op)->usl.spillLoc->name));
257 dbuf_append_str (dbuf, "[err]");
259 dbuf_append_str (dbuf, "[remat]");
264 dbuf_append_char (dbuf, '[');
265 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
266 dbuf_printf (dbuf, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
267 dbuf_append_char (dbuf, ']');
275 dbuf_append_char (dbuf, '(');
276 dbuf_printTypeChain (op->operand.typeOperand, dbuf);
277 dbuf_append_char (dbuf, ')');
285 /*-----------------------------------------------------------------*/
286 /* print functions */
287 /*-----------------------------------------------------------------*/
288 PRINTFUNC (picGetValueAtAddr)
290 dbuf_append_char (dbuf, '\t');
291 dbuf_printOperand (IC_RESULT (ic), dbuf);
292 dbuf_append_str (dbuf, " = ");
293 dbuf_append_str (dbuf, "@[");
294 dbuf_printOperand (IC_LEFT (ic), dbuf);
295 dbuf_append_str (dbuf, "]\n");
298 PRINTFUNC (picSetValueAtAddr)
300 dbuf_append_char (dbuf, '\t');
301 dbuf_append_str (dbuf, "*[");
302 dbuf_printOperand (IC_LEFT (ic), dbuf);
303 dbuf_append_str (dbuf, "] = ");
304 dbuf_printOperand (IC_RIGHT (ic), dbuf);
305 dbuf_append_char (dbuf, '\n');
308 PRINTFUNC (picAddrOf)
310 dbuf_append_char (dbuf, '\t');
311 dbuf_printOperand (IC_RESULT (ic), dbuf);
312 if (IS_ITEMP (IC_LEFT (ic)))
313 dbuf_append_str (dbuf, " = ");
315 dbuf_append_str (dbuf, " = &[");
316 dbuf_printOperand (IC_LEFT (ic), dbuf);
319 if (IS_ITEMP (IC_LEFT (ic)))
320 dbuf_append_str (dbuf, " offsetAdd ");
322 dbuf_append_str (dbuf, " , ");
323 dbuf_printOperand (IC_RIGHT (ic), dbuf);
325 if (IS_ITEMP (IC_LEFT (ic)))
326 dbuf_append_char (dbuf, '\n');
328 dbuf_append_str (dbuf, "]\n");
331 PRINTFUNC (picJumpTable)
335 dbuf_append_char (dbuf, '\t');
336 dbuf_printf (dbuf, "%s\t", s);
337 dbuf_printOperand (IC_JTCOND (ic), dbuf);
338 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
339 sym = setNextItem (IC_JTLABELS (ic)))
340 dbuf_printf (dbuf, "; %s", sym->name);
341 dbuf_append_char (dbuf, '\n');
344 PRINTFUNC (picGeneric)
346 dbuf_append_char (dbuf, '\t');
347 dbuf_printOperand (IC_RESULT (ic), dbuf);
348 dbuf_append_str (dbuf, " = ");
349 dbuf_printOperand (IC_LEFT (ic), dbuf);
350 dbuf_printf (dbuf, " %s ", s);
351 dbuf_printOperand (IC_RIGHT (ic), dbuf);
352 dbuf_append_char (dbuf, '\n');
355 PRINTFUNC (picGenericOne)
357 dbuf_append_char (dbuf, '\t');
360 dbuf_printOperand (IC_RESULT (ic), dbuf);
361 dbuf_append_str (dbuf, " = ");
366 dbuf_printf (dbuf, "%s ", s);
367 dbuf_printOperand (IC_LEFT (ic), dbuf);
370 if (!IC_RESULT (ic) && !IC_LEFT (ic))
371 dbuf_append_str (dbuf, s);
373 if (ic->op == SEND || ic->op == RECEIVE) {
374 dbuf_printf (dbuf,"{argreg = %d}",ic->argreg);
376 if (ic->op == IPUSH) {
377 dbuf_printf (dbuf,"{parmPush = %d}",ic->parmPush);
379 dbuf_append_char (dbuf, '\n');
384 dbuf_append_char (dbuf, '\t');
385 dbuf_printOperand (IC_RESULT (ic), dbuf);
386 dbuf_append_str (dbuf, " = ");
387 dbuf_printOperand (IC_LEFT (ic), dbuf);
388 dbuf_printOperand (IC_RIGHT (ic), dbuf);
389 dbuf_append_char (dbuf, '\n');
393 PRINTFUNC (picAssign)
395 dbuf_append_char (dbuf, '\t');
397 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
398 dbuf_append_str (dbuf, "*(");
400 dbuf_printOperand (IC_RESULT (ic), dbuf);
402 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
403 dbuf_append_char (dbuf, ')');
405 dbuf_printf (dbuf, " %s ", s);
406 dbuf_printOperand (IC_RIGHT (ic), dbuf);
408 dbuf_append_char (dbuf, '\n');
413 dbuf_printf (dbuf, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
418 dbuf_append_char (dbuf, '\t');
419 dbuf_printf (dbuf, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
424 dbuf_append_char (dbuf, '\t');
425 dbuf_append_str (dbuf, "if ");
426 dbuf_printOperand (IC_COND (ic), dbuf);
429 dbuf_printf (dbuf, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
432 dbuf_printf (dbuf, " != 0 goto %s($%d)", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
434 dbuf_printf (dbuf, "; zzgoto %s\n", IC_FALSE (ic)->name);
435 dbuf_append_char (dbuf, '\n');
439 PRINTFUNC (picInline)
441 dbuf_append_str (dbuf, IC_INLINE (ic));
444 PRINTFUNC (picReceive)
446 dbuf_printOperand (IC_RESULT (ic), dbuf);
447 dbuf_printf (dbuf, " = %s ", s);
448 dbuf_printOperand (IC_LEFT (ic), dbuf);
449 dbuf_append_char (dbuf, '\n');
452 PRINTFUNC (picDummyRead)
454 dbuf_append_char (dbuf, '\t');
455 dbuf_printf (dbuf, "%s ", s);
456 dbuf_printOperand (IC_RIGHT (ic), dbuf);
457 dbuf_append_char (dbuf, '\n');
460 PRINTFUNC (picCritical)
462 dbuf_append_char (dbuf, '\t');
464 dbuf_printOperand (IC_RESULT (ic), dbuf);
466 dbuf_append_str (dbuf, "(stack)");
467 dbuf_printf (dbuf, " = %s ", s);
468 dbuf_append_char (dbuf, '\n');
471 PRINTFUNC (picEndCritical)
473 dbuf_append_char (dbuf, '\t');
474 dbuf_printf (dbuf, "%s = ", s);
476 dbuf_printOperand (IC_RIGHT (ic), dbuf);
478 dbuf_append_str (dbuf, "(stack)");
479 dbuf_append_char (dbuf, '\n');
482 /*-----------------------------------------------------------------*/
483 /* piCode - prints one iCode */
484 /*-----------------------------------------------------------------*/
486 piCode (void *item, FILE * of)
495 icTab = getTableEntry (ic->op);
496 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
497 ic->filename, ic->lineno,
498 ic->seq, ic->key, ic->depth, ic->supportRtn);
499 dbuf_init (&dbuf, 1024);
500 icTab->iCodePrint (&dbuf, ic, icTab->printName);
501 dbuf_write_and_destroy (&dbuf, of);
507 printiCChain(ic,stdout);
509 /*-----------------------------------------------------------------*/
510 /* printiCChain - prints intermediate code for humans */
511 /*-----------------------------------------------------------------*/
513 printiCChain (iCode * icChain, FILE * of)
521 for (loop = icChain; loop; loop = loop->next)
523 if ((icTab = getTableEntry (loop->op)))
525 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
526 loop->filename, loop->lineno,
527 loop->seq, loop->key, loop->depth, loop->supportRtn);
529 dbuf_init(&dbuf, 1024);
530 icTab->iCodePrint (&dbuf, loop, icTab->printName);
531 dbuf_write_and_destroy (&dbuf, of);
539 /*-----------------------------------------------------------------*/
540 /* newOperand - allocate, init & return a new iCode */
541 /*-----------------------------------------------------------------*/
547 op = Safe_alloc ( sizeof (operand));
553 /*-----------------------------------------------------------------*/
554 /* newiCode - create and return a new iCode entry initialised */
555 /*-----------------------------------------------------------------*/
557 newiCode (int op, operand * left, operand * right)
561 ic = Safe_alloc ( sizeof (iCode));
563 ic->seqPoint = seqPoint;
565 ic->filename = filename;
567 ic->level = scopeLevel;
569 ic->key = iCodeKey++;
571 IC_RIGHT (ic) = right;
576 /*-----------------------------------------------------------------*/
577 /* newiCode for conditional statements */
578 /*-----------------------------------------------------------------*/
580 newiCodeCondition (operand * condition,
586 if (IS_VOID(operandType(condition))) {
587 werror(E_VOID_VALUE_USED);
590 ic = newiCode (IFX, NULL, NULL);
591 IC_COND (ic) = condition;
592 IC_TRUE (ic) = trueLabel;
593 IC_FALSE (ic) = falseLabel;
597 /*-----------------------------------------------------------------*/
598 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
599 /*-----------------------------------------------------------------*/
601 newiCodeLabelGoto (int op, symbol * label)
605 ic = newiCode (op, NULL, NULL);
609 IC_RIGHT (ic) = NULL;
610 IC_RESULT (ic) = NULL;
614 /*-----------------------------------------------------------------*/
615 /* newiTemp - allocate & return a newItemp Variable */
616 /*-----------------------------------------------------------------*/
624 SNPRINTF (buffer, sizeof(buffer), "%s", s);
628 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
631 itmp = newSymbol (buffer, 1);
632 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
638 /*-----------------------------------------------------------------*/
639 /* newiTempLabel - creates a temp variable label */
640 /*-----------------------------------------------------------------*/
642 newiTempLabel (char *s)
646 /* check if this already exists */
647 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
652 itmplbl = newSymbol (s, 1);
656 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
657 itmplbl = newSymbol (buffer, 1);
662 itmplbl->key = labelKey++;
663 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
667 /*-----------------------------------------------------------------*/
668 /* newiTempLoopHeaderLabel - creates a new loop header label */
669 /*-----------------------------------------------------------------*/
671 newiTempLoopHeaderLabel (bool pre)
675 SNPRINTF (buffer, sizeof(buffer), pre ? "preHeaderLbl%d" : LOOPEXITLBL "%d",
677 itmplbl = newSymbol (buffer, 1);
681 itmplbl->key = labelKey++;
682 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
687 /*-----------------------------------------------------------------*/
688 /* initiCode - initialises some iCode related stuff */
689 /*-----------------------------------------------------------------*/
696 /*-----------------------------------------------------------------*/
697 /* copyiCode - make a copy of the iCode given */
698 /*-----------------------------------------------------------------*/
700 copyiCode (iCode * ic)
702 iCode *nic = newiCode (ic->op, NULL, NULL);
704 nic->lineno = ic->lineno;
705 nic->filename = ic->filename;
706 nic->block = ic->block;
707 nic->level = ic->level;
708 nic->parmBytes = ic->parmBytes;
710 /* deal with the special cases first */
714 IC_COND (nic) = operandFromOperand (IC_COND (ic));
715 IC_TRUE (nic) = IC_TRUE (ic);
716 IC_FALSE (nic) = IC_FALSE (ic);
720 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
721 IC_JTLABELS (nic) = IC_JTLABELS (ic);
726 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
727 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
731 IC_INLINE (nic) = IC_INLINE (ic);
735 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
739 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
740 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
741 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
747 /*-----------------------------------------------------------------*/
748 /* getTableEntry - gets the table entry for the given operator */
749 /*-----------------------------------------------------------------*/
751 getTableEntry (int oper)
755 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
756 if (oper == codeTable[i].icode)
757 return &codeTable[i];
762 /*-----------------------------------------------------------------*/
763 /* newiTempOperand - new intermediate temp operand */
764 /*-----------------------------------------------------------------*/
766 newiTempOperand (sym_link * type, char throwType)
769 operand *op = newOperand ();
773 itmp = newiTemp (NULL);
775 etype = getSpec (type);
777 if (IS_LITERAL (etype))
780 /* copy the type information */
782 itmp->etype = getSpec (itmp->type = (throwType ? type :
783 copyLinkChain (type)));
784 if (IS_LITERAL (itmp->etype))
786 SPEC_SCLS (itmp->etype) = S_REGISTER;
787 SPEC_OCLS (itmp->etype) = reg;
790 op->operand.symOperand = itmp;
791 op->key = itmp->key = ++operandKey;
795 /*-----------------------------------------------------------------*/
796 /* operandType - returns the type chain for an operand */
797 /*-----------------------------------------------------------------*/
799 operandType (operand * op)
801 /* depending on type of operand */
806 return op->operand.valOperand->type;
809 return op->operand.symOperand->type;
812 return op->operand.typeOperand;
814 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
815 " operand type not known ");
816 assert (0); /* should never come here */
817 /* Just to keep the compiler happy */
818 return (sym_link *) 0;
822 /*-----------------------------------------------------------------*/
823 /* isParamterToCall - will return 1 if op is a parameter to args */
824 /*-----------------------------------------------------------------*/
826 isParameterToCall (value * args, operand * op)
830 wassert (IS_SYMOP(op));
835 isSymbolEqual (op->operand.symOperand, tval->sym))
842 /*-----------------------------------------------------------------*/
843 /* isOperandGlobal - return 1 if operand is a global variable */
844 /*-----------------------------------------------------------------*/
846 isOperandGlobal (operand * op)
855 (op->operand.symOperand->level == 0 ||
856 IS_STATIC (op->operand.symOperand->etype) ||
857 IS_EXTERN (op->operand.symOperand->etype))
864 /*-----------------------------------------------------------------*/
865 /* isOperandVolatile - return 1 if the operand is volatile */
866 /*-----------------------------------------------------------------*/
868 isOperandVolatile (operand * op, bool chkTemp)
873 if (IS_ITEMP (op) && !chkTemp)
876 opetype = getSpec (optype = operandType (op));
878 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
881 if (IS_VOLATILE (opetype))
886 /*-----------------------------------------------------------------*/
887 /* isOperandLiteral - returns 1 if an operand contains a literal */
888 /*-----------------------------------------------------------------*/
890 isOperandLiteral (operand * op)
897 opetype = getSpec (operandType (op));
899 if (IS_LITERAL (opetype))
905 /*-----------------------------------------------------------------*/
906 /* isOperandInFarSpace - will return true if operand is in farSpace */
907 /*-----------------------------------------------------------------*/
909 isOperandInFarSpace (operand * op)
919 if (!IS_TRUE_SYMOP (op))
922 etype = SPIL_LOC (op)->etype;
928 etype = getSpec (operandType (op));
930 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
933 /*-----------------------------------------------------------------*/
934 /* isOperandInPagedSpace - return true if operand is in pagedSpace */
935 /*-----------------------------------------------------------------*/
937 isOperandInPagedSpace (operand * op)
947 if (!IS_TRUE_SYMOP (op))
950 etype = SPIL_LOC (op)->etype;
956 etype = getSpec (operandType (op));
958 return (IN_PAGEDSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
961 /*------------------------------------------------------------------*/
962 /* isOperandInDirSpace - will return true if operand is in dirSpace */
963 /*------------------------------------------------------------------*/
965 isOperandInDirSpace (operand * op)
975 if (!IS_TRUE_SYMOP (op))
978 etype = SPIL_LOC (op)->etype;
984 etype = getSpec (operandType (op));
986 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
989 /*--------------------------------------------------------------------*/
990 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
991 /*--------------------------------------------------------------------*/
993 isOperandInCodeSpace (operand * op)
1003 etype = getSpec (operandType (op));
1005 if (!IS_TRUE_SYMOP (op))
1008 etype = SPIL_LOC (op)->etype;
1014 etype = getSpec (operandType (op));
1016 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1019 /*-----------------------------------------------------------------*/
1020 /* isOperandOnStack - will return true if operand is on stack */
1021 /*-----------------------------------------------------------------*/
1023 isOperandOnStack (operand * op)
1033 etype = getSpec (operandType (op));
1034 if (IN_STACK (etype) ||
1035 OP_SYMBOL(op)->onStack ||
1036 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1042 /*-----------------------------------------------------------------*/
1043 /* isOclsExpensive - will return true if accesses to an output */
1044 /* storage class are expensive */
1045 /*-----------------------------------------------------------------*/
1047 isOclsExpensive (struct memmap *oclass)
1049 if (port->oclsExpense)
1050 return port->oclsExpense (oclass) > 0;
1052 /* In the absence of port specific guidance, assume only */
1053 /* farspace is expensive. */
1054 return IN_FARSPACE (oclass);
1057 /*-----------------------------------------------------------------*/
1058 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1059 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1060 /*-----------------------------------------------------------------*/
1062 isiCodeInFunctionCall (iCode * ic)
1066 /* Find the next CALL/PCALL */
1069 if (lic->op == CALL || lic->op == PCALL)
1077 /* A function call was found. Scan backwards and see if an */
1078 /* IPUSH or SEND is encountered */
1081 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1083 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1091 /*-----------------------------------------------------------------*/
1092 /* operandLitValue - literal value of an operand */
1093 /*-----------------------------------------------------------------*/
1095 operandLitValue (operand * op)
1097 assert (isOperandLiteral (op));
1099 return floatFromVal (op->operand.valOperand);
1102 /*-----------------------------------------------------------------*/
1103 /* getBuiltInParms - returns parameters to a builtin functions */
1104 /*-----------------------------------------------------------------*/
1105 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1110 /* builtin functions uses only SEND for parameters */
1111 while (ic->op != CALL) {
1112 assert(ic->op == SEND && ic->builtinSEND);
1113 ic->generated = 1; /* mark the icode as generated */
1114 parms[*pcount] = IC_LEFT(ic);
1120 /* make sure this is a builtin function call */
1121 assert(IS_SYMOP(IC_LEFT(ic)));
1122 ftype = operandType(IC_LEFT(ic));
1123 assert(IFFUNC_ISBUILTIN(ftype));
1127 /*-----------------------------------------------------------------*/
1128 /* operandOperation - performs operations on operands */
1129 /*-----------------------------------------------------------------*/
1131 operandOperation (operand * left, operand * right,
1132 int op, sym_link * type)
1134 sym_link *let , *ret=NULL;
1135 operand *retval = (operand *) 0;
1137 assert (isOperandLiteral (left));
1138 let = getSpec(operandType(left));
1140 assert (isOperandLiteral (right));
1141 ret = getSpec(operandType(right));
1147 retval = operandFromValue (valCastLiteral (type,
1148 operandLitValue (left) +
1149 operandLitValue (right)));
1152 retval = operandFromValue (valCastLiteral (type,
1153 operandLitValue (left) -
1154 operandLitValue (right)));
1158 retval = operandFromValue (valCastLiteral (type,
1159 operandLitValue (left) *
1160 operandLitValue (right)));
1161 This could be all we've to do, but with gcc we've to take care about
1162 overflows. Two examples:
1163 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1164 significant bits are lost (52 in fraction, 63 bits would be
1165 necessary to keep full precision).
1166 If the resulting double value is greater than ULONG_MAX (resp.
1167 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1170 /* if it is not a specifier then we can assume that */
1171 /* it will be an unsigned long */
1172 if (IS_INT (type) ||
1175 /* long is handled here, because it can overflow with double */
1176 if (IS_LONG (type) ||
1178 /* signed and unsigned mul are the same, as long as the precision
1179 of the result isn't bigger than the precision of the operands. */
1180 retval = operandFromValue (valCastLiteral (type,
1181 (TYPE_TARGET_ULONG) operandLitValue (left) *
1182 (TYPE_TARGET_ULONG) operandLitValue (right)));
1183 else if (IS_UNSIGNED (type)) /* unsigned int */
1185 /* unsigned int is handled here in order to detect overflow */
1186 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) operandLitValue (left) *
1187 (TYPE_TARGET_UINT) operandLitValue (right);
1189 retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_UINT) ul));
1190 if (ul != (TYPE_TARGET_UINT) ul)
1193 else /* signed int */
1195 /* signed int is handled here in order to detect overflow */
1196 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) operandLitValue (left) *
1197 (TYPE_TARGET_INT) operandLitValue (right);
1199 retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_INT) l));
1200 if (l != (TYPE_TARGET_INT) l)
1205 /* all others go here: */
1206 retval = operandFromValue (valCastLiteral (type,
1207 operandLitValue (left) *
1208 operandLitValue (right)));
1211 if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
1213 werror (E_DIVIDE_BY_ZERO);
1219 if (IS_UNSIGNED (type))
1221 SPEC_USIGN (let) = 1;
1222 SPEC_USIGN (ret) = 1;
1223 retval = operandFromValue (valCastLiteral (type,
1224 (TYPE_TARGET_ULONG) operandLitValue (left) /
1225 (TYPE_TARGET_ULONG) operandLitValue (right)));
1229 retval = operandFromValue (valCastLiteral (type,
1230 operandLitValue (left) /
1231 operandLitValue (right)));
1236 if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
1238 werror (E_DIVIDE_BY_ZERO);
1243 if (IS_UNSIGNED (type))
1244 retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) %
1245 (TYPE_TARGET_ULONG) operandLitValue (right));
1247 retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) %
1248 (TYPE_TARGET_LONG) operandLitValue (right));
1252 /* The number of left shifts is always unsigned. Signed doesn't make
1253 sense here. Shifting by a negative number is impossible. */
1254 retval = operandFromValue (valCastLiteral (type,
1255 ((TYPE_TARGET_ULONG) operandLitValue (left) <<
1256 (TYPE_TARGET_ULONG) operandLitValue (right))));
1259 /* The number of right shifts is always unsigned. Signed doesn't make
1260 sense here. Shifting by a negative number is impossible. */
1261 if (IS_UNSIGNED(let))
1262 /* unsigned: logic shift right */
1263 retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) >>
1264 (TYPE_TARGET_ULONG) operandLitValue (right));
1266 /* signed: arithmetic shift right */
1267 retval = operandFromLit ((TYPE_TARGET_LONG ) operandLitValue (left) >>
1268 (TYPE_TARGET_ULONG) operandLitValue (right));
1271 if (IS_FLOAT (let) || IS_FLOAT (ret))
1273 retval = operandFromLit (operandLitValue (left) ==
1274 operandLitValue (right));
1276 else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
1278 retval = operandFromLit (operandLitValue (left) ==
1279 operandLitValue (right));
1283 /* this op doesn't care about signedness */
1284 TYPE_TARGET_ULONG l, r;
1286 l = (TYPE_TARGET_ULONG) operandLitValue (left);
1287 r = (TYPE_TARGET_ULONG) operandLitValue (right);
1288 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1289 neccessary to strip them to 16 bit.
1290 Literals are reduced to their cheapest type, therefore left and
1291 right might have different types. It's neccessary to find a
1292 common type: int (used for char too) or long */
1293 if (!IS_LONG (let) &&
1296 r = (TYPE_TARGET_UINT) r;
1297 l = (TYPE_TARGET_UINT) l;
1299 retval = operandFromLit (l == r);
1303 retval = operandFromLit (operandLitValue (left) <
1304 operandLitValue (right));
1307 retval = operandFromLit (operandLitValue (left) <=
1308 operandLitValue (right));
1311 retval = operandFromLit (operandLitValue (left) !=
1312 operandLitValue (right));
1315 retval = operandFromLit (operandLitValue (left) >
1316 operandLitValue (right));
1319 retval = operandFromLit (operandLitValue (left) >=
1320 operandLitValue (right));
1323 retval = operandFromValue (valCastLiteral (type,
1324 (TYPE_TARGET_ULONG)operandLitValue(left) &
1325 (TYPE_TARGET_ULONG)operandLitValue(right)));
1328 retval = operandFromValue (valCastLiteral (type,
1329 (TYPE_TARGET_ULONG)operandLitValue(left) |
1330 (TYPE_TARGET_ULONG)operandLitValue(right)));
1333 retval = operandFromValue (valCastLiteral (type,
1334 (TYPE_TARGET_ULONG)operandLitValue(left) ^
1335 (TYPE_TARGET_ULONG)operandLitValue(right)));
1338 retval = operandFromLit (operandLitValue (left) &&
1339 operandLitValue (right));
1342 retval = operandFromLit (operandLitValue (left) ||
1343 operandLitValue (right));
1347 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
1349 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1355 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
1357 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1362 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1363 (TYPE_TARGET_ULONG)operandLitValue(right)) & 1);
1366 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1367 (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFF);
1370 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1371 (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFFFF);
1375 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1376 ((getSize (let) * 8) - 1)) & 1);
1380 retval = operandFromValue (valCastLiteral (type,
1381 -1 * operandLitValue (left)));
1385 retval = operandFromValue (valCastLiteral (type,
1386 ~((TYPE_TARGET_ULONG)
1387 operandLitValue (left))));
1391 retval = operandFromLit (!operandLitValue (left));
1395 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1396 " operandOperation invalid operator ");
1404 /*-----------------------------------------------------------------*/
1405 /* isOperandEqual - compares two operand & return 1 if they r = */
1406 /*-----------------------------------------------------------------*/
1408 isOperandEqual (operand * left, operand * right)
1410 /* if the pointers are equal then they are equal */
1414 /* if either of them null then false */
1415 if (!left || !right)
1418 if (left->type != right->type)
1421 if (IS_SYMOP (left) && IS_SYMOP (right))
1422 return left->key == right->key;
1424 /* if types are the same */
1428 return isSymbolEqual (left->operand.symOperand,
1429 right->operand.symOperand);
1431 return (compareType (left->operand.valOperand->type,
1432 right->operand.valOperand->type) &&
1433 (floatFromVal (left->operand.valOperand) ==
1434 floatFromVal (right->operand.valOperand)));
1436 if (compareType (left->operand.typeOperand,
1437 right->operand.typeOperand) == 1)
1444 /*-------------------------------------------------------------------*/
1445 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1446 /*-------------------------------------------------------------------*/
1448 isiCodeEqual (iCode * left, iCode * right)
1450 /* if the same pointer */
1454 /* if either of them null */
1455 if (!left || !right)
1458 /* if operand are the same */
1459 if (left->op == right->op)
1462 /* compare all the elements depending on type */
1463 if (left->op != IFX)
1465 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1467 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1473 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1475 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1477 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1486 /*-----------------------------------------------------------------*/
1487 /* newiTempFromOp - create a temp Operand with same attributes */
1488 /*-----------------------------------------------------------------*/
1490 newiTempFromOp (operand * op)
1500 nop = newiTempOperand (operandType (op), TRUE);
1501 nop->isaddr = op->isaddr;
1502 nop->isvolatile = op->isvolatile;
1503 nop->isGlobal = op->isGlobal;
1504 nop->isLiteral = op->isLiteral;
1505 nop->usesDefs = op->usesDefs;
1506 nop->isParm = op->isParm;
1510 /*-----------------------------------------------------------------*/
1511 /* operand from operand - creates an operand holder for the type */
1512 /*-----------------------------------------------------------------*/
1514 operandFromOperand (operand * op)
1520 nop = newOperand ();
1521 nop->type = op->type;
1522 nop->isaddr = op->isaddr;
1524 nop->isvolatile = op->isvolatile;
1525 nop->isGlobal = op->isGlobal;
1526 nop->isLiteral = op->isLiteral;
1527 nop->usesDefs = op->usesDefs;
1528 nop->isParm = op->isParm;
1533 nop->operand.symOperand = op->operand.symOperand;
1536 nop->operand.valOperand = op->operand.valOperand;
1539 nop->operand.typeOperand = op->operand.typeOperand;
1546 /*-----------------------------------------------------------------*/
1547 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1548 /*-----------------------------------------------------------------*/
1550 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1552 operand *nop = operandFromOperand (op);
1554 if (nop->type == SYMBOL)
1556 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1557 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1563 /*-----------------------------------------------------------------*/
1564 /* operandFromSymbol - creates an operand from a symbol */
1565 /*-----------------------------------------------------------------*/
1567 operandFromSymbol (symbol * sym)
1572 /* if the symbol's type is a literal */
1573 /* then it is an enumerator type */
1574 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1575 return operandFromValue (valFromType (sym->etype));
1578 sym->key = ++operandKey;
1580 /* if this an implicit variable, means struct/union */
1581 /* member so just return it */
1582 if (sym->implicit || IS_FUNC (sym->type))
1586 op->operand.symOperand = sym;
1588 op->isvolatile = isOperandVolatile (op, TRUE);
1589 op->isGlobal = isOperandGlobal (op);
1593 /* under the following conditions create a
1594 register equivalent for a local symbol */
1595 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1596 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1598 (!(options.model == MODEL_FLAT24)) ) &&
1599 options.stackAuto == 0)
1602 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1603 !IS_FUNC (sym->type) && /* not a function */
1604 !sym->_isparm && /* not a parameter */
1605 IS_AUTO (sym) && /* is a local auto variable */
1606 !sym->addrtaken && /* whose address has not been taken */
1607 !sym->reqv && /* does not already have a reg equivalence */
1608 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1609 !sym->islbl && /* not a label */
1610 ok /* farspace check */
1614 /* we will use it after all optimizations
1615 and before liveRange calculation */
1616 sym->reqv = newiTempOperand (sym->type, 0);
1617 sym->reqv->key = sym->key;
1618 OP_SYMBOL (sym->reqv)->prereqv = sym;
1619 OP_SYMBOL (sym->reqv)->key = sym->key;
1620 OP_SYMBOL (sym->reqv)->isreqv = 1;
1621 OP_SYMBOL (sym->reqv)->islocal = 1;
1622 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1623 SPIL_LOC (sym->reqv) = sym;
1626 if (!IS_AGGREGATE (sym->type))
1630 op->operand.symOperand = sym;
1633 op->isvolatile = isOperandVolatile (op, TRUE);
1634 op->isGlobal = isOperandGlobal (op);
1635 op->isPtr = IS_PTR (operandType (op));
1636 op->isParm = sym->_isparm;
1641 /* itemp = &[_symbol] */
1643 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1644 IC_LEFT (ic)->type = SYMBOL;
1645 IC_LEFT (ic)->operand.symOperand = sym;
1646 IC_LEFT (ic)->key = sym->key;
1647 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1648 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1649 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1652 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1653 if (IS_ARRAY (sym->type))
1655 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1656 IC_RESULT (ic)->isaddr = 0;
1659 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1663 return IC_RESULT (ic);
1666 /*-----------------------------------------------------------------*/
1667 /* operandFromValue - creates an operand from value */
1668 /*-----------------------------------------------------------------*/
1670 operandFromValue (value * val)
1674 /* if this is a symbol then do the symbol thing */
1676 return operandFromSymbol (val->sym);
1678 /* this is not a symbol */
1681 op->operand.valOperand = val;
1682 op->isLiteral = isOperandLiteral (op);
1686 /*-----------------------------------------------------------------*/
1687 /* operandFromLink - operand from typeChain */
1688 /*-----------------------------------------------------------------*/
1690 operandFromLink (sym_link * type)
1694 /* operand from sym_link */
1700 op->operand.typeOperand = copyLinkChain (type);
1704 /*-----------------------------------------------------------------*/
1705 /* operandFromLit - makes an operand from a literal value */
1706 /*-----------------------------------------------------------------*/
1708 operandFromLit (double i)
1710 return operandFromValue (valueFromLit (i));
1713 /*-----------------------------------------------------------------*/
1714 /* operandFromAst - creates an operand from an ast */
1715 /*-----------------------------------------------------------------*/
1717 operandFromAst (ast * tree,int lvl)
1723 /* depending on type do */
1727 return ast2iCode (tree,lvl+1);
1731 return operandFromValue (tree->opval.val);
1735 return operandFromLink (tree->opval.lnk);
1742 /* Just to keep the compiler happy */
1743 return (operand *) 0;
1746 /*-----------------------------------------------------------------*/
1747 /* setOperandType - sets the operand's type to the given type */
1748 /*-----------------------------------------------------------------*/
1750 setOperandType (operand * op, sym_link * type)
1752 /* depending on the type of operand */
1757 op->operand.valOperand->etype =
1758 getSpec (op->operand.valOperand->type =
1759 copyLinkChain (type));
1763 if (op->operand.symOperand->isitmp)
1764 op->operand.symOperand->etype =
1765 getSpec (op->operand.symOperand->type =
1766 copyLinkChain (type));
1768 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1769 "attempt to modify type of source");
1773 op->operand.typeOperand = copyLinkChain (type);
1779 /*-----------------------------------------------------------------*/
1780 /* Get size in byte of ptr need to access an array */
1781 /*-----------------------------------------------------------------*/
1783 getArraySizePtr (operand * op)
1785 sym_link *ltype = operandType(op);
1789 int size = getSize(ltype);
1790 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1795 sym_link *letype = getSpec(ltype);
1796 switch (PTR_TYPE (SPEC_OCLS (letype)))
1808 if (GPTRSIZE > FPTRSIZE)
1809 return (GPTRSIZE-1);
1820 /*-----------------------------------------------------------------*/
1821 /* perform "usual unary conversions" */
1822 /*-----------------------------------------------------------------*/
1825 usualUnaryConversions (operand * op)
1827 if (IS_INTEGRAL (operandType (op)))
1829 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1832 return geniCodeCast (INTTYPE, op, TRUE);
1839 /*-----------------------------------------------------------------*/
1840 /* perform "usual binary conversions" */
1841 /*-----------------------------------------------------------------*/
1844 usualBinaryConversions (operand ** op1, operand ** op2,
1845 RESULT_TYPE resultType, int op)
1848 sym_link *rtype = operandType (*op2);
1849 sym_link *ltype = operandType (*op1);
1851 ctype = computeType (ltype, rtype, resultType, op);
1858 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1860 /* one byte operations: keep signedness for code generator */
1868 *op1 = geniCodeCast (ctype, *op1, TRUE);
1869 *op2 = geniCodeCast (ctype, *op2, TRUE);
1874 /*-----------------------------------------------------------------*/
1875 /* geniCodeValueAtAddress - generate intermeditate code for value */
1877 /*-----------------------------------------------------------------*/
1879 geniCodeRValue (operand * op, bool force)
1882 sym_link *type = operandType (op);
1883 sym_link *etype = getSpec (type);
1885 /* if this is an array & already */
1886 /* an address then return this */
1887 if (IS_AGGREGATE (type) ||
1888 (IS_PTR (type) && !force && !op->isaddr))
1889 return operandFromOperand (op);
1891 /* if this is not an address then must be */
1892 /* rvalue already so return this one */
1896 /* if this is not a temp symbol then */
1897 if (!IS_ITEMP (op) &&
1899 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1901 op = operandFromOperand (op);
1906 if (IS_SPEC (type) &&
1907 IS_TRUE_SYMOP (op) &&
1908 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1909 (options.model == MODEL_FLAT24) ))
1911 op = operandFromOperand (op);
1916 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1917 if (IS_PTR (type) && op->isaddr && force)
1920 type = copyLinkChain (type);
1922 IC_RESULT (ic) = newiTempOperand (type, 1);
1923 IC_RESULT (ic)->isaddr = 0;
1925 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1929 return IC_RESULT (ic);
1932 /*-----------------------------------------------------------------*/
1933 /* geniCodeCast - changes the value from one type to another */
1934 /*-----------------------------------------------------------------*/
1936 geniCodeCast (sym_link * type, operand * op, bool implicit)
1940 sym_link *opetype = getSpec (optype = operandType (op));
1944 /* one of them has size zero then error */
1945 if (IS_VOID (optype))
1947 werror (E_CAST_ZERO);
1951 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1953 geniCodeArray2Ptr (op);
1957 /* if the operand is already the desired type then do nothing */
1958 if (compareType (type, optype) == 1)
1961 /* if this is a literal then just change the type & return */
1962 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1964 return operandFromValue (valCastLiteral (type,
1965 operandLitValue (op)));
1968 /* if casting to/from pointers, do some checking */
1969 if (IS_PTR(type)) { // to a pointer
1970 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1971 if (IS_INTEGRAL(optype)) {
1972 // maybe this is NULL, than it's ok.
1973 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1974 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1975 // no way to set the storage
1976 if (IS_LITERAL(optype)) {
1977 werror(E_LITERAL_GENERIC);
1980 werror(E_NONPTR2_GENPTR);
1983 } else if (implicit) {
1984 werror(W_INTEGRAL2PTR_NOCAST);
1989 // shouldn't do that with float, array or structure unless to void
1990 if (!IS_VOID(getSpec(type)) &&
1991 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1992 werror(E_INCOMPAT_TYPES);
1996 } else { // from a pointer to a pointer
1997 if (IS_GENPTR(type) && IS_VOID(type->next))
1998 { // cast to void* is always allowed
2000 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2001 { // cast from void* is always allowed
2003 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2004 // if not a pointer to a function
2005 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2006 if (implicit) { // if not to generic, they have to match
2007 if (!IS_GENPTR(type) &&
2008 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2009 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2013 werror(E_INCOMPAT_PTYPES);
2020 } else { // to a non pointer
2021 if (IS_PTR(optype)) { // from a pointer
2022 if (implicit) { // sneaky
2023 if (IS_INTEGRAL(type)) {
2024 werror(W_PTR2INTEGRAL_NOCAST);
2026 } else { // shouldn't do that with float, array or structure
2027 werror(E_INCOMPAT_TYPES);
2034 printFromToType (optype, type);
2037 /* if they are the same size create an assignment */
2039 /* This seems very dangerous to me, since there are several */
2040 /* optimizations (for example, gcse) that don't notice the */
2041 /* cast hidden in this assignment and may simplify an */
2042 /* iCode to use the original (uncasted) operand. */
2043 /* Unfortunately, other things break when this cast is */
2044 /* made explicit. Need to fix this someday. */
2045 /* -- EEP, 2004/01/21 */
2046 if (getSize (type) == getSize (optype) &&
2047 !IS_BITFIELD (type) &&
2049 !IS_FLOAT (optype) &&
2051 !IS_FIXED (optype) &&
2052 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2053 (!IS_SPEC (type) && !IS_SPEC (optype))))
2055 ic = newiCode ('=', NULL, op);
2056 IC_RESULT (ic) = newiTempOperand (type, 0);
2057 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2058 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2059 IC_RESULT (ic)->isaddr = 0;
2063 ic = newiCode (CAST, operandFromLink (type),
2064 geniCodeRValue (op, FALSE));
2066 IC_RESULT (ic) = newiTempOperand (type, 0);
2069 /* preserve the storage class & output class */
2070 /* of the original variable */
2071 restype = getSpec (operandType (IC_RESULT (ic)));
2072 if (!IS_LITERAL(opetype) &&
2075 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2076 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2079 return IC_RESULT (ic);
2082 /*-----------------------------------------------------------------*/
2083 /* geniCodeLabel - will create a Label */
2084 /*-----------------------------------------------------------------*/
2086 geniCodeLabel (symbol * label)
2090 ic = newiCodeLabelGoto (LABEL, label);
2094 /*-----------------------------------------------------------------*/
2095 /* geniCodeGoto - will create a Goto */
2096 /*-----------------------------------------------------------------*/
2098 geniCodeGoto (symbol * label)
2102 ic = newiCodeLabelGoto (GOTO, label);
2106 /*-----------------------------------------------------------------*/
2107 /* geniCodeMultiply - gen intermediate code for multiplication */
2108 /*-----------------------------------------------------------------*/
2110 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2117 /* if they are both literal then we know the result */
2118 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2119 return operandFromValue (valMult (left->operand.valOperand,
2120 right->operand.valOperand));
2122 if (IS_LITERAL(retype)) {
2123 p2 = powof2 ((TYPE_TARGET_ULONG) floatFromVal (right->operand.valOperand));
2126 resType = usualBinaryConversions (&left, &right, resultType, '*');
2128 rtype = operandType (right);
2129 retype = getSpec (rtype);
2130 ltype = operandType (left);
2131 letype = getSpec (ltype);
2134 /* if the right is a literal & power of 2 */
2135 /* then make it a left shift */
2136 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2137 efficient in most cases than 2 bytes result = 2 bytes << literal
2138 if port has 1 byte muldiv */
2139 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2140 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2141 && (port->support.muldiv == 1))
2142 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2143 && strcmp (port->target, "pic14") != 0)
2145 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2147 /* LEFT_OP need same size for left and result, */
2148 left = geniCodeCast (resType, left, TRUE);
2149 ltype = operandType (left);
2151 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2155 /* if the size left or right > 1 then support routine */
2156 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2158 if (IS_LITERAL (retype))
2159 ic = newiCode ('*', right, left); /* multiplication by support routine with one literal */
2161 ic = newiCode ('*', left, right); /* multiplication by support routine */
2166 ic = newiCode ('*', left, right); /* normal multiplication */
2169 IC_RESULT (ic) = newiTempOperand (resType, 1);
2172 return IC_RESULT (ic);
2175 /*-----------------------------------------------------------------*/
2176 /* geniCodeDivision - gen intermediate code for division */
2177 /*-----------------------------------------------------------------*/
2179 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2184 sym_link *rtype = operandType (right);
2185 sym_link *retype = getSpec (rtype);
2186 sym_link *ltype = operandType (left);
2187 sym_link *letype = getSpec (ltype);
2189 resType = usualBinaryConversions (&left, &right, resultType, '/');
2191 /* if the right is a literal & power of 2
2192 and left is unsigned then make it a
2194 if (IS_LITERAL (retype) &&
2195 !IS_FLOAT (letype) &&
2196 !IS_FIXED (letype) &&
2197 IS_UNSIGNED(letype) &&
2198 ((p2 = powof2 ((TYPE_TARGET_ULONG)
2199 floatFromVal (right->operand.valOperand))) > 0)) {
2200 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2204 ic = newiCode ('/', left, right); /* normal division */
2205 /* if the size left or right > 1 then support routine */
2206 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2209 IC_RESULT (ic) = newiTempOperand (resType, 0);
2212 return IC_RESULT (ic);
2214 /*-----------------------------------------------------------------*/
2215 /* geniCodeModulus - gen intermediate code for modulus */
2216 /*-----------------------------------------------------------------*/
2218 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2224 /* if they are both literal then we know the result */
2225 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2226 return operandFromValue (valMod (left->operand.valOperand,
2227 right->operand.valOperand));
2229 resType = usualBinaryConversions (&left, &right, resultType, '%');
2231 /* now they are the same size */
2232 ic = newiCode ('%', left, right);
2234 /* if the size left or right > 1 then support routine */
2235 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2237 IC_RESULT (ic) = newiTempOperand (resType, 0);
2240 return IC_RESULT (ic);
2243 /*-----------------------------------------------------------------*/
2244 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2245 /*-----------------------------------------------------------------*/
2247 geniCodePtrPtrSubtract (operand * left, operand * right)
2253 /* if they are both literals then */
2254 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2256 result = operandFromValue (valMinus (left->operand.valOperand,
2257 right->operand.valOperand));
2261 ic = newiCode ('-', left, right);
2263 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2267 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2271 // should we really do this? is this ANSI?
2272 return geniCodeDivision (result,
2273 operandFromLit (getSize (ltype->next)),
2277 /*-----------------------------------------------------------------*/
2278 /* geniCodeSubtract - generates code for subtraction */
2279 /*-----------------------------------------------------------------*/
2281 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2288 /* if they both pointers then */
2289 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2290 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2291 return geniCodePtrPtrSubtract (left, right);
2293 /* if they are both literal then we know the result */
2294 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2295 && left->isLiteral && right->isLiteral)
2296 return operandFromValue (valMinus (left->operand.valOperand,
2297 right->operand.valOperand));
2299 /* if left is an array or pointer */
2300 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2302 isarray = left->isaddr;
2303 right = geniCodeMultiply (right,
2304 operandFromLit (getSize (ltype->next)),
2305 (getArraySizePtr(left) >= INTSIZE) ?
2308 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2311 { /* make them the same size */
2312 resType = usualBinaryConversions (&left, &right, resultType, '-');
2315 ic = newiCode ('-', left, right);
2317 IC_RESULT (ic) = newiTempOperand (resType, 1);
2318 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2320 /* if left or right is a float */
2321 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2322 || IS_FIXED (ltype) || IS_FIXED (rtype))
2326 return IC_RESULT (ic);
2329 /*-----------------------------------------------------------------*/
2330 /* geniCodeAdd - generates iCode for addition */
2331 /*-----------------------------------------------------------------*/
2333 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2342 /* if the right side is LITERAL zero */
2343 /* return the left side */
2344 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2347 /* if left is literal zero return right */
2348 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2351 /* if left is a pointer then size */
2352 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2354 isarray = left->isaddr;
2355 // there is no need to multiply with 1
2356 if (getSize (ltype->next) != 1)
2358 size = operandFromLit (getSize (ltype->next));
2359 SPEC_USIGN (getSpec (operandType (size))) = 1;
2360 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2361 right = geniCodeMultiply (right, size, resultType);
2362 /* Even if right is a 'unsigned char',
2363 the result will be a 'signed int' due to the promotion rules.
2364 It doesn't make sense when accessing arrays, so let's fix it here: */
2366 SPEC_USIGN (getSpec (operandType (right))) = 1;
2368 resType = copyLinkChain (ltype);
2371 { // make them the same size
2372 resType = usualBinaryConversions (&left, &right, resultType, '+');
2375 /* if they are both literals then we know */
2376 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2377 && left->isLiteral && right->isLiteral)
2378 return operandFromValue (valPlus (valFromType (ltype),
2379 valFromType (rtype)));
2381 ic = newiCode ('+', left, right);
2383 IC_RESULT (ic) = newiTempOperand (resType, 1);
2384 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2386 /* if left or right is a float then support
2388 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2389 || IS_FIXED (ltype) || IS_FIXED (rtype))
2394 return IC_RESULT (ic);
2398 /*-----------------------------------------------------------------*/
2399 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2400 /*-----------------------------------------------------------------*/
2402 aggrToPtr (sym_link * type, bool force)
2407 if (IS_PTR (type) && !force)
2410 etype = getSpec (type);
2411 ptype = newLink (DECLARATOR);
2415 /* set the pointer depending on the storage class */
2416 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2420 /*------------------------------------------------------------------*/
2421 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2422 /*------------------------------------------------------------------*/
2424 aggrToPtrDclType (sym_link * type, bool force)
2426 if (IS_PTR (type) && !force)
2427 return DCL_TYPE (type);
2429 /* return the pointer depending on the storage class */
2430 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2433 /*-----------------------------------------------------------------*/
2434 /* geniCodeArray2Ptr - array to pointer */
2435 /*-----------------------------------------------------------------*/
2437 geniCodeArray2Ptr (operand * op)
2439 sym_link *optype = operandType (op);
2440 sym_link *opetype = getSpec (optype);
2442 /* set the pointer depending on the storage class */
2443 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2450 /*-----------------------------------------------------------------*/
2451 /* geniCodeArray - array access */
2452 /*-----------------------------------------------------------------*/
2454 geniCodeArray (operand * left, operand * right, int lvl)
2458 sym_link *ltype = operandType (left);
2460 RESULT_TYPE resultType;
2462 resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
2463 if (DCL_ELEM (ltype))
2465 if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
2466 resultType = RESULT_TYPE_CHAR;
2471 if (IS_PTR (ltype->next) && left->isaddr)
2473 left = geniCodeRValue (left, FALSE);
2476 return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
2479 size = operandFromLit (getSize (ltype->next));
2480 SPEC_USIGN (getSpec (operandType (size))) = 1;
2481 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2482 right = geniCodeMultiply (right, size, resultType);
2483 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2484 It doesn't make sense when accessing arrays, so let's fix it here: */
2486 SPEC_USIGN (getSpec (operandType (right))) = 1;
2487 /* we can check for limits here */
2488 /* already done in SDCCast.c
2489 if (isOperandLiteral (right) &&
2492 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2494 werror (W_IDX_OUT_OF_BOUNDS,
2495 (int) operandLitValue (right) / getSize (ltype->next),
2500 ic = newiCode ('+', left, right);
2502 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2503 !IS_AGGREGATE (ltype->next) &&
2504 !IS_PTR (ltype->next))
2505 ? ltype : ltype->next), 0);
2507 if (!IS_AGGREGATE (ltype->next))
2509 IC_RESULT (ic)->isaddr = 1;
2510 IC_RESULT (ic)->aggr2ptr = 1;
2514 return IC_RESULT (ic);
2517 /*-----------------------------------------------------------------*/
2518 /* geniCodeStruct - generates intermediate code for structures */
2519 /*-----------------------------------------------------------------*/
2521 geniCodeStruct (operand * left, operand * right, bool islval)
2524 sym_link *type = operandType (left);
2525 sym_link *etype = getSpec (type);
2527 symbol *element = getStructElement (SPEC_STRUCT (etype),
2528 right->operand.symOperand);
2530 wassert(IS_SYMOP(right));
2532 /* add the offset */
2533 ic = newiCode ('+', left, operandFromLit (element->offset));
2535 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2537 /* preserve the storage & output class of the struct */
2538 /* as well as the volatile attribute */
2539 retype = getSpec (operandType (IC_RESULT (ic)));
2540 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2541 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2542 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2543 SPEC_CONST (retype) |= SPEC_CONST (etype);
2545 if (IS_PTR (element->type))
2546 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2548 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2551 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2554 /*-----------------------------------------------------------------*/
2555 /* geniCodePostInc - generate int code for Post increment */
2556 /*-----------------------------------------------------------------*/
2558 geniCodePostInc (operand * op)
2562 sym_link *optype = operandType (op);
2564 operand *rv = (IS_ITEMP (op) ?
2565 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2567 sym_link *rvtype = operandType (rv);
2570 /* if this is not an address we have trouble */
2573 werror (E_LVALUE_REQUIRED, "++");
2577 rOp = newiTempOperand (rvtype, 0);
2578 OP_SYMBOL(rOp)->noSpilLoc = 1;
2581 OP_SYMBOL(rv)->noSpilLoc = 1;
2583 geniCodeAssign (rOp, rv, 0, 0);
2585 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2587 werror(W_SIZEOF_VOID);
2588 if (IS_FLOAT (rvtype))
2589 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2590 else if (IS_FIXED16X16 (rvtype))
2591 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2593 ic = newiCode ('+', rv, operandFromLit (size));
2595 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2598 geniCodeAssign (op, result, 0, 0);
2604 /*-----------------------------------------------------------------*/
2605 /* geniCodePreInc - generate code for preIncrement */
2606 /*-----------------------------------------------------------------*/
2608 geniCodePreInc (operand * op, bool lvalue)
2611 sym_link *optype = operandType (op);
2612 operand *rop = (IS_ITEMP (op) ?
2613 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2615 sym_link *roptype = operandType (rop);
2621 werror (E_LVALUE_REQUIRED, "++");
2625 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2627 werror(W_SIZEOF_VOID);
2628 if (IS_FLOAT (roptype))
2629 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2630 else if (IS_FIXED16X16 (roptype))
2631 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2633 ic = newiCode ('+', rop, operandFromLit (size));
2634 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2637 (void) geniCodeAssign (op, result, 0, 0);
2638 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2644 /*-----------------------------------------------------------------*/
2645 /* geniCodePostDec - generates code for Post decrement */
2646 /*-----------------------------------------------------------------*/
2648 geniCodePostDec (operand * op)
2652 sym_link *optype = operandType (op);
2654 operand *rv = (IS_ITEMP (op) ?
2655 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2657 sym_link *rvtype = operandType (rv);
2660 /* if this is not an address we have trouble */
2663 werror (E_LVALUE_REQUIRED, "--");
2667 rOp = newiTempOperand (rvtype, 0);
2668 OP_SYMBOL(rOp)->noSpilLoc = 1;
2671 OP_SYMBOL(rv)->noSpilLoc = 1;
2673 geniCodeAssign (rOp, rv, 0, 0);
2675 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2677 werror(W_SIZEOF_VOID);
2678 if (IS_FLOAT (rvtype))
2679 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2680 else if (IS_FIXED16X16 (rvtype))
2681 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2683 ic = newiCode ('-', rv, operandFromLit (size));
2685 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2688 geniCodeAssign (op, result, 0, 0);
2694 /*-----------------------------------------------------------------*/
2695 /* geniCodePreDec - generate code for pre decrement */
2696 /*-----------------------------------------------------------------*/
2698 geniCodePreDec (operand * op, bool lvalue)
2701 sym_link *optype = operandType (op);
2702 operand *rop = (IS_ITEMP (op) ?
2703 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2705 sym_link *roptype = operandType (rop);
2711 werror (E_LVALUE_REQUIRED, "--");
2715 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2717 werror(W_SIZEOF_VOID);
2718 if (IS_FLOAT (roptype))
2719 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2720 else if (IS_FIXED16X16 (roptype))
2721 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2723 ic = newiCode ('-', rop, operandFromLit (size));
2724 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2727 (void) geniCodeAssign (op, result, 0, 0);
2728 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2735 /*-----------------------------------------------------------------*/
2736 /* geniCodeBitwise - gen int code for bitWise operators */
2737 /*-----------------------------------------------------------------*/
2739 geniCodeBitwise (operand * left, operand * right,
2740 int oper, sym_link * resType)
2744 left = geniCodeCast (resType, left, TRUE);
2745 right = geniCodeCast (resType, right, TRUE);
2747 ic = newiCode (oper, left, right);
2748 IC_RESULT (ic) = newiTempOperand (resType, 0);
2751 return IC_RESULT (ic);
2754 /*-----------------------------------------------------------------*/
2755 /* geniCodeAddressOf - gens icode for '&' address of operator */
2756 /*-----------------------------------------------------------------*/
2758 geniCodeAddressOf (operand * op)
2762 sym_link *optype = operandType (op);
2763 sym_link *opetype = getSpec (optype);
2765 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2767 op = operandFromOperand (op);
2772 /* lvalue check already done in decorateType */
2773 /* this must be a lvalue */
2774 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2775 /* werror (E_LVALUE_REQUIRED,"&"); */
2779 p = newLink (DECLARATOR);
2781 /* set the pointer depending on the storage class */
2782 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2784 p->next = copyLinkChain (optype);
2786 /* if already a temp */
2789 setOperandType (op, p);
2794 /* otherwise make this of the type coming in */
2795 ic = newiCode (ADDRESS_OF, op, NULL);
2796 IC_RESULT (ic) = newiTempOperand (p, 1);
2797 IC_RESULT (ic)->isaddr = 0;
2799 return IC_RESULT (ic);
2802 /*-----------------------------------------------------------------*/
2803 /* setOClass - sets the output class depending on the pointer type */
2804 /*-----------------------------------------------------------------*/
2806 setOClass (sym_link * ptr, sym_link * spec)
2808 switch (DCL_TYPE (ptr))
2811 SPEC_OCLS (spec) = data;
2815 SPEC_OCLS (spec) = generic;
2819 SPEC_OCLS (spec) = xdata;
2823 SPEC_OCLS (spec) = code;
2827 SPEC_OCLS (spec) = idata;
2831 SPEC_OCLS (spec) = xstack;
2835 SPEC_OCLS (spec) = eeprom;
2844 /*-----------------------------------------------------------------*/
2845 /* geniCodeDerefPtr - dereference pointer with '*' */
2846 /*-----------------------------------------------------------------*/
2848 geniCodeDerefPtr (operand * op,int lvl)
2850 sym_link *rtype, *retype;
2851 sym_link *optype = operandType (op);
2853 // if this is an array then array access
2854 if (IS_ARRAY (optype)) {
2855 // don't worry, this will be optimized out later
2856 return geniCodeArray (op, operandFromLit (0), lvl);
2859 // just in case someone screws up
2860 wassert (IS_PTR (optype));
2862 if (IS_TRUE_SYMOP (op))
2865 op = geniCodeRValue (op, TRUE);
2868 /* now get rid of the pointer part */
2869 if (isLvaluereq(lvl) && IS_ITEMP (op))
2871 retype = getSpec (rtype = copyLinkChain (optype));
2875 retype = getSpec (rtype = copyLinkChain (optype->next));
2876 /* outputclass needs 2b updated */
2877 setOClass (optype, retype);
2880 op->isGptr = IS_GENPTR (optype);
2882 op->isaddr = (IS_PTR (rtype) ||
2883 IS_STRUCT (rtype) ||
2889 if (!isLvaluereq(lvl))
2890 op = geniCodeRValue (op, TRUE);
2892 setOperandType (op, rtype);
2897 /*-----------------------------------------------------------------*/
2898 /* geniCodeUnaryMinus - does a unary minus of the operand */
2899 /*-----------------------------------------------------------------*/
2901 geniCodeUnaryMinus (operand * op)
2904 sym_link *optype = operandType (op);
2906 if (IS_LITERAL (optype))
2907 return operandFromLit (-floatFromVal (op->operand.valOperand));
2909 ic = newiCode (UNARYMINUS, op, NULL);
2910 IC_RESULT (ic) = newiTempOperand (optype, 0);
2912 return IC_RESULT (ic);
2915 /*-----------------------------------------------------------------*/
2916 /* geniCodeLeftShift - gen i code for left shift */
2917 /*-----------------------------------------------------------------*/
2919 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2924 ic = newiCode (LEFT_OP, left, right);
2926 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2927 IC_RESULT (ic) = newiTempOperand (resType, 0);
2929 return IC_RESULT (ic);
2932 /*-----------------------------------------------------------------*/
2933 /* geniCodeRightShift - gen i code for right shift */
2934 /*-----------------------------------------------------------------*/
2936 geniCodeRightShift (operand * left, operand * right)
2940 ic = newiCode (RIGHT_OP, left, right);
2941 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2943 return IC_RESULT (ic);
2946 /*-----------------------------------------------------------------*/
2947 /* geniCodeLogic- logic code */
2948 /*-----------------------------------------------------------------*/
2950 geniCodeLogic (operand * left, operand * right, int op, ast *tree)
2953 sym_link *ctype, *ttype;
2954 sym_link *rtype = operandType (right);
2955 sym_link *ltype = operandType (left);
2957 /* left is integral type and right is literal then
2958 check if the literal value is within bounds */
2959 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2961 CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE);
2964 case CCR_ALWAYS_TRUE:
2965 case CCR_ALWAYS_FALSE:
2966 if (!options.lessPedantic)
2967 werror (W_COMP_RANGE, "true resp. false");
2968 return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0);
2974 /* if one operand is a pointer and the other is a literal generic void pointer,
2975 change the type of the literal generic void pointer to match the other pointer */
2976 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2977 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2979 /* find left's definition */
2980 ic = (iCode *) setFirstItem (iCodeChain);
2983 if (((ic->op == CAST) || (ic->op == '='))
2984 && isOperandEqual(left, IC_RESULT (ic)))
2987 ic = setNextItem (iCodeChain);
2989 /* if casting literal to generic pointer, then cast to rtype instead */
2990 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2992 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2993 ltype = operandType(left);
2996 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2997 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2999 /* find right's definition */
3000 ic = (iCode *) setFirstItem (iCodeChain);
3003 if (((ic->op == CAST) || (ic->op == '='))
3004 && isOperandEqual(right, IC_RESULT (ic)))
3007 ic = setNextItem (iCodeChain);
3009 /* if casting literal to generic pointer, then cast to rtype instead */
3010 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3012 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3013 rtype = operandType(right);
3017 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
3019 ic = newiCode (op, left, right);
3020 /* store 0 or 1 in result */
3021 ttype = (tree && IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3022 IC_RESULT (ic) = newiTempOperand (ttype, 1);
3024 /* if comparing float
3025 and not a '==' || '!=' || '&&' || '||' (these
3027 if (IS_FLOAT(ctype) &&
3034 /* if comparing a fixed type use support functions */
3035 if (IS_FIXED(ctype))
3039 return IC_RESULT (ic);
3042 /*-----------------------------------------------------------------*/
3043 /* geniCodeLogicAndOr - && || operations */
3044 /*-----------------------------------------------------------------*/
3046 geniCodeLogicAndOr (ast *tree, int lvl)
3050 symbol *falseLabel = newiTempLabel (NULL);
3051 symbol *trueLabel = newiTempLabel (NULL);
3052 symbol *exitLabel = newiTempLabel (NULL);
3053 operand *op, *result, *condition;
3055 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3056 They can be reenabled by executing the following block. If you find
3057 a decent optimization you could start right here:
3062 operand *leftOp, *rightOp;
3064 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3065 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3067 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3071 /* generate two IFX for the '&&' or '||' op */
3073 /* evaluate left operand */
3074 condition = ast2iCode (tree->left, lvl + 1);
3075 op = geniCodeRValue (condition, FALSE);
3077 /* test left operand */
3078 if (tree->opval.op == AND_OP)
3079 ic = newiCodeCondition (op, NULL, falseLabel);
3081 ic = newiCodeCondition (op, trueLabel, NULL);
3084 /* evaluate right operand */
3085 condition = ast2iCode (tree->right, lvl + 1);
3086 op = geniCodeRValue (condition, FALSE);
3088 /* test right operand */
3089 ic = newiCodeCondition (op, trueLabel, NULL);
3092 /* store 0 or 1 in result */
3093 type = (IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3094 result = newiTempOperand (type, 1);
3096 geniCodeLabel (falseLabel);
3097 geniCodeAssign (result, operandFromLit (0), 0, 0);
3098 /* generate an unconditional goto */
3099 geniCodeGoto (exitLabel);
3101 geniCodeLabel (trueLabel);
3102 geniCodeAssign (result, operandFromLit (1), 0, 0);
3104 geniCodeLabel (exitLabel);
3109 /*-----------------------------------------------------------------*/
3110 /* geniCodeUnary - for a generic unary operation */
3111 /*-----------------------------------------------------------------*/
3113 geniCodeUnary (operand * op, int oper)
3115 iCode *ic = newiCode (oper, op, NULL);
3117 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3119 return IC_RESULT (ic);
3122 /*-----------------------------------------------------------------*/
3123 /* geniCodeBinary - for a generic binary operation */
3124 /*-----------------------------------------------------------------*/
3126 geniCodeBinary (operand * left, operand * right, int oper)
3128 iCode *ic = newiCode (oper, left, right);
3130 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3132 return IC_RESULT (ic);
3135 /*-----------------------------------------------------------------*/
3136 /* geniCodeConditional - geniCode for '?' ':' operation */
3137 /*-----------------------------------------------------------------*/
3139 geniCodeConditional (ast * tree,int lvl)
3142 symbol *falseLabel = newiTempLabel (NULL);
3143 symbol *exitLabel = newiTempLabel (NULL);
3144 ast *astTrue = tree->right->left;
3145 ast *astFalse = tree->right->right;
3146 operand *cond = ast2iCode (tree->left, lvl+1);
3147 operand *result = newiTempOperand (tree->right->ftype, 0);
3148 operand *opTrue, *opFalse;
3150 if (IS_AST_LIT_VALUE (astTrue) && IS_AST_LIT_VALUE (astFalse))
3152 double valTrue = AST_LIT_VALUE (astTrue);
3153 double valFalse = AST_LIT_VALUE (astFalse);
3155 if (IS_BIT (operandType (result)))
3157 if ((valTrue != 0) && (valFalse == 0))
3159 /* assign cond to result */
3160 geniCodeAssign (result, geniCodeRValue (cond, FALSE), 0, 0);
3163 else if ((valTrue == 0) && (valFalse != 0))
3165 /* assign !cond to result */
3166 result = geniCodeUnary (geniCodeRValue (cond, FALSE), '!');
3171 /* they have the same boolean value, make them equal */
3177 ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel);
3180 opTrue = ast2iCode (astTrue, lvl+1);
3182 /* move the value to the new operand */
3183 geniCodeAssign (result, geniCodeRValue (opTrue, FALSE), 0, 0);
3185 /* generate an unconditional goto */
3186 geniCodeGoto (exitLabel);
3188 /* now for the right side */
3189 geniCodeLabel (falseLabel);
3191 opFalse = ast2iCode (astFalse, lvl+1);
3192 geniCodeAssign (result, geniCodeRValue (opFalse, FALSE), 0, 0);
3194 /* create the exit label */
3195 geniCodeLabel (exitLabel);
3200 /*-----------------------------------------------------------------*/
3201 /* geniCodeAssign - generate code for assignment */
3202 /*-----------------------------------------------------------------*/
3204 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3207 sym_link *ltype = operandType (left);
3208 sym_link *rtype = operandType (right);
3210 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3212 werror (E_LVALUE_REQUIRED, "assignment");
3216 /* left is integral type and right is literal then
3217 check if the literal value is within bounds */
3218 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3219 checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3220 !options.lessPedantic)
3222 werror (W_LIT_OVERFLOW);
3225 /* if the left & right type don't exactly match */
3226 /* if pointer set then make sure the check is
3227 done with the type & not the pointer */
3228 /* then cast rights type to left */
3230 /* first check the type for pointer assignement */
3231 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3232 compareType (ltype, rtype) <= 0)
3234 if (compareType (ltype->next, rtype) < 0)
3235 right = geniCodeCast (ltype->next, right, TRUE);
3237 else if (compareType (ltype, rtype) < 0)
3238 right = geniCodeCast (ltype, right, TRUE);
3240 /* If left is a true symbol & ! volatile
3241 create an assignment to temporary for
3242 the right & then assign this temporary
3243 to the symbol. This is SSA (static single
3244 assignment). Isn't it simple and folks have
3245 published mountains of paper on it */
3246 if (IS_TRUE_SYMOP (left) &&
3247 !isOperandVolatile (left, FALSE) &&
3248 isOperandGlobal (left))
3253 if (IS_TRUE_SYMOP (right))
3254 sym = OP_SYMBOL (right);
3255 ic = newiCode ('=', NULL, right);
3256 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3257 /* avoid double fetch from volatile right, see bug 1369874 */
3258 if (!isOperandVolatile (right, FALSE))
3259 SPIL_LOC (newRight) = sym;
3264 ic = newiCode ('=', NULL, right);
3265 IC_RESULT (ic) = left;
3268 /* if left isgptr flag is set then support
3269 routine will be required */
3273 ic->nosupdate = nosupdate;
3274 /* left could be a pointer assignment,
3275 return the properly casted right instead */
3279 /*-----------------------------------------------------------------*/
3280 /* geniCodeDummyRead - generate code for dummy read */
3281 /*-----------------------------------------------------------------*/
3283 geniCodeDummyRead (operand * op)
3286 sym_link *type = operandType (op);
3288 if (!IS_VOLATILE(type))
3291 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3297 /*-----------------------------------------------------------------*/
3298 /* geniCodeSEParms - generate code for side effecting fcalls */
3299 /*-----------------------------------------------------------------*/
3301 geniCodeSEParms (ast * parms,int lvl)
3306 if (parms->type == EX_OP && parms->opval.op == PARAM)
3308 geniCodeSEParms (parms->left,lvl);
3309 geniCodeSEParms (parms->right,lvl);
3313 /* hack don't like this but too lazy to think of
3315 if (IS_ADDRESS_OF_OP (parms))
3316 parms->left->lvalue = 1;
3318 if (IS_CAST_OP (parms) &&
3319 IS_PTR (parms->ftype) &&
3320 IS_ADDRESS_OF_OP (parms->right))
3321 parms->right->left->lvalue = 1;
3323 parms->opval.oprnd =
3324 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3326 parms->type = EX_OPERAND;
3327 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3328 SPEC_ARGREG(parms->ftype);
3331 /*-----------------------------------------------------------------*/
3332 /* geniCodeParms - generates parameters */
3333 /*-----------------------------------------------------------------*/
3335 geniCodeParms (ast * parms, value *argVals, int *stack,
3336 sym_link * ftype, int lvl)
3344 if (argVals==NULL) {
3346 argVals = FUNC_ARGS (ftype);
3349 /* if this is a param node then do the left & right */
3350 if (parms->type == EX_OP && parms->opval.op == PARAM)
3352 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3353 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3357 /* get the parameter value */
3358 if (parms->type == EX_OPERAND)
3359 pval = parms->opval.oprnd;
3362 /* maybe this else should go away ?? */
3363 /* hack don't like this but too lazy to think of
3365 if (IS_ADDRESS_OF_OP (parms))
3366 parms->left->lvalue = 1;
3368 if (IS_CAST_OP (parms) &&
3369 IS_PTR (parms->ftype) &&
3370 IS_ADDRESS_OF_OP (parms->right))
3371 parms->right->left->lvalue = 1;
3373 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3376 /* if register parm then make it a send */
3377 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3378 IFFUNC_ISBUILTIN(ftype))
3380 ic = newiCode (SEND, pval, NULL);
3381 ic->argreg = SPEC_ARGREG(parms->etype);
3382 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3387 /* now decide whether to push or assign */
3388 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3392 operand *top = operandFromSymbol (argVals->sym);
3393 /* clear useDef and other bitVectors */
3394 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3395 geniCodeAssign (top, pval, 1, 0);
3399 sym_link *p = operandType (pval);
3401 ic = newiCode (IPUSH, pval, NULL);
3403 /* update the stack adjustment */
3404 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3409 argVals=argVals->next;
3413 /*-----------------------------------------------------------------*/
3414 /* geniCodeCall - generates temp code for calling */
3415 /*-----------------------------------------------------------------*/
3417 geniCodeCall (operand * left, ast * parms,int lvl)
3421 sym_link *type, *etype;
3425 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3426 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3427 werror (E_FUNCTION_EXPECTED);
3428 return operandFromValue(valueFromLit(0));
3431 /* take care of parameters with side-effecting
3432 function calls in them, this is required to take care
3433 of overlaying function parameters */
3434 geniCodeSEParms (parms,lvl);
3436 ftype = operandType (left);
3437 if (IS_FUNCPTR (ftype))
3438 ftype = ftype->next;
3440 /* first the parameters */
3441 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3443 /* now call : if symbol then pcall */
3444 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3445 ic = newiCode (PCALL, left, NULL);
3447 ic = newiCode (CALL, left, NULL);
3450 type = copyLinkChain (ftype->next);
3451 etype = getSpec (type);
3452 SPEC_EXTR (etype) = 0;
3453 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3457 /* stack adjustment after call */
3458 ic->parmBytes = stack;
3463 /*-----------------------------------------------------------------*/
3464 /* geniCodeReceive - generate intermediate code for "receive" */
3465 /*-----------------------------------------------------------------*/
3467 geniCodeReceive (value * args, operand * func)
3469 unsigned char paramByteCounter = 0;
3471 /* for all arguments that are passed in registers */
3474 if (IS_REGPARM (args->etype))
3476 operand *opr = operandFromValue (args);
3478 symbol *sym = OP_SYMBOL (opr);
3481 /* we will use it after all optimizations
3482 and before liveRange calculation */
3483 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3486 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3487 options.stackAuto == 0 &&
3488 (!(options.model == MODEL_FLAT24)) )
3493 opl = newiTempOperand (args->type, 0);
3495 sym->reqv->key = sym->key;
3496 OP_SYMBOL (sym->reqv)->key = sym->key;
3497 OP_SYMBOL (sym->reqv)->isreqv = 1;
3498 OP_SYMBOL (sym->reqv)->islocal = 0;
3499 SPIL_LOC (sym->reqv) = sym;
3503 ic = newiCode (RECEIVE, func, NULL);
3504 ic->argreg = SPEC_ARGREG(args->etype);
3505 if (ic->argreg == 1) {
3506 currFunc->recvSize = getSize (sym->type);
3508 IC_RESULT (ic) = opr;
3510 /* misuse of parmBytes (normally used for functions)
3511 * to save estimated stack position of this argument.
3512 * Normally this should be zero for RECEIVE iCodes.
3513 * No idea if this causes side effects on other ports. - dw
3515 ic->parmBytes = paramByteCounter;
3517 /* what stack position do we have? */
3518 paramByteCounter += getSize (sym->type);
3527 /*-----------------------------------------------------------------*/
3528 /* geniCodeFunctionBody - create the function body */
3529 /*-----------------------------------------------------------------*/
3531 geniCodeFunctionBody (ast * tree,int lvl)
3538 /* reset the auto generation */
3544 func = ast2iCode (tree->left,lvl+1);
3545 fetype = getSpec (operandType (func));
3547 savelineno = lineno;
3548 lineno = OP_SYMBOL (func)->lineDef;
3549 /* create an entry label */
3550 geniCodeLabel (entryLabel);
3551 lineno = savelineno;
3553 /* create a proc icode */
3554 ic = newiCode (FUNCTION, func, NULL);
3555 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3560 /* for all parameters that are passed
3561 on registers add a "receive" */
3562 geniCodeReceive (tree->values.args, func);
3564 /* generate code for the body */
3565 ast2iCode (tree->right,lvl+1);
3567 /* create a label for return */
3568 geniCodeLabel (returnLabel);
3570 /* now generate the end proc */
3571 ic = newiCode (ENDFUNCTION, func, NULL);
3577 /*-----------------------------------------------------------------*/
3578 /* geniCodeReturn - gen icode for 'return' statement */
3579 /*-----------------------------------------------------------------*/
3581 geniCodeReturn (operand * op)
3585 /* if the operand is present force an rvalue */
3587 op = geniCodeRValue (op, FALSE);
3589 ic = newiCode (RETURN, op, NULL);
3593 /*-----------------------------------------------------------------*/
3594 /* geniCodeIfx - generates code for extended if statement */
3595 /*-----------------------------------------------------------------*/
3597 geniCodeIfx (ast * tree,int lvl)
3600 operand *condition = ast2iCode (tree->left,lvl+1);
3603 /* if condition is null then exit */
3607 condition = geniCodeRValue (condition, FALSE);
3609 cetype = getSpec (operandType (condition));
3610 /* if the condition is a literal */
3611 if (IS_LITERAL (cetype))
3613 if (floatFromVal (condition->operand.valOperand))
3615 if (tree->trueLabel)
3616 geniCodeGoto (tree->trueLabel);
3622 if (tree->falseLabel)
3623 geniCodeGoto (tree->falseLabel);
3628 if (tree->trueLabel)
3630 ic = newiCodeCondition (condition,
3635 if (tree->falseLabel)
3636 geniCodeGoto (tree->falseLabel);
3640 ic = newiCodeCondition (condition,
3647 ast2iCode (tree->right,lvl+1);
3650 /*-----------------------------------------------------------------*/
3651 /* geniCodeJumpTable - tries to create a jump table for switch */
3652 /*-----------------------------------------------------------------*/
3654 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3656 int min, max, cnt = 1;
3663 int needRangeCheck = !optimize.noJTabBoundary
3664 || tree->values.switchVals.swDefault;
3665 sym_link *cetype = getSpec (operandType (cond));
3666 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3667 int sizeofMatchJump, sizeofJumpTable;
3670 if (!tree || !caseVals)
3673 /* the criteria for creating a jump table is */
3674 /* all integer numbers between the maximum & minimum must */
3675 /* be present , the maximum value should not exceed 255 */
3676 /* If not all integer numbers are present the algorithm */
3677 /* inserts jumps to the default label for the missing numbers */
3678 /* and decides later whether it is worth it */
3679 min = (int) floatFromVal (vch = caseVals);
3686 max = (int) floatFromVal (vch);
3688 /* Exit if the range is too large to handle with a jump table. */
3689 if (1 + max - min > port->jumptableCost.maxCount)
3692 switch (getSize (operandType (cond)))
3694 case 1: sizeIndex = 0; break;
3695 case 2: sizeIndex = 1; break;
3696 case 4: sizeIndex = 2; break;
3700 /* Compute the size cost of the range check and subtraction. */
3702 sizeofZeroMinCost = 0;
3706 if (!(min==0 && IS_UNSIGNED (cetype)))
3707 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3708 if (!IS_UNSIGNED (cetype))
3709 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3710 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3713 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3715 /* If the size cost of handling a non-zero minimum exceeds the */
3716 /* cost of extending the range down to zero, then it might be */
3717 /* better to extend the range to zero. */
3718 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3719 >= (min * port->jumptableCost.sizeofElement))
3721 /* Only extend the jump table if it would still be manageable. */
3722 if (1 + max <= port->jumptableCost.maxCount)
3725 if (IS_UNSIGNED (cetype))
3728 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3732 /* Compute the total size cost of a jump table. */
3733 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3734 + port->jumptableCost.sizeofDispatch
3735 + sizeofMinCost + sizeofMaxCost;
3737 /* Compute the total size cost of a match & jump sequence */
3738 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3740 /* If the size cost of the jump table is uneconomical then exit */
3741 if (sizeofMatchJump < sizeofJumpTable)
3744 /* The jump table is preferable. */
3746 /* First, a label for the default or missing cases. */
3747 if (tree->values.switchVals.swDefault)
3749 SNPRINTF (buffer, sizeof(buffer),
3751 tree->values.switchVals.swNum);
3755 SNPRINTF (buffer, sizeof(buffer),
3757 tree->values.switchVals.swNum);
3759 falseLabel = newiTempLabel (buffer);
3761 /* Build the list of labels for the jump table. */
3763 t = (int) floatFromVal (vch);
3764 for (i=min; i<=max; i++)
3768 /* Explicit case: make a new label for it. */
3769 SNPRINTF (buffer, sizeof(buffer),
3771 tree->values.switchVals.swNum,
3773 addSet (&labels, newiTempLabel (buffer));
3776 t = (int) floatFromVal (vch);
3780 /* Implicit case: use the default label. */
3781 addSet (&labels, falseLabel);
3785 /* first we rule out the boundary conditions */
3786 /* if only optimization says so */
3789 sym_link *cetype = getSpec (operandType (cond));
3790 /* no need to check the lower bound if
3791 the condition is unsigned & minimum value is zero */
3792 if (!(min == 0 && IS_UNSIGNED (cetype)))
3794 boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL);
3795 ic = newiCodeCondition (boundary, falseLabel, NULL);
3799 /* now for upper bounds */
3800 boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL);
3801 ic = newiCodeCondition (boundary, falseLabel, NULL);
3805 /* if the min is not zero then we no make it zero */
3808 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3809 if (!IS_LITERAL(getSpec(operandType(cond))))
3810 setOperandType (cond, UCHARTYPE);
3813 /* now create the jumptable */
3814 ic = newiCode (JUMPTABLE, NULL, NULL);
3815 IC_JTCOND (ic) = cond;
3816 IC_JTLABELS (ic) = labels;
3821 /*-----------------------------------------------------------------*/
3822 /* geniCodeSwitch - changes a switch to a if statement */
3823 /*-----------------------------------------------------------------*/
3825 geniCodeSwitch (ast * tree,int lvl)
3828 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3829 value *caseVals = tree->values.switchVals.swVals;
3830 symbol *trueLabel, *falseLabel;
3832 /* If the condition is a literal, then just jump to the */
3833 /* appropriate case label. */
3834 if (IS_LITERAL(getSpec(operandType(cond))))
3836 int switchVal, caseVal;
3838 switchVal = (int) floatFromVal (cond->operand.valOperand);
3841 caseVal = (int) floatFromVal (caseVals);
3842 if (caseVal == switchVal)
3844 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3845 tree->values.switchVals.swNum, caseVal);
3846 trueLabel = newiTempLabel (buffer);
3847 geniCodeGoto (trueLabel);
3850 caseVals = caseVals->next;
3852 goto defaultOrBreak;
3855 /* If cond is volatile, it might change while we are trying to */
3856 /* find the matching case. To avoid this possibility, make a */
3857 /* non-volatile copy to use instead. */
3858 if (IS_OP_VOLATILE (cond))
3863 newcond = newiTempOperand (operandType (cond), TRUE);
3864 newcond->isvolatile = 0;
3865 ic = newiCode ('=', NULL, cond);
3866 IC_RESULT (ic) = newcond;
3871 /* if we can make this a jump table */
3872 if (geniCodeJumpTable (cond, caseVals, tree))
3873 goto jumpTable; /* no need for the comparison */
3875 /* for the cases defined do */
3879 operand *compare = geniCodeLogic (cond,
3880 operandFromValue (caseVals),
3883 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3884 tree->values.switchVals.swNum,
3885 (int) floatFromVal (caseVals));
3886 trueLabel = newiTempLabel (buffer);
3888 ic = newiCodeCondition (compare, trueLabel, NULL);
3890 caseVals = caseVals->next;
3895 /* if default is present then goto break else break */
3896 if (tree->values.switchVals.swDefault)
3898 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3902 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3905 falseLabel = newiTempLabel (buffer);
3906 geniCodeGoto (falseLabel);
3909 ast2iCode (tree->right,lvl+1);
3912 /*-----------------------------------------------------------------*/
3913 /* geniCodeInline - intermediate code for inline assembler */
3914 /*-----------------------------------------------------------------*/
3916 geniCodeInline (ast * tree)
3920 ic = newiCode (INLINEASM, NULL, NULL);
3921 IC_INLINE (ic) = tree->values.inlineasm;
3925 /*-----------------------------------------------------------------*/
3926 /* geniCodeArrayInit - intermediate code for array initializer */
3927 /*-----------------------------------------------------------------*/
3929 geniCodeArrayInit (ast * tree, operand *array)
3933 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3934 ic = newiCode (ARRAYINIT, array, NULL);
3935 IC_ARRAYILIST (ic) = tree->values.constlist;
3937 operand *left=newOperand(), *right=newOperand();
3938 left->type=right->type=SYMBOL;
3939 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3940 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3941 ic = newiCode (ARRAYINIT, left, right);
3946 /*-----------------------------------------------------------------*/
3947 /* geniCodeCritical - intermediate code for a critical statement */
3948 /*-----------------------------------------------------------------*/
3950 geniCodeCritical (ast *tree, int lvl)
3956 if (!options.stackAuto)
3958 type = newLink(SPECIFIER);
3959 SPEC_VOLATILE(type) = 1;
3960 SPEC_NOUN(type) = V_BIT;
3961 SPEC_SCLS(type) = S_BIT;
3962 SPEC_BLEN(type) = 1;
3963 SPEC_BSTR(type) = 0;
3964 op = newiTempOperand(type, 1);
3967 /* If op is NULL, the original interrupt state will saved on */
3968 /* the stack. Otherwise, it will be saved in op. */
3970 /* Generate a save of the current interrupt state & disable */
3971 ic = newiCode (CRITICAL, NULL, NULL);
3972 IC_RESULT (ic) = op;
3975 /* Generate the critical code sequence */
3976 if (tree->left && tree->left->type == EX_VALUE)
3977 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3979 ast2iCode (tree->left,lvl+1);
3981 /* Generate a restore of the original interrupt state */
3982 ic = newiCode (ENDCRITICAL, NULL, op);
3986 /*-----------------------------------------------------------------*/
3987 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3988 /* particular case. Ie : assigning or dereferencing array or ptr */
3989 /*-----------------------------------------------------------------*/
3990 set * lvaluereqSet = NULL;
3991 typedef struct lvalItem
3998 /*-----------------------------------------------------------------*/
3999 /* addLvaluereq - add a flag for lvalreq for current ast level */
4000 /*-----------------------------------------------------------------*/
4001 void addLvaluereq(int lvl)
4003 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
4006 addSetHead(&lvaluereqSet,lpItem);
4009 /*-----------------------------------------------------------------*/
4010 /* delLvaluereq - del a flag for lvalreq for current ast level */
4011 /*-----------------------------------------------------------------*/
4015 lpItem = getSet(&lvaluereqSet);
4016 if(lpItem) Safe_free(lpItem);
4018 /*-----------------------------------------------------------------*/
4019 /* clearLvaluereq - clear lvalreq flag */
4020 /*-----------------------------------------------------------------*/
4021 void clearLvaluereq()
4024 lpItem = peekSet(lvaluereqSet);
4025 if(lpItem) lpItem->req = 0;
4027 /*-----------------------------------------------------------------*/
4028 /* getLvaluereq - get the last lvalreq level */
4029 /*-----------------------------------------------------------------*/
4030 int getLvaluereqLvl()
4033 lpItem = peekSet(lvaluereqSet);
4034 if(lpItem) return lpItem->lvl;
4037 /*-----------------------------------------------------------------*/
4038 /* isLvaluereq - is lvalreq valid for this level ? */
4039 /*-----------------------------------------------------------------*/
4040 int isLvaluereq(int lvl)
4043 lpItem = peekSet(lvaluereqSet);
4044 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4048 /*-----------------------------------------------------------------*/
4049 /* ast2iCode - creates an icodeList from an ast */
4050 /*-----------------------------------------------------------------*/
4052 ast2iCode (ast * tree,int lvl)
4054 operand *left = NULL;
4055 operand *right = NULL;
4059 /* set the global variables for filename & line number */
4061 filename = tree->filename;
4063 lineno = tree->lineno;
4065 block = tree->block;
4067 scopeLevel = tree->level;
4069 seqPoint = tree->seqPoint;
4071 if (tree->type == EX_VALUE)
4072 return operandFromValue (tree->opval.val);
4074 if (tree->type == EX_LINK)
4075 return operandFromLink (tree->opval.lnk);
4077 /* if we find a nullop */
4078 if (tree->type == EX_OP &&
4079 (tree->opval.op == NULLOP ||
4080 tree->opval.op == BLOCK))
4082 if (tree->left && tree->left->type == EX_VALUE)
4083 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4085 ast2iCode (tree->left,lvl+1);
4086 if (tree->right && tree->right->type == EX_VALUE)
4087 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4089 ast2iCode (tree->right,lvl+1);
4093 /* special cases for not evaluating */
4094 if (tree->opval.op != ':' &&
4095 tree->opval.op != '?' &&
4096 tree->opval.op != CALL &&
4097 tree->opval.op != IFX &&
4098 tree->opval.op != AND_OP &&
4099 tree->opval.op != OR_OP &&
4100 tree->opval.op != LABEL &&
4101 tree->opval.op != GOTO &&
4102 tree->opval.op != SWITCH &&
4103 tree->opval.op != FUNCTION &&
4104 tree->opval.op != INLINEASM &&
4105 tree->opval.op != CRITICAL)
4108 if (IS_ASSIGN_OP (tree->opval.op) ||
4109 IS_DEREF_OP (tree) ||
4110 (tree->opval.op == '&' && !tree->right) ||
4111 tree->opval.op == PTR_OP)
4114 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4115 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4118 left = operandFromAst (tree->left,lvl);
4120 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4121 left = geniCodeRValue (left, TRUE);
4125 left = operandFromAst (tree->left,lvl);
4127 if (tree->opval.op == INC_OP ||
4128 tree->opval.op == DEC_OP)
4131 right = operandFromAst (tree->right,lvl);
4136 right = operandFromAst (tree->right,lvl);
4140 /* now depending on the type of operand */
4141 /* this will be a biggy */
4142 switch (tree->opval.op)
4145 case '[': /* array operation */
4147 //sym_link *ltype = operandType (left);
4148 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4149 left = geniCodeRValue (left, FALSE);
4150 right = geniCodeRValue (right, TRUE);
4153 return geniCodeArray (left, right,lvl);
4155 case '.': /* structure dereference */
4156 if (IS_PTR (operandType (left)))
4157 left = geniCodeRValue (left, TRUE);
4159 left = geniCodeRValue (left, FALSE);
4161 return geniCodeStruct (left, right, tree->lvalue);
4163 case PTR_OP: /* structure pointer dereference */
4166 pType = operandType (left);
4167 left = geniCodeRValue (left, TRUE);
4169 setOClass (pType, getSpec (operandType (left)));
4172 return geniCodeStruct (left, right, tree->lvalue);
4174 case INC_OP: /* increment operator */
4176 return geniCodePostInc (left);
4178 return geniCodePreInc (right, tree->lvalue);
4180 case DEC_OP: /* decrement operator */
4182 return geniCodePostDec (left);
4184 return geniCodePreDec (right, tree->lvalue);
4186 case '&': /* bitwise and or address of operator */
4188 { /* this is a bitwise operator */
4189 left = geniCodeRValue (left, FALSE);
4190 right = geniCodeRValue (right, FALSE);
4191 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4194 return geniCodeAddressOf (left);
4196 case '|': /* bitwise or & xor */
4198 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4199 geniCodeRValue (right, FALSE),
4204 return geniCodeDivision (geniCodeRValue (left, FALSE),
4205 geniCodeRValue (right, FALSE),
4206 getResultTypeFromType (tree->ftype));
4209 return geniCodeModulus (geniCodeRValue (left, FALSE),
4210 geniCodeRValue (right, FALSE),
4211 getResultTypeFromType (tree->ftype));
4214 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4215 geniCodeRValue (right, FALSE),
4216 getResultTypeFromType (tree->ftype));
4218 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4222 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4223 geniCodeRValue (right, FALSE),
4224 getResultTypeFromType (tree->ftype));
4226 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4230 return geniCodeAdd (geniCodeRValue (left, FALSE),
4231 geniCodeRValue (right, FALSE),
4232 getResultTypeFromType (tree->ftype),
4235 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4238 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4239 geniCodeRValue (right, FALSE),
4240 getResultTypeFromType (tree->ftype));
4243 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4244 geniCodeRValue (right, FALSE));
4246 #if 0 // this indeed needs a second thought
4250 // let's keep this simple: get the rvalue we need
4251 op=geniCodeRValue (right, FALSE);
4252 // now cast it to whatever we want
4253 op=geniCodeCast (operandType(left), op, FALSE);
4254 // if this is going to be used as an lvalue, make it so
4260 #else // bug #604575, is it a bug ????
4261 return geniCodeCast (operandType (left),
4262 geniCodeRValue (right, FALSE), FALSE);
4269 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4274 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4275 if (!IS_BIT (operandType (op)))
4276 setOperandType (op, UCHARTYPE);
4281 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4282 geniCodeRValue (right, FALSE),
4284 if (!IS_BIT (operandType (op)))
4285 setOperandType (op, UCHARTYPE);
4290 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4291 geniCodeRValue (right, FALSE),
4293 setOperandType (op, UCHARTYPE);
4298 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4299 geniCodeRValue (right, FALSE),
4301 setOperandType (op, UINTTYPE);
4306 return geniCodeLogicAndOr (tree, lvl);
4313 /* different compilers (even different gccs) evaluate
4314 the two calls in a different order. to get the same
4315 result on all machines we have to specify a clear sequence.
4316 return geniCodeLogic (geniCodeRValue (left, FALSE),
4317 geniCodeRValue (right, FALSE),
4321 operand *leftOp, *rightOp;
4323 leftOp = geniCodeRValue (left , FALSE);
4324 rightOp = geniCodeRValue (right, FALSE);
4326 return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree);
4329 return geniCodeConditional (tree,lvl);
4332 return operandFromLit (getSize (tree->right->ftype));
4336 sym_link *rtype = operandType (right);
4337 sym_link *ltype = operandType (left);
4338 if (IS_PTR (rtype) && IS_ITEMP (right)
4339 && right->isaddr && compareType (rtype->next, ltype) == 1)
4340 right = geniCodeRValue (right, TRUE);
4342 right = geniCodeRValue (right, FALSE);
4344 return geniCodeAssign (left, right, 0, 1);
4348 geniCodeAssign (left,
4349 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4351 geniCodeRValue (right, FALSE),
4352 getResultTypeFromType (tree->ftype)),
4357 geniCodeAssign (left,
4358 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4360 geniCodeRValue (right, FALSE),
4361 getResultTypeFromType (tree->ftype)),
4365 geniCodeAssign (left,
4366 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4368 geniCodeRValue (right, FALSE),
4369 getResultTypeFromType (tree->ftype)),
4373 sym_link *rtype = operandType (right);
4374 sym_link *ltype = operandType (left);
4375 if (IS_PTR (rtype) && IS_ITEMP (right)
4376 && right->isaddr && compareType (rtype->next, ltype) == 1)
4377 right = geniCodeRValue (right, TRUE);
4379 right = geniCodeRValue (right, FALSE);
4382 return geniCodeAssign (left,
4383 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4386 getResultTypeFromType (tree->ftype),
4392 sym_link *rtype = operandType (right);
4393 sym_link *ltype = operandType (left);
4394 if (IS_PTR (rtype) && IS_ITEMP (right)
4395 && right->isaddr && compareType (rtype->next, ltype) == 1)
4397 right = geniCodeRValue (right, TRUE);
4401 right = geniCodeRValue (right, FALSE);
4404 geniCodeAssign (left,
4405 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4408 getResultTypeFromType (tree->ftype)),
4413 geniCodeAssign (left,
4414 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4416 geniCodeRValue (right, FALSE),
4417 getResultTypeFromType (tree->ftype)),
4421 geniCodeAssign (left,
4422 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4424 geniCodeRValue (right, FALSE)), 0, 1);
4427 geniCodeAssign (left,
4428 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4430 geniCodeRValue (right, FALSE),
4432 operandType (left)), 0, 1);
4435 geniCodeAssign (left,
4436 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4438 geniCodeRValue (right, FALSE),
4440 operandType (left)), 0, 1);
4443 geniCodeAssign (left,
4444 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4446 geniCodeRValue (right, FALSE),
4448 operandType (left)), 0, 1);
4450 return geniCodeRValue (right, FALSE);
4453 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4456 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4457 return ast2iCode (tree->right,lvl+1);
4460 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4461 return ast2iCode (tree->right,lvl+1);
4464 geniCodeFunctionBody (tree,lvl);
4468 geniCodeReturn (right);
4472 geniCodeIfx (tree,lvl);
4476 geniCodeSwitch (tree,lvl);
4480 geniCodeInline (tree);
4484 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4488 geniCodeCritical (tree, lvl);
4494 /*-----------------------------------------------------------------*/
4495 /* reverseICChain - gets from the list and creates a linkedlist */
4496 /*-----------------------------------------------------------------*/
4503 while ((loop = getSet (&iCodeChain)))
4515 /*-----------------------------------------------------------------*/
4516 /* iCodeFromAst - given an ast will convert it to iCode */
4517 /*-----------------------------------------------------------------*/
4519 iCodeFromAst (ast * tree)
4521 returnLabel = newiTempLabel ("_return");
4522 entryLabel = newiTempLabel ("_entry");
4524 return reverseiCChain ();
4527 static const char *opTypeToStr(OPTYPE op)
4531 case SYMBOL: return "symbol";
4532 case VALUE: return "value";
4533 case TYPE: return "type";
4535 return "undefined type";
4539 operand *validateOpType(operand *op,
4546 if (op && op->type == type)
4551 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4552 " expected %s, got %s\n",
4553 macro, args, file, line,
4554 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4556 return op; // never reached, makes compiler happy.