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 (IS_UNSIGNED (type))
1231 if ((TYPE_TARGET_ULONG) double2ul (operandLitValue (right)) == 0)
1233 werror (E_DIVIDE_BY_ZERO);
1236 SPEC_USIGN (let) = 1;
1237 SPEC_USIGN (ret) = 1;
1238 retval = operandFromValue (valCastLiteral (type,
1239 (TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) /
1240 (TYPE_TARGET_ULONG) double2ul (operandLitValue (right))));
1244 if (operandLitValue (right) == 0)
1246 werror (E_DIVIDE_BY_ZERO);
1249 retval = operandFromValue (valCastLiteral (type,
1250 operandLitValue (left) /
1251 operandLitValue (right)));
1255 if ((TYPE_TARGET_ULONG) double2ul (operandLitValue (right)) == 0)
1257 werror (E_DIVIDE_BY_ZERO);
1262 if (IS_UNSIGNED (type))
1263 retval = operandFromLit ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) %
1264 (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
1266 retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) %
1267 (TYPE_TARGET_LONG) operandLitValue (right));
1271 /* The number of left shifts is always unsigned. Signed doesn't make
1272 sense here. Shifting by a negative number is impossible. */
1273 retval = operandFromValue (valCastLiteral (type,
1274 ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) <<
1275 (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)))));
1278 /* The number of right shifts is always unsigned. Signed doesn't make
1279 sense here. Shifting by a negative number is impossible. */
1280 if (IS_UNSIGNED(let))
1281 /* unsigned: logic shift right */
1282 retval = operandFromLit ((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)) >>
1283 (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
1285 /* signed: arithmetic shift right */
1286 retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) >>
1287 (TYPE_TARGET_ULONG) double2ul (operandLitValue (right)));
1290 if (IS_FLOAT (let) || IS_FLOAT (ret))
1292 retval = operandFromLit (operandLitValue (left) ==
1293 operandLitValue (right));
1295 else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
1297 retval = operandFromLit (operandLitValue (left) ==
1298 operandLitValue (right));
1302 /* this op doesn't care about signedness */
1303 TYPE_TARGET_ULONG l, r;
1305 l = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
1306 r = (TYPE_TARGET_ULONG) double2ul (operandLitValue (right));
1307 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1308 neccessary to strip them to 16 bit.
1309 Literals are reduced to their cheapest type, therefore left and
1310 right might have different types. It's neccessary to find a
1311 common type: int (used for char too) or long */
1312 if (!IS_LONG (let) &&
1315 r = (TYPE_TARGET_UINT) r;
1316 l = (TYPE_TARGET_UINT) l;
1318 retval = operandFromLit (l == r);
1322 retval = operandFromLit (operandLitValue (left) <
1323 operandLitValue (right));
1326 retval = operandFromLit (operandLitValue (left) <=
1327 operandLitValue (right));
1330 retval = operandFromLit (operandLitValue (left) !=
1331 operandLitValue (right));
1334 retval = operandFromLit (operandLitValue (left) >
1335 operandLitValue (right));
1338 retval = operandFromLit (operandLitValue (left) >=
1339 operandLitValue (right));
1342 retval = operandFromValue (valCastLiteral (type,
1343 (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) &
1344 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
1347 retval = operandFromValue (valCastLiteral (type,
1348 (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) |
1349 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
1352 retval = operandFromValue (valCastLiteral (type,
1353 (TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) ^
1354 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))));
1357 retval = operandFromLit (operandLitValue (left) &&
1358 operandLitValue (right));
1361 retval = operandFromLit (operandLitValue (left) ||
1362 operandLitValue (right));
1366 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
1368 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1374 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) double2ul (operandLitValue (left));
1376 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1381 retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
1382 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right))) & 1);
1385 retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
1386 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)) & 0xFF));
1389 retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
1390 (TYPE_TARGET_ULONG) double2ul (operandLitValue(right)) & 0xFFFF));
1394 retval = operandFromLit (((TYPE_TARGET_ULONG) double2ul (operandLitValue(left)) >>
1395 ((getSize (let) * 8) - 1)) & 1);
1399 retval = operandFromValue (valCastLiteral (type,
1400 -1 * operandLitValue (left)));
1404 retval = operandFromValue (valCastLiteral (type,
1405 ~((TYPE_TARGET_ULONG) double2ul (operandLitValue (left)))));
1409 retval = operandFromLit (!operandLitValue (left));
1413 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1414 " operandOperation invalid operator ");
1422 /*-----------------------------------------------------------------*/
1423 /* isOperandEqual - compares two operand & return 1 if they r = */
1424 /*-----------------------------------------------------------------*/
1426 isOperandEqual (operand * left, operand * right)
1428 /* if the pointers are equal then they are equal */
1432 /* if either of them null then false */
1433 if (!left || !right)
1436 if (left->type != right->type)
1439 if (IS_SYMOP (left) && IS_SYMOP (right))
1440 return left->key == right->key;
1442 /* if types are the same */
1446 return isSymbolEqual (left->operand.symOperand,
1447 right->operand.symOperand);
1449 return (compareType (left->operand.valOperand->type,
1450 right->operand.valOperand->type) &&
1451 (floatFromVal (left->operand.valOperand) ==
1452 floatFromVal (right->operand.valOperand)));
1454 if (compareType (left->operand.typeOperand,
1455 right->operand.typeOperand) == 1)
1462 /*-------------------------------------------------------------------*/
1463 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1464 /*-------------------------------------------------------------------*/
1466 isiCodeEqual (iCode * left, iCode * right)
1468 /* if the same pointer */
1472 /* if either of them null */
1473 if (!left || !right)
1476 /* if operand are the same */
1477 if (left->op == right->op)
1480 /* compare all the elements depending on type */
1481 if (left->op != IFX)
1483 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1485 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1491 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1493 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1495 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1504 /*-----------------------------------------------------------------*/
1505 /* newiTempFromOp - create a temp Operand with same attributes */
1506 /*-----------------------------------------------------------------*/
1508 newiTempFromOp (operand * op)
1518 nop = newiTempOperand (operandType (op), TRUE);
1519 nop->isaddr = op->isaddr;
1520 nop->isvolatile = op->isvolatile;
1521 nop->isGlobal = op->isGlobal;
1522 nop->isLiteral = op->isLiteral;
1523 nop->usesDefs = op->usesDefs;
1524 nop->isParm = op->isParm;
1528 /*-----------------------------------------------------------------*/
1529 /* operand from operand - creates an operand holder for the type */
1530 /*-----------------------------------------------------------------*/
1532 operandFromOperand (operand * op)
1538 nop = newOperand ();
1539 nop->type = op->type;
1540 nop->isaddr = op->isaddr;
1542 nop->isvolatile = op->isvolatile;
1543 nop->isGlobal = op->isGlobal;
1544 nop->isLiteral = op->isLiteral;
1545 nop->usesDefs = op->usesDefs;
1546 nop->isParm = op->isParm;
1551 nop->operand.symOperand = op->operand.symOperand;
1554 nop->operand.valOperand = op->operand.valOperand;
1557 nop->operand.typeOperand = op->operand.typeOperand;
1564 /*-----------------------------------------------------------------*/
1565 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1566 /*-----------------------------------------------------------------*/
1568 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1570 operand *nop = operandFromOperand (op);
1572 if (nop->type == SYMBOL)
1574 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1575 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1581 /*-----------------------------------------------------------------*/
1582 /* operandFromSymbol - creates an operand from a symbol */
1583 /*-----------------------------------------------------------------*/
1585 operandFromSymbol (symbol * sym)
1590 /* if the symbol's type is a literal */
1591 /* then it is an enumerator type */
1592 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1593 return operandFromValue (valFromType (sym->etype));
1596 sym->key = ++operandKey;
1598 /* if this an implicit variable, means struct/union */
1599 /* member so just return it */
1600 if (sym->implicit || IS_FUNC (sym->type))
1604 op->operand.symOperand = sym;
1606 op->isvolatile = isOperandVolatile (op, TRUE);
1607 op->isGlobal = isOperandGlobal (op);
1611 /* under the following conditions create a
1612 register equivalent for a local symbol */
1613 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1614 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1616 (!(options.model == MODEL_FLAT24)) ) &&
1617 options.stackAuto == 0)
1620 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1621 !IS_FUNC (sym->type) && /* not a function */
1622 !sym->_isparm && /* not a parameter */
1623 IS_AUTO (sym) && /* is a local auto variable */
1624 !sym->addrtaken && /* whose address has not been taken */
1625 !sym->reqv && /* does not already have a reg equivalence */
1626 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1627 !sym->islbl && /* not a label */
1628 ok /* farspace check */
1632 /* we will use it after all optimizations
1633 and before liveRange calculation */
1634 sym->reqv = newiTempOperand (sym->type, 0);
1635 sym->reqv->key = sym->key;
1636 OP_SYMBOL (sym->reqv)->prereqv = sym;
1637 OP_SYMBOL (sym->reqv)->key = sym->key;
1638 OP_SYMBOL (sym->reqv)->isreqv = 1;
1639 OP_SYMBOL (sym->reqv)->islocal = 1;
1640 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1641 SPIL_LOC (sym->reqv) = sym;
1644 if (!IS_AGGREGATE (sym->type))
1648 op->operand.symOperand = sym;
1651 op->isvolatile = isOperandVolatile (op, TRUE);
1652 op->isGlobal = isOperandGlobal (op);
1653 op->isPtr = IS_PTR (operandType (op));
1654 op->isParm = sym->_isparm;
1659 /* itemp = &[_symbol] */
1661 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1662 IC_LEFT (ic)->type = SYMBOL;
1663 IC_LEFT (ic)->operand.symOperand = sym;
1664 IC_LEFT (ic)->key = sym->key;
1665 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1666 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1667 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1670 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1671 if (IS_ARRAY (sym->type))
1673 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1674 IC_RESULT (ic)->isaddr = 0;
1677 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1681 return IC_RESULT (ic);
1684 /*-----------------------------------------------------------------*/
1685 /* operandFromValue - creates an operand from value */
1686 /*-----------------------------------------------------------------*/
1688 operandFromValue (value * val)
1692 /* if this is a symbol then do the symbol thing */
1694 return operandFromSymbol (val->sym);
1696 /* this is not a symbol */
1699 op->operand.valOperand = val;
1700 op->isLiteral = isOperandLiteral (op);
1704 /*-----------------------------------------------------------------*/
1705 /* operandFromLink - operand from typeChain */
1706 /*-----------------------------------------------------------------*/
1708 operandFromLink (sym_link * type)
1712 /* operand from sym_link */
1718 op->operand.typeOperand = copyLinkChain (type);
1722 /*-----------------------------------------------------------------*/
1723 /* operandFromLit - makes an operand from a literal value */
1724 /*-----------------------------------------------------------------*/
1726 operandFromLit (double i)
1728 return operandFromValue (valueFromLit (i));
1731 /*-----------------------------------------------------------------*/
1732 /* operandFromAst - creates an operand from an ast */
1733 /*-----------------------------------------------------------------*/
1735 operandFromAst (ast * tree,int lvl)
1741 /* depending on type do */
1745 return ast2iCode (tree,lvl+1);
1749 return operandFromValue (tree->opval.val);
1753 return operandFromLink (tree->opval.lnk);
1760 /* Just to keep the compiler happy */
1761 return (operand *) 0;
1764 /*-----------------------------------------------------------------*/
1765 /* setOperandType - sets the operand's type to the given type */
1766 /*-----------------------------------------------------------------*/
1768 setOperandType (operand * op, sym_link * type)
1770 /* depending on the type of operand */
1775 op->operand.valOperand->etype =
1776 getSpec (op->operand.valOperand->type =
1777 copyLinkChain (type));
1781 if (op->operand.symOperand->isitmp)
1782 op->operand.symOperand->etype =
1783 getSpec (op->operand.symOperand->type =
1784 copyLinkChain (type));
1786 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1787 "attempt to modify type of source");
1791 op->operand.typeOperand = copyLinkChain (type);
1797 /*-----------------------------------------------------------------*/
1798 /* Get size in byte of ptr need to access an array */
1799 /*-----------------------------------------------------------------*/
1801 getArraySizePtr (operand * op)
1803 sym_link *ltype = operandType(op);
1807 int size = getSize(ltype);
1808 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1813 sym_link *letype = getSpec(ltype);
1814 switch (PTR_TYPE (SPEC_OCLS (letype)))
1826 if (GPTRSIZE > FPTRSIZE)
1827 return (GPTRSIZE-1);
1838 /*-----------------------------------------------------------------*/
1839 /* perform "usual unary conversions" */
1840 /*-----------------------------------------------------------------*/
1843 usualUnaryConversions (operand * op)
1845 if (IS_INTEGRAL (operandType (op)))
1847 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1850 return geniCodeCast (INTTYPE, op, TRUE);
1857 /*-----------------------------------------------------------------*/
1858 /* perform "usual binary conversions" */
1859 /*-----------------------------------------------------------------*/
1862 usualBinaryConversions (operand ** op1, operand ** op2,
1863 RESULT_TYPE resultType, int op)
1866 sym_link *rtype = operandType (*op2);
1867 sym_link *ltype = operandType (*op1);
1869 ctype = computeType (ltype, rtype, resultType, op);
1876 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1878 /* one byte operations: keep signedness for code generator */
1886 *op1 = geniCodeCast (ctype, *op1, TRUE);
1887 *op2 = geniCodeCast (ctype, *op2, TRUE);
1892 /*-----------------------------------------------------------------*/
1893 /* geniCodeValueAtAddress - generate intermeditate code for value */
1895 /*-----------------------------------------------------------------*/
1897 geniCodeRValue (operand * op, bool force)
1900 sym_link *type = operandType (op);
1901 sym_link *etype = getSpec (type);
1903 /* if this is an array & already */
1904 /* an address then return this */
1905 if (IS_AGGREGATE (type) ||
1906 (IS_PTR (type) && !force && !op->isaddr))
1907 return operandFromOperand (op);
1909 /* if this is not an address then must be */
1910 /* rvalue already so return this one */
1914 /* if this is not a temp symbol then */
1915 if (!IS_ITEMP (op) &&
1917 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1919 op = operandFromOperand (op);
1924 if (IS_SPEC (type) &&
1925 IS_TRUE_SYMOP (op) &&
1926 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1927 (options.model == MODEL_FLAT24) ))
1929 op = operandFromOperand (op);
1934 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1935 if (IS_PTR (type) && op->isaddr && force)
1938 type = copyLinkChain (type);
1940 IC_RESULT (ic) = newiTempOperand (type, 1);
1941 IC_RESULT (ic)->isaddr = 0;
1943 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1947 return IC_RESULT (ic);
1950 /*-----------------------------------------------------------------*/
1951 /* geniCodeCast - changes the value from one type to another */
1952 /*-----------------------------------------------------------------*/
1954 geniCodeCast (sym_link * type, operand * op, bool implicit)
1958 sym_link *opetype = getSpec (optype = operandType (op));
1962 /* one of them has size zero then error */
1963 if (IS_VOID (optype))
1965 werror (E_CAST_ZERO);
1969 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1971 geniCodeArray2Ptr (op);
1975 /* if the operand is already the desired type then do nothing */
1976 if (compareType (type, optype) == 1)
1979 /* if this is a literal then just change the type & return */
1980 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1982 return operandFromValue (valCastLiteral (type,
1983 operandLitValue (op)));
1986 /* if casting to/from pointers, do some checking */
1987 if (IS_PTR(type)) { // to a pointer
1988 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1989 if (IS_INTEGRAL(optype)) {
1990 // maybe this is NULL, than it's ok.
1991 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1992 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1993 // no way to set the storage
1994 if (IS_LITERAL(optype)) {
1995 werror(E_LITERAL_GENERIC);
1998 werror(E_NONPTR2_GENPTR);
2001 } else if (implicit) {
2002 werror(W_INTEGRAL2PTR_NOCAST);
2007 // shouldn't do that with float, array or structure unless to void
2008 if (!IS_VOID(getSpec(type)) &&
2009 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2010 werror(E_INCOMPAT_TYPES);
2014 } else { // from a pointer to a pointer
2015 if (IS_GENPTR(type) && IS_VOID(type->next))
2016 { // cast to void* is always allowed
2018 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2019 { // cast from void* is always allowed
2021 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2022 // if not a pointer to a function
2023 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2024 if (implicit) { // if not to generic, they have to match
2025 if (!IS_GENPTR(type) &&
2026 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2027 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2031 werror(E_INCOMPAT_PTYPES);
2038 } else { // to a non pointer
2039 if (IS_PTR(optype)) { // from a pointer
2040 if (implicit) { // sneaky
2041 if (IS_INTEGRAL(type)) {
2042 werror(W_PTR2INTEGRAL_NOCAST);
2044 } else { // shouldn't do that with float, array or structure
2045 werror(E_INCOMPAT_TYPES);
2052 printFromToType (optype, type);
2055 /* if they are the same size create an assignment */
2057 /* This seems very dangerous to me, since there are several */
2058 /* optimizations (for example, gcse) that don't notice the */
2059 /* cast hidden in this assignment and may simplify an */
2060 /* iCode to use the original (uncasted) operand. */
2061 /* Unfortunately, other things break when this cast is */
2062 /* made explicit. Need to fix this someday. */
2063 /* -- EEP, 2004/01/21 */
2064 if (getSize (type) == getSize (optype) &&
2065 !IS_BITFIELD (type) &&
2067 !IS_FLOAT (optype) &&
2069 !IS_FIXED (optype) &&
2070 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2071 (IS_DECL (type) && IS_DECL (optype) && DCL_TYPE (type) == DCL_TYPE (optype))))
2073 ic = newiCode ('=', NULL, op);
2074 IC_RESULT (ic) = newiTempOperand (type, 0);
2075 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2076 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2077 IC_RESULT (ic)->isaddr = 0;
2081 ic = newiCode (CAST, operandFromLink (type),
2082 geniCodeRValue (op, FALSE));
2084 IC_RESULT (ic) = newiTempOperand (type, 0);
2087 /* preserve the storage class & output class */
2088 /* of the original variable */
2089 restype = getSpec (operandType (IC_RESULT (ic)));
2090 if (!IS_LITERAL(opetype) &&
2093 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2094 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2097 return IC_RESULT (ic);
2100 /*-----------------------------------------------------------------*/
2101 /* geniCodeLabel - will create a Label */
2102 /*-----------------------------------------------------------------*/
2104 geniCodeLabel (symbol * label)
2108 ic = newiCodeLabelGoto (LABEL, label);
2112 /*-----------------------------------------------------------------*/
2113 /* geniCodeGoto - will create a Goto */
2114 /*-----------------------------------------------------------------*/
2116 geniCodeGoto (symbol * label)
2120 ic = newiCodeLabelGoto (GOTO, label);
2124 /*-----------------------------------------------------------------*/
2125 /* geniCodeMultiply - gen intermediate code for multiplication */
2126 /*-----------------------------------------------------------------*/
2128 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2135 /* if they are both literal then we know the result */
2136 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2137 return operandFromValue (valMult (left->operand.valOperand,
2138 right->operand.valOperand));
2140 if (IS_LITERAL(retype)) {
2141 p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand));
2144 resType = usualBinaryConversions (&left, &right, resultType, '*');
2146 rtype = operandType (right);
2147 retype = getSpec (rtype);
2148 ltype = operandType (left);
2149 letype = getSpec (ltype);
2152 /* if the right is a literal & power of 2 */
2153 /* then make it a left shift */
2154 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2155 efficient in most cases than 2 bytes result = 2 bytes << literal
2156 if port has 1 byte muldiv */
2157 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2158 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2159 && (port->support.muldiv == 1))
2160 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2161 && strcmp (port->target, "pic14") != 0)
2163 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2165 /* LEFT_OP need same size for left and result, */
2166 left = geniCodeCast (resType, left, TRUE);
2167 ltype = operandType (left);
2169 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2173 /* if the size left or right > 1 then support routine */
2174 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2176 if (IS_LITERAL (retype))
2177 ic = newiCode ('*', right, left); /* multiplication by support routine with one literal */
2179 ic = newiCode ('*', left, right); /* multiplication by support routine */
2184 ic = newiCode ('*', left, right); /* normal multiplication */
2187 IC_RESULT (ic) = newiTempOperand (resType, 1);
2190 return IC_RESULT (ic);
2193 /*-----------------------------------------------------------------*/
2194 /* geniCodeDivision - gen intermediate code for division */
2195 /*-----------------------------------------------------------------*/
2197 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2202 sym_link *rtype = operandType (right);
2203 sym_link *retype = getSpec (rtype);
2204 sym_link *ltype = operandType (left);
2205 sym_link *letype = getSpec (ltype);
2207 resType = usualBinaryConversions (&left, &right, resultType, '/');
2209 /* if the right is a literal & power of 2
2210 and left is unsigned then make it a
2212 if (IS_LITERAL (retype) &&
2213 !IS_FLOAT (letype) &&
2214 !IS_FIXED (letype) &&
2215 IS_UNSIGNED(letype) &&
2216 ((p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand))) > 0)) {
2217 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2221 ic = newiCode ('/', left, right); /* normal division */
2222 /* if the size left or right > 1 then support routine */
2223 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2226 IC_RESULT (ic) = newiTempOperand (resType, 0);
2229 return IC_RESULT (ic);
2231 /*-----------------------------------------------------------------*/
2232 /* geniCodeModulus - gen intermediate code for modulus */
2233 /*-----------------------------------------------------------------*/
2235 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2241 /* if they are both literal then we know the result */
2242 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2243 return operandFromValue (valMod (left->operand.valOperand,
2244 right->operand.valOperand));
2246 resType = usualBinaryConversions (&left, &right, resultType, '%');
2248 /* now they are the same size */
2249 ic = newiCode ('%', left, right);
2251 /* if the size left or right > 1 then support routine */
2252 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2254 IC_RESULT (ic) = newiTempOperand (resType, 0);
2257 return IC_RESULT (ic);
2260 /*-----------------------------------------------------------------*/
2261 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2262 /*-----------------------------------------------------------------*/
2264 geniCodePtrPtrSubtract (operand * left, operand * right)
2270 /* if they are both literals then */
2271 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2273 result = operandFromValue (valMinus (left->operand.valOperand,
2274 right->operand.valOperand));
2278 ic = newiCode ('-', left, right);
2280 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2284 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2288 // should we really do this? is this ANSI?
2289 return geniCodeDivision (result,
2290 operandFromLit (getSize (ltype->next)),
2294 /*-----------------------------------------------------------------*/
2295 /* geniCodeSubtract - generates code for subtraction */
2296 /*-----------------------------------------------------------------*/
2298 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2305 /* if they both pointers then */
2306 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2307 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2308 return geniCodePtrPtrSubtract (left, right);
2310 /* if they are both literal then we know the result */
2311 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2312 && left->isLiteral && right->isLiteral)
2313 return operandFromValue (valMinus (left->operand.valOperand,
2314 right->operand.valOperand));
2316 /* if left is an array or pointer */
2317 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2319 isarray = left->isaddr;
2320 right = geniCodeMultiply (right,
2321 operandFromLit (getSize (ltype->next)),
2322 (getArraySizePtr(left) >= INTSIZE) ?
2325 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2328 { /* make them the same size */
2329 resType = usualBinaryConversions (&left, &right, resultType, '-');
2332 ic = newiCode ('-', left, right);
2334 IC_RESULT (ic) = newiTempOperand (resType, 1);
2335 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2337 /* if left or right is a float */
2338 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2339 || IS_FIXED (ltype) || IS_FIXED (rtype))
2343 return IC_RESULT (ic);
2346 /*-----------------------------------------------------------------*/
2347 /* geniCodeAdd - generates iCode for addition */
2348 /*-----------------------------------------------------------------*/
2350 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2359 /* if the right side is LITERAL zero */
2360 /* return the left side */
2361 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2364 /* if left is literal zero return right */
2365 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2368 /* if left is a pointer then size */
2369 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2371 isarray = left->isaddr;
2372 // there is no need to multiply with 1
2373 if (getSize (ltype->next) != 1)
2375 size = operandFromLit (getSize (ltype->next));
2376 SPEC_USIGN (getSpec (operandType (size))) = 1;
2377 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2378 right = geniCodeMultiply (right, size, resultType);
2379 /* Even if right is a 'unsigned char',
2380 the result will be a 'signed int' due to the promotion rules.
2381 It doesn't make sense when accessing arrays, so let's fix it here: */
2383 SPEC_USIGN (getSpec (operandType (right))) = 1;
2385 resType = copyLinkChain (ltype);
2388 { // make them the same size
2389 resType = usualBinaryConversions (&left, &right, resultType, '+');
2392 /* if they are both literals then we know */
2393 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2394 && left->isLiteral && right->isLiteral)
2395 return operandFromValue (valPlus (valFromType (ltype),
2396 valFromType (rtype)));
2398 ic = newiCode ('+', left, right);
2400 IC_RESULT (ic) = newiTempOperand (resType, 1);
2401 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2403 /* if left or right is a float then support
2405 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2406 || IS_FIXED (ltype) || IS_FIXED (rtype))
2411 return IC_RESULT (ic);
2415 /*-----------------------------------------------------------------*/
2416 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2417 /*-----------------------------------------------------------------*/
2419 aggrToPtr (sym_link * type, bool force)
2424 if (IS_PTR (type) && !force)
2427 etype = getSpec (type);
2428 ptype = newLink (DECLARATOR);
2432 /* set the pointer depending on the storage class */
2433 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2437 /*------------------------------------------------------------------*/
2438 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2439 /*------------------------------------------------------------------*/
2441 aggrToPtrDclType (sym_link * type, bool force)
2443 if (IS_PTR (type) && !force)
2444 return DCL_TYPE (type);
2446 /* return the pointer depending on the storage class */
2447 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2450 /*-----------------------------------------------------------------*/
2451 /* geniCodeArray2Ptr - array to pointer */
2452 /*-----------------------------------------------------------------*/
2454 geniCodeArray2Ptr (operand * op)
2456 sym_link *optype = operandType (op);
2457 sym_link *opetype = getSpec (optype);
2459 /* set the pointer depending on the storage class */
2460 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2467 /*-----------------------------------------------------------------*/
2468 /* geniCodeArray - array access */
2469 /*-----------------------------------------------------------------*/
2471 geniCodeArray (operand * left, operand * right, int lvl)
2475 sym_link *ltype = operandType (left);
2477 RESULT_TYPE resultType;
2479 resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
2480 if (DCL_ELEM (ltype))
2482 if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
2483 resultType = RESULT_TYPE_CHAR;
2488 if (IS_PTR (ltype->next) && left->isaddr)
2490 left = geniCodeRValue (left, FALSE);
2493 return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
2496 size = operandFromLit (getSize (ltype->next));
2497 SPEC_USIGN (getSpec (operandType (size))) = 1;
2498 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2499 right = geniCodeMultiply (right, size, resultType);
2500 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2501 It doesn't make sense when accessing arrays, so let's fix it here: */
2503 SPEC_USIGN (getSpec (operandType (right))) = 1;
2504 /* we can check for limits here */
2505 /* already done in SDCCast.c
2506 if (isOperandLiteral (right) &&
2509 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2511 werror (W_IDX_OUT_OF_BOUNDS,
2512 (int) operandLitValue (right) / getSize (ltype->next),
2517 ic = newiCode ('+', left, right);
2519 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2520 !IS_AGGREGATE (ltype->next) &&
2521 !IS_PTR (ltype->next))
2522 ? ltype : ltype->next), 0);
2524 if (!IS_AGGREGATE (ltype->next))
2526 IC_RESULT (ic)->isaddr = 1;
2527 IC_RESULT (ic)->aggr2ptr = 1;
2531 return IC_RESULT (ic);
2534 /*-----------------------------------------------------------------*/
2535 /* geniCodeStruct - generates intermediate code for structures */
2536 /*-----------------------------------------------------------------*/
2538 geniCodeStruct (operand * left, operand * right, bool islval)
2541 sym_link *type = operandType (left);
2542 sym_link *etype = getSpec (type);
2544 symbol *element = getStructElement (SPEC_STRUCT (etype),
2545 right->operand.symOperand);
2547 wassert(IS_SYMOP(right));
2549 /* add the offset */
2550 ic = newiCode ('+', left, operandFromLit (element->offset));
2552 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2554 /* preserve the storage & output class of the struct */
2555 /* as well as the volatile attribute */
2556 retype = getSpec (operandType (IC_RESULT (ic)));
2557 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2558 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2559 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2560 SPEC_CONST (retype) |= SPEC_CONST (etype);
2562 if (IS_PTR (element->type))
2563 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2565 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2568 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2571 /*-----------------------------------------------------------------*/
2572 /* geniCodePostInc - generate int code for Post increment */
2573 /*-----------------------------------------------------------------*/
2575 geniCodePostInc (operand * op)
2579 sym_link *optype = operandType (op);
2581 operand *rv = (IS_ITEMP (op) ?
2582 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2584 sym_link *rvtype = operandType (rv);
2587 /* if this is not an address we have trouble */
2590 werror (E_LVALUE_REQUIRED, "++");
2594 rOp = newiTempOperand (rvtype, 0);
2595 OP_SYMBOL(rOp)->noSpilLoc = 1;
2598 OP_SYMBOL(rv)->noSpilLoc = 1;
2600 geniCodeAssign (rOp, rv, 0, 0);
2602 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2604 werror(W_SIZEOF_VOID);
2605 if (IS_FLOAT (rvtype))
2606 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2607 else if (IS_FIXED16X16 (rvtype))
2608 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2610 ic = newiCode ('+', rv, operandFromLit (size));
2612 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2615 geniCodeAssign (op, result, 0, 0);
2621 /*-----------------------------------------------------------------*/
2622 /* geniCodePreInc - generate code for preIncrement */
2623 /*-----------------------------------------------------------------*/
2625 geniCodePreInc (operand * op, bool lvalue)
2628 sym_link *optype = operandType (op);
2629 operand *rop = (IS_ITEMP (op) ?
2630 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2632 sym_link *roptype = operandType (rop);
2638 werror (E_LVALUE_REQUIRED, "++");
2642 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2644 werror(W_SIZEOF_VOID);
2645 if (IS_FLOAT (roptype))
2646 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2647 else if (IS_FIXED16X16 (roptype))
2648 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2650 ic = newiCode ('+', rop, operandFromLit (size));
2651 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2654 (void) geniCodeAssign (op, result, 0, 0);
2655 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2661 /*-----------------------------------------------------------------*/
2662 /* geniCodePostDec - generates code for Post decrement */
2663 /*-----------------------------------------------------------------*/
2665 geniCodePostDec (operand * op)
2669 sym_link *optype = operandType (op);
2671 operand *rv = (IS_ITEMP (op) ?
2672 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2674 sym_link *rvtype = operandType (rv);
2677 /* if this is not an address we have trouble */
2680 werror (E_LVALUE_REQUIRED, "--");
2684 rOp = newiTempOperand (rvtype, 0);
2685 OP_SYMBOL(rOp)->noSpilLoc = 1;
2688 OP_SYMBOL(rv)->noSpilLoc = 1;
2690 geniCodeAssign (rOp, rv, 0, 0);
2692 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2694 werror(W_SIZEOF_VOID);
2695 if (IS_FLOAT (rvtype))
2696 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2697 else if (IS_FIXED16X16 (rvtype))
2698 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2700 ic = newiCode ('-', rv, operandFromLit (size));
2702 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2705 geniCodeAssign (op, result, 0, 0);
2711 /*-----------------------------------------------------------------*/
2712 /* geniCodePreDec - generate code for pre decrement */
2713 /*-----------------------------------------------------------------*/
2715 geniCodePreDec (operand * op, bool lvalue)
2718 sym_link *optype = operandType (op);
2719 operand *rop = (IS_ITEMP (op) ?
2720 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2722 sym_link *roptype = operandType (rop);
2728 werror (E_LVALUE_REQUIRED, "--");
2732 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2734 werror(W_SIZEOF_VOID);
2735 if (IS_FLOAT (roptype))
2736 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2737 else if (IS_FIXED16X16 (roptype))
2738 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2740 ic = newiCode ('-', rop, operandFromLit (size));
2741 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2744 (void) geniCodeAssign (op, result, 0, 0);
2745 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2752 /*-----------------------------------------------------------------*/
2753 /* geniCodeBitwise - gen int code for bitWise operators */
2754 /*-----------------------------------------------------------------*/
2756 geniCodeBitwise (operand * left, operand * right,
2757 int oper, sym_link * resType)
2761 left = geniCodeCast (resType, left, TRUE);
2762 right = geniCodeCast (resType, right, TRUE);
2764 ic = newiCode (oper, left, right);
2765 IC_RESULT (ic) = newiTempOperand (resType, 0);
2768 return IC_RESULT (ic);
2771 /*-----------------------------------------------------------------*/
2772 /* geniCodeAddressOf - gens icode for '&' address of operator */
2773 /*-----------------------------------------------------------------*/
2775 geniCodeAddressOf (operand * op)
2779 sym_link *optype = operandType (op);
2780 sym_link *opetype = getSpec (optype);
2782 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2784 op = operandFromOperand (op);
2789 /* lvalue check already done in decorateType */
2790 /* this must be a lvalue */
2791 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2792 /* werror (E_LVALUE_REQUIRED,"&"); */
2796 p = newLink (DECLARATOR);
2798 /* set the pointer depending on the storage class */
2799 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2801 p->next = copyLinkChain (optype);
2803 /* if already a temp */
2806 setOperandType (op, p);
2811 /* otherwise make this of the type coming in */
2812 ic = newiCode (ADDRESS_OF, op, NULL);
2813 IC_RESULT (ic) = newiTempOperand (p, 1);
2814 IC_RESULT (ic)->isaddr = 0;
2816 return IC_RESULT (ic);
2819 /*-----------------------------------------------------------------*/
2820 /* setOClass - sets the output class depending on the pointer type */
2821 /*-----------------------------------------------------------------*/
2823 setOClass (sym_link * ptr, sym_link * spec)
2825 switch (DCL_TYPE (ptr))
2828 SPEC_OCLS (spec) = data;
2832 SPEC_OCLS (spec) = generic;
2836 SPEC_OCLS (spec) = xdata;
2840 SPEC_OCLS (spec) = code;
2844 SPEC_OCLS (spec) = idata;
2848 SPEC_OCLS (spec) = xstack;
2852 SPEC_OCLS (spec) = eeprom;
2861 /*-----------------------------------------------------------------*/
2862 /* geniCodeDerefPtr - dereference pointer with '*' */
2863 /*-----------------------------------------------------------------*/
2865 geniCodeDerefPtr (operand * op,int lvl)
2867 sym_link *rtype, *retype;
2868 sym_link *optype = operandType (op);
2870 // if this is an array then array access
2871 if (IS_ARRAY (optype)) {
2872 // don't worry, this will be optimized out later
2873 return geniCodeArray (op, operandFromLit (0), lvl);
2876 // just in case someone screws up
2877 wassert (IS_PTR (optype));
2879 if (IS_TRUE_SYMOP (op))
2882 op = geniCodeRValue (op, TRUE);
2885 /* now get rid of the pointer part */
2886 if (isLvaluereq(lvl) && IS_ITEMP (op))
2888 retype = getSpec (rtype = copyLinkChain (optype));
2892 retype = getSpec (rtype = copyLinkChain (optype->next));
2893 /* outputclass needs 2b updated */
2894 setOClass (optype, retype);
2897 op->isGptr = IS_GENPTR (optype);
2899 op->isaddr = (IS_PTR (rtype) ||
2900 IS_STRUCT (rtype) ||
2906 if (!isLvaluereq(lvl))
2907 op = geniCodeRValue (op, TRUE);
2909 setOperandType (op, rtype);
2914 /*-----------------------------------------------------------------*/
2915 /* geniCodeUnaryMinus - does a unary minus of the operand */
2916 /*-----------------------------------------------------------------*/
2918 geniCodeUnaryMinus (operand * op)
2921 sym_link *optype = operandType (op);
2923 if (IS_LITERAL (optype))
2924 return operandFromLit (-floatFromVal (op->operand.valOperand));
2926 ic = newiCode (UNARYMINUS, op, NULL);
2927 IC_RESULT (ic) = newiTempOperand (optype, 0);
2929 return IC_RESULT (ic);
2932 /*-----------------------------------------------------------------*/
2933 /* geniCodeLeftShift - gen i code for left shift */
2934 /*-----------------------------------------------------------------*/
2936 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2941 ic = newiCode (LEFT_OP, left, right);
2943 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2944 IC_RESULT (ic) = newiTempOperand (resType, 0);
2946 return IC_RESULT (ic);
2949 /*-----------------------------------------------------------------*/
2950 /* geniCodeRightShift - gen i code for right shift */
2951 /*-----------------------------------------------------------------*/
2953 geniCodeRightShift (operand * left, operand * right)
2957 ic = newiCode (RIGHT_OP, left, right);
2958 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2960 return IC_RESULT (ic);
2963 /*-----------------------------------------------------------------*/
2964 /* geniCodeLogic- logic code */
2965 /*-----------------------------------------------------------------*/
2967 geniCodeLogic (operand * left, operand * right, int op, ast *tree)
2970 sym_link *ctype, *ttype;
2971 sym_link *rtype = operandType (right);
2972 sym_link *ltype = operandType (left);
2974 /* left is integral type and right is literal then
2975 check if the literal value is within bounds */
2976 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2978 CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE);
2981 case CCR_ALWAYS_TRUE:
2982 case CCR_ALWAYS_FALSE:
2983 if (!options.lessPedantic)
2984 werror (W_COMP_RANGE, "true resp. false");
2985 return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0);
2991 /* if one operand is a pointer and the other is a literal generic void pointer,
2992 change the type of the literal generic void pointer to match the other pointer */
2993 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2994 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2996 /* find left's definition */
2997 ic = (iCode *) setFirstItem (iCodeChain);
3000 if (((ic->op == CAST) || (ic->op == '='))
3001 && isOperandEqual(left, IC_RESULT (ic)))
3004 ic = setNextItem (iCodeChain);
3006 /* if casting literal to generic pointer, then cast to rtype instead */
3007 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3009 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3010 ltype = operandType(left);
3013 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3014 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3016 /* find right's definition */
3017 ic = (iCode *) setFirstItem (iCodeChain);
3020 if (((ic->op == CAST) || (ic->op == '='))
3021 && isOperandEqual(right, IC_RESULT (ic)))
3024 ic = setNextItem (iCodeChain);
3026 /* if casting literal to generic pointer, then cast to rtype instead */
3027 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3029 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3030 rtype = operandType(right);
3034 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
3036 ic = newiCode (op, left, right);
3037 /* store 0 or 1 in result */
3038 ttype = (tree && IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3039 IC_RESULT (ic) = newiTempOperand (ttype, 1);
3041 /* if comparing float
3042 and not a '==' || '!=' || '&&' || '||' (these
3044 if (IS_FLOAT(ctype) &&
3051 /* if comparing a fixed type use support functions */
3052 if (IS_FIXED(ctype))
3056 return IC_RESULT (ic);
3059 /*-----------------------------------------------------------------*/
3060 /* geniCodeLogicAndOr - && || operations */
3061 /*-----------------------------------------------------------------*/
3063 geniCodeLogicAndOr (ast *tree, int lvl)
3067 symbol *falseLabel = newiTempLabel (NULL);
3068 symbol *trueLabel = newiTempLabel (NULL);
3069 symbol *exitLabel = newiTempLabel (NULL);
3070 operand *op, *result, *condition;
3072 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3073 They can be reenabled by executing the following block. If you find
3074 a decent optimization you could start right here:
3079 operand *leftOp, *rightOp;
3081 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3082 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3084 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3088 /* generate two IFX for the '&&' or '||' op */
3090 /* evaluate left operand */
3091 condition = ast2iCode (tree->left, lvl + 1);
3092 op = geniCodeRValue (condition, FALSE);
3094 /* test left operand */
3095 if (tree->opval.op == AND_OP)
3096 ic = newiCodeCondition (op, NULL, falseLabel);
3098 ic = newiCodeCondition (op, trueLabel, NULL);
3101 /* evaluate right operand */
3102 condition = ast2iCode (tree->right, lvl + 1);
3103 op = geniCodeRValue (condition, FALSE);
3105 /* test right operand */
3106 ic = newiCodeCondition (op, trueLabel, NULL);
3109 /* store 0 or 1 in result */
3110 type = (IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3111 result = newiTempOperand (type, 1);
3113 geniCodeLabel (falseLabel);
3114 geniCodeAssign (result, operandFromLit (0), 0, 0);
3115 /* generate an unconditional goto */
3116 geniCodeGoto (exitLabel);
3118 geniCodeLabel (trueLabel);
3119 geniCodeAssign (result, operandFromLit (1), 0, 0);
3121 geniCodeLabel (exitLabel);
3126 /*-----------------------------------------------------------------*/
3127 /* geniCodeUnary - for a generic unary operation */
3128 /*-----------------------------------------------------------------*/
3130 geniCodeUnary (operand * op, int oper)
3132 iCode *ic = newiCode (oper, op, NULL);
3134 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3136 return IC_RESULT (ic);
3139 /*-----------------------------------------------------------------*/
3140 /* geniCodeBinary - for a generic binary operation */
3141 /*-----------------------------------------------------------------*/
3143 geniCodeBinary (operand * left, operand * right, int oper)
3145 iCode *ic = newiCode (oper, left, right);
3147 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3149 return IC_RESULT (ic);
3152 /*-----------------------------------------------------------------*/
3153 /* geniCodeConditional - geniCode for '?' ':' operation */
3154 /*-----------------------------------------------------------------*/
3156 geniCodeConditional (ast * tree,int lvl)
3159 symbol *falseLabel = newiTempLabel (NULL);
3160 symbol *exitLabel = newiTempLabel (NULL);
3161 ast *astTrue = tree->right->left;
3162 ast *astFalse = tree->right->right;
3163 operand *cond = ast2iCode (tree->left, lvl+1);
3164 operand *result = newiTempOperand (tree->right->ftype, 0);
3165 operand *opTrue, *opFalse;
3167 ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel);
3170 opTrue = ast2iCode (astTrue, lvl+1);
3172 /* move the value to the new operand */
3173 geniCodeAssign (result, geniCodeRValue (opTrue, FALSE), 0, 0);
3175 /* generate an unconditional goto */
3176 geniCodeGoto (exitLabel);
3178 /* now for the right side */
3179 geniCodeLabel (falseLabel);
3181 opFalse = ast2iCode (astFalse, lvl+1);
3182 geniCodeAssign (result, geniCodeRValue (opFalse, FALSE), 0, 0);
3184 /* create the exit label */
3185 geniCodeLabel (exitLabel);
3190 /*-----------------------------------------------------------------*/
3191 /* geniCodeAssign - generate code for assignment */
3192 /*-----------------------------------------------------------------*/
3194 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3197 sym_link *ltype = operandType (left);
3198 sym_link *rtype = operandType (right);
3200 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3202 werror (E_LVALUE_REQUIRED, "assignment");
3206 /* left is integral type and right is literal then
3207 check if the literal value is within bounds */
3208 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3209 checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3210 !options.lessPedantic)
3212 werror (W_LIT_OVERFLOW);
3215 /* if the left & right type don't exactly match */
3216 /* if pointer set then make sure the check is
3217 done with the type & not the pointer */
3218 /* then cast rights type to left */
3220 /* first check the type for pointer assignement */
3221 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3222 compareType (ltype, rtype) <= 0)
3225 right = geniCodeCast (ltype, right, TRUE);
3226 else if (compareType (ltype->next, rtype) < 0)
3227 right = geniCodeCast (ltype->next, right, TRUE);
3229 else if (compareType (ltype, rtype) < 0)
3230 right = geniCodeCast (ltype, right, TRUE);
3232 /* If left is a true symbol & ! volatile
3233 create an assignment to temporary for
3234 the right & then assign this temporary
3235 to the symbol. This is SSA (static single
3236 assignment). Isn't it simple and folks have
3237 published mountains of paper on it */
3238 if (IS_TRUE_SYMOP (left) &&
3239 !isOperandVolatile (left, FALSE) &&
3240 isOperandGlobal (left))
3245 if (IS_TRUE_SYMOP (right))
3246 sym = OP_SYMBOL (right);
3247 ic = newiCode ('=', NULL, right);
3248 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3249 /* avoid double fetch from volatile right, see bug 1369874 */
3250 if (!isOperandVolatile (right, FALSE))
3251 SPIL_LOC (newRight) = sym;
3256 ic = newiCode ('=', NULL, right);
3257 IC_RESULT (ic) = left;
3260 /* if left isgptr flag is set then support
3261 routine will be required */
3265 ic->nosupdate = nosupdate;
3266 /* left could be a pointer assignment,
3267 return the properly casted right instead */
3271 /*-----------------------------------------------------------------*/
3272 /* geniCodeDummyRead - generate code for dummy read */
3273 /*-----------------------------------------------------------------*/
3275 geniCodeDummyRead (operand * op)
3278 sym_link *type = operandType (op);
3280 if (!IS_VOLATILE(type))
3283 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3289 /*-----------------------------------------------------------------*/
3290 /* geniCodeSEParms - generate code for side effecting fcalls */
3291 /*-----------------------------------------------------------------*/
3293 geniCodeSEParms (ast * parms,int lvl)
3298 if (parms->type == EX_OP && parms->opval.op == PARAM)
3300 geniCodeSEParms (parms->left,lvl);
3301 geniCodeSEParms (parms->right,lvl);
3305 /* hack don't like this but too lazy to think of
3307 if (IS_ADDRESS_OF_OP (parms))
3308 parms->left->lvalue = 1;
3310 if (IS_CAST_OP (parms) &&
3311 IS_PTR (parms->ftype) &&
3312 IS_ADDRESS_OF_OP (parms->right))
3313 parms->right->left->lvalue = 1;
3315 parms->opval.oprnd =
3316 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3318 parms->type = EX_OPERAND;
3319 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3320 SPEC_ARGREG(parms->ftype);
3323 /*-----------------------------------------------------------------*/
3324 /* geniCodeParms - generates parameters */
3325 /*-----------------------------------------------------------------*/
3327 geniCodeParms (ast * parms, value *argVals, int *stack,
3328 sym_link * ftype, int lvl)
3336 if (argVals==NULL) {
3338 argVals = FUNC_ARGS (ftype);
3341 /* if this is a param node then do the left & right */
3342 if (parms->type == EX_OP && parms->opval.op == PARAM)
3344 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3345 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3349 /* get the parameter value */
3350 if (parms->type == EX_OPERAND)
3351 pval = parms->opval.oprnd;
3354 /* maybe this else should go away ?? */
3355 /* hack don't like this but too lazy to think of
3357 if (IS_ADDRESS_OF_OP (parms))
3358 parms->left->lvalue = 1;
3360 if (IS_CAST_OP (parms) &&
3361 IS_PTR (parms->ftype) &&
3362 IS_ADDRESS_OF_OP (parms->right))
3363 parms->right->left->lvalue = 1;
3365 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3368 /* if register parm then make it a send */
3369 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3370 IFFUNC_ISBUILTIN(ftype))
3372 ic = newiCode (SEND, pval, NULL);
3373 ic->argreg = SPEC_ARGREG(parms->etype);
3374 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3379 /* now decide whether to push or assign */
3380 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3384 operand *top = operandFromSymbol (argVals->sym);
3385 /* clear useDef and other bitVectors */
3386 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3387 geniCodeAssign (top, pval, 1, 0);
3391 sym_link *p = operandType (pval);
3393 ic = newiCode (IPUSH, pval, NULL);
3395 /* update the stack adjustment */
3396 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3401 argVals=argVals->next;
3405 /*-----------------------------------------------------------------*/
3406 /* geniCodeCall - generates temp code for calling */
3407 /*-----------------------------------------------------------------*/
3409 geniCodeCall (operand * left, ast * parms,int lvl)
3413 sym_link *type, *etype;
3417 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3418 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3419 werror (E_FUNCTION_EXPECTED);
3420 return operandFromValue(valueFromLit(0));
3423 /* take care of parameters with side-effecting
3424 function calls in them, this is required to take care
3425 of overlaying function parameters */
3426 geniCodeSEParms (parms,lvl);
3428 ftype = operandType (left);
3429 if (IS_FUNCPTR (ftype))
3430 ftype = ftype->next;
3432 /* first the parameters */
3433 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3435 /* now call : if symbol then pcall */
3436 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3437 ic = newiCode (PCALL, left, NULL);
3439 ic = newiCode (CALL, left, NULL);
3442 type = copyLinkChain (ftype->next);
3443 etype = getSpec (type);
3444 SPEC_EXTR (etype) = 0;
3445 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3449 /* stack adjustment after call */
3450 ic->parmBytes = stack;
3455 /*-----------------------------------------------------------------*/
3456 /* geniCodeReceive - generate intermediate code for "receive" */
3457 /*-----------------------------------------------------------------*/
3459 geniCodeReceive (value * args, operand * func)
3461 unsigned char paramByteCounter = 0;
3463 /* for all arguments that are passed in registers */
3466 if (IS_REGPARM (args->etype))
3468 operand *opr = operandFromValue (args);
3470 symbol *sym = OP_SYMBOL (opr);
3473 /* we will use it after all optimizations
3474 and before liveRange calculation */
3475 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3478 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3479 options.stackAuto == 0 &&
3480 (!(options.model == MODEL_FLAT24)) )
3485 opl = newiTempOperand (args->type, 0);
3487 sym->reqv->key = sym->key;
3488 OP_SYMBOL (sym->reqv)->key = sym->key;
3489 OP_SYMBOL (sym->reqv)->isreqv = 1;
3490 OP_SYMBOL (sym->reqv)->islocal = 0;
3491 SPIL_LOC (sym->reqv) = sym;
3495 ic = newiCode (RECEIVE, func, NULL);
3496 ic->argreg = SPEC_ARGREG(args->etype);
3497 if (ic->argreg == 1) {
3498 currFunc->recvSize = getSize (sym->type);
3500 IC_RESULT (ic) = opr;
3502 /* misuse of parmBytes (normally used for functions)
3503 * to save estimated stack position of this argument.
3504 * Normally this should be zero for RECEIVE iCodes.
3505 * No idea if this causes side effects on other ports. - dw
3507 ic->parmBytes = paramByteCounter;
3509 /* what stack position do we have? */
3510 paramByteCounter += getSize (sym->type);
3519 /*-----------------------------------------------------------------*/
3520 /* geniCodeFunctionBody - create the function body */
3521 /*-----------------------------------------------------------------*/
3523 geniCodeFunctionBody (ast * tree,int lvl)
3530 /* reset the auto generation */
3536 func = ast2iCode (tree->left,lvl+1);
3537 fetype = getSpec (operandType (func));
3539 savelineno = lineno;
3540 lineno = OP_SYMBOL (func)->lineDef;
3541 /* create an entry label */
3542 geniCodeLabel (entryLabel);
3543 lineno = savelineno;
3545 /* create a proc icode */
3546 ic = newiCode (FUNCTION, func, NULL);
3547 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3552 /* for all parameters that are passed
3553 on registers add a "receive" */
3554 geniCodeReceive (tree->values.args, func);
3556 /* generate code for the body */
3557 ast2iCode (tree->right,lvl+1);
3559 /* create a label for return */
3560 geniCodeLabel (returnLabel);
3562 /* now generate the end proc */
3563 ic = newiCode (ENDFUNCTION, func, NULL);
3569 /*-----------------------------------------------------------------*/
3570 /* geniCodeReturn - gen icode for 'return' statement */
3571 /*-----------------------------------------------------------------*/
3573 geniCodeReturn (operand * op)
3577 /* if the operand is present force an rvalue */
3579 op = geniCodeRValue (op, FALSE);
3581 ic = newiCode (RETURN, op, NULL);
3585 /*-----------------------------------------------------------------*/
3586 /* geniCodeIfx - generates code for extended if statement */
3587 /*-----------------------------------------------------------------*/
3589 geniCodeIfx (ast * tree,int lvl)
3592 operand *condition = ast2iCode (tree->left,lvl+1);
3595 /* if condition is null then exit */
3599 condition = geniCodeRValue (condition, FALSE);
3601 cetype = getSpec (operandType (condition));
3602 /* if the condition is a literal */
3603 if (IS_LITERAL (cetype))
3605 if (floatFromVal (condition->operand.valOperand))
3607 if (tree->trueLabel)
3608 geniCodeGoto (tree->trueLabel);
3614 if (tree->falseLabel)
3615 geniCodeGoto (tree->falseLabel);
3620 if (tree->trueLabel)
3622 ic = newiCodeCondition (condition,
3627 if (tree->falseLabel)
3628 geniCodeGoto (tree->falseLabel);
3632 ic = newiCodeCondition (condition,
3639 ast2iCode (tree->right,lvl+1);
3642 /*-----------------------------------------------------------------*/
3643 /* geniCodeJumpTable - tries to create a jump table for switch */
3644 /*-----------------------------------------------------------------*/
3646 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3648 int min, max, cnt = 1;
3655 int needRangeCheck = !optimize.noJTabBoundary
3656 || tree->values.switchVals.swDefault;
3657 sym_link *cetype = getSpec (operandType (cond));
3658 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3659 int sizeofMatchJump, sizeofJumpTable;
3662 if (!tree || !caseVals)
3665 /* the criteria for creating a jump table is */
3666 /* all integer numbers between the maximum & minimum must */
3667 /* be present , the maximum value should not exceed 255 */
3668 /* If not all integer numbers are present the algorithm */
3669 /* inserts jumps to the default label for the missing numbers */
3670 /* and decides later whether it is worth it */
3671 min = (int) ulFromVal (vch = caseVals);
3678 max = (int) ulFromVal (vch);
3680 /* Exit if the range is too large to handle with a jump table. */
3681 if (1 + max - min > port->jumptableCost.maxCount)
3684 switch (getSize (operandType (cond)))
3686 case 1: sizeIndex = 0; break;
3687 case 2: sizeIndex = 1; break;
3688 case 4: sizeIndex = 2; break;
3692 /* Compute the size cost of the range check and subtraction. */
3694 sizeofZeroMinCost = 0;
3698 if (!(min==0 && IS_UNSIGNED (cetype)))
3699 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3700 if (!IS_UNSIGNED (cetype))
3701 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3702 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3705 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3707 /* If the size cost of handling a non-zero minimum exceeds the */
3708 /* cost of extending the range down to zero, then it might be */
3709 /* better to extend the range to zero. */
3710 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3711 >= (min * port->jumptableCost.sizeofElement))
3713 /* Only extend the jump table if it would still be manageable. */
3714 if (1 + max <= port->jumptableCost.maxCount)
3717 if (IS_UNSIGNED (cetype))
3720 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3724 /* Compute the total size cost of a jump table. */
3725 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3726 + port->jumptableCost.sizeofDispatch
3727 + sizeofMinCost + sizeofMaxCost;
3729 /* Compute the total size cost of a match & jump sequence */
3730 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3732 /* If the size cost of the jump table is uneconomical then exit */
3733 if (sizeofMatchJump < sizeofJumpTable)
3736 /* The jump table is preferable. */
3738 /* First, a label for the default or missing cases. */
3739 if (tree->values.switchVals.swDefault)
3741 SNPRINTF (buffer, sizeof(buffer),
3743 tree->values.switchVals.swNum);
3747 SNPRINTF (buffer, sizeof(buffer),
3749 tree->values.switchVals.swNum);
3751 falseLabel = newiTempLabel (buffer);
3753 /* Build the list of labels for the jump table. */
3755 t = (int) ulFromVal (vch);
3756 for (i=min; i<=max; i++)
3760 /* Explicit case: make a new label for it. */
3761 SNPRINTF (buffer, sizeof(buffer),
3763 tree->values.switchVals.swNum,
3765 addSet (&labels, newiTempLabel (buffer));
3768 t = (int) ulFromVal (vch);
3772 /* Implicit case: use the default label. */
3773 addSet (&labels, falseLabel);
3777 /* first we rule out the boundary conditions */
3778 /* if only optimization says so */
3781 sym_link *cetype = getSpec (operandType (cond));
3782 /* no need to check the lower bound if
3783 the condition is unsigned & minimum value is zero */
3784 if (!(min == 0 && IS_UNSIGNED (cetype)))
3786 boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL);
3787 ic = newiCodeCondition (boundary, falseLabel, NULL);
3791 /* now for upper bounds */
3792 boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL);
3793 ic = newiCodeCondition (boundary, falseLabel, NULL);
3797 /* if the min is not zero then we no make it zero */
3800 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3801 if (!IS_LITERAL(getSpec(operandType(cond))))
3802 setOperandType (cond, UCHARTYPE);
3805 /* now create the jumptable */
3806 ic = newiCode (JUMPTABLE, NULL, NULL);
3807 IC_JTCOND (ic) = cond;
3808 IC_JTLABELS (ic) = labels;
3813 /*-----------------------------------------------------------------*/
3814 /* geniCodeSwitch - changes a switch to a if statement */
3815 /*-----------------------------------------------------------------*/
3817 geniCodeSwitch (ast * tree,int lvl)
3820 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3821 value *caseVals = tree->values.switchVals.swVals;
3822 symbol *trueLabel, *falseLabel;
3824 /* If the condition is a literal, then just jump to the */
3825 /* appropriate case label. */
3826 if (IS_LITERAL(getSpec(operandType(cond))))
3828 int switchVal, caseVal;
3830 switchVal = (int) ulFromVal (cond->operand.valOperand);
3833 caseVal = (int) ulFromVal (caseVals);
3834 if (caseVal == switchVal)
3836 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3837 tree->values.switchVals.swNum, caseVal);
3838 trueLabel = newiTempLabel (buffer);
3839 geniCodeGoto (trueLabel);
3842 caseVals = caseVals->next;
3844 goto defaultOrBreak;
3847 /* If cond is volatile, it might change while we are trying to */
3848 /* find the matching case. To avoid this possibility, make a */
3849 /* non-volatile copy to use instead. */
3850 if (IS_OP_VOLATILE (cond))
3855 newcond = newiTempOperand (operandType (cond), TRUE);
3856 newcond->isvolatile = 0;
3857 ic = newiCode ('=', NULL, cond);
3858 IC_RESULT (ic) = newcond;
3863 /* if we can make this a jump table */
3864 if (geniCodeJumpTable (cond, caseVals, tree))
3865 goto jumpTable; /* no need for the comparison */
3867 /* for the cases defined do */
3871 operand *compare = geniCodeLogic (cond,
3872 operandFromValue (caseVals),
3875 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3876 tree->values.switchVals.swNum,
3877 (int) ulFromVal (caseVals));
3878 trueLabel = newiTempLabel (buffer);
3880 ic = newiCodeCondition (compare, trueLabel, NULL);
3882 caseVals = caseVals->next;
3887 /* if default is present then goto break else break */
3888 if (tree->values.switchVals.swDefault)
3890 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3894 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3897 falseLabel = newiTempLabel (buffer);
3898 geniCodeGoto (falseLabel);
3901 ast2iCode (tree->right,lvl+1);
3904 /*-----------------------------------------------------------------*/
3905 /* geniCodeInline - intermediate code for inline assembler */
3906 /*-----------------------------------------------------------------*/
3908 geniCodeInline (ast * tree)
3912 ic = newiCode (INLINEASM, NULL, NULL);
3913 IC_INLINE (ic) = tree->values.inlineasm;
3917 /*-----------------------------------------------------------------*/
3918 /* geniCodeArrayInit - intermediate code for array initializer */
3919 /*-----------------------------------------------------------------*/
3921 geniCodeArrayInit (ast * tree, operand *array)
3925 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3926 ic = newiCode (ARRAYINIT, array, NULL);
3927 IC_ARRAYILIST (ic) = tree->values.constlist;
3929 operand *left=newOperand(), *right=newOperand();
3930 left->type=right->type=SYMBOL;
3931 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3932 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3933 ic = newiCode (ARRAYINIT, left, right);
3938 /*-----------------------------------------------------------------*/
3939 /* geniCodeCritical - intermediate code for a critical statement */
3940 /*-----------------------------------------------------------------*/
3942 geniCodeCritical (ast *tree, int lvl)
3948 if (!options.stackAuto)
3950 type = newLink(SPECIFIER);
3951 SPEC_VOLATILE(type) = 1;
3952 SPEC_NOUN(type) = V_BIT;
3953 SPEC_SCLS(type) = S_BIT;
3954 SPEC_BLEN(type) = 1;
3955 SPEC_BSTR(type) = 0;
3956 op = newiTempOperand(type, 1);
3959 /* If op is NULL, the original interrupt state will saved on */
3960 /* the stack. Otherwise, it will be saved in op. */
3962 /* Generate a save of the current interrupt state & disable */
3963 ic = newiCode (CRITICAL, NULL, NULL);
3964 IC_RESULT (ic) = op;
3967 /* Generate the critical code sequence */
3968 if (tree->left && tree->left->type == EX_VALUE)
3969 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3971 ast2iCode (tree->left,lvl+1);
3973 /* Generate a restore of the original interrupt state */
3974 ic = newiCode (ENDCRITICAL, NULL, op);
3978 /*-----------------------------------------------------------------*/
3979 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3980 /* particular case. Ie : assigning or dereferencing array or ptr */
3981 /*-----------------------------------------------------------------*/
3982 set * lvaluereqSet = NULL;
3983 typedef struct lvalItem
3990 /*-----------------------------------------------------------------*/
3991 /* addLvaluereq - add a flag for lvalreq for current ast level */
3992 /*-----------------------------------------------------------------*/
3993 void addLvaluereq(int lvl)
3995 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3998 addSetHead(&lvaluereqSet,lpItem);
4001 /*-----------------------------------------------------------------*/
4002 /* delLvaluereq - del a flag for lvalreq for current ast level */
4003 /*-----------------------------------------------------------------*/
4007 lpItem = getSet(&lvaluereqSet);
4008 if(lpItem) Safe_free(lpItem);
4010 /*-----------------------------------------------------------------*/
4011 /* clearLvaluereq - clear lvalreq flag */
4012 /*-----------------------------------------------------------------*/
4013 void clearLvaluereq()
4016 lpItem = peekSet(lvaluereqSet);
4017 if(lpItem) lpItem->req = 0;
4019 /*-----------------------------------------------------------------*/
4020 /* getLvaluereq - get the last lvalreq level */
4021 /*-----------------------------------------------------------------*/
4022 int getLvaluereqLvl()
4025 lpItem = peekSet(lvaluereqSet);
4026 if(lpItem) return lpItem->lvl;
4029 /*-----------------------------------------------------------------*/
4030 /* isLvaluereq - is lvalreq valid for this level ? */
4031 /*-----------------------------------------------------------------*/
4032 int isLvaluereq(int lvl)
4035 lpItem = peekSet(lvaluereqSet);
4036 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4040 /*-----------------------------------------------------------------*/
4041 /* ast2iCode - creates an icodeList from an ast */
4042 /*-----------------------------------------------------------------*/
4044 ast2iCode (ast * tree,int lvl)
4046 operand *left = NULL;
4047 operand *right = NULL;
4051 /* set the global variables for filename & line number */
4053 filename = tree->filename;
4055 lineno = tree->lineno;
4057 block = tree->block;
4059 scopeLevel = tree->level;
4061 seqPoint = tree->seqPoint;
4063 if (tree->type == EX_VALUE)
4064 return operandFromValue (tree->opval.val);
4066 if (tree->type == EX_LINK)
4067 return operandFromLink (tree->opval.lnk);
4069 /* if we find a nullop */
4070 if (tree->type == EX_OP &&
4071 (tree->opval.op == NULLOP ||
4072 tree->opval.op == BLOCK))
4074 if (tree->left && tree->left->type == EX_VALUE)
4075 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4077 ast2iCode (tree->left,lvl+1);
4078 if (tree->right && tree->right->type == EX_VALUE)
4079 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4081 ast2iCode (tree->right,lvl+1);
4085 /* special cases for not evaluating */
4086 if (tree->opval.op != ':' &&
4087 tree->opval.op != '?' &&
4088 tree->opval.op != CALL &&
4089 tree->opval.op != IFX &&
4090 tree->opval.op != AND_OP &&
4091 tree->opval.op != OR_OP &&
4092 tree->opval.op != LABEL &&
4093 tree->opval.op != GOTO &&
4094 tree->opval.op != SWITCH &&
4095 tree->opval.op != FUNCTION &&
4096 tree->opval.op != INLINEASM &&
4097 tree->opval.op != CRITICAL)
4100 if (IS_ASSIGN_OP (tree->opval.op) ||
4101 IS_DEREF_OP (tree) ||
4102 (tree->opval.op == '&' && !tree->right) ||
4103 tree->opval.op == PTR_OP)
4106 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4107 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4110 left = operandFromAst (tree->left,lvl);
4112 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4113 left = geniCodeRValue (left, TRUE);
4117 left = operandFromAst (tree->left,lvl);
4119 if (tree->opval.op == INC_OP ||
4120 tree->opval.op == DEC_OP)
4123 right = operandFromAst (tree->right,lvl);
4128 right = operandFromAst (tree->right,lvl);
4132 /* now depending on the type of operand */
4133 /* this will be a biggy */
4134 switch (tree->opval.op)
4137 case '[': /* array operation */
4139 //sym_link *ltype = operandType (left);
4140 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4141 left = geniCodeRValue (left, FALSE);
4142 right = geniCodeRValue (right, TRUE);
4145 return geniCodeArray (left, right,lvl);
4147 case '.': /* structure dereference */
4148 if (IS_PTR (operandType (left)))
4149 left = geniCodeRValue (left, TRUE);
4151 left = geniCodeRValue (left, FALSE);
4153 return geniCodeStruct (left, right, tree->lvalue);
4155 case PTR_OP: /* structure pointer dereference */
4158 pType = operandType (left);
4159 left = geniCodeRValue (left, TRUE);
4161 setOClass (pType, getSpec (operandType (left)));
4164 return geniCodeStruct (left, right, tree->lvalue);
4166 case INC_OP: /* increment operator */
4168 return geniCodePostInc (left);
4170 return geniCodePreInc (right, tree->lvalue);
4172 case DEC_OP: /* decrement operator */
4174 return geniCodePostDec (left);
4176 return geniCodePreDec (right, tree->lvalue);
4178 case '&': /* bitwise and or address of operator */
4180 { /* this is a bitwise operator */
4181 left = geniCodeRValue (left, FALSE);
4182 right = geniCodeRValue (right, FALSE);
4183 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4186 return geniCodeAddressOf (left);
4188 case '|': /* bitwise or & xor */
4190 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4191 geniCodeRValue (right, FALSE),
4196 return geniCodeDivision (geniCodeRValue (left, FALSE),
4197 geniCodeRValue (right, FALSE),
4198 getResultTypeFromType (tree->ftype));
4201 return geniCodeModulus (geniCodeRValue (left, FALSE),
4202 geniCodeRValue (right, FALSE),
4203 getResultTypeFromType (tree->ftype));
4206 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4207 geniCodeRValue (right, FALSE),
4208 getResultTypeFromType (tree->ftype));
4210 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4214 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4215 geniCodeRValue (right, FALSE),
4216 getResultTypeFromType (tree->ftype));
4218 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4222 return geniCodeAdd (geniCodeRValue (left, FALSE),
4223 geniCodeRValue (right, FALSE),
4224 getResultTypeFromType (tree->ftype),
4227 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4230 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4231 geniCodeRValue (right, FALSE),
4232 getResultTypeFromType (tree->ftype));
4235 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4236 geniCodeRValue (right, FALSE));
4238 #if 0 // this indeed needs a second thought
4242 // let's keep this simple: get the rvalue we need
4243 op=geniCodeRValue (right, FALSE);
4244 // now cast it to whatever we want
4245 op=geniCodeCast (operandType(left), op, FALSE);
4246 // if this is going to be used as an lvalue, make it so
4252 #else // bug #604575, is it a bug ????
4253 return geniCodeCast (operandType (left),
4254 geniCodeRValue (right, FALSE), FALSE);
4261 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4266 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4267 if (!IS_BIT (operandType (op)))
4268 setOperandType (op, UCHARTYPE);
4273 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4274 geniCodeRValue (right, FALSE),
4276 if (!IS_BIT (operandType (op)))
4277 setOperandType (op, UCHARTYPE);
4282 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4283 geniCodeRValue (right, FALSE),
4285 setOperandType (op, UCHARTYPE);
4290 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4291 geniCodeRValue (right, FALSE),
4293 setOperandType (op, UINTTYPE);
4298 return geniCodeLogicAndOr (tree, lvl);
4305 /* different compilers (even different gccs) evaluate
4306 the two calls in a different order. to get the same
4307 result on all machines we have to specify a clear sequence.
4308 return geniCodeLogic (geniCodeRValue (left, FALSE),
4309 geniCodeRValue (right, FALSE),
4313 operand *leftOp, *rightOp;
4315 leftOp = geniCodeRValue (left , FALSE);
4316 rightOp = geniCodeRValue (right, FALSE);
4318 return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree);
4321 return geniCodeConditional (tree,lvl);
4324 return operandFromLit (getSize (tree->right->ftype));
4328 sym_link *rtype = operandType (right);
4329 sym_link *ltype = operandType (left);
4330 if (IS_PTR (rtype) && IS_ITEMP (right)
4331 && right->isaddr && compareType (rtype->next, ltype) == 1)
4332 right = geniCodeRValue (right, TRUE);
4334 right = geniCodeRValue (right, FALSE);
4336 return geniCodeAssign (left, right, 0, 1);
4340 geniCodeAssign (left,
4341 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4343 geniCodeRValue (right, FALSE),
4344 getResultTypeFromType (tree->ftype)),
4349 geniCodeAssign (left,
4350 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4352 geniCodeRValue (right, FALSE),
4353 getResultTypeFromType (tree->ftype)),
4357 geniCodeAssign (left,
4358 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4360 geniCodeRValue (right, FALSE),
4361 getResultTypeFromType (tree->ftype)),
4365 sym_link *rtype = operandType (right);
4366 sym_link *ltype = operandType (left);
4367 if (IS_PTR (rtype) && IS_ITEMP (right)
4368 && right->isaddr && compareType (rtype->next, ltype) == 1)
4369 right = geniCodeRValue (right, TRUE);
4371 right = geniCodeRValue (right, FALSE);
4374 return geniCodeAssign (left,
4375 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4378 getResultTypeFromType (tree->ftype),
4384 sym_link *rtype = operandType (right);
4385 sym_link *ltype = operandType (left);
4386 if (IS_PTR (rtype) && IS_ITEMP (right)
4387 && right->isaddr && compareType (rtype->next, ltype) == 1)
4389 right = geniCodeRValue (right, TRUE);
4393 right = geniCodeRValue (right, FALSE);
4396 geniCodeAssign (left,
4397 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4400 getResultTypeFromType (tree->ftype)),
4405 geniCodeAssign (left,
4406 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4408 geniCodeRValue (right, FALSE),
4409 getResultTypeFromType (tree->ftype)),
4413 geniCodeAssign (left,
4414 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4416 geniCodeRValue (right, FALSE)), 0, 1);
4419 geniCodeAssign (left,
4420 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4422 geniCodeRValue (right, FALSE),
4424 operandType (left)), 0, 1);
4427 geniCodeAssign (left,
4428 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4430 geniCodeRValue (right, FALSE),
4432 operandType (left)), 0, 1);
4435 geniCodeAssign (left,
4436 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4438 geniCodeRValue (right, FALSE),
4440 operandType (left)), 0, 1);
4442 return geniCodeRValue (right, FALSE);
4445 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4448 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4449 return ast2iCode (tree->right,lvl+1);
4452 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4453 return ast2iCode (tree->right,lvl+1);
4456 geniCodeFunctionBody (tree,lvl);
4460 geniCodeReturn (right);
4464 geniCodeIfx (tree,lvl);
4468 geniCodeSwitch (tree,lvl);
4472 geniCodeInline (tree);
4476 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4480 geniCodeCritical (tree, lvl);
4486 /*-----------------------------------------------------------------*/
4487 /* reverseICChain - gets from the list and creates a linkedlist */
4488 /*-----------------------------------------------------------------*/
4495 while ((loop = getSet (&iCodeChain)))
4507 /*-----------------------------------------------------------------*/
4508 /* iCodeFromAst - given an ast will convert it to iCode */
4509 /*-----------------------------------------------------------------*/
4511 iCodeFromAst (ast * tree)
4513 returnLabel = newiTempLabel ("_return");
4514 entryLabel = newiTempLabel ("_entry");
4516 return reverseiCChain ();
4519 static const char *opTypeToStr(OPTYPE op)
4523 case SYMBOL: return "symbol";
4524 case VALUE: return "value";
4525 case TYPE: return "type";
4527 return "undefined type";
4531 operand *validateOpType(operand *op,
4538 if (op && op->type == type)
4543 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4544 " expected %s, got %s\n",
4545 macro, args, file, line,
4546 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4548 return op; // never reached, makes compiler happy.