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 //preserve original behaviour for PIC16
1958 if (TARGET_IS_PIC16)
1961 //for HC08 only zeropage ptr is different
1964 if (IS_DATA_PTR (type))
1970 if (IS_DATA_PTR (type) && TARGET_MCS51_LIKE)
1973 return DCL_TYPE (type);
1974 else if (IS_FUNC (type))
1976 else if (IS_ARRAY (type))
1977 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
1981 /*-----------------------------------------------------------------*/
1982 /* geniCodeCast - changes the value from one type to another */
1983 /*-----------------------------------------------------------------*/
1985 geniCodeCast (sym_link * type, operand * op, bool implicit)
1989 sym_link *opetype = getSpec (optype = operandType (op));
1993 /* one of them has size zero then error */
1994 if (IS_VOID (optype))
1996 werror (E_CAST_ZERO);
2000 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
2002 geniCodeArray2Ptr (op);
2006 /* if the operand is already the desired type then do nothing */
2007 if (compareType (type, optype) == 1)
2010 /* if this is a literal then just change the type & return */
2011 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
2013 return operandFromValue (valCastLiteral (type, operandLitValue (op)));
2016 /* if casting to/from pointers, do some checking */
2017 if (IS_PTR(type)) { // to a pointer
2018 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
2019 if (IS_INTEGRAL(optype)) {
2020 // maybe this is NULL, than it's ok.
2021 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
2022 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
2023 // no way to set the storage
2024 if (IS_LITERAL(optype)) {
2025 werror(E_LITERAL_GENERIC);
2028 werror(E_NONPTR2_GENPTR);
2031 } else if (implicit) {
2032 werror(W_INTEGRAL2PTR_NOCAST);
2037 // shouldn't do that with float, array or structure unless to void
2038 if (!IS_VOID(getSpec(type)) &&
2039 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2040 werror(E_INCOMPAT_TYPES);
2044 } else { // from a pointer to a pointer
2045 if (IS_GENPTR(type) && IS_VOID(type->next))
2046 { // cast to void* is always allowed
2048 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2049 { // cast from void* is always allowed
2051 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2052 // if not a pointer to a function
2053 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2054 if (implicit) { // if not to generic, they have to match
2055 if (!IS_GENPTR(type) &&
2056 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2057 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2061 werror(E_INCOMPAT_PTYPES);
2068 } else { // to a non pointer
2069 if (IS_PTR(optype)) { // from a pointer
2070 if (implicit) { // sneaky
2071 if (IS_INTEGRAL(type)) {
2072 werror(W_PTR2INTEGRAL_NOCAST);
2074 } else { // shouldn't do that with float, array or structure
2075 werror(E_INCOMPAT_TYPES);
2082 printFromToType (optype, type);
2085 /* if they are the same size create an assignment */
2087 /* This seems very dangerous to me, since there are several */
2088 /* optimizations (for example, gcse) that don't notice the */
2089 /* cast hidden in this assignment and may simplify an */
2090 /* iCode to use the original (uncasted) operand. */
2091 /* Unfortunately, other things break when this cast is */
2092 /* made explicit. Need to fix this someday. */
2093 /* -- EEP, 2004/01/21 */
2094 if (getSize (type) == getSize (optype) &&
2095 !IS_BITFIELD (type) &&
2097 !IS_FLOAT (optype) &&
2099 !IS_FIXED (optype) &&
2100 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2101 (IS_DECL (type) && IS_DECL (optype) && getPtrType (type) == getPtrType (optype))))
2103 ic = newiCode ('=', NULL, op);
2104 IC_RESULT (ic) = newiTempOperand (type, 0);
2105 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2106 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2107 IC_RESULT (ic)->isaddr = 0;
2111 ic = newiCode (CAST, operandFromLink (type),
2112 geniCodeRValue (op, FALSE));
2114 IC_RESULT (ic) = newiTempOperand (type, 0);
2117 /* preserve the storage class & output class */
2118 /* of the original variable */
2119 restype = getSpec (operandType (IC_RESULT (ic)));
2120 if (!IS_LITERAL(opetype) &&
2123 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2124 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2127 return IC_RESULT (ic);
2130 /*-----------------------------------------------------------------*/
2131 /* geniCodeLabel - will create a Label */
2132 /*-----------------------------------------------------------------*/
2134 geniCodeLabel (symbol * label)
2138 ic = newiCodeLabelGoto (LABEL, label);
2142 /*-----------------------------------------------------------------*/
2143 /* geniCodeGoto - will create a Goto */
2144 /*-----------------------------------------------------------------*/
2146 geniCodeGoto (symbol * label)
2150 ic = newiCodeLabelGoto (GOTO, label);
2154 /*-----------------------------------------------------------------*/
2155 /* geniCodeMultiply - gen intermediate code for multiplication */
2156 /*-----------------------------------------------------------------*/
2158 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2165 /* if they are both literal then we know the result */
2166 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2167 return operandFromValue (valMult (left->operand.valOperand,
2168 right->operand.valOperand));
2170 if (IS_LITERAL(retype)) {
2171 p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand));
2174 resType = usualBinaryConversions (&left, &right, resultType, '*');
2176 rtype = operandType (right);
2177 retype = getSpec (rtype);
2178 ltype = operandType (left);
2179 letype = getSpec (ltype);
2182 /* if the right is a literal & power of 2 */
2183 /* then make it a left shift */
2184 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2185 efficient in most cases than 2 bytes result = 2 bytes << literal
2186 if port has 1 byte muldiv */
2187 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2188 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2189 && (port->support.muldiv == 1))
2190 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2191 && strcmp (port->target, "pic14") != 0)
2193 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2195 /* LEFT_OP need same size for left and result, */
2196 left = geniCodeCast (resType, left, TRUE);
2197 ltype = operandType (left);
2199 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2203 /* if the size left or right > 1 then support routine */
2204 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2206 if (IS_LITERAL (retype))
2207 ic = newiCode ('*', right, left); /* multiplication by support routine with one literal */
2209 ic = newiCode ('*', left, right); /* multiplication by support routine */
2214 ic = newiCode ('*', left, right); /* normal multiplication */
2217 IC_RESULT (ic) = newiTempOperand (resType, 1);
2220 return IC_RESULT (ic);
2223 /*-----------------------------------------------------------------*/
2224 /* geniCodeDivision - gen intermediate code for division */
2225 /*-----------------------------------------------------------------*/
2227 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2232 sym_link *rtype = operandType (right);
2233 sym_link *retype = getSpec (rtype);
2234 sym_link *ltype = operandType (left);
2235 sym_link *letype = getSpec (ltype);
2237 resType = usualBinaryConversions (&left, &right, resultType, '/');
2239 /* if the right is a literal & power of 2
2240 and left is unsigned then make it a
2242 if (IS_LITERAL (retype) &&
2243 !IS_FLOAT (letype) &&
2244 !IS_FIXED (letype) &&
2245 IS_UNSIGNED(letype) &&
2246 ((p2 = powof2 ((TYPE_TARGET_ULONG) ulFromVal (right->operand.valOperand))) > 0)) {
2247 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2251 ic = newiCode ('/', left, right); /* normal division */
2252 /* if the size left or right > 1 then support routine */
2253 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2256 IC_RESULT (ic) = newiTempOperand (resType, 0);
2259 return IC_RESULT (ic);
2261 /*-----------------------------------------------------------------*/
2262 /* geniCodeModulus - gen intermediate code for modulus */
2263 /*-----------------------------------------------------------------*/
2265 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2271 /* if they are both literal then we know the result */
2272 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2273 return operandFromValue (valMod (left->operand.valOperand,
2274 right->operand.valOperand));
2276 resType = usualBinaryConversions (&left, &right, resultType, '%');
2278 /* now they are the same size */
2279 ic = newiCode ('%', left, right);
2281 /* if the size left or right > 1 then support routine */
2282 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2284 IC_RESULT (ic) = newiTempOperand (resType, 0);
2287 return IC_RESULT (ic);
2290 /*-----------------------------------------------------------------*/
2291 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2292 /*-----------------------------------------------------------------*/
2294 geniCodePtrPtrSubtract (operand * left, operand * right)
2300 /* if they are both literals then */
2301 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2303 result = operandFromValue (valMinus (left->operand.valOperand,
2304 right->operand.valOperand));
2308 ic = newiCode ('-', left, right);
2310 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2314 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2318 // should we really do this? is this ANSI?
2319 return geniCodeDivision (result,
2320 operandFromLit (getSize (ltype->next)),
2324 /*-----------------------------------------------------------------*/
2325 /* geniCodeSubtract - generates code for subtraction */
2326 /*-----------------------------------------------------------------*/
2328 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2335 /* if they both pointers then */
2336 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2337 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2338 return geniCodePtrPtrSubtract (left, right);
2340 /* if they are both literal then we know the result */
2341 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2342 && left->isLiteral && right->isLiteral)
2343 return operandFromValue (valMinus (left->operand.valOperand,
2344 right->operand.valOperand));
2346 /* if left is an array or pointer */
2347 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2349 isarray = left->isaddr;
2350 right = geniCodeMultiply (right,
2351 operandFromLit (getSize (ltype->next)),
2352 (getArraySizePtr(left) >= INTSIZE) ?
2355 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2358 { /* make them the same size */
2359 resType = usualBinaryConversions (&left, &right, resultType, '-');
2362 ic = newiCode ('-', left, right);
2364 IC_RESULT (ic) = newiTempOperand (resType, 1);
2365 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2367 /* if left or right is a float */
2368 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2369 || IS_FIXED (ltype) || IS_FIXED (rtype))
2373 return IC_RESULT (ic);
2376 /*-----------------------------------------------------------------*/
2377 /* geniCodeAdd - generates iCode for addition */
2378 /*-----------------------------------------------------------------*/
2380 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2389 /* if the right side is LITERAL zero */
2390 /* return the left side */
2391 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2394 /* if left is literal zero return right */
2395 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2398 /* if left is a pointer then size */
2399 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2401 isarray = left->isaddr;
2402 // there is no need to multiply with 1
2403 if (getSize (ltype->next) != 1)
2405 size = operandFromLit (getSize (ltype->next));
2406 SPEC_USIGN (getSpec (operandType (size))) = 1;
2407 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2408 right = geniCodeMultiply (right, size, resultType);
2409 /* Even if right is a 'unsigned char',
2410 the result will be a 'signed int' due to the promotion rules.
2411 It doesn't make sense when accessing arrays, so let's fix it here: */
2413 SPEC_USIGN (getSpec (operandType (right))) = 1;
2415 resType = copyLinkChain (ltype);
2418 { // make them the same size
2419 resType = usualBinaryConversions (&left, &right, resultType, '+');
2422 /* if they are both literals then we know */
2423 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2424 && left->isLiteral && right->isLiteral)
2425 return operandFromValue (valPlus (valFromType (ltype),
2426 valFromType (rtype)));
2428 ic = newiCode ('+', left, right);
2430 IC_RESULT (ic) = newiTempOperand (resType, 1);
2431 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2433 /* if left or right is a float then support
2435 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2436 || IS_FIXED (ltype) || IS_FIXED (rtype))
2441 return IC_RESULT (ic);
2445 /*-----------------------------------------------------------------*/
2446 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2447 /*-----------------------------------------------------------------*/
2449 aggrToPtr (sym_link * type, bool force)
2454 if (IS_PTR (type) && !force)
2457 etype = getSpec (type);
2458 ptype = newLink (DECLARATOR);
2462 /* set the pointer depending on the storage class */
2463 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2467 /*------------------------------------------------------------------*/
2468 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2469 /*------------------------------------------------------------------*/
2471 aggrToPtrDclType (sym_link * type, bool force)
2473 if (IS_PTR (type) && !force)
2474 return DCL_TYPE (type);
2476 /* return the pointer depending on the storage class */
2477 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2480 /*-----------------------------------------------------------------*/
2481 /* geniCodeArray2Ptr - array to pointer */
2482 /*-----------------------------------------------------------------*/
2484 geniCodeArray2Ptr (operand * op)
2486 sym_link *optype = operandType (op);
2487 sym_link *opetype = getSpec (optype);
2489 /* set the pointer depending on the storage class */
2490 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2497 /*-----------------------------------------------------------------*/
2498 /* geniCodeArray - array access */
2499 /*-----------------------------------------------------------------*/
2501 geniCodeArray (operand * left, operand * right, int lvl)
2505 sym_link *ltype = operandType (left);
2507 RESULT_TYPE resultType;
2509 resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
2510 if (DCL_ELEM (ltype))
2512 if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
2513 resultType = RESULT_TYPE_CHAR;
2518 if (IS_PTR (ltype->next) && left->isaddr)
2520 left = geniCodeRValue (left, FALSE);
2523 return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
2526 size = operandFromLit (getSize (ltype->next));
2527 SPEC_USIGN (getSpec (operandType (size))) = 1;
2528 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2529 right = geniCodeMultiply (right, size, resultType);
2530 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2531 It doesn't make sense when accessing arrays, so let's fix it here: */
2533 SPEC_USIGN (getSpec (operandType (right))) = 1;
2534 /* we can check for limits here */
2535 /* already done in SDCCast.c
2536 if (isOperandLiteral (right) &&
2539 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2541 werror (W_IDX_OUT_OF_BOUNDS,
2542 (int) operandLitValue (right) / getSize (ltype->next),
2547 ic = newiCode ('+', left, right);
2549 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2550 !IS_AGGREGATE (ltype->next) &&
2551 !IS_PTR (ltype->next))
2552 ? ltype : ltype->next), 0);
2554 if (!IS_AGGREGATE (ltype->next))
2556 IC_RESULT (ic)->isaddr = 1;
2557 IC_RESULT (ic)->aggr2ptr = 1;
2561 return IC_RESULT (ic);
2564 /*-----------------------------------------------------------------*/
2565 /* geniCodeStruct - generates intermediate code for structures */
2566 /*-----------------------------------------------------------------*/
2568 geniCodeStruct (operand * left, operand * right, bool islval)
2571 sym_link *type = operandType (left);
2572 sym_link *etype = getSpec (type);
2574 symbol *element = getStructElement (SPEC_STRUCT (etype),
2575 right->operand.symOperand);
2577 wassert(IS_SYMOP(right));
2579 /* add the offset */
2580 ic = newiCode ('+', left, operandFromLit (element->offset));
2582 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2584 /* preserve the storage & output class of the struct */
2585 /* as well as the volatile attribute */
2586 retype = getSpec (operandType (IC_RESULT (ic)));
2587 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2588 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2589 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2590 SPEC_CONST (retype) |= SPEC_CONST (etype);
2592 if (IS_PTR (element->type))
2593 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2595 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2598 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2601 /*-----------------------------------------------------------------*/
2602 /* geniCodePostInc - generate int code for Post increment */
2603 /*-----------------------------------------------------------------*/
2605 geniCodePostInc (operand * op)
2609 sym_link *optype = operandType (op);
2611 operand *rv = (IS_ITEMP (op) ?
2612 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2614 sym_link *rvtype = operandType (rv);
2617 /* if this is not an address we have trouble */
2620 werror (E_LVALUE_REQUIRED, "++");
2624 rOp = newiTempOperand (rvtype, 0);
2625 OP_SYMBOL(rOp)->noSpilLoc = 1;
2628 OP_SYMBOL(rv)->noSpilLoc = 1;
2630 geniCodeAssign (rOp, rv, 0, 0);
2632 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2634 werror(W_SIZEOF_VOID);
2635 if (IS_FLOAT (rvtype))
2636 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2637 else if (IS_FIXED16X16 (rvtype))
2638 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2640 ic = newiCode ('+', rv, operandFromLit (size));
2642 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2645 geniCodeAssign (op, result, 0, 0);
2651 /*-----------------------------------------------------------------*/
2652 /* geniCodePreInc - generate code for preIncrement */
2653 /*-----------------------------------------------------------------*/
2655 geniCodePreInc (operand * op, bool lvalue)
2658 sym_link *optype = operandType (op);
2659 operand *rop = (IS_ITEMP (op) ?
2660 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2662 sym_link *roptype = operandType (rop);
2668 werror (E_LVALUE_REQUIRED, "++");
2672 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2674 werror(W_SIZEOF_VOID);
2675 if (IS_FLOAT (roptype))
2676 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2677 else if (IS_FIXED16X16 (roptype))
2678 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2680 ic = newiCode ('+', rop, operandFromLit (size));
2681 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2684 (void) geniCodeAssign (op, result, 0, 0);
2685 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2691 /*-----------------------------------------------------------------*/
2692 /* geniCodePostDec - generates code for Post decrement */
2693 /*-----------------------------------------------------------------*/
2695 geniCodePostDec (operand * op)
2699 sym_link *optype = operandType (op);
2701 operand *rv = (IS_ITEMP (op) ?
2702 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2704 sym_link *rvtype = operandType (rv);
2707 /* if this is not an address we have trouble */
2710 werror (E_LVALUE_REQUIRED, "--");
2714 rOp = newiTempOperand (rvtype, 0);
2715 OP_SYMBOL(rOp)->noSpilLoc = 1;
2718 OP_SYMBOL(rv)->noSpilLoc = 1;
2720 geniCodeAssign (rOp, rv, 0, 0);
2722 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2724 werror(W_SIZEOF_VOID);
2725 if (IS_FLOAT (rvtype))
2726 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2727 else if (IS_FIXED16X16 (rvtype))
2728 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2730 ic = newiCode ('-', rv, operandFromLit (size));
2732 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2735 geniCodeAssign (op, result, 0, 0);
2741 /*-----------------------------------------------------------------*/
2742 /* geniCodePreDec - generate code for pre decrement */
2743 /*-----------------------------------------------------------------*/
2745 geniCodePreDec (operand * op, bool lvalue)
2748 sym_link *optype = operandType (op);
2749 operand *rop = (IS_ITEMP (op) ?
2750 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2752 sym_link *roptype = operandType (rop);
2758 werror (E_LVALUE_REQUIRED, "--");
2762 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2764 werror(W_SIZEOF_VOID);
2765 if (IS_FLOAT (roptype))
2766 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2767 else if (IS_FIXED16X16 (roptype))
2768 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2770 ic = newiCode ('-', rop, operandFromLit (size));
2771 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2774 (void) geniCodeAssign (op, result, 0, 0);
2775 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2782 /*-----------------------------------------------------------------*/
2783 /* geniCodeBitwise - gen int code for bitWise operators */
2784 /*-----------------------------------------------------------------*/
2786 geniCodeBitwise (operand * left, operand * right,
2787 int oper, sym_link * resType)
2791 left = geniCodeCast (resType, left, TRUE);
2792 right = geniCodeCast (resType, right, TRUE);
2794 ic = newiCode (oper, left, right);
2795 IC_RESULT (ic) = newiTempOperand (resType, 0);
2798 return IC_RESULT (ic);
2801 /*-----------------------------------------------------------------*/
2802 /* geniCodeAddressOf - gens icode for '&' address of operator */
2803 /*-----------------------------------------------------------------*/
2805 geniCodeAddressOf (operand * op)
2809 sym_link *optype = operandType (op);
2810 sym_link *opetype = getSpec (optype);
2812 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2814 op = operandFromOperand (op);
2819 /* lvalue check already done in decorateType */
2820 /* this must be a lvalue */
2821 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2822 /* werror (E_LVALUE_REQUIRED,"&"); */
2826 p = newLink (DECLARATOR);
2828 /* set the pointer depending on the storage class */
2829 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2831 p->next = copyLinkChain (optype);
2833 /* if already a temp */
2836 setOperandType (op, p);
2841 /* otherwise make this of the type coming in */
2842 ic = newiCode (ADDRESS_OF, op, NULL);
2843 IC_RESULT (ic) = newiTempOperand (p, 1);
2844 IC_RESULT (ic)->isaddr = 0;
2846 return IC_RESULT (ic);
2849 /*-----------------------------------------------------------------*/
2850 /* setOClass - sets the output class depending on the pointer type */
2851 /*-----------------------------------------------------------------*/
2853 setOClass (sym_link * ptr, sym_link * spec)
2855 switch (DCL_TYPE (ptr))
2858 SPEC_OCLS (spec) = data;
2862 SPEC_OCLS (spec) = generic;
2866 SPEC_OCLS (spec) = xdata;
2870 SPEC_OCLS (spec) = code;
2874 SPEC_OCLS (spec) = idata;
2878 SPEC_OCLS (spec) = xstack;
2882 SPEC_OCLS (spec) = eeprom;
2891 /*-----------------------------------------------------------------*/
2892 /* geniCodeDerefPtr - dereference pointer with '*' */
2893 /*-----------------------------------------------------------------*/
2895 geniCodeDerefPtr (operand * op,int lvl)
2897 sym_link *rtype, *retype;
2898 sym_link *optype = operandType (op);
2900 // if this is an array then array access
2901 if (IS_ARRAY (optype)) {
2902 // don't worry, this will be optimized out later
2903 return geniCodeArray (op, operandFromLit (0), lvl);
2906 // just in case someone screws up
2907 wassert (IS_PTR (optype));
2909 if (IS_TRUE_SYMOP (op))
2912 op = geniCodeRValue (op, TRUE);
2915 /* now get rid of the pointer part */
2916 if (isLvaluereq(lvl) && IS_ITEMP (op))
2918 retype = getSpec (rtype = copyLinkChain (optype));
2922 retype = getSpec (rtype = copyLinkChain (optype->next));
2923 /* outputclass needs 2b updated */
2924 setOClass (optype, retype);
2927 op->isGptr = IS_GENPTR (optype);
2929 op->isaddr = (IS_PTR (rtype) ||
2930 IS_STRUCT (rtype) ||
2936 if (!isLvaluereq(lvl))
2937 op = geniCodeRValue (op, TRUE);
2939 setOperandType (op, rtype);
2944 /*-----------------------------------------------------------------*/
2945 /* geniCodeUnaryMinus - does a unary minus of the operand */
2946 /*-----------------------------------------------------------------*/
2948 geniCodeUnaryMinus (operand * op)
2951 sym_link *optype = operandType (op);
2953 if (IS_LITERAL (optype))
2954 return operandFromLit (-floatFromVal (op->operand.valOperand));
2956 ic = newiCode (UNARYMINUS, op, NULL);
2957 IC_RESULT (ic) = newiTempOperand (optype, 0);
2959 return IC_RESULT (ic);
2962 /*-----------------------------------------------------------------*/
2963 /* geniCodeLeftShift - gen i code for left shift */
2964 /*-----------------------------------------------------------------*/
2966 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2971 ic = newiCode (LEFT_OP, left, right);
2973 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2974 IC_RESULT (ic) = newiTempOperand (resType, 0);
2976 return IC_RESULT (ic);
2979 /*-----------------------------------------------------------------*/
2980 /* geniCodeRightShift - gen i code for right shift */
2981 /*-----------------------------------------------------------------*/
2983 geniCodeRightShift (operand * left, operand * right)
2987 ic = newiCode (RIGHT_OP, left, right);
2988 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2990 return IC_RESULT (ic);
2993 /*-----------------------------------------------------------------*/
2994 /* geniCodeLogic- logic code */
2995 /*-----------------------------------------------------------------*/
2997 geniCodeLogic (operand * left, operand * right, int op, ast *tree)
3000 sym_link *ctype, *ttype;
3001 sym_link *rtype = operandType (right);
3002 sym_link *ltype = operandType (left);
3004 /* left is integral type and right is literal then
3005 check if the literal value is within bounds */
3006 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
3008 CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE);
3011 case CCR_ALWAYS_TRUE:
3012 case CCR_ALWAYS_FALSE:
3013 if (!options.lessPedantic)
3014 werror (W_COMP_RANGE, "true resp. false");
3015 return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0);
3021 /* if one operand is a pointer and the other is a literal generic void pointer,
3022 change the type of the literal generic void pointer to match the other pointer */
3023 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
3024 && IS_PTR (rtype) && !IS_GENPTR(rtype))
3026 /* find left's definition */
3027 ic = (iCode *) setFirstItem (iCodeChain);
3030 if (((ic->op == CAST) || (ic->op == '='))
3031 && isOperandEqual(left, IC_RESULT (ic)))
3034 ic = setNextItem (iCodeChain);
3036 /* if casting literal to generic pointer, then cast to rtype instead */
3037 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3039 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3040 ltype = operandType(left);
3043 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3044 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3046 /* find right's definition */
3047 ic = (iCode *) setFirstItem (iCodeChain);
3050 if (((ic->op == CAST) || (ic->op == '='))
3051 && isOperandEqual(right, IC_RESULT (ic)))
3054 ic = setNextItem (iCodeChain);
3056 /* if casting literal to generic pointer, then cast to rtype instead */
3057 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3059 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3060 rtype = operandType(right);
3064 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
3066 ic = newiCode (op, left, right);
3067 /* store 0 or 1 in result */
3068 ttype = (tree && IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3069 IC_RESULT (ic) = newiTempOperand (ttype, 1);
3071 /* if comparing float
3072 and not a '==' || '!=' || '&&' || '||' (these
3074 if (IS_FLOAT(ctype) &&
3081 /* if comparing a fixed type use support functions */
3082 if (IS_FIXED(ctype))
3086 return IC_RESULT (ic);
3089 /*-----------------------------------------------------------------*/
3090 /* geniCodeLogicAndOr - && || operations */
3091 /*-----------------------------------------------------------------*/
3093 geniCodeLogicAndOr (ast *tree, int lvl)
3097 symbol *falseLabel = newiTempLabel (NULL);
3098 symbol *trueLabel = newiTempLabel (NULL);
3099 symbol *exitLabel = newiTempLabel (NULL);
3100 operand *op, *result, *condition;
3102 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3103 They can be reenabled by executing the following block. If you find
3104 a decent optimization you could start right here:
3109 operand *leftOp, *rightOp;
3111 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3112 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3114 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3118 /* generate two IFX for the '&&' or '||' op */
3120 /* evaluate left operand */
3121 condition = ast2iCode (tree->left, lvl + 1);
3122 op = geniCodeRValue (condition, FALSE);
3124 /* test left operand */
3125 if (tree->opval.op == AND_OP)
3126 ic = newiCodeCondition (op, NULL, falseLabel);
3128 ic = newiCodeCondition (op, trueLabel, NULL);
3131 /* evaluate right operand */
3132 condition = ast2iCode (tree->right, lvl + 1);
3133 op = geniCodeRValue (condition, FALSE);
3135 /* test right operand */
3136 ic = newiCodeCondition (op, trueLabel, NULL);
3139 /* store 0 or 1 in result */
3140 type = (IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3141 result = newiTempOperand (type, 1);
3143 geniCodeLabel (falseLabel);
3144 geniCodeAssign (result, operandFromLit (0), 0, 0);
3145 /* generate an unconditional goto */
3146 geniCodeGoto (exitLabel);
3148 geniCodeLabel (trueLabel);
3149 geniCodeAssign (result, operandFromLit (1), 0, 0);
3151 geniCodeLabel (exitLabel);
3156 /*-----------------------------------------------------------------*/
3157 /* geniCodeUnary - for a generic unary operation */
3158 /*-----------------------------------------------------------------*/
3160 geniCodeUnary (operand * op, int oper)
3162 iCode *ic = newiCode (oper, op, NULL);
3164 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3166 return IC_RESULT (ic);
3169 /*-----------------------------------------------------------------*/
3170 /* geniCodeBinary - for a generic binary operation */
3171 /*-----------------------------------------------------------------*/
3173 geniCodeBinary (operand * left, operand * right, int oper)
3175 iCode *ic = newiCode (oper, left, right);
3177 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3179 return IC_RESULT (ic);
3182 /*-----------------------------------------------------------------*/
3183 /* geniCodeConditional - geniCode for '?' ':' operation */
3184 /*-----------------------------------------------------------------*/
3186 geniCodeConditional (ast * tree,int lvl)
3189 symbol *falseLabel = newiTempLabel (NULL);
3190 symbol *exitLabel = newiTempLabel (NULL);
3191 ast *astTrue = tree->right->left;
3192 ast *astFalse = tree->right->right;
3193 operand *cond = ast2iCode (tree->left, lvl+1);
3194 operand *result = newiTempOperand (tree->ftype, 0);
3195 operand *opTrue, *opFalse;
3197 ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel);
3200 opTrue = ast2iCode (astTrue, lvl+1);
3202 /* move the value to the new operand */
3203 geniCodeAssign (result, geniCodeRValue (opTrue, FALSE), 0, 0);
3205 /* generate an unconditional goto */
3206 geniCodeGoto (exitLabel);
3208 /* now for the right side */
3209 geniCodeLabel (falseLabel);
3211 opFalse = ast2iCode (astFalse, lvl+1);
3212 geniCodeAssign (result, geniCodeRValue (opFalse, FALSE), 0, 0);
3214 /* create the exit label */
3215 geniCodeLabel (exitLabel);
3220 /*-----------------------------------------------------------------*/
3221 /* geniCodeAssign - generate code for assignment */
3222 /*-----------------------------------------------------------------*/
3224 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3227 sym_link *ltype = operandType (left);
3228 sym_link *rtype = operandType (right);
3230 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3232 werror (E_LVALUE_REQUIRED, "assignment");
3236 /* left is integral type and right is literal then
3237 check if the literal value is within bounds */
3238 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3239 checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3240 !options.lessPedantic)
3242 werror (W_LIT_OVERFLOW);
3245 /* if the left & right type don't exactly match */
3246 /* if pointer set then make sure the check is
3247 done with the type & not the pointer */
3248 /* then cast rights type to left */
3250 /* first check the type for pointer assignement */
3251 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3252 compareType (ltype, rtype) <= 0)
3255 right = geniCodeCast (ltype, right, TRUE);
3256 else if (compareType (ltype->next, rtype) < 0)
3257 right = geniCodeCast (ltype->next, right, TRUE);
3259 else if (compareType (ltype, rtype) < 0)
3260 right = geniCodeCast (ltype, right, TRUE);
3262 /* If left is a true symbol & ! volatile
3263 create an assignment to temporary for
3264 the right & then assign this temporary
3265 to the symbol. This is SSA (static single
3266 assignment). Isn't it simple and folks have
3267 published mountains of paper on it */
3268 if (IS_TRUE_SYMOP (left) &&
3269 !isOperandVolatile (left, FALSE) &&
3270 isOperandGlobal (left))
3275 if (IS_TRUE_SYMOP (right))
3276 sym = OP_SYMBOL (right);
3277 ic = newiCode ('=', NULL, right);
3278 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3279 /* avoid double fetch from volatile right, see bug 1369874 */
3280 if (!isOperandVolatile (right, FALSE))
3281 SPIL_LOC (newRight) = sym;
3286 ic = newiCode ('=', NULL, right);
3287 IC_RESULT (ic) = left;
3290 /* if left isgptr flag is set then support
3291 routine will be required */
3295 ic->nosupdate = nosupdate;
3296 /* left could be a pointer assignment,
3297 return the properly casted right instead */
3301 /*-----------------------------------------------------------------*/
3302 /* geniCodeDummyRead - generate code for dummy read */
3303 /*-----------------------------------------------------------------*/
3305 geniCodeDummyRead (operand * op)
3308 sym_link *type = operandType (op);
3310 if (!IS_VOLATILE(type))
3313 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3319 /*-----------------------------------------------------------------*/
3320 /* geniCodeSEParms - generate code for side effecting fcalls */
3321 /*-----------------------------------------------------------------*/
3323 geniCodeSEParms (ast * parms,int lvl)
3328 if (parms->type == EX_OP && parms->opval.op == PARAM)
3330 geniCodeSEParms (parms->left,lvl);
3331 geniCodeSEParms (parms->right,lvl);
3335 /* hack don't like this but too lazy to think of
3337 if (IS_ADDRESS_OF_OP (parms))
3338 parms->left->lvalue = 1;
3340 if (IS_CAST_OP (parms) &&
3341 IS_PTR (parms->ftype) &&
3342 IS_ADDRESS_OF_OP (parms->right))
3343 parms->right->left->lvalue = 1;
3345 parms->opval.oprnd =
3346 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3348 parms->type = EX_OPERAND;
3349 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3350 SPEC_ARGREG(parms->ftype);
3353 /*-----------------------------------------------------------------*/
3354 /* geniCodeParms - generates parameters */
3355 /*-----------------------------------------------------------------*/
3357 geniCodeParms (ast * parms, value *argVals, int *stack,
3358 sym_link * ftype, int lvl)
3366 if (argVals==NULL) {
3368 argVals = FUNC_ARGS (ftype);
3371 /* if this is a param node then do the left & right */
3372 if (parms->type == EX_OP && parms->opval.op == PARAM)
3374 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3375 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3379 /* get the parameter value */
3380 if (parms->type == EX_OPERAND)
3381 pval = parms->opval.oprnd;
3384 /* maybe this else should go away ?? */
3385 /* hack don't like this but too lazy to think of
3387 if (IS_ADDRESS_OF_OP (parms))
3388 parms->left->lvalue = 1;
3390 if (IS_CAST_OP (parms) &&
3391 IS_PTR (parms->ftype) &&
3392 IS_ADDRESS_OF_OP (parms->right))
3393 parms->right->left->lvalue = 1;
3395 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3398 /* if register parm then make it a send */
3399 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3400 IFFUNC_ISBUILTIN(ftype))
3402 ic = newiCode (SEND, pval, NULL);
3403 ic->argreg = SPEC_ARGREG(parms->etype);
3404 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3409 /* now decide whether to push or assign */
3410 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3414 operand *top = operandFromSymbol (argVals->sym);
3415 /* clear useDef and other bitVectors */
3416 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3417 geniCodeAssign (top, pval, 1, 0);
3421 sym_link *p = operandType (pval);
3423 ic = newiCode (IPUSH, pval, NULL);
3425 /* update the stack adjustment */
3426 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3431 argVals=argVals->next;
3435 /*-----------------------------------------------------------------*/
3436 /* geniCodeCall - generates temp code for calling */
3437 /*-----------------------------------------------------------------*/
3439 geniCodeCall (operand * left, ast * parms,int lvl)
3443 sym_link *type, *etype;
3447 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3448 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3449 werror (E_FUNCTION_EXPECTED);
3450 return operandFromValue(valueFromLit(0));
3453 /* take care of parameters with side-effecting
3454 function calls in them, this is required to take care
3455 of overlaying function parameters */
3456 geniCodeSEParms (parms,lvl);
3458 ftype = operandType (left);
3459 if (IS_FUNCPTR (ftype))
3460 ftype = ftype->next;
3462 /* first the parameters */
3463 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3465 /* now call : if symbol then pcall */
3466 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3467 ic = newiCode (PCALL, left, NULL);
3469 ic = newiCode (CALL, left, NULL);
3472 type = copyLinkChain (ftype->next);
3473 etype = getSpec (type);
3474 SPEC_EXTR (etype) = 0;
3475 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3479 /* stack adjustment after call */
3480 ic->parmBytes = stack;
3485 /*-----------------------------------------------------------------*/
3486 /* geniCodeReceive - generate intermediate code for "receive" */
3487 /*-----------------------------------------------------------------*/
3489 geniCodeReceive (value * args, operand * func)
3491 unsigned char paramByteCounter = 0;
3493 /* for all arguments that are passed in registers */
3496 if (IS_REGPARM (args->etype))
3498 operand *opr = operandFromValue (args);
3500 symbol *sym = OP_SYMBOL (opr);
3503 /* we will use it after all optimizations
3504 and before liveRange calculation */
3505 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3508 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3509 options.stackAuto == 0 &&
3510 (!(options.model == MODEL_FLAT24)) )
3515 opl = newiTempOperand (args->type, 0);
3517 sym->reqv->key = sym->key;
3518 OP_SYMBOL (sym->reqv)->key = sym->key;
3519 OP_SYMBOL (sym->reqv)->isreqv = 1;
3520 OP_SYMBOL (sym->reqv)->islocal = 0;
3521 SPIL_LOC (sym->reqv) = sym;
3525 ic = newiCode (RECEIVE, func, NULL);
3526 ic->argreg = SPEC_ARGREG(args->etype);
3527 if (ic->argreg == 1) {
3528 currFunc->recvSize = getSize (sym->type);
3530 IC_RESULT (ic) = opr;
3532 /* misuse of parmBytes (normally used for functions)
3533 * to save estimated stack position of this argument.
3534 * Normally this should be zero for RECEIVE iCodes.
3535 * No idea if this causes side effects on other ports. - dw
3537 ic->parmBytes = paramByteCounter;
3539 /* what stack position do we have? */
3540 paramByteCounter += getSize (sym->type);
3549 /*-----------------------------------------------------------------*/
3550 /* geniCodeFunctionBody - create the function body */
3551 /*-----------------------------------------------------------------*/
3553 geniCodeFunctionBody (ast * tree,int lvl)
3561 /* reset the auto generation */
3567 func = ast2iCode (tree->left,lvl+1);
3568 fetype = getSpec (operandType (func));
3570 savefilename = filename;
3571 savelineno = lineno;
3572 filename = OP_SYMBOL (func)->fileDef;
3573 lineno = OP_SYMBOL (func)->lineDef;
3574 /* create an entry label */
3575 geniCodeLabel (entryLabel);
3576 filename = savefilename;
3577 lineno = savelineno;
3579 /* create a proc icode */
3580 ic = newiCode (FUNCTION, func, NULL);
3581 filename = ic->filename = OP_SYMBOL (func)->fileDef;
3582 lineno = ic->lineno = OP_SYMBOL (func)->lineDef;
3587 /* for all parameters that are passed
3588 on registers add a "receive" */
3589 geniCodeReceive (tree->values.args, func);
3591 /* generate code for the body */
3592 ast2iCode (tree->right,lvl+1);
3594 /* create a label for return */
3595 geniCodeLabel (returnLabel);
3597 /* now generate the end proc */
3598 ic = newiCode (ENDFUNCTION, func, NULL);
3604 /*-----------------------------------------------------------------*/
3605 /* geniCodeReturn - gen icode for 'return' statement */
3606 /*-----------------------------------------------------------------*/
3608 geniCodeReturn (operand * op)
3612 /* if the operand is present force an rvalue */
3614 op = geniCodeRValue (op, FALSE);
3616 ic = newiCode (RETURN, op, NULL);
3620 /*-----------------------------------------------------------------*/
3621 /* geniCodeIfx - generates code for extended if statement */
3622 /*-----------------------------------------------------------------*/
3624 geniCodeIfx (ast * tree,int lvl)
3627 operand *condition = ast2iCode (tree->left,lvl+1);
3630 /* if condition is null then exit */
3634 condition = geniCodeRValue (condition, FALSE);
3636 cetype = getSpec (operandType (condition));
3637 /* if the condition is a literal */
3638 if (IS_LITERAL (cetype))
3640 if (floatFromVal (condition->operand.valOperand))
3642 if (tree->trueLabel)
3643 geniCodeGoto (tree->trueLabel);
3649 if (tree->falseLabel)
3650 geniCodeGoto (tree->falseLabel);
3655 if (tree->trueLabel)
3657 ic = newiCodeCondition (condition,
3662 if (tree->falseLabel)
3663 geniCodeGoto (tree->falseLabel);
3667 ic = newiCodeCondition (condition,
3674 ast2iCode (tree->right,lvl+1);
3677 /*-----------------------------------------------------------------*/
3678 /* geniCodeJumpTable - tries to create a jump table for switch */
3679 /*-----------------------------------------------------------------*/
3681 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3683 int min, max, cnt = 1;
3690 int needRangeCheck = !optimize.noJTabBoundary
3691 || tree->values.switchVals.swDefault;
3692 sym_link *cetype = getSpec (operandType (cond));
3693 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3694 int sizeofMatchJump, sizeofJumpTable;
3697 if (!tree || !caseVals)
3700 /* the criteria for creating a jump table is */
3701 /* all integer numbers between the maximum & minimum must */
3702 /* be present , the maximum value should not exceed 255 */
3703 /* If not all integer numbers are present the algorithm */
3704 /* inserts jumps to the default label for the missing numbers */
3705 /* and decides later whether it is worth it */
3706 min = (int) ulFromVal (vch = caseVals);
3713 max = (int) ulFromVal (vch);
3715 /* Exit if the range is too large to handle with a jump table. */
3716 if (1 + max - min > port->jumptableCost.maxCount)
3719 switch (getSize (operandType (cond)))
3721 case 1: sizeIndex = 0; break;
3722 case 2: sizeIndex = 1; break;
3723 case 4: sizeIndex = 2; break;
3727 /* Compute the size cost of the range check and subtraction. */
3729 sizeofZeroMinCost = 0;
3733 if (!(min==0 && IS_UNSIGNED (cetype)))
3734 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3735 if (!IS_UNSIGNED (cetype))
3736 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3737 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3740 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3742 /* If the size cost of handling a non-zero minimum exceeds the */
3743 /* cost of extending the range down to zero, then it might be */
3744 /* better to extend the range to zero. */
3745 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3746 >= (min * port->jumptableCost.sizeofElement))
3748 /* Only extend the jump table if it would still be manageable. */
3749 if (1 + max <= port->jumptableCost.maxCount)
3752 if (IS_UNSIGNED (cetype))
3755 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3759 /* Compute the total size cost of a jump table. */
3760 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3761 + port->jumptableCost.sizeofDispatch
3762 + sizeofMinCost + sizeofMaxCost;
3764 /* Compute the total size cost of a match & jump sequence */
3765 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3767 /* If the size cost of the jump table is uneconomical then exit */
3768 if (sizeofMatchJump < sizeofJumpTable)
3771 /* The jump table is preferable. */
3773 /* First, a label for the default or missing cases. */
3774 if (tree->values.switchVals.swDefault)
3776 SNPRINTF (buffer, sizeof(buffer),
3778 tree->values.switchVals.swNum);
3782 SNPRINTF (buffer, sizeof(buffer),
3784 tree->values.switchVals.swNum);
3786 falseLabel = newiTempLabel (buffer);
3788 /* Build the list of labels for the jump table. */
3790 t = (int) ulFromVal (vch);
3791 for (i=min; i<=max; i++)
3795 /* Explicit case: make a new label for it. */
3796 SNPRINTF (buffer, sizeof(buffer),
3798 tree->values.switchVals.swNum,
3800 addSet (&labels, newiTempLabel (buffer));
3803 t = (int) ulFromVal (vch);
3807 /* Implicit case: use the default label. */
3808 addSet (&labels, falseLabel);
3812 /* first we rule out the boundary conditions */
3813 /* if only optimization says so */
3816 sym_link *cetype = getSpec (operandType (cond));
3817 /* no need to check the lower bound if
3818 the condition is unsigned & minimum value is zero */
3819 if (!(min == 0 && IS_UNSIGNED (cetype)))
3821 boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL);
3822 ic = newiCodeCondition (boundary, falseLabel, NULL);
3826 /* now for upper bounds */
3827 boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL);
3828 ic = newiCodeCondition (boundary, falseLabel, NULL);
3832 /* if the min is not zero then we no make it zero */
3835 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3836 if (!IS_LITERAL(getSpec(operandType(cond))))
3837 setOperandType (cond, UCHARTYPE);
3840 /* now create the jumptable */
3841 ic = newiCode (JUMPTABLE, NULL, NULL);
3842 IC_JTCOND (ic) = cond;
3843 IC_JTLABELS (ic) = labels;
3848 /*-----------------------------------------------------------------*/
3849 /* geniCodeSwitch - changes a switch to a if statement */
3850 /*-----------------------------------------------------------------*/
3852 geniCodeSwitch (ast * tree,int lvl)
3855 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3856 value *caseVals = tree->values.switchVals.swVals;
3857 symbol *trueLabel, *falseLabel;
3859 /* If the condition is a literal, then just jump to the */
3860 /* appropriate case label. */
3861 if (IS_LITERAL(getSpec(operandType(cond))))
3863 int switchVal, caseVal;
3865 switchVal = (int) ulFromVal (cond->operand.valOperand);
3868 caseVal = (int) ulFromVal (caseVals);
3869 if (caseVal == switchVal)
3871 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3872 tree->values.switchVals.swNum, caseVal);
3873 trueLabel = newiTempLabel (buffer);
3874 geniCodeGoto (trueLabel);
3877 caseVals = caseVals->next;
3879 goto defaultOrBreak;
3882 /* If cond is volatile, it might change while we are trying to */
3883 /* find the matching case. To avoid this possibility, make a */
3884 /* non-volatile copy to use instead. */
3885 if (IS_OP_VOLATILE (cond))
3890 newcond = newiTempOperand (operandType (cond), TRUE);
3891 newcond->isvolatile = 0;
3892 ic = newiCode ('=', NULL, cond);
3893 IC_RESULT (ic) = newcond;
3898 /* if we can make this a jump table */
3899 if (geniCodeJumpTable (cond, caseVals, tree))
3900 goto jumpTable; /* no need for the comparison */
3902 /* for the cases defined do */
3906 operand *compare = geniCodeLogic (cond,
3907 operandFromValue (caseVals),
3910 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3911 tree->values.switchVals.swNum,
3912 (int) ulFromVal (caseVals));
3913 trueLabel = newiTempLabel (buffer);
3915 ic = newiCodeCondition (compare, trueLabel, NULL);
3917 caseVals = caseVals->next;
3922 /* if default is present then goto break else break */
3923 if (tree->values.switchVals.swDefault)
3925 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3929 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3932 falseLabel = newiTempLabel (buffer);
3933 geniCodeGoto (falseLabel);
3936 ast2iCode (tree->right,lvl+1);
3939 /*-----------------------------------------------------------------*/
3940 /* geniCodeInline - intermediate code for inline assembler */
3941 /*-----------------------------------------------------------------*/
3943 geniCodeInline (ast * tree)
3947 ic = newiCode (INLINEASM, NULL, NULL);
3948 IC_INLINE (ic) = tree->values.inlineasm;
3952 /*-----------------------------------------------------------------*/
3953 /* geniCodeArrayInit - intermediate code for array initializer */
3954 /*-----------------------------------------------------------------*/
3956 geniCodeArrayInit (ast * tree, operand *array)
3960 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3961 ic = newiCode (ARRAYINIT, array, NULL);
3962 IC_ARRAYILIST (ic) = tree->values.constlist;
3964 operand *left=newOperand(), *right=newOperand();
3965 left->type=right->type=SYMBOL;
3966 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3967 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3968 ic = newiCode (ARRAYINIT, left, right);
3973 /*-----------------------------------------------------------------*/
3974 /* geniCodeCritical - intermediate code for a critical statement */
3975 /*-----------------------------------------------------------------*/
3977 geniCodeCritical (ast *tree, int lvl)
3983 if (!options.stackAuto && !TARGET_IS_HC08)
3985 type = newLink(SPECIFIER);
3986 SPEC_VOLATILE(type) = 1;
3987 SPEC_NOUN(type) = V_BIT;
3988 SPEC_SCLS(type) = S_BIT;
3989 SPEC_BLEN(type) = 1;
3990 SPEC_BSTR(type) = 0;
3991 op = newiTempOperand(type, 1);
3994 /* If op is NULL, the original interrupt state will saved on */
3995 /* the stack. Otherwise, it will be saved in op. */
3997 /* Generate a save of the current interrupt state & disable */
3998 ic = newiCode (CRITICAL, NULL, NULL);
3999 IC_RESULT (ic) = op;
4002 /* Generate the critical code sequence */
4003 if (tree->left && tree->left->type == EX_VALUE)
4004 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4006 ast2iCode (tree->left,lvl+1);
4008 /* Generate a restore of the original interrupt state */
4009 ic = newiCode (ENDCRITICAL, NULL, op);
4013 /*-----------------------------------------------------------------*/
4014 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
4015 /* particular case. Ie : assigning or dereferencing array or ptr */
4016 /*-----------------------------------------------------------------*/
4017 set * lvaluereqSet = NULL;
4018 typedef struct lvalItem
4025 /*-----------------------------------------------------------------*/
4026 /* addLvaluereq - add a flag for lvalreq for current ast level */
4027 /*-----------------------------------------------------------------*/
4028 void addLvaluereq(int lvl)
4030 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
4033 addSetHead(&lvaluereqSet,lpItem);
4036 /*-----------------------------------------------------------------*/
4037 /* delLvaluereq - del a flag for lvalreq for current ast level */
4038 /*-----------------------------------------------------------------*/
4042 lpItem = getSet(&lvaluereqSet);
4043 if(lpItem) Safe_free(lpItem);
4045 /*-----------------------------------------------------------------*/
4046 /* clearLvaluereq - clear lvalreq flag */
4047 /*-----------------------------------------------------------------*/
4048 void clearLvaluereq()
4051 lpItem = peekSet(lvaluereqSet);
4052 if(lpItem) lpItem->req = 0;
4054 /*-----------------------------------------------------------------*/
4055 /* getLvaluereq - get the last lvalreq level */
4056 /*-----------------------------------------------------------------*/
4057 int getLvaluereqLvl()
4060 lpItem = peekSet(lvaluereqSet);
4061 if(lpItem) return lpItem->lvl;
4064 /*-----------------------------------------------------------------*/
4065 /* isLvaluereq - is lvalreq valid for this level ? */
4066 /*-----------------------------------------------------------------*/
4067 int isLvaluereq(int lvl)
4070 lpItem = peekSet(lvaluereqSet);
4071 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4075 /*-----------------------------------------------------------------*/
4076 /* ast2iCode - creates an icodeList from an ast */
4077 /*-----------------------------------------------------------------*/
4079 ast2iCode (ast * tree,int lvl)
4081 operand *left = NULL;
4082 operand *right = NULL;
4086 /* set the global variables for filename & line number */
4088 filename = tree->filename;
4090 lineno = tree->lineno;
4092 block = tree->block;
4094 scopeLevel = tree->level;
4096 seqPoint = tree->seqPoint;
4098 if (tree->type == EX_VALUE)
4099 return operandFromValue (tree->opval.val);
4101 if (tree->type == EX_LINK)
4102 return operandFromLink (tree->opval.lnk);
4104 /* if we find a nullop */
4105 if (tree->type == EX_OP &&
4106 (tree->opval.op == NULLOP ||
4107 tree->opval.op == BLOCK))
4109 if (tree->left && tree->left->type == EX_VALUE)
4110 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4112 ast2iCode (tree->left,lvl+1);
4113 if (tree->right && tree->right->type == EX_VALUE)
4114 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4116 ast2iCode (tree->right,lvl+1);
4120 /* special cases for not evaluating */
4121 if (tree->opval.op != ':' &&
4122 tree->opval.op != '?' &&
4123 tree->opval.op != CALL &&
4124 tree->opval.op != IFX &&
4125 tree->opval.op != AND_OP &&
4126 tree->opval.op != OR_OP &&
4127 tree->opval.op != LABEL &&
4128 tree->opval.op != GOTO &&
4129 tree->opval.op != SWITCH &&
4130 tree->opval.op != FUNCTION &&
4131 tree->opval.op != INLINEASM &&
4132 tree->opval.op != CRITICAL)
4135 if (IS_ASSIGN_OP (tree->opval.op) ||
4136 IS_DEREF_OP (tree) ||
4137 (tree->opval.op == '&' && !tree->right) ||
4138 tree->opval.op == PTR_OP)
4141 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4142 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4145 left = operandFromAst (tree->left,lvl);
4147 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4148 left = geniCodeRValue (left, TRUE);
4152 left = operandFromAst (tree->left,lvl);
4154 if (tree->opval.op == INC_OP ||
4155 tree->opval.op == DEC_OP)
4158 right = operandFromAst (tree->right,lvl);
4163 right = operandFromAst (tree->right,lvl);
4167 /* now depending on the type of operand */
4168 /* this will be a biggy */
4169 switch (tree->opval.op)
4172 case '[': /* array operation */
4174 //sym_link *ltype = operandType (left);
4175 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4176 left = geniCodeRValue (left, FALSE);
4177 right = geniCodeRValue (right, TRUE);
4180 return geniCodeArray (left, right,lvl);
4182 case '.': /* structure dereference */
4183 if (IS_PTR (operandType (left)))
4184 left = geniCodeRValue (left, TRUE);
4186 left = geniCodeRValue (left, FALSE);
4188 return geniCodeStruct (left, right, tree->lvalue);
4190 case PTR_OP: /* structure pointer dereference */
4193 pType = operandType (left);
4194 left = geniCodeRValue (left, TRUE);
4196 setOClass (pType, getSpec (operandType (left)));
4199 return geniCodeStruct (left, right, tree->lvalue);
4201 case INC_OP: /* increment operator */
4203 return geniCodePostInc (left);
4205 return geniCodePreInc (right, tree->lvalue);
4207 case DEC_OP: /* decrement operator */
4209 return geniCodePostDec (left);
4211 return geniCodePreDec (right, tree->lvalue);
4213 case '&': /* bitwise and or address of operator */
4215 { /* this is a bitwise operator */
4216 left = geniCodeRValue (left, FALSE);
4217 right = geniCodeRValue (right, FALSE);
4218 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4221 return geniCodeAddressOf (left);
4223 case '|': /* bitwise or & xor */
4225 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4226 geniCodeRValue (right, FALSE),
4231 return geniCodeDivision (geniCodeRValue (left, FALSE),
4232 geniCodeRValue (right, FALSE),
4233 getResultTypeFromType (tree->ftype));
4236 return geniCodeModulus (geniCodeRValue (left, FALSE),
4237 geniCodeRValue (right, FALSE),
4238 getResultTypeFromType (tree->ftype));
4241 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4242 geniCodeRValue (right, FALSE),
4243 getResultTypeFromType (tree->ftype));
4245 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4249 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4250 geniCodeRValue (right, FALSE),
4251 getResultTypeFromType (tree->ftype));
4253 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4257 return geniCodeAdd (geniCodeRValue (left, FALSE),
4258 geniCodeRValue (right, FALSE),
4259 getResultTypeFromType (tree->ftype),
4262 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4265 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4266 geniCodeRValue (right, FALSE),
4267 getResultTypeFromType (tree->ftype));
4270 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4271 geniCodeRValue (right, FALSE));
4273 #if 0 // this indeed needs a second thought
4277 // let's keep this simple: get the rvalue we need
4278 op=geniCodeRValue (right, FALSE);
4279 // now cast it to whatever we want
4280 op=geniCodeCast (operandType(left), op, FALSE);
4281 // if this is going to be used as an lvalue, make it so
4287 #else // bug #604575, is it a bug ????
4288 return geniCodeCast (operandType (left),
4289 geniCodeRValue (right, FALSE), FALSE);
4296 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4301 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4302 if (!IS_BIT (operandType (op)))
4303 setOperandType (op, UCHARTYPE);
4308 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4309 geniCodeRValue (right, FALSE),
4311 if (!IS_BIT (operandType (op)))
4312 setOperandType (op, UCHARTYPE);
4317 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4318 geniCodeRValue (right, FALSE),
4320 setOperandType (op, UCHARTYPE);
4325 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4326 geniCodeRValue (right, FALSE),
4328 setOperandType (op, UINTTYPE);
4333 return geniCodeLogicAndOr (tree, lvl);
4340 /* different compilers (even different gccs) evaluate
4341 the two calls in a different order. to get the same
4342 result on all machines we have to specify a clear sequence.
4343 return geniCodeLogic (geniCodeRValue (left, FALSE),
4344 geniCodeRValue (right, FALSE),
4348 operand *leftOp, *rightOp;
4350 leftOp = geniCodeRValue (left , FALSE);
4351 rightOp = geniCodeRValue (right, FALSE);
4353 return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree);
4356 return geniCodeConditional (tree,lvl);
4359 return operandFromLit (getSize (tree->right->ftype));
4363 sym_link *rtype = operandType (right);
4364 sym_link *ltype = operandType (left);
4365 if (IS_PTR (rtype) && IS_ITEMP (right)
4366 && right->isaddr && compareType (rtype->next, ltype) == 1)
4367 right = geniCodeRValue (right, TRUE);
4369 right = geniCodeRValue (right, FALSE);
4371 return geniCodeAssign (left, right, 0, 1);
4375 geniCodeAssign (left,
4376 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4378 geniCodeRValue (right, FALSE),
4379 getResultTypeFromType (tree->ftype)),
4384 geniCodeAssign (left,
4385 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4387 geniCodeRValue (right, FALSE),
4388 getResultTypeFromType (tree->ftype)),
4392 geniCodeAssign (left,
4393 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4395 geniCodeRValue (right, FALSE),
4396 getResultTypeFromType (tree->ftype)),
4400 sym_link *rtype = operandType (right);
4401 sym_link *ltype = operandType (left);
4402 if (IS_PTR (rtype) && IS_ITEMP (right)
4403 && right->isaddr && compareType (rtype->next, ltype) == 1)
4404 right = geniCodeRValue (right, TRUE);
4406 right = geniCodeRValue (right, FALSE);
4409 return geniCodeAssign (left,
4410 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4413 getResultTypeFromType (tree->ftype),
4419 sym_link *rtype = operandType (right);
4420 sym_link *ltype = operandType (left);
4421 if (IS_PTR (rtype) && IS_ITEMP (right)
4422 && right->isaddr && compareType (rtype->next, ltype) == 1)
4424 right = geniCodeRValue (right, TRUE);
4428 right = geniCodeRValue (right, FALSE);
4431 geniCodeAssign (left,
4432 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4435 getResultTypeFromType (tree->ftype)),
4440 geniCodeAssign (left,
4441 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4443 geniCodeRValue (right, FALSE),
4444 getResultTypeFromType (tree->ftype)),
4448 geniCodeAssign (left,
4449 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4451 geniCodeRValue (right, FALSE)), 0, 1);
4454 geniCodeAssign (left,
4455 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4457 geniCodeRValue (right, FALSE),
4459 operandType (left)), 0, 1);
4462 geniCodeAssign (left,
4463 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4465 geniCodeRValue (right, FALSE),
4467 operandType (left)), 0, 1);
4470 geniCodeAssign (left,
4471 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4473 geniCodeRValue (right, FALSE),
4475 operandType (left)), 0, 1);
4477 return geniCodeRValue (right, FALSE);
4480 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4483 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4484 return ast2iCode (tree->right,lvl+1);
4487 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4488 return ast2iCode (tree->right,lvl+1);
4491 geniCodeFunctionBody (tree,lvl);
4495 geniCodeReturn (right);
4499 geniCodeIfx (tree,lvl);
4503 geniCodeSwitch (tree,lvl);
4507 geniCodeInline (tree);
4511 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4515 geniCodeCritical (tree, lvl);
4521 /*-----------------------------------------------------------------*/
4522 /* reverseICChain - gets from the list and creates a linkedlist */
4523 /*-----------------------------------------------------------------*/
4530 while ((loop = getSet (&iCodeChain)))
4542 /*-----------------------------------------------------------------*/
4543 /* iCodeFromAst - given an ast will convert it to iCode */
4544 /*-----------------------------------------------------------------*/
4546 iCodeFromAst (ast * tree)
4548 returnLabel = newiTempLabel ("_return");
4549 entryLabel = newiTempLabel ("_entry");
4551 return reverseiCChain ();
4554 static const char *opTypeToStr(OPTYPE op)
4558 case SYMBOL: return "symbol";
4559 case VALUE: return "value";
4560 case TYPE: return "type";
4562 return "undefined type";
4566 operand *validateOpType(operand *op,
4573 if (op && op->type == type)
4578 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4579 " expected %s, got %s\n",
4580 macro, args, file, line,
4581 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4583 return op; // never reached, makes compiler happy.