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;
564 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->filename = ic->filename;
705 nic->lineno = ic->lineno;
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 */
805 return op->operand.valOperand->type;
808 return op->operand.symOperand->type;
811 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 static DECLARATOR_TYPE
1951 getPtrType(sym_link *type)
1953 //for Z80 anything goes
1954 if (TARGET_Z80_LIKE)
1957 //for HC08 only zeropage ptr is different
1960 if (IS_DATA_PTR (type))
1966 if (IS_DATA_PTR (type) && TARGET_MCS51_LIKE)
1969 return DCL_TYPE (type);
1970 else if (IS_FUNC (type))
1972 else if (IS_ARRAY (type))
1973 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
1977 /*-----------------------------------------------------------------*/
1978 /* geniCodeCast - changes the value from one type to another */
1979 /*-----------------------------------------------------------------*/
1981 geniCodeCast (sym_link * type, operand * op, bool implicit)
1985 sym_link *opetype = getSpec (optype = operandType (op));
1989 /* one of them has size zero then error */
1990 if (IS_VOID (optype))
1992 werror (E_CAST_ZERO);
1996 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1998 geniCodeArray2Ptr (op);
2002 /* if the operand is already the desired type then do nothing */
2003 if (compareType (type, optype) == 1)
2006 /* if this is a literal then just change the type & return */
2007 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
2009 return operandFromValue (valCastLiteral (type, operandLitValue (op)));
2012 /* if casting to/from pointers, do some checking */
2013 if (IS_PTR(type)) { // to a pointer
2014 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
2015 if (IS_INTEGRAL(optype)) {
2016 // maybe this is NULL, than it's ok.
2017 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
2018 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
2019 // no way to set the storage
2020 if (IS_LITERAL(optype)) {
2021 werror(E_LITERAL_GENERIC);
2024 werror(E_NONPTR2_GENPTR);
2027 } else if (implicit) {
2028 werror(W_INTEGRAL2PTR_NOCAST);
2033 // shouldn't do that with float, array or structure unless to void
2034 if (!IS_VOID(getSpec(type)) &&
2035 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2036 werror(E_INCOMPAT_TYPES);
2040 } else { // from a pointer to a pointer
2041 if (IS_GENPTR(type) && IS_VOID(type->next))
2042 { // cast to void* is always allowed
2044 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2045 { // cast from void* is always allowed
2047 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2048 // if not a pointer to a function
2049 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2050 if (implicit) { // if not to generic, they have to match
2051 if (!IS_GENPTR(type) &&
2052 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2053 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2057 werror(E_INCOMPAT_PTYPES);
2064 } else { // to a non pointer
2065 if (IS_PTR(optype)) { // from a pointer
2066 if (implicit) { // sneaky
2067 if (IS_INTEGRAL(type)) {
2068 werror(W_PTR2INTEGRAL_NOCAST);
2070 } else { // shouldn't do that with float, array or structure
2071 werror(E_INCOMPAT_TYPES);
2078 printFromToType (optype, type);
2081 /* if they are the same size create an assignment */
2083 /* This seems very dangerous to me, since there are several */
2084 /* optimizations (for example, gcse) that don't notice the */
2085 /* cast hidden in this assignment and may simplify an */
2086 /* iCode to use the original (uncasted) operand. */
2087 /* Unfortunately, other things break when this cast is */
2088 /* made explicit. Need to fix this someday. */
2089 /* -- EEP, 2004/01/21 */
2090 if (getSize (type) == getSize (optype) &&
2091 !IS_BITFIELD (type) &&
2093 !IS_FLOAT (optype) &&
2095 !IS_FIXED (optype) &&
2096 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2097 (IS_DECL (type) && IS_DECL (optype) && getPtrType (type) == getPtrType (optype))))
2099 ic = newiCode ('=', NULL, op);
2100 IC_RESULT (ic) = newiTempOperand (type, 0);
2101 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2102 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2103 IC_RESULT (ic)->isaddr = 0;
2107 ic = newiCode (CAST, operandFromLink (type),
2108 geniCodeRValue (op, FALSE));
2110 IC_RESULT (ic) = newiTempOperand (type, 0);
2113 /* preserve the storage class & output class */
2114 /* of the original variable */
2115 restype = getSpec (operandType (IC_RESULT (ic)));
2116 if (!IS_LITERAL(opetype) &&
2119 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2120 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2123 return IC_RESULT (ic);
2126 /*-----------------------------------------------------------------*/
2127 /* geniCodeLabel - will create a Label */
2128 /*-----------------------------------------------------------------*/
2130 geniCodeLabel (symbol * label)
2134 ic = newiCodeLabelGoto (LABEL, label);
2138 /*-----------------------------------------------------------------*/
2139 /* geniCodeGoto - will create a Goto */
2140 /*-----------------------------------------------------------------*/
2142 geniCodeGoto (symbol * label)
2146 ic = newiCodeLabelGoto (GOTO, label);
2150 /*-----------------------------------------------------------------*/
2151 /* geniCodeMultiply - gen intermediate code for multiplication */
2152 /*-----------------------------------------------------------------*/
2154 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2161 /* if they are both literal then we know the result */
2162 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2163 return operandFromValue (valMult (left->operand.valOperand,
2164 right->operand.valOperand));
2166 if (IS_LITERAL(retype)) {
2167 p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand));
2170 resType = usualBinaryConversions (&left, &right, resultType, '*');
2172 rtype = operandType (right);
2173 retype = getSpec (rtype);
2174 ltype = operandType (left);
2175 letype = getSpec (ltype);
2178 /* if the right is a literal & power of 2 */
2179 /* then make it a left shift */
2180 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2181 efficient in most cases than 2 bytes result = 2 bytes << literal
2182 if port has 1 byte muldiv */
2183 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2184 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2185 && (port->support.muldiv == 1))
2186 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2187 && strcmp (port->target, "pic14") != 0)
2189 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2191 /* LEFT_OP need same size for left and result, */
2192 left = geniCodeCast (resType, left, TRUE);
2193 ltype = operandType (left);
2195 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2199 /* if the size left or right > 1 then support routine */
2200 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2202 if (IS_LITERAL (retype))
2203 ic = newiCode ('*', right, left); /* multiplication by support routine with one literal */
2205 ic = newiCode ('*', left, right); /* multiplication by support routine */
2210 ic = newiCode ('*', left, right); /* normal multiplication */
2213 IC_RESULT (ic) = newiTempOperand (resType, 1);
2216 return IC_RESULT (ic);
2219 /*-----------------------------------------------------------------*/
2220 /* geniCodeDivision - gen intermediate code for division */
2221 /*-----------------------------------------------------------------*/
2223 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2228 sym_link *rtype = operandType (right);
2229 sym_link *retype = getSpec (rtype);
2230 sym_link *ltype = operandType (left);
2231 sym_link *letype = getSpec (ltype);
2233 resType = usualBinaryConversions (&left, &right, resultType, '/');
2235 /* if the right is a literal & power of 2
2236 and left is unsigned then make it a
2238 if (IS_LITERAL (retype) &&
2239 !IS_FLOAT (letype) &&
2240 !IS_FIXED (letype) &&
2241 IS_UNSIGNED(letype) &&
2242 ((p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand))) > 0)) {
2243 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2247 ic = newiCode ('/', left, right); /* normal division */
2248 /* if the size left or right > 1 then support routine */
2249 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2252 IC_RESULT (ic) = newiTempOperand (resType, 0);
2255 return IC_RESULT (ic);
2257 /*-----------------------------------------------------------------*/
2258 /* geniCodeModulus - gen intermediate code for modulus */
2259 /*-----------------------------------------------------------------*/
2261 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2267 /* if they are both literal then we know the result */
2268 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2269 return operandFromValue (valMod (left->operand.valOperand,
2270 right->operand.valOperand));
2272 resType = usualBinaryConversions (&left, &right, resultType, '%');
2274 /* now they are the same size */
2275 ic = newiCode ('%', left, right);
2277 /* if the size left or right > 1 then support routine */
2278 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2280 IC_RESULT (ic) = newiTempOperand (resType, 0);
2283 return IC_RESULT (ic);
2286 /*-----------------------------------------------------------------*/
2287 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2288 /*-----------------------------------------------------------------*/
2290 geniCodePtrPtrSubtract (operand * left, operand * right)
2296 /* if they are both literals then */
2297 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2299 result = operandFromValue (valMinus (left->operand.valOperand,
2300 right->operand.valOperand));
2304 ic = newiCode ('-', left, right);
2306 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2310 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2314 // should we really do this? is this ANSI?
2315 return geniCodeDivision (result,
2316 operandFromLit (getSize (ltype->next)),
2320 /*-----------------------------------------------------------------*/
2321 /* geniCodeSubtract - generates code for subtraction */
2322 /*-----------------------------------------------------------------*/
2324 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2331 /* if they both pointers then */
2332 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2333 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2334 return geniCodePtrPtrSubtract (left, right);
2336 /* if they are both literal then we know the result */
2337 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2338 && left->isLiteral && right->isLiteral)
2339 return operandFromValue (valMinus (left->operand.valOperand,
2340 right->operand.valOperand));
2342 /* if left is an array or pointer */
2343 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2345 isarray = left->isaddr;
2346 right = geniCodeMultiply (right,
2347 operandFromLit (getSize (ltype->next)),
2348 (getArraySizePtr(left) >= INTSIZE) ?
2351 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2354 { /* make them the same size */
2355 resType = usualBinaryConversions (&left, &right, resultType, '-');
2358 ic = newiCode ('-', left, right);
2360 IC_RESULT (ic) = newiTempOperand (resType, 1);
2361 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2363 /* if left or right is a float */
2364 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2365 || IS_FIXED (ltype) || IS_FIXED (rtype))
2369 return IC_RESULT (ic);
2372 /*-----------------------------------------------------------------*/
2373 /* geniCodeAdd - generates iCode for addition */
2374 /*-----------------------------------------------------------------*/
2376 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2385 /* if the right side is LITERAL zero */
2386 /* return the left side */
2387 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2390 /* if left is literal zero return right */
2391 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2394 /* if left is a pointer then size */
2395 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2397 isarray = left->isaddr;
2398 // there is no need to multiply with 1
2399 if (getSize (ltype->next) != 1)
2401 size = operandFromLit (getSize (ltype->next));
2402 SPEC_USIGN (getSpec (operandType (size))) = 1;
2403 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2404 right = geniCodeMultiply (right, size, resultType);
2405 /* Even if right is a 'unsigned char',
2406 the result will be a 'signed int' due to the promotion rules.
2407 It doesn't make sense when accessing arrays, so let's fix it here: */
2409 SPEC_USIGN (getSpec (operandType (right))) = 1;
2411 resType = copyLinkChain (ltype);
2414 { // make them the same size
2415 resType = usualBinaryConversions (&left, &right, resultType, '+');
2418 /* if they are both literals then we know */
2419 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2420 && left->isLiteral && right->isLiteral)
2421 return operandFromValue (valPlus (valFromType (ltype),
2422 valFromType (rtype)));
2424 ic = newiCode ('+', left, right);
2426 IC_RESULT (ic) = newiTempOperand (resType, 1);
2427 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2429 /* if left or right is a float then support
2431 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2432 || IS_FIXED (ltype) || IS_FIXED (rtype))
2437 return IC_RESULT (ic);
2441 /*-----------------------------------------------------------------*/
2442 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2443 /*-----------------------------------------------------------------*/
2445 aggrToPtr (sym_link * type, bool force)
2450 if (IS_PTR (type) && !force)
2453 etype = getSpec (type);
2454 ptype = newLink (DECLARATOR);
2458 /* set the pointer depending on the storage class */
2459 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2463 /*------------------------------------------------------------------*/
2464 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2465 /*------------------------------------------------------------------*/
2467 aggrToPtrDclType (sym_link * type, bool force)
2469 if (IS_PTR (type) && !force)
2470 return DCL_TYPE (type);
2472 /* return the pointer depending on the storage class */
2473 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2476 /*-----------------------------------------------------------------*/
2477 /* geniCodeArray2Ptr - array to pointer */
2478 /*-----------------------------------------------------------------*/
2480 geniCodeArray2Ptr (operand * op)
2482 sym_link *optype = operandType (op);
2483 sym_link *opetype = getSpec (optype);
2485 /* set the pointer depending on the storage class */
2486 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2493 /*-----------------------------------------------------------------*/
2494 /* geniCodeArray - array access */
2495 /*-----------------------------------------------------------------*/
2497 geniCodeArray (operand * left, operand * right, int lvl)
2501 sym_link *ltype = operandType (left);
2503 RESULT_TYPE resultType;
2505 resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
2506 if (DCL_ELEM (ltype))
2508 if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
2509 resultType = RESULT_TYPE_CHAR;
2514 if (IS_PTR (ltype->next) && left->isaddr)
2516 left = geniCodeRValue (left, FALSE);
2519 return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
2522 size = operandFromLit (getSize (ltype->next));
2523 SPEC_USIGN (getSpec (operandType (size))) = 1;
2524 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2525 right = geniCodeMultiply (right, size, resultType);
2526 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2527 It doesn't make sense when accessing arrays, so let's fix it here: */
2529 SPEC_USIGN (getSpec (operandType (right))) = 1;
2530 /* we can check for limits here */
2531 /* already done in SDCCast.c
2532 if (isOperandLiteral (right) &&
2535 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2537 werror (W_IDX_OUT_OF_BOUNDS,
2538 (int) operandLitValue (right) / getSize (ltype->next),
2543 ic = newiCode ('+', left, right);
2545 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2546 !IS_AGGREGATE (ltype->next) &&
2547 !IS_PTR (ltype->next))
2548 ? ltype : ltype->next), 0);
2550 if (!IS_AGGREGATE (ltype->next))
2552 IC_RESULT (ic)->isaddr = 1;
2553 IC_RESULT (ic)->aggr2ptr = 1;
2557 return IC_RESULT (ic);
2560 /*-----------------------------------------------------------------*/
2561 /* geniCodeStruct - generates intermediate code for structures */
2562 /*-----------------------------------------------------------------*/
2564 geniCodeStruct (operand * left, operand * right, bool islval)
2567 sym_link *type = operandType (left);
2568 sym_link *etype = getSpec (type);
2570 symbol *element = getStructElement (SPEC_STRUCT (etype),
2571 right->operand.symOperand);
2573 wassert(IS_SYMOP(right));
2575 /* add the offset */
2576 ic = newiCode ('+', left, operandFromLit (element->offset));
2578 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2580 /* preserve the storage & output class of the struct */
2581 /* as well as the volatile attribute */
2582 retype = getSpec (operandType (IC_RESULT (ic)));
2583 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2584 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2585 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2586 SPEC_CONST (retype) |= SPEC_CONST (etype);
2588 if (IS_PTR (element->type))
2589 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2591 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2594 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2597 /*-----------------------------------------------------------------*/
2598 /* geniCodePostInc - generate int code for Post increment */
2599 /*-----------------------------------------------------------------*/
2601 geniCodePostInc (operand * op)
2605 sym_link *optype = operandType (op);
2607 operand *rv = (IS_ITEMP (op) ?
2608 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2610 sym_link *rvtype = operandType (rv);
2613 /* if this is not an address we have trouble */
2616 werror (E_LVALUE_REQUIRED, "++");
2620 rOp = newiTempOperand (rvtype, 0);
2621 OP_SYMBOL(rOp)->noSpilLoc = 1;
2624 OP_SYMBOL(rv)->noSpilLoc = 1;
2626 geniCodeAssign (rOp, rv, 0, 0);
2628 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2630 werror(W_SIZEOF_VOID);
2631 if (IS_FLOAT (rvtype))
2632 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2633 else if (IS_FIXED16X16 (rvtype))
2634 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2636 ic = newiCode ('+', rv, operandFromLit (size));
2638 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2641 geniCodeAssign (op, result, 0, 0);
2647 /*-----------------------------------------------------------------*/
2648 /* geniCodePreInc - generate code for preIncrement */
2649 /*-----------------------------------------------------------------*/
2651 geniCodePreInc (operand * op, bool lvalue)
2654 sym_link *optype = operandType (op);
2655 operand *rop = (IS_ITEMP (op) ?
2656 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2658 sym_link *roptype = operandType (rop);
2664 werror (E_LVALUE_REQUIRED, "++");
2668 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2670 werror(W_SIZEOF_VOID);
2671 if (IS_FLOAT (roptype))
2672 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2673 else if (IS_FIXED16X16 (roptype))
2674 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2676 ic = newiCode ('+', rop, operandFromLit (size));
2677 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2680 (void) geniCodeAssign (op, result, 0, 0);
2681 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2687 /*-----------------------------------------------------------------*/
2688 /* geniCodePostDec - generates code for Post decrement */
2689 /*-----------------------------------------------------------------*/
2691 geniCodePostDec (operand * op)
2695 sym_link *optype = operandType (op);
2697 operand *rv = (IS_ITEMP (op) ?
2698 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2700 sym_link *rvtype = operandType (rv);
2703 /* if this is not an address we have trouble */
2706 werror (E_LVALUE_REQUIRED, "--");
2710 rOp = newiTempOperand (rvtype, 0);
2711 OP_SYMBOL(rOp)->noSpilLoc = 1;
2714 OP_SYMBOL(rv)->noSpilLoc = 1;
2716 geniCodeAssign (rOp, rv, 0, 0);
2718 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2720 werror(W_SIZEOF_VOID);
2721 if (IS_FLOAT (rvtype))
2722 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2723 else if (IS_FIXED16X16 (rvtype))
2724 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2726 ic = newiCode ('-', rv, operandFromLit (size));
2728 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2731 geniCodeAssign (op, result, 0, 0);
2737 /*-----------------------------------------------------------------*/
2738 /* geniCodePreDec - generate code for pre decrement */
2739 /*-----------------------------------------------------------------*/
2741 geniCodePreDec (operand * op, bool lvalue)
2744 sym_link *optype = operandType (op);
2745 operand *rop = (IS_ITEMP (op) ?
2746 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2748 sym_link *roptype = operandType (rop);
2754 werror (E_LVALUE_REQUIRED, "--");
2758 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2760 werror(W_SIZEOF_VOID);
2761 if (IS_FLOAT (roptype))
2762 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2763 else if (IS_FIXED16X16 (roptype))
2764 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2766 ic = newiCode ('-', rop, operandFromLit (size));
2767 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2770 (void) geniCodeAssign (op, result, 0, 0);
2771 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2778 /*-----------------------------------------------------------------*/
2779 /* geniCodeBitwise - gen int code for bitWise operators */
2780 /*-----------------------------------------------------------------*/
2782 geniCodeBitwise (operand * left, operand * right,
2783 int oper, sym_link * resType)
2787 left = geniCodeCast (resType, left, TRUE);
2788 right = geniCodeCast (resType, right, TRUE);
2790 ic = newiCode (oper, left, right);
2791 IC_RESULT (ic) = newiTempOperand (resType, 0);
2794 return IC_RESULT (ic);
2797 /*-----------------------------------------------------------------*/
2798 /* geniCodeAddressOf - gens icode for '&' address of operator */
2799 /*-----------------------------------------------------------------*/
2801 geniCodeAddressOf (operand * op)
2805 sym_link *optype = operandType (op);
2806 sym_link *opetype = getSpec (optype);
2808 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2810 op = operandFromOperand (op);
2815 /* lvalue check already done in decorateType */
2816 /* this must be a lvalue */
2817 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2818 /* werror (E_LVALUE_REQUIRED,"&"); */
2822 p = newLink (DECLARATOR);
2824 /* set the pointer depending on the storage class */
2825 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2827 p->next = copyLinkChain (optype);
2829 /* if already a temp */
2832 setOperandType (op, p);
2837 /* otherwise make this of the type coming in */
2838 ic = newiCode (ADDRESS_OF, op, NULL);
2839 IC_RESULT (ic) = newiTempOperand (p, 1);
2840 IC_RESULT (ic)->isaddr = 0;
2842 return IC_RESULT (ic);
2845 /*-----------------------------------------------------------------*/
2846 /* setOClass - sets the output class depending on the pointer type */
2847 /*-----------------------------------------------------------------*/
2849 setOClass (sym_link * ptr, sym_link * spec)
2851 switch (DCL_TYPE (ptr))
2854 SPEC_OCLS (spec) = data;
2858 SPEC_OCLS (spec) = generic;
2862 SPEC_OCLS (spec) = xdata;
2866 SPEC_OCLS (spec) = code;
2870 SPEC_OCLS (spec) = idata;
2874 SPEC_OCLS (spec) = xstack;
2878 SPEC_OCLS (spec) = eeprom;
2887 /*-----------------------------------------------------------------*/
2888 /* geniCodeDerefPtr - dereference pointer with '*' */
2889 /*-----------------------------------------------------------------*/
2891 geniCodeDerefPtr (operand * op,int lvl)
2893 sym_link *rtype, *retype;
2894 sym_link *optype = operandType (op);
2896 // if this is an array then array access
2897 if (IS_ARRAY (optype)) {
2898 // don't worry, this will be optimized out later
2899 return geniCodeArray (op, operandFromLit (0), lvl);
2902 // just in case someone screws up
2903 wassert (IS_PTR (optype));
2905 if (IS_TRUE_SYMOP (op))
2908 op = geniCodeRValue (op, TRUE);
2911 /* now get rid of the pointer part */
2912 if (isLvaluereq(lvl) && IS_ITEMP (op))
2914 retype = getSpec (rtype = copyLinkChain (optype));
2918 retype = getSpec (rtype = copyLinkChain (optype->next));
2919 /* outputclass needs 2b updated */
2920 setOClass (optype, retype);
2923 op->isGptr = IS_GENPTR (optype);
2925 op->isaddr = (IS_PTR (rtype) ||
2926 IS_STRUCT (rtype) ||
2932 if (!isLvaluereq(lvl))
2933 op = geniCodeRValue (op, TRUE);
2935 setOperandType (op, rtype);
2940 /*-----------------------------------------------------------------*/
2941 /* geniCodeUnaryMinus - does a unary minus of the operand */
2942 /*-----------------------------------------------------------------*/
2944 geniCodeUnaryMinus (operand * op)
2947 sym_link *optype = operandType (op);
2949 if (IS_LITERAL (optype))
2950 return operandFromLit (-floatFromVal (op->operand.valOperand));
2952 ic = newiCode (UNARYMINUS, op, NULL);
2953 IC_RESULT (ic) = newiTempOperand (optype, 0);
2955 return IC_RESULT (ic);
2958 /*-----------------------------------------------------------------*/
2959 /* geniCodeLeftShift - gen i code for left shift */
2960 /*-----------------------------------------------------------------*/
2962 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2967 ic = newiCode (LEFT_OP, left, right);
2969 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2970 IC_RESULT (ic) = newiTempOperand (resType, 0);
2972 return IC_RESULT (ic);
2975 /*-----------------------------------------------------------------*/
2976 /* geniCodeRightShift - gen i code for right shift */
2977 /*-----------------------------------------------------------------*/
2979 geniCodeRightShift (operand * left, operand * right)
2983 ic = newiCode (RIGHT_OP, left, right);
2984 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2986 return IC_RESULT (ic);
2989 /*-----------------------------------------------------------------*/
2990 /* geniCodeLogic- logic code */
2991 /*-----------------------------------------------------------------*/
2993 geniCodeLogic (operand * left, operand * right, int op, ast *tree)
2996 sym_link *ctype, *ttype;
2997 sym_link *rtype = operandType (right);
2998 sym_link *ltype = operandType (left);
3000 /* left is integral type and right is literal then
3001 check if the literal value is within bounds */
3002 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
3004 CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE);
3007 case CCR_ALWAYS_TRUE:
3008 case CCR_ALWAYS_FALSE:
3009 if (!options.lessPedantic)
3010 werror (W_COMP_RANGE, "true resp. false");
3011 return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0);
3017 /* if one operand is a pointer and the other is a literal generic void pointer,
3018 change the type of the literal generic void pointer to match the other pointer */
3019 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
3020 && IS_PTR (rtype) && !IS_GENPTR(rtype))
3022 /* find left's definition */
3023 ic = (iCode *) setFirstItem (iCodeChain);
3026 if (((ic->op == CAST) || (ic->op == '='))
3027 && isOperandEqual(left, IC_RESULT (ic)))
3030 ic = setNextItem (iCodeChain);
3032 /* if casting literal to generic pointer, then cast to rtype instead */
3033 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3035 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3036 ltype = operandType(left);
3039 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3040 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3042 /* find right's definition */
3043 ic = (iCode *) setFirstItem (iCodeChain);
3046 if (((ic->op == CAST) || (ic->op == '='))
3047 && isOperandEqual(right, IC_RESULT (ic)))
3050 ic = setNextItem (iCodeChain);
3052 /* if casting literal to generic pointer, then cast to rtype instead */
3053 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3055 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3056 rtype = operandType(right);
3060 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
3062 ic = newiCode (op, left, right);
3063 /* store 0 or 1 in result */
3064 ttype = (tree && IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3065 IC_RESULT (ic) = newiTempOperand (ttype, 1);
3067 /* if comparing float
3068 and not a '==' || '!=' || '&&' || '||' (these
3070 if (IS_FLOAT(ctype) &&
3077 /* if comparing a fixed type use support functions */
3078 if (IS_FIXED(ctype))
3082 return IC_RESULT (ic);
3085 /*-----------------------------------------------------------------*/
3086 /* geniCodeLogicAndOr - && || operations */
3087 /*-----------------------------------------------------------------*/
3089 geniCodeLogicAndOr (ast *tree, int lvl)
3093 symbol *falseLabel = newiTempLabel (NULL);
3094 symbol *trueLabel = newiTempLabel (NULL);
3095 symbol *exitLabel = newiTempLabel (NULL);
3096 operand *op, *result, *condition;
3098 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3099 They can be reenabled by executing the following block. If you find
3100 a decent optimization you could start right here:
3105 operand *leftOp, *rightOp;
3107 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3108 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3110 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3114 /* generate two IFX for the '&&' or '||' op */
3116 /* evaluate left operand */
3117 condition = ast2iCode (tree->left, lvl + 1);
3118 op = geniCodeRValue (condition, FALSE);
3120 /* test left operand */
3121 if (tree->opval.op == AND_OP)
3122 ic = newiCodeCondition (op, NULL, falseLabel);
3124 ic = newiCodeCondition (op, trueLabel, NULL);
3127 /* evaluate right operand */
3128 condition = ast2iCode (tree->right, lvl + 1);
3129 op = geniCodeRValue (condition, FALSE);
3131 /* test right operand */
3132 ic = newiCodeCondition (op, trueLabel, NULL);
3135 /* store 0 or 1 in result */
3136 type = (IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3137 result = newiTempOperand (type, 1);
3139 geniCodeLabel (falseLabel);
3140 geniCodeAssign (result, operandFromLit (0), 0, 0);
3141 /* generate an unconditional goto */
3142 geniCodeGoto (exitLabel);
3144 geniCodeLabel (trueLabel);
3145 geniCodeAssign (result, operandFromLit (1), 0, 0);
3147 geniCodeLabel (exitLabel);
3152 /*-----------------------------------------------------------------*/
3153 /* geniCodeUnary - for a generic unary operation */
3154 /*-----------------------------------------------------------------*/
3156 geniCodeUnary (operand * op, int oper)
3158 iCode *ic = newiCode (oper, op, NULL);
3160 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3162 return IC_RESULT (ic);
3165 /*-----------------------------------------------------------------*/
3166 /* geniCodeBinary - for a generic binary operation */
3167 /*-----------------------------------------------------------------*/
3169 geniCodeBinary (operand * left, operand * right, int oper)
3171 iCode *ic = newiCode (oper, left, right);
3173 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3175 return IC_RESULT (ic);
3178 /*-----------------------------------------------------------------*/
3179 /* geniCodeConditional - geniCode for '?' ':' operation */
3180 /*-----------------------------------------------------------------*/
3182 geniCodeConditional (ast * tree,int lvl)
3185 symbol *falseLabel = newiTempLabel (NULL);
3186 symbol *exitLabel = newiTempLabel (NULL);
3187 ast *astTrue = tree->right->left;
3188 ast *astFalse = tree->right->right;
3189 operand *cond = ast2iCode (tree->left, lvl+1);
3190 operand *result = newiTempOperand (tree->right->ftype, 0);
3191 operand *opTrue, *opFalse;
3193 ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel);
3196 opTrue = ast2iCode (astTrue, lvl+1);
3198 /* move the value to the new operand */
3199 geniCodeAssign (result, geniCodeRValue (opTrue, FALSE), 0, 0);
3201 /* generate an unconditional goto */
3202 geniCodeGoto (exitLabel);
3204 /* now for the right side */
3205 geniCodeLabel (falseLabel);
3207 opFalse = ast2iCode (astFalse, lvl+1);
3208 geniCodeAssign (result, geniCodeRValue (opFalse, FALSE), 0, 0);
3210 /* create the exit label */
3211 geniCodeLabel (exitLabel);
3216 /*-----------------------------------------------------------------*/
3217 /* geniCodeAssign - generate code for assignment */
3218 /*-----------------------------------------------------------------*/
3220 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3223 sym_link *ltype = operandType (left);
3224 sym_link *rtype = operandType (right);
3226 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3228 werror (E_LVALUE_REQUIRED, "assignment");
3232 /* left is integral type and right is literal then
3233 check if the literal value is within bounds */
3234 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3235 checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3236 !options.lessPedantic)
3238 werror (W_LIT_OVERFLOW);
3241 /* if the left & right type don't exactly match */
3242 /* if pointer set then make sure the check is
3243 done with the type & not the pointer */
3244 /* then cast rights type to left */
3246 /* first check the type for pointer assignement */
3247 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3248 compareType (ltype, rtype) <= 0)
3251 right = geniCodeCast (ltype, right, TRUE);
3252 else if (compareType (ltype->next, rtype) < 0)
3253 right = geniCodeCast (ltype->next, right, TRUE);
3255 else if (compareType (ltype, rtype) < 0)
3256 right = geniCodeCast (ltype, right, TRUE);
3258 /* If left is a true symbol & ! volatile
3259 create an assignment to temporary for
3260 the right & then assign this temporary
3261 to the symbol. This is SSA (static single
3262 assignment). Isn't it simple and folks have
3263 published mountains of paper on it */
3264 if (IS_TRUE_SYMOP (left) &&
3265 !isOperandVolatile (left, FALSE) &&
3266 isOperandGlobal (left))
3271 if (IS_TRUE_SYMOP (right))
3272 sym = OP_SYMBOL (right);
3273 ic = newiCode ('=', NULL, right);
3274 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3275 /* avoid double fetch from volatile right, see bug 1369874 */
3276 if (!isOperandVolatile (right, FALSE))
3277 SPIL_LOC (newRight) = sym;
3282 ic = newiCode ('=', NULL, right);
3283 IC_RESULT (ic) = left;
3286 /* if left isgptr flag is set then support
3287 routine will be required */
3291 ic->nosupdate = nosupdate;
3292 /* left could be a pointer assignment,
3293 return the properly casted right instead */
3297 /*-----------------------------------------------------------------*/
3298 /* geniCodeDummyRead - generate code for dummy read */
3299 /*-----------------------------------------------------------------*/
3301 geniCodeDummyRead (operand * op)
3304 sym_link *type = operandType (op);
3306 if (!IS_VOLATILE(type))
3309 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3315 /*-----------------------------------------------------------------*/
3316 /* geniCodeSEParms - generate code for side effecting fcalls */
3317 /*-----------------------------------------------------------------*/
3319 geniCodeSEParms (ast * parms,int lvl)
3324 if (parms->type == EX_OP && parms->opval.op == PARAM)
3326 geniCodeSEParms (parms->left,lvl);
3327 geniCodeSEParms (parms->right,lvl);
3331 /* hack don't like this but too lazy to think of
3333 if (IS_ADDRESS_OF_OP (parms))
3334 parms->left->lvalue = 1;
3336 if (IS_CAST_OP (parms) &&
3337 IS_PTR (parms->ftype) &&
3338 IS_ADDRESS_OF_OP (parms->right))
3339 parms->right->left->lvalue = 1;
3341 parms->opval.oprnd =
3342 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3344 parms->type = EX_OPERAND;
3345 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3346 SPEC_ARGREG(parms->ftype);
3349 /*-----------------------------------------------------------------*/
3350 /* geniCodeParms - generates parameters */
3351 /*-----------------------------------------------------------------*/
3353 geniCodeParms (ast * parms, value *argVals, int *stack,
3354 sym_link * ftype, int lvl)
3362 if (argVals==NULL) {
3364 argVals = FUNC_ARGS (ftype);
3367 /* if this is a param node then do the left & right */
3368 if (parms->type == EX_OP && parms->opval.op == PARAM)
3370 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3371 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3375 /* get the parameter value */
3376 if (parms->type == EX_OPERAND)
3377 pval = parms->opval.oprnd;
3380 /* maybe this else should go away ?? */
3381 /* hack don't like this but too lazy to think of
3383 if (IS_ADDRESS_OF_OP (parms))
3384 parms->left->lvalue = 1;
3386 if (IS_CAST_OP (parms) &&
3387 IS_PTR (parms->ftype) &&
3388 IS_ADDRESS_OF_OP (parms->right))
3389 parms->right->left->lvalue = 1;
3391 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3394 /* if register parm then make it a send */
3395 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3396 IFFUNC_ISBUILTIN(ftype))
3398 ic = newiCode (SEND, pval, NULL);
3399 ic->argreg = SPEC_ARGREG(parms->etype);
3400 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3405 /* now decide whether to push or assign */
3406 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3410 operand *top = operandFromSymbol (argVals->sym);
3411 /* clear useDef and other bitVectors */
3412 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3413 geniCodeAssign (top, pval, 1, 0);
3417 sym_link *p = operandType (pval);
3419 ic = newiCode (IPUSH, pval, NULL);
3421 /* update the stack adjustment */
3422 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3427 argVals=argVals->next;
3431 /*-----------------------------------------------------------------*/
3432 /* geniCodeCall - generates temp code for calling */
3433 /*-----------------------------------------------------------------*/
3435 geniCodeCall (operand * left, ast * parms,int lvl)
3439 sym_link *type, *etype;
3443 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3444 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3445 werror (E_FUNCTION_EXPECTED);
3446 return operandFromValue(valueFromLit(0));
3449 /* take care of parameters with side-effecting
3450 function calls in them, this is required to take care
3451 of overlaying function parameters */
3452 geniCodeSEParms (parms,lvl);
3454 ftype = operandType (left);
3455 if (IS_FUNCPTR (ftype))
3456 ftype = ftype->next;
3458 /* first the parameters */
3459 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3461 /* now call : if symbol then pcall */
3462 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3463 ic = newiCode (PCALL, left, NULL);
3465 ic = newiCode (CALL, left, NULL);
3468 type = copyLinkChain (ftype->next);
3469 etype = getSpec (type);
3470 SPEC_EXTR (etype) = 0;
3471 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3475 /* stack adjustment after call */
3476 ic->parmBytes = stack;
3481 /*-----------------------------------------------------------------*/
3482 /* geniCodeReceive - generate intermediate code for "receive" */
3483 /*-----------------------------------------------------------------*/
3485 geniCodeReceive (value * args, operand * func)
3487 unsigned char paramByteCounter = 0;
3489 /* for all arguments that are passed in registers */
3492 if (IS_REGPARM (args->etype))
3494 operand *opr = operandFromValue (args);
3496 symbol *sym = OP_SYMBOL (opr);
3499 /* we will use it after all optimizations
3500 and before liveRange calculation */
3501 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3504 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3505 options.stackAuto == 0 &&
3506 (!(options.model == MODEL_FLAT24)) )
3511 opl = newiTempOperand (args->type, 0);
3513 sym->reqv->key = sym->key;
3514 OP_SYMBOL (sym->reqv)->key = sym->key;
3515 OP_SYMBOL (sym->reqv)->isreqv = 1;
3516 OP_SYMBOL (sym->reqv)->islocal = 0;
3517 SPIL_LOC (sym->reqv) = sym;
3521 ic = newiCode (RECEIVE, func, NULL);
3522 ic->argreg = SPEC_ARGREG(args->etype);
3523 if (ic->argreg == 1) {
3524 currFunc->recvSize = getSize (sym->type);
3526 IC_RESULT (ic) = opr;
3528 /* misuse of parmBytes (normally used for functions)
3529 * to save estimated stack position of this argument.
3530 * Normally this should be zero for RECEIVE iCodes.
3531 * No idea if this causes side effects on other ports. - dw
3533 ic->parmBytes = paramByteCounter;
3535 /* what stack position do we have? */
3536 paramByteCounter += getSize (sym->type);
3545 /*-----------------------------------------------------------------*/
3546 /* geniCodeFunctionBody - create the function body */
3547 /*-----------------------------------------------------------------*/
3549 geniCodeFunctionBody (ast * tree,int lvl)
3557 /* reset the auto generation */
3563 func = ast2iCode (tree->left,lvl+1);
3564 fetype = getSpec (operandType (func));
3566 savefilename = filename;
3567 savelineno = lineno;
3568 filename = OP_SYMBOL (func)->fileDef;
3569 lineno = OP_SYMBOL (func)->lineDef;
3570 /* create an entry label */
3571 geniCodeLabel (entryLabel);
3572 filename = savefilename;
3573 lineno = savelineno;
3575 /* create a proc icode */
3576 ic = newiCode (FUNCTION, func, NULL);
3577 filename = ic->filename = OP_SYMBOL (func)->fileDef;
3578 lineno = ic->lineno = OP_SYMBOL (func)->lineDef;
3583 /* for all parameters that are passed
3584 on registers add a "receive" */
3585 geniCodeReceive (tree->values.args, func);
3587 /* generate code for the body */
3588 ast2iCode (tree->right,lvl+1);
3590 /* create a label for return */
3591 geniCodeLabel (returnLabel);
3593 /* now generate the end proc */
3594 ic = newiCode (ENDFUNCTION, func, NULL);
3600 /*-----------------------------------------------------------------*/
3601 /* geniCodeReturn - gen icode for 'return' statement */
3602 /*-----------------------------------------------------------------*/
3604 geniCodeReturn (operand * op)
3608 /* if the operand is present force an rvalue */
3610 op = geniCodeRValue (op, FALSE);
3612 ic = newiCode (RETURN, op, NULL);
3616 /*-----------------------------------------------------------------*/
3617 /* geniCodeIfx - generates code for extended if statement */
3618 /*-----------------------------------------------------------------*/
3620 geniCodeIfx (ast * tree,int lvl)
3623 operand *condition = ast2iCode (tree->left,lvl+1);
3626 /* if condition is null then exit */
3630 condition = geniCodeRValue (condition, FALSE);
3632 cetype = getSpec (operandType (condition));
3633 /* if the condition is a literal */
3634 if (IS_LITERAL (cetype))
3636 if (floatFromVal (condition->operand.valOperand))
3638 if (tree->trueLabel)
3639 geniCodeGoto (tree->trueLabel);
3645 if (tree->falseLabel)
3646 geniCodeGoto (tree->falseLabel);
3651 if (tree->trueLabel)
3653 ic = newiCodeCondition (condition,
3658 if (tree->falseLabel)
3659 geniCodeGoto (tree->falseLabel);
3663 ic = newiCodeCondition (condition,
3670 ast2iCode (tree->right,lvl+1);
3673 /*-----------------------------------------------------------------*/
3674 /* geniCodeJumpTable - tries to create a jump table for switch */
3675 /*-----------------------------------------------------------------*/
3677 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3679 int min, max, cnt = 1;
3686 int needRangeCheck = !optimize.noJTabBoundary
3687 || tree->values.switchVals.swDefault;
3688 sym_link *cetype = getSpec (operandType (cond));
3689 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3690 int sizeofMatchJump, sizeofJumpTable;
3693 if (!tree || !caseVals)
3696 /* the criteria for creating a jump table is */
3697 /* all integer numbers between the maximum & minimum must */
3698 /* be present , the maximum value should not exceed 255 */
3699 /* If not all integer numbers are present the algorithm */
3700 /* inserts jumps to the default label for the missing numbers */
3701 /* and decides later whether it is worth it */
3702 min = (int) ulFromVal (vch = caseVals);
3709 max = (int) ulFromVal (vch);
3711 /* Exit if the range is too large to handle with a jump table. */
3712 if (1 + max - min > port->jumptableCost.maxCount)
3715 switch (getSize (operandType (cond)))
3717 case 1: sizeIndex = 0; break;
3718 case 2: sizeIndex = 1; break;
3719 case 4: sizeIndex = 2; break;
3723 /* Compute the size cost of the range check and subtraction. */
3725 sizeofZeroMinCost = 0;
3729 if (!(min==0 && IS_UNSIGNED (cetype)))
3730 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3731 if (!IS_UNSIGNED (cetype))
3732 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3733 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3736 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3738 /* If the size cost of handling a non-zero minimum exceeds the */
3739 /* cost of extending the range down to zero, then it might be */
3740 /* better to extend the range to zero. */
3741 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3742 >= (min * port->jumptableCost.sizeofElement))
3744 /* Only extend the jump table if it would still be manageable. */
3745 if (1 + max <= port->jumptableCost.maxCount)
3748 if (IS_UNSIGNED (cetype))
3751 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3755 /* Compute the total size cost of a jump table. */
3756 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3757 + port->jumptableCost.sizeofDispatch
3758 + sizeofMinCost + sizeofMaxCost;
3760 /* Compute the total size cost of a match & jump sequence */
3761 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3763 /* If the size cost of the jump table is uneconomical then exit */
3764 if (sizeofMatchJump < sizeofJumpTable)
3767 /* The jump table is preferable. */
3769 /* First, a label for the default or missing cases. */
3770 if (tree->values.switchVals.swDefault)
3772 SNPRINTF (buffer, sizeof(buffer),
3774 tree->values.switchVals.swNum);
3778 SNPRINTF (buffer, sizeof(buffer),
3780 tree->values.switchVals.swNum);
3782 falseLabel = newiTempLabel (buffer);
3784 /* Build the list of labels for the jump table. */
3786 t = (int) ulFromVal (vch);
3787 for (i=min; i<=max; i++)
3791 /* Explicit case: make a new label for it. */
3792 SNPRINTF (buffer, sizeof(buffer),
3794 tree->values.switchVals.swNum,
3796 addSet (&labels, newiTempLabel (buffer));
3799 t = (int) ulFromVal (vch);
3803 /* Implicit case: use the default label. */
3804 addSet (&labels, falseLabel);
3808 /* first we rule out the boundary conditions */
3809 /* if only optimization says so */
3812 sym_link *cetype = getSpec (operandType (cond));
3813 /* no need to check the lower bound if
3814 the condition is unsigned & minimum value is zero */
3815 if (!(min == 0 && IS_UNSIGNED (cetype)))
3817 boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL);
3818 ic = newiCodeCondition (boundary, falseLabel, NULL);
3822 /* now for upper bounds */
3823 boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL);
3824 ic = newiCodeCondition (boundary, falseLabel, NULL);
3828 /* if the min is not zero then we no make it zero */
3831 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3832 if (!IS_LITERAL(getSpec(operandType(cond))))
3833 setOperandType (cond, UCHARTYPE);
3836 /* now create the jumptable */
3837 ic = newiCode (JUMPTABLE, NULL, NULL);
3838 IC_JTCOND (ic) = cond;
3839 IC_JTLABELS (ic) = labels;
3844 /*-----------------------------------------------------------------*/
3845 /* geniCodeSwitch - changes a switch to a if statement */
3846 /*-----------------------------------------------------------------*/
3848 geniCodeSwitch (ast * tree,int lvl)
3851 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3852 value *caseVals = tree->values.switchVals.swVals;
3853 symbol *trueLabel, *falseLabel;
3855 /* If the condition is a literal, then just jump to the */
3856 /* appropriate case label. */
3857 if (IS_LITERAL(getSpec(operandType(cond))))
3859 int switchVal, caseVal;
3861 switchVal = (int) ulFromVal (cond->operand.valOperand);
3864 caseVal = (int) ulFromVal (caseVals);
3865 if (caseVal == switchVal)
3867 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3868 tree->values.switchVals.swNum, caseVal);
3869 trueLabel = newiTempLabel (buffer);
3870 geniCodeGoto (trueLabel);
3873 caseVals = caseVals->next;
3875 goto defaultOrBreak;
3878 /* If cond is volatile, it might change while we are trying to */
3879 /* find the matching case. To avoid this possibility, make a */
3880 /* non-volatile copy to use instead. */
3881 if (IS_OP_VOLATILE (cond))
3886 newcond = newiTempOperand (operandType (cond), TRUE);
3887 newcond->isvolatile = 0;
3888 ic = newiCode ('=', NULL, cond);
3889 IC_RESULT (ic) = newcond;
3894 /* if we can make this a jump table */
3895 if (geniCodeJumpTable (cond, caseVals, tree))
3896 goto jumpTable; /* no need for the comparison */
3898 /* for the cases defined do */
3902 operand *compare = geniCodeLogic (cond,
3903 operandFromValue (caseVals),
3906 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3907 tree->values.switchVals.swNum,
3908 (int) ulFromVal (caseVals));
3909 trueLabel = newiTempLabel (buffer);
3911 ic = newiCodeCondition (compare, trueLabel, NULL);
3913 caseVals = caseVals->next;
3918 /* if default is present then goto break else break */
3919 if (tree->values.switchVals.swDefault)
3921 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3925 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3928 falseLabel = newiTempLabel (buffer);
3929 geniCodeGoto (falseLabel);
3932 ast2iCode (tree->right,lvl+1);
3935 /*-----------------------------------------------------------------*/
3936 /* geniCodeInline - intermediate code for inline assembler */
3937 /*-----------------------------------------------------------------*/
3939 geniCodeInline (ast * tree)
3943 ic = newiCode (INLINEASM, NULL, NULL);
3944 IC_INLINE (ic) = tree->values.inlineasm;
3948 /*-----------------------------------------------------------------*/
3949 /* geniCodeArrayInit - intermediate code for array initializer */
3950 /*-----------------------------------------------------------------*/
3952 geniCodeArrayInit (ast * tree, operand *array)
3956 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3957 ic = newiCode (ARRAYINIT, array, NULL);
3958 IC_ARRAYILIST (ic) = tree->values.constlist;
3960 operand *left=newOperand(), *right=newOperand();
3961 left->type=right->type=SYMBOL;
3962 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3963 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3964 ic = newiCode (ARRAYINIT, left, right);
3969 /*-----------------------------------------------------------------*/
3970 /* geniCodeCritical - intermediate code for a critical statement */
3971 /*-----------------------------------------------------------------*/
3973 geniCodeCritical (ast *tree, int lvl)
3979 if (!options.stackAuto)
3981 type = newLink(SPECIFIER);
3982 SPEC_VOLATILE(type) = 1;
3983 SPEC_NOUN(type) = V_BIT;
3984 SPEC_SCLS(type) = S_BIT;
3985 SPEC_BLEN(type) = 1;
3986 SPEC_BSTR(type) = 0;
3987 op = newiTempOperand(type, 1);
3990 /* If op is NULL, the original interrupt state will saved on */
3991 /* the stack. Otherwise, it will be saved in op. */
3993 /* Generate a save of the current interrupt state & disable */
3994 ic = newiCode (CRITICAL, NULL, NULL);
3995 IC_RESULT (ic) = op;
3998 /* Generate the critical code sequence */
3999 if (tree->left && tree->left->type == EX_VALUE)
4000 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4002 ast2iCode (tree->left,lvl+1);
4004 /* Generate a restore of the original interrupt state */
4005 ic = newiCode (ENDCRITICAL, NULL, op);
4009 /*-----------------------------------------------------------------*/
4010 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
4011 /* particular case. Ie : assigning or dereferencing array or ptr */
4012 /*-----------------------------------------------------------------*/
4013 set * lvaluereqSet = NULL;
4014 typedef struct lvalItem
4021 /*-----------------------------------------------------------------*/
4022 /* addLvaluereq - add a flag for lvalreq for current ast level */
4023 /*-----------------------------------------------------------------*/
4024 void addLvaluereq(int lvl)
4026 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
4029 addSetHead(&lvaluereqSet,lpItem);
4032 /*-----------------------------------------------------------------*/
4033 /* delLvaluereq - del a flag for lvalreq for current ast level */
4034 /*-----------------------------------------------------------------*/
4038 lpItem = getSet(&lvaluereqSet);
4039 if(lpItem) Safe_free(lpItem);
4041 /*-----------------------------------------------------------------*/
4042 /* clearLvaluereq - clear lvalreq flag */
4043 /*-----------------------------------------------------------------*/
4044 void clearLvaluereq()
4047 lpItem = peekSet(lvaluereqSet);
4048 if(lpItem) lpItem->req = 0;
4050 /*-----------------------------------------------------------------*/
4051 /* getLvaluereq - get the last lvalreq level */
4052 /*-----------------------------------------------------------------*/
4053 int getLvaluereqLvl()
4056 lpItem = peekSet(lvaluereqSet);
4057 if(lpItem) return lpItem->lvl;
4060 /*-----------------------------------------------------------------*/
4061 /* isLvaluereq - is lvalreq valid for this level ? */
4062 /*-----------------------------------------------------------------*/
4063 int isLvaluereq(int lvl)
4066 lpItem = peekSet(lvaluereqSet);
4067 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4071 /*-----------------------------------------------------------------*/
4072 /* ast2iCode - creates an icodeList from an ast */
4073 /*-----------------------------------------------------------------*/
4075 ast2iCode (ast * tree,int lvl)
4077 operand *left = NULL;
4078 operand *right = NULL;
4082 /* set the global variables for filename & line number */
4084 filename = tree->filename;
4086 lineno = tree->lineno;
4088 block = tree->block;
4090 scopeLevel = tree->level;
4092 seqPoint = tree->seqPoint;
4094 if (tree->type == EX_VALUE)
4095 return operandFromValue (tree->opval.val);
4097 if (tree->type == EX_LINK)
4098 return operandFromLink (tree->opval.lnk);
4100 /* if we find a nullop */
4101 if (tree->type == EX_OP &&
4102 (tree->opval.op == NULLOP ||
4103 tree->opval.op == BLOCK))
4105 if (tree->left && tree->left->type == EX_VALUE)
4106 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4108 ast2iCode (tree->left,lvl+1);
4109 if (tree->right && tree->right->type == EX_VALUE)
4110 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4112 ast2iCode (tree->right,lvl+1);
4116 /* special cases for not evaluating */
4117 if (tree->opval.op != ':' &&
4118 tree->opval.op != '?' &&
4119 tree->opval.op != CALL &&
4120 tree->opval.op != IFX &&
4121 tree->opval.op != AND_OP &&
4122 tree->opval.op != OR_OP &&
4123 tree->opval.op != LABEL &&
4124 tree->opval.op != GOTO &&
4125 tree->opval.op != SWITCH &&
4126 tree->opval.op != FUNCTION &&
4127 tree->opval.op != INLINEASM &&
4128 tree->opval.op != CRITICAL)
4131 if (IS_ASSIGN_OP (tree->opval.op) ||
4132 IS_DEREF_OP (tree) ||
4133 (tree->opval.op == '&' && !tree->right) ||
4134 tree->opval.op == PTR_OP)
4137 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4138 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4141 left = operandFromAst (tree->left,lvl);
4143 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4144 left = geniCodeRValue (left, TRUE);
4148 left = operandFromAst (tree->left,lvl);
4150 if (tree->opval.op == INC_OP ||
4151 tree->opval.op == DEC_OP)
4154 right = operandFromAst (tree->right,lvl);
4159 right = operandFromAst (tree->right,lvl);
4163 /* now depending on the type of operand */
4164 /* this will be a biggy */
4165 switch (tree->opval.op)
4168 case '[': /* array operation */
4170 //sym_link *ltype = operandType (left);
4171 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4172 left = geniCodeRValue (left, FALSE);
4173 right = geniCodeRValue (right, TRUE);
4176 return geniCodeArray (left, right,lvl);
4178 case '.': /* structure dereference */
4179 if (IS_PTR (operandType (left)))
4180 left = geniCodeRValue (left, TRUE);
4182 left = geniCodeRValue (left, FALSE);
4184 return geniCodeStruct (left, right, tree->lvalue);
4186 case PTR_OP: /* structure pointer dereference */
4189 pType = operandType (left);
4190 left = geniCodeRValue (left, TRUE);
4192 setOClass (pType, getSpec (operandType (left)));
4195 return geniCodeStruct (left, right, tree->lvalue);
4197 case INC_OP: /* increment operator */
4199 return geniCodePostInc (left);
4201 return geniCodePreInc (right, tree->lvalue);
4203 case DEC_OP: /* decrement operator */
4205 return geniCodePostDec (left);
4207 return geniCodePreDec (right, tree->lvalue);
4209 case '&': /* bitwise and or address of operator */
4211 { /* this is a bitwise operator */
4212 left = geniCodeRValue (left, FALSE);
4213 right = geniCodeRValue (right, FALSE);
4214 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4217 return geniCodeAddressOf (left);
4219 case '|': /* bitwise or & xor */
4221 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4222 geniCodeRValue (right, FALSE),
4227 return geniCodeDivision (geniCodeRValue (left, FALSE),
4228 geniCodeRValue (right, FALSE),
4229 getResultTypeFromType (tree->ftype));
4232 return geniCodeModulus (geniCodeRValue (left, FALSE),
4233 geniCodeRValue (right, FALSE),
4234 getResultTypeFromType (tree->ftype));
4237 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4238 geniCodeRValue (right, FALSE),
4239 getResultTypeFromType (tree->ftype));
4241 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4245 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4246 geniCodeRValue (right, FALSE),
4247 getResultTypeFromType (tree->ftype));
4249 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4253 return geniCodeAdd (geniCodeRValue (left, FALSE),
4254 geniCodeRValue (right, FALSE),
4255 getResultTypeFromType (tree->ftype),
4258 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4261 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4262 geniCodeRValue (right, FALSE),
4263 getResultTypeFromType (tree->ftype));
4266 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4267 geniCodeRValue (right, FALSE));
4269 #if 0 // this indeed needs a second thought
4273 // let's keep this simple: get the rvalue we need
4274 op=geniCodeRValue (right, FALSE);
4275 // now cast it to whatever we want
4276 op=geniCodeCast (operandType(left), op, FALSE);
4277 // if this is going to be used as an lvalue, make it so
4283 #else // bug #604575, is it a bug ????
4284 return geniCodeCast (operandType (left),
4285 geniCodeRValue (right, FALSE), FALSE);
4292 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4297 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4298 if (!IS_BIT (operandType (op)))
4299 setOperandType (op, UCHARTYPE);
4304 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4305 geniCodeRValue (right, FALSE),
4307 if (!IS_BIT (operandType (op)))
4308 setOperandType (op, UCHARTYPE);
4313 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4314 geniCodeRValue (right, FALSE),
4316 setOperandType (op, UCHARTYPE);
4321 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4322 geniCodeRValue (right, FALSE),
4324 setOperandType (op, UINTTYPE);
4329 return geniCodeLogicAndOr (tree, lvl);
4336 /* different compilers (even different gccs) evaluate
4337 the two calls in a different order. to get the same
4338 result on all machines we have to specify a clear sequence.
4339 return geniCodeLogic (geniCodeRValue (left, FALSE),
4340 geniCodeRValue (right, FALSE),
4344 operand *leftOp, *rightOp;
4346 leftOp = geniCodeRValue (left , FALSE);
4347 rightOp = geniCodeRValue (right, FALSE);
4349 return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree);
4352 return geniCodeConditional (tree,lvl);
4355 return operandFromLit (getSize (tree->right->ftype));
4359 sym_link *rtype = operandType (right);
4360 sym_link *ltype = operandType (left);
4361 if (IS_PTR (rtype) && IS_ITEMP (right)
4362 && right->isaddr && compareType (rtype->next, ltype) == 1)
4363 right = geniCodeRValue (right, TRUE);
4365 right = geniCodeRValue (right, FALSE);
4367 return geniCodeAssign (left, right, 0, 1);
4371 geniCodeAssign (left,
4372 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4374 geniCodeRValue (right, FALSE),
4375 getResultTypeFromType (tree->ftype)),
4380 geniCodeAssign (left,
4381 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4383 geniCodeRValue (right, FALSE),
4384 getResultTypeFromType (tree->ftype)),
4388 geniCodeAssign (left,
4389 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4391 geniCodeRValue (right, FALSE),
4392 getResultTypeFromType (tree->ftype)),
4396 sym_link *rtype = operandType (right);
4397 sym_link *ltype = operandType (left);
4398 if (IS_PTR (rtype) && IS_ITEMP (right)
4399 && right->isaddr && compareType (rtype->next, ltype) == 1)
4400 right = geniCodeRValue (right, TRUE);
4402 right = geniCodeRValue (right, FALSE);
4405 return geniCodeAssign (left,
4406 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4409 getResultTypeFromType (tree->ftype),
4415 sym_link *rtype = operandType (right);
4416 sym_link *ltype = operandType (left);
4417 if (IS_PTR (rtype) && IS_ITEMP (right)
4418 && right->isaddr && compareType (rtype->next, ltype) == 1)
4420 right = geniCodeRValue (right, TRUE);
4424 right = geniCodeRValue (right, FALSE);
4427 geniCodeAssign (left,
4428 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4431 getResultTypeFromType (tree->ftype)),
4436 geniCodeAssign (left,
4437 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4439 geniCodeRValue (right, FALSE),
4440 getResultTypeFromType (tree->ftype)),
4444 geniCodeAssign (left,
4445 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4447 geniCodeRValue (right, FALSE)), 0, 1);
4450 geniCodeAssign (left,
4451 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4453 geniCodeRValue (right, FALSE),
4455 operandType (left)), 0, 1);
4458 geniCodeAssign (left,
4459 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4461 geniCodeRValue (right, FALSE),
4463 operandType (left)), 0, 1);
4466 geniCodeAssign (left,
4467 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4469 geniCodeRValue (right, FALSE),
4471 operandType (left)), 0, 1);
4473 return geniCodeRValue (right, FALSE);
4476 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4479 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4480 return ast2iCode (tree->right,lvl+1);
4483 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4484 return ast2iCode (tree->right,lvl+1);
4487 geniCodeFunctionBody (tree,lvl);
4491 geniCodeReturn (right);
4495 geniCodeIfx (tree,lvl);
4499 geniCodeSwitch (tree,lvl);
4503 geniCodeInline (tree);
4507 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4511 geniCodeCritical (tree, lvl);
4517 /*-----------------------------------------------------------------*/
4518 /* reverseICChain - gets from the list and creates a linkedlist */
4519 /*-----------------------------------------------------------------*/
4526 while ((loop = getSet (&iCodeChain)))
4538 /*-----------------------------------------------------------------*/
4539 /* iCodeFromAst - given an ast will convert it to iCode */
4540 /*-----------------------------------------------------------------*/
4542 iCodeFromAst (ast * tree)
4544 returnLabel = newiTempLabel ("_return");
4545 entryLabel = newiTempLabel ("_entry");
4547 return reverseiCChain ();
4550 static const char *opTypeToStr(OPTYPE op)
4554 case SYMBOL: return "symbol";
4555 case VALUE: return "value";
4556 case TYPE: return "type";
4558 return "undefined type";
4562 operand *validateOpType(operand *op,
4569 if (op && op->type == type)
4574 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4575 " expected %s, got %s\n",
4576 macro, args, file, line,
4577 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4579 return op; // never reached, makes compiler happy.