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 int) ulFromVal (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 /* operandSize - returns size of an operand in bytes */
824 /*-----------------------------------------------------------------*/
826 operandSize (operand * op)
830 /* if nothing return 0 */
834 type = operandType (op);
835 if (op->aggr2ptr == 2)
837 return getSize (type);
840 /*-----------------------------------------------------------------*/
841 /* isParamterToCall - will return 1 if op is a parameter to args */
842 /*-----------------------------------------------------------------*/
844 isParameterToCall (value * args, operand * op)
848 wassert (IS_SYMOP(op));
853 isSymbolEqual (op->operand.symOperand, tval->sym))
860 /*-----------------------------------------------------------------*/
861 /* isOperandGlobal - return 1 if operand is a global variable */
862 /*-----------------------------------------------------------------*/
864 isOperandGlobal (operand * op)
873 (op->operand.symOperand->level == 0 ||
874 IS_STATIC (op->operand.symOperand->etype) ||
875 IS_EXTERN (op->operand.symOperand->etype))
882 /*-----------------------------------------------------------------*/
883 /* isOperandVolatile - return 1 if the operand is volatile */
884 /*-----------------------------------------------------------------*/
886 isOperandVolatile (operand * op, bool chkTemp)
891 if (IS_ITEMP (op) && !chkTemp)
894 opetype = getSpec (optype = operandType (op));
896 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
899 if (IS_VOLATILE (opetype))
904 /*-----------------------------------------------------------------*/
905 /* isOperandLiteral - returns 1 if an operand contains a literal */
906 /*-----------------------------------------------------------------*/
908 isOperandLiteral (operand * op)
915 opetype = getSpec (operandType (op));
917 if (IS_LITERAL (opetype))
923 /*-----------------------------------------------------------------*/
924 /* isOperandInFarSpace - will return true if operand is in farSpace */
925 /*-----------------------------------------------------------------*/
927 isOperandInFarSpace (operand * op)
937 if (!IS_TRUE_SYMOP (op))
940 etype = SPIL_LOC (op)->etype;
946 etype = getSpec (operandType (op));
948 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
951 /*-----------------------------------------------------------------*/
952 /* isOperandInPagedSpace - return true if operand is in pagedSpace */
953 /*-----------------------------------------------------------------*/
955 isOperandInPagedSpace (operand * op)
965 if (!IS_TRUE_SYMOP (op))
968 etype = SPIL_LOC (op)->etype;
974 etype = getSpec (operandType (op));
976 return (IN_PAGEDSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
979 /*------------------------------------------------------------------*/
980 /* isOperandInDirSpace - will return true if operand is in dirSpace */
981 /*------------------------------------------------------------------*/
983 isOperandInDirSpace (operand * op)
993 if (!IS_TRUE_SYMOP (op))
996 etype = SPIL_LOC (op)->etype;
1002 etype = getSpec (operandType (op));
1004 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1007 /*--------------------------------------------------------------------*/
1008 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
1009 /*--------------------------------------------------------------------*/
1011 isOperandInCodeSpace (operand * op)
1021 etype = getSpec (operandType (op));
1023 if (!IS_TRUE_SYMOP (op))
1026 etype = SPIL_LOC (op)->etype;
1032 etype = getSpec (operandType (op));
1034 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
1037 /*-----------------------------------------------------------------*/
1038 /* isOperandOnStack - will return true if operand is on stack */
1039 /*-----------------------------------------------------------------*/
1041 isOperandOnStack (operand * op)
1051 etype = getSpec (operandType (op));
1052 if (IN_STACK (etype) ||
1053 OP_SYMBOL(op)->onStack ||
1054 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
1060 /*-----------------------------------------------------------------*/
1061 /* isOclsExpensive - will return true if accesses to an output */
1062 /* storage class are expensive */
1063 /*-----------------------------------------------------------------*/
1065 isOclsExpensive (struct memmap *oclass)
1067 if (port->oclsExpense)
1068 return port->oclsExpense (oclass) > 0;
1070 /* In the absence of port specific guidance, assume only */
1071 /* farspace is expensive. */
1072 return IN_FARSPACE (oclass);
1075 /*-----------------------------------------------------------------*/
1076 /* isiCodeInFunctionCall - return TRUE if an iCode is between a */
1077 /* CALL/PCALL and the first IPUSH/SEND associated with the call */
1078 /*-----------------------------------------------------------------*/
1080 isiCodeInFunctionCall (iCode * ic)
1084 /* Find the next CALL/PCALL */
1087 if (lic->op == CALL || lic->op == PCALL)
1095 /* A function call was found. Scan backwards and see if an */
1096 /* IPUSH or SEND is encountered */
1099 if (lic != ic && (ic->op == CALL || ic->op == PCALL))
1101 if (ic->op == SEND || (ic->op == IPUSH && ic->parmPush))
1109 /*-----------------------------------------------------------------*/
1110 /* operandLitValue - literal value of an operand */
1111 /*-----------------------------------------------------------------*/
1113 operandLitValue (operand * op)
1115 assert (isOperandLiteral (op));
1117 return floatFromVal (op->operand.valOperand);
1120 /*-----------------------------------------------------------------*/
1121 /* getBuiltInParms - returns parameters to a builtin functions */
1122 /*-----------------------------------------------------------------*/
1123 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1128 /* builtin functions uses only SEND for parameters */
1129 while (ic->op != CALL) {
1130 assert(ic->op == SEND && ic->builtinSEND);
1131 ic->generated = 1; /* mark the icode as generated */
1132 parms[*pcount] = IC_LEFT(ic);
1138 /* make sure this is a builtin function call */
1139 assert(IS_SYMOP(IC_LEFT(ic)));
1140 ftype = operandType(IC_LEFT(ic));
1141 assert(IFFUNC_ISBUILTIN(ftype));
1145 /*-----------------------------------------------------------------*/
1146 /* operandOperation - performs operations on operands */
1147 /*-----------------------------------------------------------------*/
1149 operandOperation (operand * left, operand * right,
1150 int op, sym_link * type)
1152 sym_link *let , *ret=NULL;
1153 operand *retval = (operand *) 0;
1155 assert (isOperandLiteral (left));
1156 let = getSpec(operandType(left));
1158 assert (isOperandLiteral (right));
1159 ret = getSpec(operandType(right));
1165 retval = operandFromValue (valCastLiteral (type,
1166 operandLitValue (left) +
1167 operandLitValue (right)));
1170 retval = operandFromValue (valCastLiteral (type,
1171 operandLitValue (left) -
1172 operandLitValue (right)));
1176 retval = operandFromValue (valCastLiteral (type,
1177 operandLitValue (left) *
1178 operandLitValue (right)));
1179 This could be all we've to do, but with gcc we've to take care about
1180 overflows. Two examples:
1181 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1182 significant bits are lost (52 in fraction, 63 bits would be
1183 necessary to keep full precision).
1184 If the resulting double value is greater than ULONG_MAX (resp.
1185 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1188 /* if it is not a specifier then we can assume that */
1189 /* it will be an unsigned long */
1190 if (IS_INT (type) ||
1193 /* long is handled here, because it can overflow with double */
1194 if (IS_LONG (type) ||
1196 /* signed and unsigned mul are the same, as long as the precision
1197 of the result isn't bigger than the precision of the operands. */
1198 retval = operandFromValue (valCastLiteral (type,
1199 (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) *
1200 (TYPE_TARGET_ULONG) double2ul (operandLitValue (right))));
1201 else if (IS_UNSIGNED (type)) /* unsigned int */
1203 /* unsigned int is handled here in order to detect overflow */
1204 TYPE_TARGET_ULONG ul = (TYPE_TARGET_UINT) double2ul (operandLitValue (left)) *
1205 (TYPE_TARGET_UINT) double2ul (operandLitValue (right));
1207 retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_UINT) ul));
1208 if (ul != (TYPE_TARGET_UINT) ul)
1211 else /* signed int */
1213 /* signed int is handled here in order to detect overflow */
1214 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) operandLitValue (left) *
1215 (TYPE_TARGET_INT) operandLitValue (right);
1217 retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_INT) l));
1218 if (l != (TYPE_TARGET_INT) l)
1223 /* all others go here: */
1224 retval = operandFromValue (valCastLiteral (type,
1225 operandLitValue (left) *
1226 operandLitValue (right)));
1229 if ((TYPE_TARGET_ULONG) double2ul (operandLitValue (right)) == 0)
1231 werror (E_DIVIDE_BY_ZERO);
1237 if (IS_UNSIGNED (type))
1239 SPEC_USIGN (let) = 1;
1240 SPEC_USIGN (ret) = 1;
1241 retval = operandFromValue (valCastLiteral (type,
1242 (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) /
1243 (TYPE_TARGET_ULONG) double2ul (operandLitValue (right))));
1247 retval = operandFromValue (valCastLiteral (type,
1248 operandLitValue (left) /
1249 operandLitValue (right)));
1254 if ((TYPE_TARGET_ULONG) double2ul (operandLitValue (right)) == 0)
1256 werror (E_DIVIDE_BY_ZERO);
1261 if (IS_UNSIGNED (type))
1262 retval = operandFromLit ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) %
1263 (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
1265 retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) %
1266 (TYPE_TARGET_LONG) operandLitValue (right));
1270 /* The number of left shifts is always unsigned. Signed doesn't make
1271 sense here. Shifting by a negative number is impossible. */
1272 retval = operandFromValue (valCastLiteral (type,
1273 ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) <<
1274 (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)))));
1277 /* The number of right shifts is always unsigned. Signed doesn't make
1278 sense here. Shifting by a negative number is impossible. */
1279 if (IS_UNSIGNED(let))
1280 /* unsigned: logic shift right */
1281 retval = operandFromLit ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) >>
1282 (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
1284 /* signed: arithmetic shift right */
1285 retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) >>
1286 (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
1289 if (IS_FLOAT (let) || IS_FLOAT (ret))
1291 retval = operandFromLit (operandLitValue (left) ==
1292 operandLitValue (right));
1294 else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
1296 retval = operandFromLit (operandLitValue (left) ==
1297 operandLitValue (right));
1301 /* this op doesn't care about signedness */
1302 TYPE_TARGET_ULONG l, r;
1304 l = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
1305 r = (TYPE_TARGET_ULONG) double2ul (operandLitValue (right));
1306 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1307 neccessary to strip them to 16 bit.
1308 Literals are reduced to their cheapest type, therefore left and
1309 right might have different types. It's neccessary to find a
1310 common type: int (used for char too) or long */
1311 if (!IS_LONG (let) &&
1314 r = (TYPE_TARGET_UINT) r;
1315 l = (TYPE_TARGET_UINT) l;
1317 retval = operandFromLit (l == r);
1321 retval = operandFromLit (operandLitValue (left) <
1322 operandLitValue (right));
1325 retval = operandFromLit (operandLitValue (left) <=
1326 operandLitValue (right));
1329 retval = operandFromLit (operandLitValue (left) !=
1330 operandLitValue (right));
1333 retval = operandFromLit (operandLitValue (left) >
1334 operandLitValue (right));
1337 retval = operandFromLit (operandLitValue (left) >=
1338 operandLitValue (right));
1341 retval = operandFromValue (valCastLiteral (type,
1342 (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) &
1343 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
1346 retval = operandFromValue (valCastLiteral (type,
1347 (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) |
1348 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
1351 retval = operandFromValue (valCastLiteral (type,
1352 (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) ^
1353 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
1356 retval = operandFromLit (operandLitValue (left) &&
1357 operandLitValue (right));
1360 retval = operandFromLit (operandLitValue (left) ||
1361 operandLitValue (right));
1365 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
1367 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1373 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
1375 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1380 retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
1381 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))) & 1);
1384 retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
1385 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)) & 0xFF));
1388 retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
1389 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)) & 0xFFFF));
1393 retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
1394 ((getSize (let) * 8) - 1)) & 1);
1398 retval = operandFromValue (valCastLiteral (type,
1399 -1 * operandLitValue (left)));
1403 retval = operandFromValue (valCastLiteral (type,
1404 ~((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)))));
1408 retval = operandFromLit (!operandLitValue (left));
1412 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1413 " operandOperation invalid operator ");
1421 /*-----------------------------------------------------------------*/
1422 /* isOperandEqual - compares two operand & return 1 if they r = */
1423 /*-----------------------------------------------------------------*/
1425 isOperandEqual (operand * left, operand * right)
1427 /* if the pointers are equal then they are equal */
1431 /* if either of them null then false */
1432 if (!left || !right)
1435 if (left->type != right->type)
1438 if (IS_SYMOP (left) && IS_SYMOP (right))
1439 return left->key == right->key;
1441 /* if types are the same */
1445 return isSymbolEqual (left->operand.symOperand,
1446 right->operand.symOperand);
1448 return (compareType (left->operand.valOperand->type,
1449 right->operand.valOperand->type) &&
1450 (floatFromVal (left->operand.valOperand) ==
1451 floatFromVal (right->operand.valOperand)));
1453 if (compareType (left->operand.typeOperand,
1454 right->operand.typeOperand) == 1)
1461 /*-------------------------------------------------------------------*/
1462 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1463 /*-------------------------------------------------------------------*/
1465 isiCodeEqual (iCode * left, iCode * right)
1467 /* if the same pointer */
1471 /* if either of them null */
1472 if (!left || !right)
1475 /* if operand are the same */
1476 if (left->op == right->op)
1479 /* compare all the elements depending on type */
1480 if (left->op != IFX)
1482 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1484 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1490 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1492 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1494 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1503 /*-----------------------------------------------------------------*/
1504 /* newiTempFromOp - create a temp Operand with same attributes */
1505 /*-----------------------------------------------------------------*/
1507 newiTempFromOp (operand * op)
1517 nop = newiTempOperand (operandType (op), TRUE);
1518 nop->isaddr = op->isaddr;
1519 nop->isvolatile = op->isvolatile;
1520 nop->isGlobal = op->isGlobal;
1521 nop->isLiteral = op->isLiteral;
1522 nop->usesDefs = op->usesDefs;
1523 nop->isParm = op->isParm;
1527 /*-----------------------------------------------------------------*/
1528 /* operand from operand - creates an operand holder for the type */
1529 /*-----------------------------------------------------------------*/
1531 operandFromOperand (operand * op)
1537 nop = newOperand ();
1538 nop->type = op->type;
1539 nop->isaddr = op->isaddr;
1541 nop->isvolatile = op->isvolatile;
1542 nop->isGlobal = op->isGlobal;
1543 nop->isLiteral = op->isLiteral;
1544 nop->usesDefs = op->usesDefs;
1545 nop->isParm = op->isParm;
1550 nop->operand.symOperand = op->operand.symOperand;
1553 nop->operand.valOperand = op->operand.valOperand;
1556 nop->operand.typeOperand = op->operand.typeOperand;
1563 /*-----------------------------------------------------------------*/
1564 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1565 /*-----------------------------------------------------------------*/
1567 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1569 operand *nop = operandFromOperand (op);
1571 if (nop->type == SYMBOL)
1573 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1574 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1580 /*-----------------------------------------------------------------*/
1581 /* operandFromSymbol - creates an operand from a symbol */
1582 /*-----------------------------------------------------------------*/
1584 operandFromSymbol (symbol * sym)
1589 /* if the symbol's type is a literal */
1590 /* then it is an enumerator type */
1591 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1592 return operandFromValue (valFromType (sym->etype));
1595 sym->key = ++operandKey;
1597 /* if this an implicit variable, means struct/union */
1598 /* member so just return it */
1599 if (sym->implicit || IS_FUNC (sym->type))
1603 op->operand.symOperand = sym;
1605 op->isvolatile = isOperandVolatile (op, TRUE);
1606 op->isGlobal = isOperandGlobal (op);
1610 /* under the following conditions create a
1611 register equivalent for a local symbol */
1612 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1613 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1615 (!(options.model == MODEL_FLAT24)) ) &&
1616 options.stackAuto == 0)
1619 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1620 !IS_FUNC (sym->type) && /* not a function */
1621 !sym->_isparm && /* not a parameter */
1622 IS_AUTO (sym) && /* is a local auto variable */
1623 !sym->addrtaken && /* whose address has not been taken */
1624 !sym->reqv && /* does not already have a reg equivalence */
1625 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1626 !sym->islbl && /* not a label */
1627 ok /* farspace check */
1631 /* we will use it after all optimizations
1632 and before liveRange calculation */
1633 sym->reqv = newiTempOperand (sym->type, 0);
1634 sym->reqv->key = sym->key;
1635 OP_SYMBOL (sym->reqv)->prereqv = sym;
1636 OP_SYMBOL (sym->reqv)->key = sym->key;
1637 OP_SYMBOL (sym->reqv)->isreqv = 1;
1638 OP_SYMBOL (sym->reqv)->islocal = 1;
1639 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1640 SPIL_LOC (sym->reqv) = sym;
1643 if (!IS_AGGREGATE (sym->type))
1647 op->operand.symOperand = sym;
1650 op->isvolatile = isOperandVolatile (op, TRUE);
1651 op->isGlobal = isOperandGlobal (op);
1652 op->isPtr = IS_PTR (operandType (op));
1653 op->isParm = sym->_isparm;
1658 /* itemp = &[_symbol] */
1660 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1661 IC_LEFT (ic)->type = SYMBOL;
1662 IC_LEFT (ic)->operand.symOperand = sym;
1663 IC_LEFT (ic)->key = sym->key;
1664 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1665 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1666 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1669 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1670 if (IS_ARRAY (sym->type))
1672 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1673 IC_RESULT (ic)->isaddr = 0;
1676 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1680 return IC_RESULT (ic);
1683 /*-----------------------------------------------------------------*/
1684 /* operandFromValue - creates an operand from value */
1685 /*-----------------------------------------------------------------*/
1687 operandFromValue (value * val)
1691 /* if this is a symbol then do the symbol thing */
1693 return operandFromSymbol (val->sym);
1695 /* this is not a symbol */
1698 op->operand.valOperand = val;
1699 op->isLiteral = isOperandLiteral (op);
1703 /*-----------------------------------------------------------------*/
1704 /* operandFromLink - operand from typeChain */
1705 /*-----------------------------------------------------------------*/
1707 operandFromLink (sym_link * type)
1711 /* operand from sym_link */
1717 op->operand.typeOperand = copyLinkChain (type);
1721 /*-----------------------------------------------------------------*/
1722 /* operandFromLit - makes an operand from a literal value */
1723 /*-----------------------------------------------------------------*/
1725 operandFromLit (double i)
1727 return operandFromValue (valueFromLit (i));
1730 /*-----------------------------------------------------------------*/
1731 /* operandFromAst - creates an operand from an ast */
1732 /*-----------------------------------------------------------------*/
1734 operandFromAst (ast * tree,int lvl)
1740 /* depending on type do */
1744 return ast2iCode (tree,lvl+1);
1748 return operandFromValue (tree->opval.val);
1752 return operandFromLink (tree->opval.lnk);
1759 /* Just to keep the compiler happy */
1760 return (operand *) 0;
1763 /*-----------------------------------------------------------------*/
1764 /* setOperandType - sets the operand's type to the given type */
1765 /*-----------------------------------------------------------------*/
1767 setOperandType (operand * op, sym_link * type)
1769 /* depending on the type of operand */
1774 op->operand.valOperand->etype =
1775 getSpec (op->operand.valOperand->type =
1776 copyLinkChain (type));
1780 if (op->operand.symOperand->isitmp)
1781 op->operand.symOperand->etype =
1782 getSpec (op->operand.symOperand->type =
1783 copyLinkChain (type));
1785 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1786 "attempt to modify type of source");
1790 op->operand.typeOperand = copyLinkChain (type);
1796 /*-----------------------------------------------------------------*/
1797 /* Get size in byte of ptr need to access an array */
1798 /*-----------------------------------------------------------------*/
1800 getArraySizePtr (operand * op)
1802 sym_link *ltype = operandType(op);
1806 int size = getSize(ltype);
1807 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1812 sym_link *letype = getSpec(ltype);
1813 switch (PTR_TYPE (SPEC_OCLS (letype)))
1825 if (GPTRSIZE > FPTRSIZE)
1826 return (GPTRSIZE-1);
1837 /*-----------------------------------------------------------------*/
1838 /* perform "usual unary conversions" */
1839 /*-----------------------------------------------------------------*/
1842 usualUnaryConversions (operand * op)
1844 if (IS_INTEGRAL (operandType (op)))
1846 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1849 return geniCodeCast (INTTYPE, op, TRUE);
1856 /*-----------------------------------------------------------------*/
1857 /* perform "usual binary conversions" */
1858 /*-----------------------------------------------------------------*/
1861 usualBinaryConversions (operand ** op1, operand ** op2,
1862 RESULT_TYPE resultType, int op)
1865 sym_link *rtype = operandType (*op2);
1866 sym_link *ltype = operandType (*op1);
1868 ctype = computeType (ltype, rtype, resultType, op);
1875 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1877 /* one byte operations: keep signedness for code generator */
1885 *op1 = geniCodeCast (ctype, *op1, TRUE);
1886 *op2 = geniCodeCast (ctype, *op2, TRUE);
1891 /*-----------------------------------------------------------------*/
1892 /* geniCodeValueAtAddress - generate intermeditate code for value */
1894 /*-----------------------------------------------------------------*/
1896 geniCodeRValue (operand * op, bool force)
1899 sym_link *type = operandType (op);
1900 sym_link *etype = getSpec (type);
1902 /* if this is an array & already */
1903 /* an address then return this */
1904 if (IS_AGGREGATE (type) ||
1905 (IS_PTR (type) && !force && !op->isaddr))
1906 return operandFromOperand (op);
1908 /* if this is not an address then must be */
1909 /* rvalue already so return this one */
1913 /* if this is not a temp symbol then */
1914 if (!IS_ITEMP (op) &&
1916 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1918 op = operandFromOperand (op);
1923 if (IS_SPEC (type) &&
1924 IS_TRUE_SYMOP (op) &&
1925 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1926 (options.model == MODEL_FLAT24) ))
1928 op = operandFromOperand (op);
1933 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1934 if (IS_PTR (type) && op->isaddr && force)
1937 type = copyLinkChain (type);
1939 IC_RESULT (ic) = newiTempOperand (type, 1);
1940 IC_RESULT (ic)->isaddr = 0;
1942 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1946 return IC_RESULT (ic);
1949 /*-----------------------------------------------------------------*/
1950 /* geniCodeCast - changes the value from one type to another */
1951 /*-----------------------------------------------------------------*/
1953 geniCodeCast (sym_link * type, operand * op, bool implicit)
1957 sym_link *opetype = getSpec (optype = operandType (op));
1961 /* one of them has size zero then error */
1962 if (IS_VOID (optype))
1964 werror (E_CAST_ZERO);
1968 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1970 geniCodeArray2Ptr (op);
1974 /* if the operand is already the desired type then do nothing */
1975 if (compareType (type, optype) == 1)
1978 /* if this is a literal then just change the type & return */
1979 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1981 return operandFromValue (valCastLiteral (type,
1982 operandLitValue (op)));
1985 /* if casting to/from pointers, do some checking */
1986 if (IS_PTR(type)) { // to a pointer
1987 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1988 if (IS_INTEGRAL(optype)) {
1989 // maybe this is NULL, than it's ok.
1990 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1991 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1992 // no way to set the storage
1993 if (IS_LITERAL(optype)) {
1994 werror(E_LITERAL_GENERIC);
1997 werror(E_NONPTR2_GENPTR);
2000 } else if (implicit) {
2001 werror(W_INTEGRAL2PTR_NOCAST);
2006 // shouldn't do that with float, array or structure unless to void
2007 if (!IS_VOID(getSpec(type)) &&
2008 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2009 werror(E_INCOMPAT_TYPES);
2013 } else { // from a pointer to a pointer
2014 if (IS_GENPTR(type) && IS_VOID(type->next))
2015 { // cast to void* is always allowed
2017 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2018 { // cast from void* is always allowed
2020 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2021 // if not a pointer to a function
2022 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2023 if (implicit) { // if not to generic, they have to match
2024 if (!IS_GENPTR(type) &&
2025 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2026 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2030 werror(E_INCOMPAT_PTYPES);
2037 } else { // to a non pointer
2038 if (IS_PTR(optype)) { // from a pointer
2039 if (implicit) { // sneaky
2040 if (IS_INTEGRAL(type)) {
2041 werror(W_PTR2INTEGRAL_NOCAST);
2043 } else { // shouldn't do that with float, array or structure
2044 werror(E_INCOMPAT_TYPES);
2051 printFromToType (optype, type);
2054 /* if they are the same size create an assignment */
2056 /* This seems very dangerous to me, since there are several */
2057 /* optimizations (for example, gcse) that don't notice the */
2058 /* cast hidden in this assignment and may simplify an */
2059 /* iCode to use the original (uncasted) operand. */
2060 /* Unfortunately, other things break when this cast is */
2061 /* made explicit. Need to fix this someday. */
2062 /* -- EEP, 2004/01/21 */
2063 if (getSize (type) == getSize (optype) &&
2064 !IS_BITFIELD (type) &&
2066 !IS_FLOAT (optype) &&
2068 !IS_FIXED (optype) &&
2069 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2070 (!IS_SPEC (type) && !IS_SPEC (optype))))
2072 ic = newiCode ('=', NULL, op);
2073 IC_RESULT (ic) = newiTempOperand (type, 0);
2074 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2075 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2076 IC_RESULT (ic)->isaddr = 0;
2080 ic = newiCode (CAST, operandFromLink (type),
2081 geniCodeRValue (op, FALSE));
2083 IC_RESULT (ic) = newiTempOperand (type, 0);
2086 /* preserve the storage class & output class */
2087 /* of the original variable */
2088 restype = getSpec (operandType (IC_RESULT (ic)));
2089 if (!IS_LITERAL(opetype) &&
2092 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2093 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2096 return IC_RESULT (ic);
2099 /*-----------------------------------------------------------------*/
2100 /* geniCodeLabel - will create a Label */
2101 /*-----------------------------------------------------------------*/
2103 geniCodeLabel (symbol * label)
2107 ic = newiCodeLabelGoto (LABEL, label);
2111 /*-----------------------------------------------------------------*/
2112 /* geniCodeGoto - will create a Goto */
2113 /*-----------------------------------------------------------------*/
2115 geniCodeGoto (symbol * label)
2119 ic = newiCodeLabelGoto (GOTO, label);
2123 /*-----------------------------------------------------------------*/
2124 /* geniCodeMultiply - gen intermediate code for multiplication */
2125 /*-----------------------------------------------------------------*/
2127 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2134 /* if they are both literal then we know the result */
2135 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2136 return operandFromValue (valMult (left->operand.valOperand,
2137 right->operand.valOperand));
2139 if (IS_LITERAL(retype)) {
2140 p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand));
2143 resType = usualBinaryConversions (&left, &right, resultType, '*');
2145 rtype = operandType (right);
2146 retype = getSpec (rtype);
2147 ltype = operandType (left);
2148 letype = getSpec (ltype);
2151 /* if the right is a literal & power of 2 */
2152 /* then make it a left shift */
2153 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2154 efficient in most cases than 2 bytes result = 2 bytes << literal
2155 if port has 1 byte muldiv */
2156 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2157 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2158 && (port->support.muldiv == 1))
2159 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2160 && strcmp (port->target, "pic14") != 0)
2162 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2164 /* LEFT_OP need same size for left and result, */
2165 left = geniCodeCast (resType, left, TRUE);
2166 ltype = operandType (left);
2168 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2172 /* if the size left or right > 1 then support routine */
2173 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2175 if (IS_LITERAL (retype))
2176 ic = newiCode ('*', right, left); /* multiplication by support routine with one literal */
2178 ic = newiCode ('*', left, right); /* multiplication by support routine */
2183 ic = newiCode ('*', left, right); /* normal multiplication */
2186 IC_RESULT (ic) = newiTempOperand (resType, 1);
2189 return IC_RESULT (ic);
2192 /*-----------------------------------------------------------------*/
2193 /* geniCodeDivision - gen intermediate code for division */
2194 /*-----------------------------------------------------------------*/
2196 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2201 sym_link *rtype = operandType (right);
2202 sym_link *retype = getSpec (rtype);
2203 sym_link *ltype = operandType (left);
2204 sym_link *letype = getSpec (ltype);
2206 resType = usualBinaryConversions (&left, &right, resultType, '/');
2208 /* if the right is a literal & power of 2
2209 and left is unsigned then make it a
2211 if (IS_LITERAL (retype) &&
2212 !IS_FLOAT (letype) &&
2213 !IS_FIXED (letype) &&
2214 IS_UNSIGNED(letype) &&
2215 ((p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand))) > 0)) {
2216 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2220 ic = newiCode ('/', left, right); /* normal division */
2221 /* if the size left or right > 1 then support routine */
2222 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2225 IC_RESULT (ic) = newiTempOperand (resType, 0);
2228 return IC_RESULT (ic);
2230 /*-----------------------------------------------------------------*/
2231 /* geniCodeModulus - gen intermediate code for modulus */
2232 /*-----------------------------------------------------------------*/
2234 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2240 /* if they are both literal then we know the result */
2241 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2242 return operandFromValue (valMod (left->operand.valOperand,
2243 right->operand.valOperand));
2245 resType = usualBinaryConversions (&left, &right, resultType, '%');
2247 /* now they are the same size */
2248 ic = newiCode ('%', left, right);
2250 /* if the size left or right > 1 then support routine */
2251 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2253 IC_RESULT (ic) = newiTempOperand (resType, 0);
2256 return IC_RESULT (ic);
2259 /*-----------------------------------------------------------------*/
2260 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2261 /*-----------------------------------------------------------------*/
2263 geniCodePtrPtrSubtract (operand * left, operand * right)
2269 /* if they are both literals then */
2270 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2272 result = operandFromValue (valMinus (left->operand.valOperand,
2273 right->operand.valOperand));
2277 ic = newiCode ('-', left, right);
2279 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2283 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2287 // should we really do this? is this ANSI?
2288 return geniCodeDivision (result,
2289 operandFromLit (getSize (ltype->next)),
2293 /*-----------------------------------------------------------------*/
2294 /* geniCodeSubtract - generates code for subtraction */
2295 /*-----------------------------------------------------------------*/
2297 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2304 /* if they both pointers then */
2305 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2306 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2307 return geniCodePtrPtrSubtract (left, right);
2309 /* if they are both literal then we know the result */
2310 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2311 && left->isLiteral && right->isLiteral)
2312 return operandFromValue (valMinus (left->operand.valOperand,
2313 right->operand.valOperand));
2315 /* if left is an array or pointer */
2316 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2318 isarray = left->isaddr;
2319 right = geniCodeMultiply (right,
2320 operandFromLit (getSize (ltype->next)),
2321 (getArraySizePtr(left) >= INTSIZE) ?
2324 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2327 { /* make them the same size */
2328 resType = usualBinaryConversions (&left, &right, resultType, '-');
2331 ic = newiCode ('-', left, right);
2333 IC_RESULT (ic) = newiTempOperand (resType, 1);
2334 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2336 /* if left or right is a float */
2337 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2338 || IS_FIXED (ltype) || IS_FIXED (rtype))
2342 return IC_RESULT (ic);
2345 /*-----------------------------------------------------------------*/
2346 /* geniCodeAdd - generates iCode for addition */
2347 /*-----------------------------------------------------------------*/
2349 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2358 /* if the right side is LITERAL zero */
2359 /* return the left side */
2360 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2363 /* if left is literal zero return right */
2364 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2367 /* if left is a pointer then size */
2368 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2370 isarray = left->isaddr;
2371 // there is no need to multiply with 1
2372 if (getSize (ltype->next) != 1)
2374 size = operandFromLit (getSize (ltype->next));
2375 SPEC_USIGN (getSpec (operandType (size))) = 1;
2376 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2377 right = geniCodeMultiply (right, size, resultType);
2378 /* Even if right is a 'unsigned char',
2379 the result will be a 'signed int' due to the promotion rules.
2380 It doesn't make sense when accessing arrays, so let's fix it here: */
2382 SPEC_USIGN (getSpec (operandType (right))) = 1;
2384 resType = copyLinkChain (ltype);
2387 { // make them the same size
2388 resType = usualBinaryConversions (&left, &right, resultType, '+');
2391 /* if they are both literals then we know */
2392 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2393 && left->isLiteral && right->isLiteral)
2394 return operandFromValue (valPlus (valFromType (ltype),
2395 valFromType (rtype)));
2397 ic = newiCode ('+', left, right);
2399 IC_RESULT (ic) = newiTempOperand (resType, 1);
2400 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2402 /* if left or right is a float then support
2404 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2405 || IS_FIXED (ltype) || IS_FIXED (rtype))
2410 return IC_RESULT (ic);
2414 /*-----------------------------------------------------------------*/
2415 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2416 /*-----------------------------------------------------------------*/
2418 aggrToPtr (sym_link * type, bool force)
2423 if (IS_PTR (type) && !force)
2426 etype = getSpec (type);
2427 ptype = newLink (DECLARATOR);
2431 /* set the pointer depending on the storage class */
2432 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2436 /*------------------------------------------------------------------*/
2437 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2438 /*------------------------------------------------------------------*/
2440 aggrToPtrDclType (sym_link * type, bool force)
2442 if (IS_PTR (type) && !force)
2443 return DCL_TYPE (type);
2445 /* return the pointer depending on the storage class */
2446 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2449 /*-----------------------------------------------------------------*/
2450 /* geniCodeArray2Ptr - array to pointer */
2451 /*-----------------------------------------------------------------*/
2453 geniCodeArray2Ptr (operand * op)
2455 sym_link *optype = operandType (op);
2456 sym_link *opetype = getSpec (optype);
2458 /* set the pointer depending on the storage class */
2459 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2466 /*-----------------------------------------------------------------*/
2467 /* geniCodeArray - array access */
2468 /*-----------------------------------------------------------------*/
2470 geniCodeArray (operand * left, operand * right, int lvl)
2474 sym_link *ltype = operandType (left);
2476 RESULT_TYPE resultType;
2478 resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
2479 if (DCL_ELEM (ltype))
2481 if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
2482 resultType = RESULT_TYPE_CHAR;
2487 if (IS_PTR (ltype->next) && left->isaddr)
2489 left = geniCodeRValue (left, FALSE);
2492 return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
2495 size = operandFromLit (getSize (ltype->next));
2496 SPEC_USIGN (getSpec (operandType (size))) = 1;
2497 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2498 right = geniCodeMultiply (right, size, resultType);
2499 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2500 It doesn't make sense when accessing arrays, so let's fix it here: */
2502 SPEC_USIGN (getSpec (operandType (right))) = 1;
2503 /* we can check for limits here */
2504 /* already done in SDCCast.c
2505 if (isOperandLiteral (right) &&
2508 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2510 werror (W_IDX_OUT_OF_BOUNDS,
2511 (int) operandLitValue (right) / getSize (ltype->next),
2516 ic = newiCode ('+', left, right);
2518 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2519 !IS_AGGREGATE (ltype->next) &&
2520 !IS_PTR (ltype->next))
2521 ? ltype : ltype->next), 0);
2523 if (!IS_AGGREGATE (ltype->next))
2525 IC_RESULT (ic)->isaddr = 1;
2526 IC_RESULT (ic)->aggr2ptr = 1;
2530 return IC_RESULT (ic);
2533 /*-----------------------------------------------------------------*/
2534 /* geniCodeStruct - generates intermediate code for structures */
2535 /*-----------------------------------------------------------------*/
2537 geniCodeStruct (operand * left, operand * right, bool islval)
2540 sym_link *type = operandType (left);
2541 sym_link *etype = getSpec (type);
2543 symbol *element = getStructElement (SPEC_STRUCT (etype),
2544 right->operand.symOperand);
2546 wassert(IS_SYMOP(right));
2548 /* add the offset */
2549 ic = newiCode ('+', left, operandFromLit (element->offset));
2551 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2553 /* preserve the storage & output class of the struct */
2554 /* as well as the volatile attribute */
2555 retype = getSpec (operandType (IC_RESULT (ic)));
2556 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2557 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2558 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2559 SPEC_CONST (retype) |= SPEC_CONST (etype);
2561 if (IS_PTR (element->type))
2562 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2564 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2567 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2570 /*-----------------------------------------------------------------*/
2571 /* geniCodePostInc - generate int code for Post increment */
2572 /*-----------------------------------------------------------------*/
2574 geniCodePostInc (operand * op)
2578 sym_link *optype = operandType (op);
2580 operand *rv = (IS_ITEMP (op) ?
2581 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2583 sym_link *rvtype = operandType (rv);
2586 /* if this is not an address we have trouble */
2589 werror (E_LVALUE_REQUIRED, "++");
2593 rOp = newiTempOperand (rvtype, 0);
2594 OP_SYMBOL(rOp)->noSpilLoc = 1;
2597 OP_SYMBOL(rv)->noSpilLoc = 1;
2599 geniCodeAssign (rOp, rv, 0, 0);
2601 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2603 werror(W_SIZEOF_VOID);
2604 if (IS_FLOAT (rvtype))
2605 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2606 else if (IS_FIXED16X16 (rvtype))
2607 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2609 ic = newiCode ('+', rv, operandFromLit (size));
2611 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2614 geniCodeAssign (op, result, 0, 0);
2620 /*-----------------------------------------------------------------*/
2621 /* geniCodePreInc - generate code for preIncrement */
2622 /*-----------------------------------------------------------------*/
2624 geniCodePreInc (operand * op, bool lvalue)
2627 sym_link *optype = operandType (op);
2628 operand *rop = (IS_ITEMP (op) ?
2629 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2631 sym_link *roptype = operandType (rop);
2637 werror (E_LVALUE_REQUIRED, "++");
2641 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2643 werror(W_SIZEOF_VOID);
2644 if (IS_FLOAT (roptype))
2645 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2646 else if (IS_FIXED16X16 (roptype))
2647 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2649 ic = newiCode ('+', rop, operandFromLit (size));
2650 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2653 (void) geniCodeAssign (op, result, 0, 0);
2654 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2660 /*-----------------------------------------------------------------*/
2661 /* geniCodePostDec - generates code for Post decrement */
2662 /*-----------------------------------------------------------------*/
2664 geniCodePostDec (operand * op)
2668 sym_link *optype = operandType (op);
2670 operand *rv = (IS_ITEMP (op) ?
2671 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2673 sym_link *rvtype = operandType (rv);
2676 /* if this is not an address we have trouble */
2679 werror (E_LVALUE_REQUIRED, "--");
2683 rOp = newiTempOperand (rvtype, 0);
2684 OP_SYMBOL(rOp)->noSpilLoc = 1;
2687 OP_SYMBOL(rv)->noSpilLoc = 1;
2689 geniCodeAssign (rOp, rv, 0, 0);
2691 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2693 werror(W_SIZEOF_VOID);
2694 if (IS_FLOAT (rvtype))
2695 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2696 else if (IS_FIXED16X16 (rvtype))
2697 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2699 ic = newiCode ('-', rv, operandFromLit (size));
2701 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2704 geniCodeAssign (op, result, 0, 0);
2710 /*-----------------------------------------------------------------*/
2711 /* geniCodePreDec - generate code for pre decrement */
2712 /*-----------------------------------------------------------------*/
2714 geniCodePreDec (operand * op, bool lvalue)
2717 sym_link *optype = operandType (op);
2718 operand *rop = (IS_ITEMP (op) ?
2719 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2721 sym_link *roptype = operandType (rop);
2727 werror (E_LVALUE_REQUIRED, "--");
2731 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2733 werror(W_SIZEOF_VOID);
2734 if (IS_FLOAT (roptype))
2735 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2736 else if (IS_FIXED16X16 (roptype))
2737 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2739 ic = newiCode ('-', rop, operandFromLit (size));
2740 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2743 (void) geniCodeAssign (op, result, 0, 0);
2744 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2751 /*-----------------------------------------------------------------*/
2752 /* geniCodeBitwise - gen int code for bitWise operators */
2753 /*-----------------------------------------------------------------*/
2755 geniCodeBitwise (operand * left, operand * right,
2756 int oper, sym_link * resType)
2760 left = geniCodeCast (resType, left, TRUE);
2761 right = geniCodeCast (resType, right, TRUE);
2763 ic = newiCode (oper, left, right);
2764 IC_RESULT (ic) = newiTempOperand (resType, 0);
2767 return IC_RESULT (ic);
2770 /*-----------------------------------------------------------------*/
2771 /* geniCodeAddressOf - gens icode for '&' address of operator */
2772 /*-----------------------------------------------------------------*/
2774 geniCodeAddressOf (operand * op)
2778 sym_link *optype = operandType (op);
2779 sym_link *opetype = getSpec (optype);
2781 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2783 op = operandFromOperand (op);
2788 /* lvalue check already done in decorateType */
2789 /* this must be a lvalue */
2790 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2791 /* werror (E_LVALUE_REQUIRED,"&"); */
2795 p = newLink (DECLARATOR);
2797 /* set the pointer depending on the storage class */
2798 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2800 p->next = copyLinkChain (optype);
2802 /* if already a temp */
2805 setOperandType (op, p);
2810 /* otherwise make this of the type coming in */
2811 ic = newiCode (ADDRESS_OF, op, NULL);
2812 IC_RESULT (ic) = newiTempOperand (p, 1);
2813 IC_RESULT (ic)->isaddr = 0;
2815 return IC_RESULT (ic);
2818 /*-----------------------------------------------------------------*/
2819 /* setOClass - sets the output class depending on the pointer type */
2820 /*-----------------------------------------------------------------*/
2822 setOClass (sym_link * ptr, sym_link * spec)
2824 switch (DCL_TYPE (ptr))
2827 SPEC_OCLS (spec) = data;
2831 SPEC_OCLS (spec) = generic;
2835 SPEC_OCLS (spec) = xdata;
2839 SPEC_OCLS (spec) = code;
2843 SPEC_OCLS (spec) = idata;
2847 SPEC_OCLS (spec) = xstack;
2851 SPEC_OCLS (spec) = eeprom;
2860 /*-----------------------------------------------------------------*/
2861 /* geniCodeDerefPtr - dereference pointer with '*' */
2862 /*-----------------------------------------------------------------*/
2864 geniCodeDerefPtr (operand * op,int lvl)
2866 sym_link *rtype, *retype;
2867 sym_link *optype = operandType (op);
2869 // if this is an array then array access
2870 if (IS_ARRAY (optype)) {
2871 // don't worry, this will be optimized out later
2872 return geniCodeArray (op, operandFromLit (0), lvl);
2875 // just in case someone screws up
2876 wassert (IS_PTR (optype));
2878 if (IS_TRUE_SYMOP (op))
2881 op = geniCodeRValue (op, TRUE);
2884 /* now get rid of the pointer part */
2885 if (isLvaluereq(lvl) && IS_ITEMP (op))
2887 retype = getSpec (rtype = copyLinkChain (optype));
2891 retype = getSpec (rtype = copyLinkChain (optype->next));
2892 /* outputclass needs 2b updated */
2893 setOClass (optype, retype);
2896 op->isGptr = IS_GENPTR (optype);
2898 op->isaddr = (IS_PTR (rtype) ||
2899 IS_STRUCT (rtype) ||
2905 if (!isLvaluereq(lvl))
2906 op = geniCodeRValue (op, TRUE);
2908 setOperandType (op, rtype);
2913 /*-----------------------------------------------------------------*/
2914 /* geniCodeUnaryMinus - does a unary minus of the operand */
2915 /*-----------------------------------------------------------------*/
2917 geniCodeUnaryMinus (operand * op)
2920 sym_link *optype = operandType (op);
2922 if (IS_LITERAL (optype))
2923 return operandFromLit (-floatFromVal (op->operand.valOperand));
2925 ic = newiCode (UNARYMINUS, op, NULL);
2926 IC_RESULT (ic) = newiTempOperand (optype, 0);
2928 return IC_RESULT (ic);
2931 /*-----------------------------------------------------------------*/
2932 /* geniCodeLeftShift - gen i code for left shift */
2933 /*-----------------------------------------------------------------*/
2935 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2940 ic = newiCode (LEFT_OP, left, right);
2942 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2943 IC_RESULT (ic) = newiTempOperand (resType, 0);
2945 return IC_RESULT (ic);
2948 /*-----------------------------------------------------------------*/
2949 /* geniCodeRightShift - gen i code for right shift */
2950 /*-----------------------------------------------------------------*/
2952 geniCodeRightShift (operand * left, operand * right)
2956 ic = newiCode (RIGHT_OP, left, right);
2957 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2959 return IC_RESULT (ic);
2962 /*-----------------------------------------------------------------*/
2963 /* geniCodeLogic- logic code */
2964 /*-----------------------------------------------------------------*/
2966 geniCodeLogic (operand * left, operand * right, int op, ast *tree)
2969 sym_link *ctype, *ttype;
2970 sym_link *rtype = operandType (right);
2971 sym_link *ltype = operandType (left);
2973 /* left is integral type and right is literal then
2974 check if the literal value is within bounds */
2975 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2977 CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE);
2980 case CCR_ALWAYS_TRUE:
2981 case CCR_ALWAYS_FALSE:
2982 if (!options.lessPedantic)
2983 werror (W_COMP_RANGE, "true resp. false");
2984 return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0);
2990 /* if one operand is a pointer and the other is a literal generic void pointer,
2991 change the type of the literal generic void pointer to match the other pointer */
2992 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2993 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2995 /* find left's definition */
2996 ic = (iCode *) setFirstItem (iCodeChain);
2999 if (((ic->op == CAST) || (ic->op == '='))
3000 && isOperandEqual(left, IC_RESULT (ic)))
3003 ic = setNextItem (iCodeChain);
3005 /* if casting literal to generic pointer, then cast to rtype instead */
3006 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3008 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3009 ltype = operandType(left);
3012 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3013 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3015 /* find right's definition */
3016 ic = (iCode *) setFirstItem (iCodeChain);
3019 if (((ic->op == CAST) || (ic->op == '='))
3020 && isOperandEqual(right, IC_RESULT (ic)))
3023 ic = setNextItem (iCodeChain);
3025 /* if casting literal to generic pointer, then cast to rtype instead */
3026 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3028 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3029 rtype = operandType(right);
3033 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
3035 ic = newiCode (op, left, right);
3036 /* store 0 or 1 in result */
3037 ttype = (tree && IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3038 IC_RESULT (ic) = newiTempOperand (ttype, 1);
3040 /* if comparing float
3041 and not a '==' || '!=' || '&&' || '||' (these
3043 if (IS_FLOAT(ctype) &&
3050 /* if comparing a fixed type use support functions */
3051 if (IS_FIXED(ctype))
3055 return IC_RESULT (ic);
3058 /*-----------------------------------------------------------------*/
3059 /* geniCodeLogicAndOr - && || operations */
3060 /*-----------------------------------------------------------------*/
3062 geniCodeLogicAndOr (ast *tree, int lvl)
3066 symbol *falseLabel = newiTempLabel (NULL);
3067 symbol *trueLabel = newiTempLabel (NULL);
3068 symbol *exitLabel = newiTempLabel (NULL);
3069 operand *op, *result, *condition;
3071 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3072 They can be reenabled by executing the following block. If you find
3073 a decent optimization you could start right here:
3078 operand *leftOp, *rightOp;
3080 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3081 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3083 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3087 /* generate two IFX for the '&&' or '||' op */
3089 /* evaluate left operand */
3090 condition = ast2iCode (tree->left, lvl + 1);
3091 op = geniCodeRValue (condition, FALSE);
3093 /* test left operand */
3094 if (tree->opval.op == AND_OP)
3095 ic = newiCodeCondition (op, NULL, falseLabel);
3097 ic = newiCodeCondition (op, trueLabel, NULL);
3100 /* evaluate right operand */
3101 condition = ast2iCode (tree->right, lvl + 1);
3102 op = geniCodeRValue (condition, FALSE);
3104 /* test right operand */
3105 ic = newiCodeCondition (op, trueLabel, NULL);
3108 /* store 0 or 1 in result */
3109 type = (IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3110 result = newiTempOperand (type, 1);
3112 geniCodeLabel (falseLabel);
3113 geniCodeAssign (result, operandFromLit (0), 0, 0);
3114 /* generate an unconditional goto */
3115 geniCodeGoto (exitLabel);
3117 geniCodeLabel (trueLabel);
3118 geniCodeAssign (result, operandFromLit (1), 0, 0);
3120 geniCodeLabel (exitLabel);
3125 /*-----------------------------------------------------------------*/
3126 /* geniCodeUnary - for a generic unary operation */
3127 /*-----------------------------------------------------------------*/
3129 geniCodeUnary (operand * op, int oper)
3131 iCode *ic = newiCode (oper, op, NULL);
3133 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3135 return IC_RESULT (ic);
3138 /*-----------------------------------------------------------------*/
3139 /* geniCodeBinary - for a generic binary operation */
3140 /*-----------------------------------------------------------------*/
3142 geniCodeBinary (operand * left, operand * right, int oper)
3144 iCode *ic = newiCode (oper, left, right);
3146 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3148 return IC_RESULT (ic);
3151 /*-----------------------------------------------------------------*/
3152 /* geniCodeConditional - geniCode for '?' ':' operation */
3153 /*-----------------------------------------------------------------*/
3155 geniCodeConditional (ast * tree,int lvl)
3158 symbol *falseLabel = newiTempLabel (NULL);
3159 symbol *exitLabel = newiTempLabel (NULL);
3160 ast *astTrue = tree->right->left;
3161 ast *astFalse = tree->right->right;
3162 operand *cond = ast2iCode (tree->left, lvl+1);
3163 operand *result = newiTempOperand (tree->right->ftype, 0);
3164 operand *opTrue, *opFalse;
3166 ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel);
3169 opTrue = ast2iCode (astTrue, lvl+1);
3171 /* move the value to the new operand */
3172 geniCodeAssign (result, geniCodeRValue (opTrue, FALSE), 0, 0);
3174 /* generate an unconditional goto */
3175 geniCodeGoto (exitLabel);
3177 /* now for the right side */
3178 geniCodeLabel (falseLabel);
3180 opFalse = ast2iCode (astFalse, lvl+1);
3181 geniCodeAssign (result, geniCodeRValue (opFalse, FALSE), 0, 0);
3183 /* create the exit label */
3184 geniCodeLabel (exitLabel);
3189 /*-----------------------------------------------------------------*/
3190 /* geniCodeAssign - generate code for assignment */
3191 /*-----------------------------------------------------------------*/
3193 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3196 sym_link *ltype = operandType (left);
3197 sym_link *rtype = operandType (right);
3199 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3201 werror (E_LVALUE_REQUIRED, "assignment");
3205 /* left is integral type and right is literal then
3206 check if the literal value is within bounds */
3207 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3208 checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3209 !options.lessPedantic)
3211 werror (W_LIT_OVERFLOW);
3214 /* if the left & right type don't exactly match */
3215 /* if pointer set then make sure the check is
3216 done with the type & not the pointer */
3217 /* then cast rights type to left */
3219 /* first check the type for pointer assignement */
3220 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3221 compareType (ltype, rtype) <= 0)
3224 right = geniCodeCast (ltype, right, TRUE);
3225 else if (compareType (ltype->next, rtype) < 0)
3226 right = geniCodeCast (ltype->next, right, TRUE);
3228 else if (compareType (ltype, rtype) < 0)
3229 right = geniCodeCast (ltype, right, TRUE);
3231 /* If left is a true symbol & ! volatile
3232 create an assignment to temporary for
3233 the right & then assign this temporary
3234 to the symbol. This is SSA (static single
3235 assignment). Isn't it simple and folks have
3236 published mountains of paper on it */
3237 if (IS_TRUE_SYMOP (left) &&
3238 !isOperandVolatile (left, FALSE) &&
3239 isOperandGlobal (left))
3244 if (IS_TRUE_SYMOP (right))
3245 sym = OP_SYMBOL (right);
3246 ic = newiCode ('=', NULL, right);
3247 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3248 /* avoid double fetch from volatile right, see bug 1369874 */
3249 if (!isOperandVolatile (right, FALSE))
3250 SPIL_LOC (newRight) = sym;
3255 ic = newiCode ('=', NULL, right);
3256 IC_RESULT (ic) = left;
3259 /* if left isgptr flag is set then support
3260 routine will be required */
3264 ic->nosupdate = nosupdate;
3265 /* left could be a pointer assignment,
3266 return the properly casted right instead */
3270 /*-----------------------------------------------------------------*/
3271 /* geniCodeDummyRead - generate code for dummy read */
3272 /*-----------------------------------------------------------------*/
3274 geniCodeDummyRead (operand * op)
3277 sym_link *type = operandType (op);
3279 if (!IS_VOLATILE(type))
3282 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3288 /*-----------------------------------------------------------------*/
3289 /* geniCodeSEParms - generate code for side effecting fcalls */
3290 /*-----------------------------------------------------------------*/
3292 geniCodeSEParms (ast * parms,int lvl)
3297 if (parms->type == EX_OP && parms->opval.op == PARAM)
3299 geniCodeSEParms (parms->left,lvl);
3300 geniCodeSEParms (parms->right,lvl);
3304 /* hack don't like this but too lazy to think of
3306 if (IS_ADDRESS_OF_OP (parms))
3307 parms->left->lvalue = 1;
3309 if (IS_CAST_OP (parms) &&
3310 IS_PTR (parms->ftype) &&
3311 IS_ADDRESS_OF_OP (parms->right))
3312 parms->right->left->lvalue = 1;
3314 parms->opval.oprnd =
3315 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3317 parms->type = EX_OPERAND;
3318 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3319 SPEC_ARGREG(parms->ftype);
3322 /*-----------------------------------------------------------------*/
3323 /* geniCodeParms - generates parameters */
3324 /*-----------------------------------------------------------------*/
3326 geniCodeParms (ast * parms, value *argVals, int *stack,
3327 sym_link * ftype, int lvl)
3335 if (argVals==NULL) {
3337 argVals = FUNC_ARGS (ftype);
3340 /* if this is a param node then do the left & right */
3341 if (parms->type == EX_OP && parms->opval.op == PARAM)
3343 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3344 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3348 /* get the parameter value */
3349 if (parms->type == EX_OPERAND)
3350 pval = parms->opval.oprnd;
3353 /* maybe this else should go away ?? */
3354 /* hack don't like this but too lazy to think of
3356 if (IS_ADDRESS_OF_OP (parms))
3357 parms->left->lvalue = 1;
3359 if (IS_CAST_OP (parms) &&
3360 IS_PTR (parms->ftype) &&
3361 IS_ADDRESS_OF_OP (parms->right))
3362 parms->right->left->lvalue = 1;
3364 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3367 /* if register parm then make it a send */
3368 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3369 IFFUNC_ISBUILTIN(ftype))
3371 ic = newiCode (SEND, pval, NULL);
3372 ic->argreg = SPEC_ARGREG(parms->etype);
3373 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3378 /* now decide whether to push or assign */
3379 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3383 operand *top = operandFromSymbol (argVals->sym);
3384 /* clear useDef and other bitVectors */
3385 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3386 geniCodeAssign (top, pval, 1, 0);
3390 sym_link *p = operandType (pval);
3392 ic = newiCode (IPUSH, pval, NULL);
3394 /* update the stack adjustment */
3395 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3400 argVals=argVals->next;
3404 /*-----------------------------------------------------------------*/
3405 /* geniCodeCall - generates temp code for calling */
3406 /*-----------------------------------------------------------------*/
3408 geniCodeCall (operand * left, ast * parms,int lvl)
3412 sym_link *type, *etype;
3416 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3417 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3418 werror (E_FUNCTION_EXPECTED);
3419 return operandFromValue(valueFromLit(0));
3422 /* take care of parameters with side-effecting
3423 function calls in them, this is required to take care
3424 of overlaying function parameters */
3425 geniCodeSEParms (parms,lvl);
3427 ftype = operandType (left);
3428 if (IS_FUNCPTR (ftype))
3429 ftype = ftype->next;
3431 /* first the parameters */
3432 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3434 /* now call : if symbol then pcall */
3435 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3436 ic = newiCode (PCALL, left, NULL);
3438 ic = newiCode (CALL, left, NULL);
3441 type = copyLinkChain (ftype->next);
3442 etype = getSpec (type);
3443 SPEC_EXTR (etype) = 0;
3444 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3448 /* stack adjustment after call */
3449 ic->parmBytes = stack;
3454 /*-----------------------------------------------------------------*/
3455 /* geniCodeReceive - generate intermediate code for "receive" */
3456 /*-----------------------------------------------------------------*/
3458 geniCodeReceive (value * args, operand * func)
3460 unsigned char paramByteCounter = 0;
3462 /* for all arguments that are passed in registers */
3465 if (IS_REGPARM (args->etype))
3467 operand *opr = operandFromValue (args);
3469 symbol *sym = OP_SYMBOL (opr);
3472 /* we will use it after all optimizations
3473 and before liveRange calculation */
3474 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3477 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3478 options.stackAuto == 0 &&
3479 (!(options.model == MODEL_FLAT24)) )
3484 opl = newiTempOperand (args->type, 0);
3486 sym->reqv->key = sym->key;
3487 OP_SYMBOL (sym->reqv)->key = sym->key;
3488 OP_SYMBOL (sym->reqv)->isreqv = 1;
3489 OP_SYMBOL (sym->reqv)->islocal = 0;
3490 SPIL_LOC (sym->reqv) = sym;
3494 ic = newiCode (RECEIVE, func, NULL);
3495 ic->argreg = SPEC_ARGREG(args->etype);
3496 if (ic->argreg == 1) {
3497 currFunc->recvSize = getSize (sym->type);
3499 IC_RESULT (ic) = opr;
3501 /* misuse of parmBytes (normally used for functions)
3502 * to save estimated stack position of this argument.
3503 * Normally this should be zero for RECEIVE iCodes.
3504 * No idea if this causes side effects on other ports. - dw
3506 ic->parmBytes = paramByteCounter;
3508 /* what stack position do we have? */
3509 paramByteCounter += getSize (sym->type);
3518 /*-----------------------------------------------------------------*/
3519 /* geniCodeFunctionBody - create the function body */
3520 /*-----------------------------------------------------------------*/
3522 geniCodeFunctionBody (ast * tree,int lvl)
3529 /* reset the auto generation */
3535 func = ast2iCode (tree->left,lvl+1);
3536 fetype = getSpec (operandType (func));
3538 savelineno = lineno;
3539 lineno = OP_SYMBOL (func)->lineDef;
3540 /* create an entry label */
3541 geniCodeLabel (entryLabel);
3542 lineno = savelineno;
3544 /* create a proc icode */
3545 ic = newiCode (FUNCTION, func, NULL);
3546 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3551 /* for all parameters that are passed
3552 on registers add a "receive" */
3553 geniCodeReceive (tree->values.args, func);
3555 /* generate code for the body */
3556 ast2iCode (tree->right,lvl+1);
3558 /* create a label for return */
3559 geniCodeLabel (returnLabel);
3561 /* now generate the end proc */
3562 ic = newiCode (ENDFUNCTION, func, NULL);
3568 /*-----------------------------------------------------------------*/
3569 /* geniCodeReturn - gen icode for 'return' statement */
3570 /*-----------------------------------------------------------------*/
3572 geniCodeReturn (operand * op)
3576 /* if the operand is present force an rvalue */
3578 op = geniCodeRValue (op, FALSE);
3580 ic = newiCode (RETURN, op, NULL);
3584 /*-----------------------------------------------------------------*/
3585 /* geniCodeIfx - generates code for extended if statement */
3586 /*-----------------------------------------------------------------*/
3588 geniCodeIfx (ast * tree,int lvl)
3591 operand *condition = ast2iCode (tree->left,lvl+1);
3594 /* if condition is null then exit */
3598 condition = geniCodeRValue (condition, FALSE);
3600 cetype = getSpec (operandType (condition));
3601 /* if the condition is a literal */
3602 if (IS_LITERAL (cetype))
3604 if (floatFromVal (condition->operand.valOperand))
3606 if (tree->trueLabel)
3607 geniCodeGoto (tree->trueLabel);
3613 if (tree->falseLabel)
3614 geniCodeGoto (tree->falseLabel);
3619 if (tree->trueLabel)
3621 ic = newiCodeCondition (condition,
3626 if (tree->falseLabel)
3627 geniCodeGoto (tree->falseLabel);
3631 ic = newiCodeCondition (condition,
3638 ast2iCode (tree->right,lvl+1);
3641 /*-----------------------------------------------------------------*/
3642 /* geniCodeJumpTable - tries to create a jump table for switch */
3643 /*-----------------------------------------------------------------*/
3645 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3647 int min, max, cnt = 1;
3654 int needRangeCheck = !optimize.noJTabBoundary
3655 || tree->values.switchVals.swDefault;
3656 sym_link *cetype = getSpec (operandType (cond));
3657 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3658 int sizeofMatchJump, sizeofJumpTable;
3661 if (!tree || !caseVals)
3664 /* the criteria for creating a jump table is */
3665 /* all integer numbers between the maximum & minimum must */
3666 /* be present , the maximum value should not exceed 255 */
3667 /* If not all integer numbers are present the algorithm */
3668 /* inserts jumps to the default label for the missing numbers */
3669 /* and decides later whether it is worth it */
3670 min = (int) ulFromVal (vch = caseVals);
3677 max = (int) ulFromVal (vch);
3679 /* Exit if the range is too large to handle with a jump table. */
3680 if (1 + max - min > port->jumptableCost.maxCount)
3683 switch (getSize (operandType (cond)))
3685 case 1: sizeIndex = 0; break;
3686 case 2: sizeIndex = 1; break;
3687 case 4: sizeIndex = 2; break;
3691 /* Compute the size cost of the range check and subtraction. */
3693 sizeofZeroMinCost = 0;
3697 if (!(min==0 && IS_UNSIGNED (cetype)))
3698 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3699 if (!IS_UNSIGNED (cetype))
3700 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3701 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3704 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3706 /* If the size cost of handling a non-zero minimum exceeds the */
3707 /* cost of extending the range down to zero, then it might be */
3708 /* better to extend the range to zero. */
3709 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3710 >= (min * port->jumptableCost.sizeofElement))
3712 /* Only extend the jump table if it would still be manageable. */
3713 if (1 + max <= port->jumptableCost.maxCount)
3716 if (IS_UNSIGNED (cetype))
3719 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3723 /* Compute the total size cost of a jump table. */
3724 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3725 + port->jumptableCost.sizeofDispatch
3726 + sizeofMinCost + sizeofMaxCost;
3728 /* Compute the total size cost of a match & jump sequence */
3729 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3731 /* If the size cost of the jump table is uneconomical then exit */
3732 if (sizeofMatchJump < sizeofJumpTable)
3735 /* The jump table is preferable. */
3737 /* First, a label for the default or missing cases. */
3738 if (tree->values.switchVals.swDefault)
3740 SNPRINTF (buffer, sizeof(buffer),
3742 tree->values.switchVals.swNum);
3746 SNPRINTF (buffer, sizeof(buffer),
3748 tree->values.switchVals.swNum);
3750 falseLabel = newiTempLabel (buffer);
3752 /* Build the list of labels for the jump table. */
3754 t = (int) ulFromVal (vch);
3755 for (i=min; i<=max; i++)
3759 /* Explicit case: make a new label for it. */
3760 SNPRINTF (buffer, sizeof(buffer),
3762 tree->values.switchVals.swNum,
3764 addSet (&labels, newiTempLabel (buffer));
3767 t = (int) ulFromVal (vch);
3771 /* Implicit case: use the default label. */
3772 addSet (&labels, falseLabel);
3776 /* first we rule out the boundary conditions */
3777 /* if only optimization says so */
3780 sym_link *cetype = getSpec (operandType (cond));
3781 /* no need to check the lower bound if
3782 the condition is unsigned & minimum value is zero */
3783 if (!(min == 0 && IS_UNSIGNED (cetype)))
3785 boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL);
3786 ic = newiCodeCondition (boundary, falseLabel, NULL);
3790 /* now for upper bounds */
3791 boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL);
3792 ic = newiCodeCondition (boundary, falseLabel, NULL);
3796 /* if the min is not zero then we no make it zero */
3799 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3800 if (!IS_LITERAL(getSpec(operandType(cond))))
3801 setOperandType (cond, UCHARTYPE);
3804 /* now create the jumptable */
3805 ic = newiCode (JUMPTABLE, NULL, NULL);
3806 IC_JTCOND (ic) = cond;
3807 IC_JTLABELS (ic) = labels;
3812 /*-----------------------------------------------------------------*/
3813 /* geniCodeSwitch - changes a switch to a if statement */
3814 /*-----------------------------------------------------------------*/
3816 geniCodeSwitch (ast * tree,int lvl)
3819 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3820 value *caseVals = tree->values.switchVals.swVals;
3821 symbol *trueLabel, *falseLabel;
3823 /* If the condition is a literal, then just jump to the */
3824 /* appropriate case label. */
3825 if (IS_LITERAL(getSpec(operandType(cond))))
3827 int switchVal, caseVal;
3829 switchVal = (int) ulFromVal (cond->operand.valOperand);
3832 caseVal = (int) ulFromVal (caseVals);
3833 if (caseVal == switchVal)
3835 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3836 tree->values.switchVals.swNum, caseVal);
3837 trueLabel = newiTempLabel (buffer);
3838 geniCodeGoto (trueLabel);
3841 caseVals = caseVals->next;
3843 goto defaultOrBreak;
3846 /* If cond is volatile, it might change while we are trying to */
3847 /* find the matching case. To avoid this possibility, make a */
3848 /* non-volatile copy to use instead. */
3849 if (IS_OP_VOLATILE (cond))
3854 newcond = newiTempOperand (operandType (cond), TRUE);
3855 newcond->isvolatile = 0;
3856 ic = newiCode ('=', NULL, cond);
3857 IC_RESULT (ic) = newcond;
3862 /* if we can make this a jump table */
3863 if (geniCodeJumpTable (cond, caseVals, tree))
3864 goto jumpTable; /* no need for the comparison */
3866 /* for the cases defined do */
3870 operand *compare = geniCodeLogic (cond,
3871 operandFromValue (caseVals),
3874 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3875 tree->values.switchVals.swNum,
3876 (int) ulFromVal (caseVals));
3877 trueLabel = newiTempLabel (buffer);
3879 ic = newiCodeCondition (compare, trueLabel, NULL);
3881 caseVals = caseVals->next;
3886 /* if default is present then goto break else break */
3887 if (tree->values.switchVals.swDefault)
3889 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3893 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3896 falseLabel = newiTempLabel (buffer);
3897 geniCodeGoto (falseLabel);
3900 ast2iCode (tree->right,lvl+1);
3903 /*-----------------------------------------------------------------*/
3904 /* geniCodeInline - intermediate code for inline assembler */
3905 /*-----------------------------------------------------------------*/
3907 geniCodeInline (ast * tree)
3911 ic = newiCode (INLINEASM, NULL, NULL);
3912 IC_INLINE (ic) = tree->values.inlineasm;
3916 /*-----------------------------------------------------------------*/
3917 /* geniCodeArrayInit - intermediate code for array initializer */
3918 /*-----------------------------------------------------------------*/
3920 geniCodeArrayInit (ast * tree, operand *array)
3924 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3925 ic = newiCode (ARRAYINIT, array, NULL);
3926 IC_ARRAYILIST (ic) = tree->values.constlist;
3928 operand *left=newOperand(), *right=newOperand();
3929 left->type=right->type=SYMBOL;
3930 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3931 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3932 ic = newiCode (ARRAYINIT, left, right);
3937 /*-----------------------------------------------------------------*/
3938 /* geniCodeCritical - intermediate code for a critical statement */
3939 /*-----------------------------------------------------------------*/
3941 geniCodeCritical (ast *tree, int lvl)
3947 if (!options.stackAuto)
3949 type = newLink(SPECIFIER);
3950 SPEC_VOLATILE(type) = 1;
3951 SPEC_NOUN(type) = V_BIT;
3952 SPEC_SCLS(type) = S_BIT;
3953 SPEC_BLEN(type) = 1;
3954 SPEC_BSTR(type) = 0;
3955 op = newiTempOperand(type, 1);
3958 /* If op is NULL, the original interrupt state will saved on */
3959 /* the stack. Otherwise, it will be saved in op. */
3961 /* Generate a save of the current interrupt state & disable */
3962 ic = newiCode (CRITICAL, NULL, NULL);
3963 IC_RESULT (ic) = op;
3966 /* Generate the critical code sequence */
3967 if (tree->left && tree->left->type == EX_VALUE)
3968 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3970 ast2iCode (tree->left,lvl+1);
3972 /* Generate a restore of the original interrupt state */
3973 ic = newiCode (ENDCRITICAL, NULL, op);
3977 /*-----------------------------------------------------------------*/
3978 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3979 /* particular case. Ie : assigning or dereferencing array or ptr */
3980 /*-----------------------------------------------------------------*/
3981 set * lvaluereqSet = NULL;
3982 typedef struct lvalItem
3989 /*-----------------------------------------------------------------*/
3990 /* addLvaluereq - add a flag for lvalreq for current ast level */
3991 /*-----------------------------------------------------------------*/
3992 void addLvaluereq(int lvl)
3994 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3997 addSetHead(&lvaluereqSet,lpItem);
4000 /*-----------------------------------------------------------------*/
4001 /* delLvaluereq - del a flag for lvalreq for current ast level */
4002 /*-----------------------------------------------------------------*/
4006 lpItem = getSet(&lvaluereqSet);
4007 if(lpItem) Safe_free(lpItem);
4009 /*-----------------------------------------------------------------*/
4010 /* clearLvaluereq - clear lvalreq flag */
4011 /*-----------------------------------------------------------------*/
4012 void clearLvaluereq()
4015 lpItem = peekSet(lvaluereqSet);
4016 if(lpItem) lpItem->req = 0;
4018 /*-----------------------------------------------------------------*/
4019 /* getLvaluereq - get the last lvalreq level */
4020 /*-----------------------------------------------------------------*/
4021 int getLvaluereqLvl()
4024 lpItem = peekSet(lvaluereqSet);
4025 if(lpItem) return lpItem->lvl;
4028 /*-----------------------------------------------------------------*/
4029 /* isLvaluereq - is lvalreq valid for this level ? */
4030 /*-----------------------------------------------------------------*/
4031 int isLvaluereq(int lvl)
4034 lpItem = peekSet(lvaluereqSet);
4035 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4039 /*-----------------------------------------------------------------*/
4040 /* ast2iCode - creates an icodeList from an ast */
4041 /*-----------------------------------------------------------------*/
4043 ast2iCode (ast * tree,int lvl)
4045 operand *left = NULL;
4046 operand *right = NULL;
4050 /* set the global variables for filename & line number */
4052 filename = tree->filename;
4054 lineno = tree->lineno;
4056 block = tree->block;
4058 scopeLevel = tree->level;
4060 seqPoint = tree->seqPoint;
4062 if (tree->type == EX_VALUE)
4063 return operandFromValue (tree->opval.val);
4065 if (tree->type == EX_LINK)
4066 return operandFromLink (tree->opval.lnk);
4068 /* if we find a nullop */
4069 if (tree->type == EX_OP &&
4070 (tree->opval.op == NULLOP ||
4071 tree->opval.op == BLOCK))
4073 if (tree->left && tree->left->type == EX_VALUE)
4074 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4076 ast2iCode (tree->left,lvl+1);
4077 if (tree->right && tree->right->type == EX_VALUE)
4078 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4080 ast2iCode (tree->right,lvl+1);
4084 /* special cases for not evaluating */
4085 if (tree->opval.op != ':' &&
4086 tree->opval.op != '?' &&
4087 tree->opval.op != CALL &&
4088 tree->opval.op != IFX &&
4089 tree->opval.op != AND_OP &&
4090 tree->opval.op != OR_OP &&
4091 tree->opval.op != LABEL &&
4092 tree->opval.op != GOTO &&
4093 tree->opval.op != SWITCH &&
4094 tree->opval.op != FUNCTION &&
4095 tree->opval.op != INLINEASM &&
4096 tree->opval.op != CRITICAL)
4099 if (IS_ASSIGN_OP (tree->opval.op) ||
4100 IS_DEREF_OP (tree) ||
4101 (tree->opval.op == '&' && !tree->right) ||
4102 tree->opval.op == PTR_OP)
4105 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4106 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4109 left = operandFromAst (tree->left,lvl);
4111 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4112 left = geniCodeRValue (left, TRUE);
4116 left = operandFromAst (tree->left,lvl);
4118 if (tree->opval.op == INC_OP ||
4119 tree->opval.op == DEC_OP)
4122 right = operandFromAst (tree->right,lvl);
4127 right = operandFromAst (tree->right,lvl);
4131 /* now depending on the type of operand */
4132 /* this will be a biggy */
4133 switch (tree->opval.op)
4136 case '[': /* array operation */
4138 //sym_link *ltype = operandType (left);
4139 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4140 left = geniCodeRValue (left, FALSE);
4141 right = geniCodeRValue (right, TRUE);
4144 return geniCodeArray (left, right,lvl);
4146 case '.': /* structure dereference */
4147 if (IS_PTR (operandType (left)))
4148 left = geniCodeRValue (left, TRUE);
4150 left = geniCodeRValue (left, FALSE);
4152 return geniCodeStruct (left, right, tree->lvalue);
4154 case PTR_OP: /* structure pointer dereference */
4157 pType = operandType (left);
4158 left = geniCodeRValue (left, TRUE);
4160 setOClass (pType, getSpec (operandType (left)));
4163 return geniCodeStruct (left, right, tree->lvalue);
4165 case INC_OP: /* increment operator */
4167 return geniCodePostInc (left);
4169 return geniCodePreInc (right, tree->lvalue);
4171 case DEC_OP: /* decrement operator */
4173 return geniCodePostDec (left);
4175 return geniCodePreDec (right, tree->lvalue);
4177 case '&': /* bitwise and or address of operator */
4179 { /* this is a bitwise operator */
4180 left = geniCodeRValue (left, FALSE);
4181 right = geniCodeRValue (right, FALSE);
4182 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4185 return geniCodeAddressOf (left);
4187 case '|': /* bitwise or & xor */
4189 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4190 geniCodeRValue (right, FALSE),
4195 return geniCodeDivision (geniCodeRValue (left, FALSE),
4196 geniCodeRValue (right, FALSE),
4197 getResultTypeFromType (tree->ftype));
4200 return geniCodeModulus (geniCodeRValue (left, FALSE),
4201 geniCodeRValue (right, FALSE),
4202 getResultTypeFromType (tree->ftype));
4205 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4206 geniCodeRValue (right, FALSE),
4207 getResultTypeFromType (tree->ftype));
4209 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4213 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4214 geniCodeRValue (right, FALSE),
4215 getResultTypeFromType (tree->ftype));
4217 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4221 return geniCodeAdd (geniCodeRValue (left, FALSE),
4222 geniCodeRValue (right, FALSE),
4223 getResultTypeFromType (tree->ftype),
4226 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4229 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4230 geniCodeRValue (right, FALSE),
4231 getResultTypeFromType (tree->ftype));
4234 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4235 geniCodeRValue (right, FALSE));
4237 #if 0 // this indeed needs a second thought
4241 // let's keep this simple: get the rvalue we need
4242 op=geniCodeRValue (right, FALSE);
4243 // now cast it to whatever we want
4244 op=geniCodeCast (operandType(left), op, FALSE);
4245 // if this is going to be used as an lvalue, make it so
4251 #else // bug #604575, is it a bug ????
4252 return geniCodeCast (operandType (left),
4253 geniCodeRValue (right, FALSE), FALSE);
4260 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4265 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4266 if (!IS_BIT (operandType (op)))
4267 setOperandType (op, UCHARTYPE);
4272 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4273 geniCodeRValue (right, FALSE),
4275 if (!IS_BIT (operandType (op)))
4276 setOperandType (op, UCHARTYPE);
4281 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4282 geniCodeRValue (right, FALSE),
4284 setOperandType (op, UCHARTYPE);
4289 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4290 geniCodeRValue (right, FALSE),
4292 setOperandType (op, UINTTYPE);
4297 return geniCodeLogicAndOr (tree, lvl);
4304 /* different compilers (even different gccs) evaluate
4305 the two calls in a different order. to get the same
4306 result on all machines we have to specify a clear sequence.
4307 return geniCodeLogic (geniCodeRValue (left, FALSE),
4308 geniCodeRValue (right, FALSE),
4312 operand *leftOp, *rightOp;
4314 leftOp = geniCodeRValue (left , FALSE);
4315 rightOp = geniCodeRValue (right, FALSE);
4317 return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree);
4320 return geniCodeConditional (tree,lvl);
4323 return operandFromLit (getSize (tree->right->ftype));
4327 sym_link *rtype = operandType (right);
4328 sym_link *ltype = operandType (left);
4329 if (IS_PTR (rtype) && IS_ITEMP (right)
4330 && right->isaddr && compareType (rtype->next, ltype) == 1)
4331 right = geniCodeRValue (right, TRUE);
4333 right = geniCodeRValue (right, FALSE);
4335 return geniCodeAssign (left, right, 0, 1);
4339 geniCodeAssign (left,
4340 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4342 geniCodeRValue (right, FALSE),
4343 getResultTypeFromType (tree->ftype)),
4348 geniCodeAssign (left,
4349 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4351 geniCodeRValue (right, FALSE),
4352 getResultTypeFromType (tree->ftype)),
4356 geniCodeAssign (left,
4357 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4359 geniCodeRValue (right, FALSE),
4360 getResultTypeFromType (tree->ftype)),
4364 sym_link *rtype = operandType (right);
4365 sym_link *ltype = operandType (left);
4366 if (IS_PTR (rtype) && IS_ITEMP (right)
4367 && right->isaddr && compareType (rtype->next, ltype) == 1)
4368 right = geniCodeRValue (right, TRUE);
4370 right = geniCodeRValue (right, FALSE);
4373 return geniCodeAssign (left,
4374 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4377 getResultTypeFromType (tree->ftype),
4383 sym_link *rtype = operandType (right);
4384 sym_link *ltype = operandType (left);
4385 if (IS_PTR (rtype) && IS_ITEMP (right)
4386 && right->isaddr && compareType (rtype->next, ltype) == 1)
4388 right = geniCodeRValue (right, TRUE);
4392 right = geniCodeRValue (right, FALSE);
4395 geniCodeAssign (left,
4396 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4399 getResultTypeFromType (tree->ftype)),
4404 geniCodeAssign (left,
4405 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4407 geniCodeRValue (right, FALSE),
4408 getResultTypeFromType (tree->ftype)),
4412 geniCodeAssign (left,
4413 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4415 geniCodeRValue (right, FALSE)), 0, 1);
4418 geniCodeAssign (left,
4419 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4421 geniCodeRValue (right, FALSE),
4423 operandType (left)), 0, 1);
4426 geniCodeAssign (left,
4427 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4429 geniCodeRValue (right, FALSE),
4431 operandType (left)), 0, 1);
4434 geniCodeAssign (left,
4435 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4437 geniCodeRValue (right, FALSE),
4439 operandType (left)), 0, 1);
4441 return geniCodeRValue (right, FALSE);
4444 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4447 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4448 return ast2iCode (tree->right,lvl+1);
4451 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4452 return ast2iCode (tree->right,lvl+1);
4455 geniCodeFunctionBody (tree,lvl);
4459 geniCodeReturn (right);
4463 geniCodeIfx (tree,lvl);
4467 geniCodeSwitch (tree,lvl);
4471 geniCodeInline (tree);
4475 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4479 geniCodeCritical (tree, lvl);
4485 /*-----------------------------------------------------------------*/
4486 /* reverseICChain - gets from the list and creates a linkedlist */
4487 /*-----------------------------------------------------------------*/
4494 while ((loop = getSet (&iCodeChain)))
4506 /*-----------------------------------------------------------------*/
4507 /* iCodeFromAst - given an ast will convert it to iCode */
4508 /*-----------------------------------------------------------------*/
4510 iCodeFromAst (ast * tree)
4512 returnLabel = newiTempLabel ("_return");
4513 entryLabel = newiTempLabel ("_entry");
4515 return reverseiCChain ();
4518 static const char *opTypeToStr(OPTYPE op)
4522 case SYMBOL: return "symbol";
4523 case VALUE: return "value";
4524 case TYPE: return "type";
4526 return "undefined type";
4530 operand *validateOpType(operand *op,
4537 if (op && op->type == type)
4542 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4543 " expected %s, got %s\n",
4544 macro, args, file, line,
4545 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4547 return op; // never reached, makes compiler happy.