1 /*-------------------------------------------------------------------------
3 SDCCicode.c - intermediate code generation etc.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
28 #include "dbuf_string.h"
30 /*-----------------------------------------------------------------*/
31 /* global variables */
33 set *iCodeChain = NULL;
38 char *filename; /* current file name */
39 int lineno = 1; /* current line number */
44 symbol *returnLabel; /* function return label */
45 symbol *entryLabel; /* function entry label */
47 /*-----------------------------------------------------------------*/
48 /* forward definition of some functions */
49 operand *geniCodeAssign (operand *, operand *, int, int);
50 static operand *geniCodeArray (operand *, operand *,int);
51 static operand *geniCodeArray2Ptr (operand *);
52 operand *geniCodeRValue (operand *, bool);
53 operand *geniCodeDerefPtr (operand *,int);
54 int isLvaluereq(int lvl);
55 void setOClass (sym_link * ptr, sym_link * spec);
56 static operand *geniCodeCast (sym_link *, operand *, bool);
58 #define PRINTFUNC(x) void x (struct dbuf_s *dbuf, iCode *ic, char *s)
59 /* forward definition of ic print functions */
60 PRINTFUNC (picGetValueAtAddr);
61 PRINTFUNC (picSetValueAtAddr);
62 PRINTFUNC (picAddrOf);
63 PRINTFUNC (picGeneric);
64 PRINTFUNC (picGenericOne);
66 PRINTFUNC (picAssign);
70 PRINTFUNC (picJumpTable);
71 PRINTFUNC (picInline);
72 PRINTFUNC (picReceive);
73 PRINTFUNC (picDummyRead);
74 PRINTFUNC (picCritical);
75 PRINTFUNC (picEndCritical);
77 iCodeTable codeTable[] =
79 {'!', "not", picGenericOne, NULL},
80 {'~', "~", picGenericOne, NULL},
81 {RRC, "rrc", picGenericOne, NULL},
82 {RLC, "rlc", picGenericOne, NULL},
83 {GETHBIT, "ghbit", picGenericOne, NULL},
84 {GETABIT, "gabit", picGenericOne, NULL},
85 {GETBYTE, "gbyte", picGenericOne, NULL},
86 {GETWORD, "gword", picGenericOne, NULL},
87 {UNARYMINUS, "-", picGenericOne, NULL},
88 {IPUSH, "push", picGenericOne, NULL},
89 {IPOP, "pop", picGenericOne, NULL},
90 {CALL, "call", picGenericOne, NULL},
91 {PCALL, "pcall", picGenericOne, NULL},
92 {FUNCTION, "proc", picGenericOne, NULL},
93 {ENDFUNCTION, "eproc", picGenericOne, NULL},
94 {RETURN, "ret", picGenericOne, NULL},
95 {'+', "+", picGeneric, NULL},
96 {'-', "-", picGeneric, NULL},
97 {'*', "*", picGeneric, NULL},
98 {'/', "/", picGeneric, NULL},
99 {'%', "%", picGeneric, NULL},
100 {'>', ">", picGeneric, NULL},
101 {'<', "<", picGeneric, NULL},
102 {LE_OP, "<=", picGeneric, NULL},
103 {GE_OP, ">=", picGeneric, NULL},
104 {EQ_OP, "==", picGeneric, NULL},
105 {NE_OP, "!=", picGeneric, NULL},
106 {AND_OP, "&&", picGeneric, NULL},
107 {OR_OP, "||", picGeneric, NULL},
108 {'^', "^", picGeneric, NULL},
109 {'|', "|", picGeneric, NULL},
110 {BITWISEAND, "&", picGeneric, NULL},
111 {LEFT_OP, "<<", picGeneric, NULL},
112 {RIGHT_OP, ">>", picGeneric, NULL},
113 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
114 {ADDRESS_OF, "&", picAddrOf, NULL},
115 {CAST, "<>", picCast, NULL},
116 {'=', ":=", picAssign, NULL},
117 {LABEL, "", picLabel, NULL},
118 {GOTO, "", picGoto, NULL},
119 {JUMPTABLE, "jtab", picJumpTable, NULL},
120 {IFX, "if", picIfx, NULL},
121 {INLINEASM, "", picInline, NULL},
122 {RECEIVE, "recv", picReceive, NULL},
123 {SEND, "send", picGenericOne, NULL},
124 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
125 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL},
126 {CRITICAL, "critical_start", picCritical, NULL},
127 {ENDCRITICAL, "critical_end", picEndCritical, NULL},
128 {SWAP, "swap", picGenericOne, NULL}
131 /*-----------------------------------------------------------------*/
132 /* operandName - returns the name of the operand */
133 /*-----------------------------------------------------------------*/
135 printOperand (operand * op, FILE * file)
146 dbuf_init (&dbuf, 1024);
147 ret = dbuf_printOperand(op, &dbuf);
148 dbuf_write_and_destroy (&dbuf, file);
157 dbuf_printOperand (operand * op, struct dbuf_s *dbuf)
168 opetype = getSpec (operandType (op));
169 if (IS_FLOAT (opetype))
170 dbuf_printf (dbuf, "%g {", SPEC_CVAL (opetype).v_float);
171 else if (IS_FIXED16X16 (opetype))
172 dbuf_printf (dbuf, "%g {", doubleFromFixed16x16(SPEC_CVAL (opetype).v_fixed16x16));
174 dbuf_printf (dbuf, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
175 dbuf_printTypeChain (operandType (op), dbuf);
176 dbuf_append_char (dbuf, '}');
182 if(REGA && !getenv("PRINT_SHORT_OPERANDS")) {
183 dbuf_printf (dbuf, "%s [k%d lr%d:%d so:%d]{ ia%d a2p%d re%d rm%d nos%d ru%d dp%d}", /*{ar%d rm%d ru%d p%d a%d u%d i%d au%d k%d ks%d}" , */
184 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
186 OP_LIVEFROM (op), OP_LIVETO (op),
187 OP_SYMBOL (op)->stack,
188 op->isaddr, op->aggr2ptr, OP_SYMBOL (op)->isreqv,
189 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
190 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
193 dbuf_append_char (dbuf, '{');
194 dbuf_printTypeChain (operandType (op), dbuf);
195 if (SPIL_LOC (op) && IS_ITEMP (op))
196 dbuf_printf (dbuf, "}{ sir@ %s", SPIL_LOC (op)->rname);
197 dbuf_append_char (dbuf, '}');
201 /* if assigned to registers */
202 if (OP_SYMBOL (op)->nRegs)
204 if (OP_SYMBOL (op)->isspilt)
206 if (!OP_SYMBOL (op)->remat)
207 if (OP_SYMBOL (op)->usl.spillLoc)
208 dbuf_printf (dbuf, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
209 OP_SYMBOL (op)->usl.spillLoc->rname :
210 OP_SYMBOL (op)->usl.spillLoc->name));
212 dbuf_append_str (dbuf, "[err]");
214 dbuf_append_str (dbuf, "[remat]");
219 dbuf_append_char (dbuf, '[');
220 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
221 dbuf_printf (dbuf, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
222 dbuf_append_char (dbuf, ']');
225 //#else /* } else { */
227 /* (getenv("PRINT_SHORT_OPERANDS") != NULL) */
228 dbuf_printf (dbuf, "%s ", (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
230 if(getenv("PRINT_SHORT_OPERANDS")[0] < '1')
232 dbuf_printf (dbuf, "[lr%d:%d so:%d]",
233 OP_LIVEFROM (op), OP_LIVETO (op),
234 OP_SYMBOL (op)->stack);
237 if(getenv("PRINT_SHORT_OPERANDS")[0] < '2')
239 dbuf_append_char (dbuf, '{');
240 dbuf_printTypeChain (operandType (op), dbuf);
241 if (SPIL_LOC (op) && IS_ITEMP (op))
242 dbuf_printf (dbuf, "}{ sir@ %s", SPIL_LOC (op)->rname);
243 dbuf_append_char (dbuf, '}');
246 /* if assigned to registers */
247 if (OP_SYMBOL (op)->nRegs)
249 if (OP_SYMBOL (op)->isspilt)
251 if (!OP_SYMBOL (op)->remat)
252 if (OP_SYMBOL (op)->usl.spillLoc)
253 dbuf_printf (dbuf, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
254 OP_SYMBOL (op)->usl.spillLoc->rname :
255 OP_SYMBOL (op)->usl.spillLoc->name));
257 dbuf_append_str (dbuf, "[err]");
259 dbuf_append_str (dbuf, "[remat]");
264 dbuf_append_char (dbuf, '[');
265 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
266 dbuf_printf (dbuf, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
267 dbuf_append_char (dbuf, ']');
275 dbuf_append_char (dbuf, '(');
276 dbuf_printTypeChain (op->operand.typeOperand, dbuf);
277 dbuf_append_char (dbuf, ')');
285 /*-----------------------------------------------------------------*/
286 /* print functions */
287 /*-----------------------------------------------------------------*/
288 PRINTFUNC (picGetValueAtAddr)
290 dbuf_append_char (dbuf, '\t');
291 dbuf_printOperand (IC_RESULT (ic), dbuf);
292 dbuf_append_str (dbuf, " = ");
293 dbuf_append_str (dbuf, "@[");
294 dbuf_printOperand (IC_LEFT (ic), dbuf);
295 dbuf_append_str (dbuf, "]\n");
298 PRINTFUNC (picSetValueAtAddr)
300 dbuf_append_char (dbuf, '\t');
301 dbuf_append_str (dbuf, "*[");
302 dbuf_printOperand (IC_LEFT (ic), dbuf);
303 dbuf_append_str (dbuf, "] = ");
304 dbuf_printOperand (IC_RIGHT (ic), dbuf);
305 dbuf_append_char (dbuf, '\n');
308 PRINTFUNC (picAddrOf)
310 dbuf_append_char (dbuf, '\t');
311 dbuf_printOperand (IC_RESULT (ic), dbuf);
312 if (IS_ITEMP (IC_LEFT (ic)))
313 dbuf_append_str (dbuf, " = ");
315 dbuf_append_str (dbuf, " = &[");
316 dbuf_printOperand (IC_LEFT (ic), dbuf);
319 if (IS_ITEMP (IC_LEFT (ic)))
320 dbuf_append_str (dbuf, " offsetAdd ");
322 dbuf_append_str (dbuf, " , ");
323 dbuf_printOperand (IC_RIGHT (ic), dbuf);
325 if (IS_ITEMP (IC_LEFT (ic)))
326 dbuf_append_char (dbuf, '\n');
328 dbuf_append_str (dbuf, "]\n");
331 PRINTFUNC (picJumpTable)
335 dbuf_append_char (dbuf, '\t');
336 dbuf_printf (dbuf, "%s\t", s);
337 dbuf_printOperand (IC_JTCOND (ic), dbuf);
338 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
339 sym = setNextItem (IC_JTLABELS (ic)))
340 dbuf_printf (dbuf, "; %s", sym->name);
341 dbuf_append_char (dbuf, '\n');
344 PRINTFUNC (picGeneric)
346 dbuf_append_char (dbuf, '\t');
347 dbuf_printOperand (IC_RESULT (ic), dbuf);
348 dbuf_append_str (dbuf, " = ");
349 dbuf_printOperand (IC_LEFT (ic), dbuf);
350 dbuf_printf (dbuf, " %s ", s);
351 dbuf_printOperand (IC_RIGHT (ic), dbuf);
352 dbuf_append_char (dbuf, '\n');
355 PRINTFUNC (picGenericOne)
357 dbuf_append_char (dbuf, '\t');
360 dbuf_printOperand (IC_RESULT (ic), dbuf);
361 dbuf_append_str (dbuf, " = ");
366 dbuf_printf (dbuf, "%s ", s);
367 dbuf_printOperand (IC_LEFT (ic), dbuf);
370 if (!IC_RESULT (ic) && !IC_LEFT (ic))
371 dbuf_append_str (dbuf, s);
373 if (ic->op == SEND || ic->op == RECEIVE) {
374 dbuf_printf (dbuf,"{argreg = %d}",ic->argreg);
376 if (ic->op == IPUSH) {
377 dbuf_printf (dbuf,"{parmPush = %d}",ic->parmPush);
379 dbuf_append_char (dbuf, '\n');
384 dbuf_append_char (dbuf, '\t');
385 dbuf_printOperand (IC_RESULT (ic), dbuf);
386 dbuf_append_str (dbuf, " = ");
387 dbuf_printOperand (IC_LEFT (ic), dbuf);
388 dbuf_printOperand (IC_RIGHT (ic), dbuf);
389 dbuf_append_char (dbuf, '\n');
393 PRINTFUNC (picAssign)
395 dbuf_append_char (dbuf, '\t');
397 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
398 dbuf_append_str (dbuf, "*(");
400 dbuf_printOperand (IC_RESULT (ic), dbuf);
402 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
403 dbuf_append_char (dbuf, ')');
405 dbuf_printf (dbuf, " %s ", s);
406 dbuf_printOperand (IC_RIGHT (ic), dbuf);
408 dbuf_append_char (dbuf, '\n');
413 dbuf_printf (dbuf, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
418 dbuf_append_char (dbuf, '\t');
419 dbuf_printf (dbuf, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
424 dbuf_append_char (dbuf, '\t');
425 dbuf_append_str (dbuf, "if ");
426 dbuf_printOperand (IC_COND (ic), dbuf);
429 dbuf_printf (dbuf, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
432 dbuf_printf (dbuf, " != 0 goto %s($%d)", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
434 dbuf_printf (dbuf, "; zzgoto %s\n", IC_FALSE (ic)->name);
435 dbuf_append_char (dbuf, '\n');
439 PRINTFUNC (picInline)
441 dbuf_append_str (dbuf, IC_INLINE (ic));
444 PRINTFUNC (picReceive)
446 dbuf_printOperand (IC_RESULT (ic), dbuf);
447 dbuf_printf (dbuf, " = %s ", s);
448 dbuf_printOperand (IC_LEFT (ic), dbuf);
449 dbuf_append_char (dbuf, '\n');
452 PRINTFUNC (picDummyRead)
454 dbuf_append_char (dbuf, '\t');
455 dbuf_printf (dbuf, "%s ", s);
456 dbuf_printOperand (IC_RIGHT (ic), dbuf);
457 dbuf_append_char (dbuf, '\n');
460 PRINTFUNC (picCritical)
462 dbuf_append_char (dbuf, '\t');
464 dbuf_printOperand (IC_RESULT (ic), dbuf);
466 dbuf_append_str (dbuf, "(stack)");
467 dbuf_printf (dbuf, " = %s ", s);
468 dbuf_append_char (dbuf, '\n');
471 PRINTFUNC (picEndCritical)
473 dbuf_append_char (dbuf, '\t');
474 dbuf_printf (dbuf, "%s = ", s);
476 dbuf_printOperand (IC_RIGHT (ic), dbuf);
478 dbuf_append_str (dbuf, "(stack)");
479 dbuf_append_char (dbuf, '\n');
482 /*-----------------------------------------------------------------*/
483 /* piCode - prints one iCode */
484 /*-----------------------------------------------------------------*/
486 piCode (void *item, FILE * of)
495 icTab = getTableEntry (ic->op);
496 fprintf (of, "%s(%d:%d:%d:%d:%d)\t",
497 ic->filename, ic->lineno,
498 ic->seq, ic->key, ic->depth, ic->supportRtn);
499 dbuf_init (&dbuf, 1024);
500 icTab->iCodePrint (&dbuf, ic, icTab->printName);
501 dbuf_write_and_destroy (&dbuf, of);
507 printiCChain(ic,stdout);
509 /*-----------------------------------------------------------------*/
510 /* printiCChain - prints intermediate code for humans */
511 /*-----------------------------------------------------------------*/
513 printiCChain (iCode * icChain, FILE * of)
521 for (loop = icChain; loop; loop = loop->next)
523 if ((icTab = getTableEntry (loop->op)))
525 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
526 loop->filename, loop->lineno,
527 loop->seq, loop->key, loop->depth, loop->supportRtn);
529 dbuf_init(&dbuf, 1024);
530 icTab->iCodePrint (&dbuf, loop, icTab->printName);
531 dbuf_write_and_destroy (&dbuf, of);
539 /*-----------------------------------------------------------------*/
540 /* newOperand - allocate, init & return a new iCode */
541 /*-----------------------------------------------------------------*/
547 op = Safe_alloc ( sizeof (operand));
553 /*-----------------------------------------------------------------*/
554 /* newiCode - create and return a new iCode entry initialised */
555 /*-----------------------------------------------------------------*/
557 newiCode (int op, operand * left, operand * right)
561 ic = Safe_alloc ( sizeof (iCode));
563 ic->seqPoint = seqPoint;
565 ic->filename = filename;
567 ic->level = scopeLevel;
569 ic->key = iCodeKey++;
571 IC_RIGHT (ic) = right;
576 /*-----------------------------------------------------------------*/
577 /* newiCode for conditional statements */
578 /*-----------------------------------------------------------------*/
580 newiCodeCondition (operand * condition,
586 if (IS_VOID(operandType(condition))) {
587 werror(E_VOID_VALUE_USED);
590 ic = newiCode (IFX, NULL, NULL);
591 IC_COND (ic) = condition;
592 IC_TRUE (ic) = trueLabel;
593 IC_FALSE (ic) = falseLabel;
597 /*-----------------------------------------------------------------*/
598 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
599 /*-----------------------------------------------------------------*/
601 newiCodeLabelGoto (int op, symbol * label)
605 ic = newiCode (op, NULL, NULL);
609 IC_RIGHT (ic) = NULL;
610 IC_RESULT (ic) = NULL;
614 /*-----------------------------------------------------------------*/
615 /* newiTemp - allocate & return a newItemp Variable */
616 /*-----------------------------------------------------------------*/
624 SNPRINTF (buffer, sizeof(buffer), "%s", s);
628 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
631 itmp = newSymbol (buffer, 1);
632 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
638 /*-----------------------------------------------------------------*/
639 /* newiTempLabel - creates a temp variable label */
640 /*-----------------------------------------------------------------*/
642 newiTempLabel (char *s)
646 /* check if this already exists */
647 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
652 itmplbl = newSymbol (s, 1);
656 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
657 itmplbl = newSymbol (buffer, 1);
662 itmplbl->key = labelKey++;
663 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
667 /*-----------------------------------------------------------------*/
668 /* newiTempLoopHeaderLabel - creates a new loop header label */
669 /*-----------------------------------------------------------------*/
671 newiTempLoopHeaderLabel (bool pre)
675 SNPRINTF (buffer, sizeof(buffer), pre ? "preHeaderLbl%d" : LOOPEXITLBL "%d",
677 itmplbl = newSymbol (buffer, 1);
681 itmplbl->key = labelKey++;
682 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
687 /*-----------------------------------------------------------------*/
688 /* initiCode - initialises some iCode related stuff */
689 /*-----------------------------------------------------------------*/
696 /*-----------------------------------------------------------------*/
697 /* copyiCode - make a copy of the iCode given */
698 /*-----------------------------------------------------------------*/
700 copyiCode (iCode * ic)
702 iCode *nic = newiCode (ic->op, NULL, NULL);
704 nic->lineno = ic->lineno;
705 nic->filename = ic->filename;
706 nic->block = ic->block;
707 nic->level = ic->level;
708 nic->parmBytes = ic->parmBytes;
710 /* deal with the special cases first */
714 IC_COND (nic) = operandFromOperand (IC_COND (ic));
715 IC_TRUE (nic) = IC_TRUE (ic);
716 IC_FALSE (nic) = IC_FALSE (ic);
720 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
721 IC_JTLABELS (nic) = IC_JTLABELS (ic);
726 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
727 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
731 IC_INLINE (nic) = IC_INLINE (ic);
735 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
739 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
740 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
741 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
747 /*-----------------------------------------------------------------*/
748 /* getTableEntry - gets the table entry for the given operator */
749 /*-----------------------------------------------------------------*/
751 getTableEntry (int oper)
755 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
756 if (oper == codeTable[i].icode)
757 return &codeTable[i];
762 /*-----------------------------------------------------------------*/
763 /* newiTempOperand - new intermediate temp operand */
764 /*-----------------------------------------------------------------*/
766 newiTempOperand (sym_link * type, char throwType)
769 operand *op = newOperand ();
773 itmp = newiTemp (NULL);
775 etype = getSpec (type);
777 if (IS_LITERAL (etype))
780 /* copy the type information */
782 itmp->etype = getSpec (itmp->type = (throwType ? type :
783 copyLinkChain (type)));
784 if (IS_LITERAL (itmp->etype))
786 SPEC_SCLS (itmp->etype) = S_REGISTER;
787 SPEC_OCLS (itmp->etype) = reg;
790 op->operand.symOperand = itmp;
791 op->key = itmp->key = ++operandKey;
795 /*-----------------------------------------------------------------*/
796 /* operandType - returns the type chain for an operand */
797 /*-----------------------------------------------------------------*/
799 operandType (operand * op)
801 /* depending on type of operand */
806 return op->operand.valOperand->type;
809 return op->operand.symOperand->type;
812 return op->operand.typeOperand;
814 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
815 " operand type not known ");
816 assert (0); /* should never come here */
817 /* Just to keep the compiler happy */
818 return (sym_link *) 0;
822 /*-----------------------------------------------------------------*/
823 /* 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) operandLitValue (left) *
1200 (TYPE_TARGET_ULONG) 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) operandLitValue (left) *
1205 (TYPE_TARGET_UINT) operandLitValue (right);
1207 retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_UINT) ul));
1208 if (ul != (TYPE_TARGET_UINT) ul)
1211 else /* signed int */
1213 /* signed int is handled here in order to detect overflow */
1214 TYPE_TARGET_LONG l = (TYPE_TARGET_INT) operandLitValue (left) *
1215 (TYPE_TARGET_INT) operandLitValue (right);
1217 retval = operandFromValue (valCastLiteral (type, (TYPE_TARGET_INT) l));
1218 if (l != (TYPE_TARGET_INT) l)
1223 /* all others go here: */
1224 retval = operandFromValue (valCastLiteral (type,
1225 operandLitValue (left) *
1226 operandLitValue (right)));
1229 if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
1231 werror (E_DIVIDE_BY_ZERO);
1237 if (IS_UNSIGNED (type))
1239 SPEC_USIGN (let) = 1;
1240 SPEC_USIGN (ret) = 1;
1241 retval = operandFromValue (valCastLiteral (type,
1242 (TYPE_TARGET_ULONG) operandLitValue (left) /
1243 (TYPE_TARGET_ULONG) operandLitValue (right)));
1247 retval = operandFromValue (valCastLiteral (type,
1248 operandLitValue (left) /
1249 operandLitValue (right)));
1254 if ((TYPE_TARGET_ULONG) operandLitValue (right) == 0)
1256 werror (E_DIVIDE_BY_ZERO);
1261 if (IS_UNSIGNED (type))
1262 retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) %
1263 (TYPE_TARGET_ULONG) operandLitValue (right));
1265 retval = operandFromLit ((TYPE_TARGET_LONG) operandLitValue (left) %
1266 (TYPE_TARGET_LONG) operandLitValue (right));
1270 /* The number of left shifts is always unsigned. Signed doesn't make
1271 sense here. Shifting by a negative number is impossible. */
1272 retval = operandFromValue (valCastLiteral (type,
1273 ((TYPE_TARGET_ULONG) operandLitValue (left) <<
1274 (TYPE_TARGET_ULONG) operandLitValue (right))));
1277 /* The number of right shifts is always unsigned. Signed doesn't make
1278 sense here. Shifting by a negative number is impossible. */
1279 if (IS_UNSIGNED(let))
1280 /* unsigned: logic shift right */
1281 retval = operandFromLit ((TYPE_TARGET_ULONG) operandLitValue (left) >>
1282 (TYPE_TARGET_ULONG) operandLitValue (right));
1284 /* signed: arithmetic shift right */
1285 retval = operandFromLit ((TYPE_TARGET_LONG ) operandLitValue (left) >>
1286 (TYPE_TARGET_ULONG) operandLitValue (right));
1289 if (IS_FLOAT (let) || IS_FLOAT (ret))
1291 retval = operandFromLit (operandLitValue (left) ==
1292 operandLitValue (right));
1294 else if (IS_FIXED16X16 (let) || IS_FIXED16X16 (ret))
1296 retval = operandFromLit (operandLitValue (left) ==
1297 operandLitValue (right));
1301 /* this op doesn't care about signedness */
1302 TYPE_TARGET_ULONG l, r;
1304 l = (TYPE_TARGET_ULONG) operandLitValue (left);
1305 r = (TYPE_TARGET_ULONG) operandLitValue (right);
1306 /* In order to correctly compare 'signed int' and 'unsigned int' it's
1307 neccessary to strip them to 16 bit.
1308 Literals are reduced to their cheapest type, therefore left and
1309 right might have different types. It's neccessary to find a
1310 common type: int (used for char too) or long */
1311 if (!IS_LONG (let) &&
1314 r = (TYPE_TARGET_UINT) r;
1315 l = (TYPE_TARGET_UINT) l;
1317 retval = operandFromLit (l == r);
1321 retval = operandFromLit (operandLitValue (left) <
1322 operandLitValue (right));
1325 retval = operandFromLit (operandLitValue (left) <=
1326 operandLitValue (right));
1329 retval = operandFromLit (operandLitValue (left) !=
1330 operandLitValue (right));
1333 retval = operandFromLit (operandLitValue (left) >
1334 operandLitValue (right));
1337 retval = operandFromLit (operandLitValue (left) >=
1338 operandLitValue (right));
1341 retval = operandFromValue (valCastLiteral (type,
1342 (TYPE_TARGET_ULONG)operandLitValue(left) &
1343 (TYPE_TARGET_ULONG)operandLitValue(right)));
1346 retval = operandFromValue (valCastLiteral (type,
1347 (TYPE_TARGET_ULONG)operandLitValue(left) |
1348 (TYPE_TARGET_ULONG)operandLitValue(right)));
1351 retval = operandFromValue (valCastLiteral (type,
1352 (TYPE_TARGET_ULONG)operandLitValue(left) ^
1353 (TYPE_TARGET_ULONG)operandLitValue(right)));
1356 retval = operandFromLit (operandLitValue (left) &&
1357 operandLitValue (right));
1360 retval = operandFromLit (operandLitValue (left) ||
1361 operandLitValue (right));
1365 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
1367 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1373 TYPE_TARGET_ULONG i = (TYPE_TARGET_ULONG) operandLitValue (left);
1375 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1380 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1381 (TYPE_TARGET_ULONG)operandLitValue(right)) & 1);
1384 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1385 (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFF);
1388 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1389 (TYPE_TARGET_ULONG)operandLitValue(right)) & 0xFFFF);
1393 retval = operandFromLit (((TYPE_TARGET_ULONG)operandLitValue(left) >>
1394 ((getSize (let) * 8) - 1)) & 1);
1398 retval = operandFromValue (valCastLiteral (type,
1399 -1 * operandLitValue (left)));
1403 retval = operandFromValue (valCastLiteral (type,
1404 ~((TYPE_TARGET_ULONG)
1405 operandLitValue (left))));
1409 retval = operandFromLit (!operandLitValue (left));
1413 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1414 " operandOperation invalid operator ");
1422 /*-----------------------------------------------------------------*/
1423 /* isOperandEqual - compares two operand & return 1 if they r = */
1424 /*-----------------------------------------------------------------*/
1426 isOperandEqual (operand * left, operand * right)
1428 /* if the pointers are equal then they are equal */
1432 /* if either of them null then false */
1433 if (!left || !right)
1436 if (left->type != right->type)
1439 if (IS_SYMOP (left) && IS_SYMOP (right))
1440 return left->key == right->key;
1442 /* if types are the same */
1446 return isSymbolEqual (left->operand.symOperand,
1447 right->operand.symOperand);
1449 return (compareType (left->operand.valOperand->type,
1450 right->operand.valOperand->type) &&
1451 (floatFromVal (left->operand.valOperand) ==
1452 floatFromVal (right->operand.valOperand)));
1454 if (compareType (left->operand.typeOperand,
1455 right->operand.typeOperand) == 1)
1462 /*-------------------------------------------------------------------*/
1463 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1464 /*-------------------------------------------------------------------*/
1466 isiCodeEqual (iCode * left, iCode * right)
1468 /* if the same pointer */
1472 /* if either of them null */
1473 if (!left || !right)
1476 /* if operand are the same */
1477 if (left->op == right->op)
1480 /* compare all the elements depending on type */
1481 if (left->op != IFX)
1483 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1485 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1491 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1493 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1495 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1504 /*-----------------------------------------------------------------*/
1505 /* newiTempFromOp - create a temp Operand with same attributes */
1506 /*-----------------------------------------------------------------*/
1508 newiTempFromOp (operand * op)
1518 nop = newiTempOperand (operandType (op), TRUE);
1519 nop->isaddr = op->isaddr;
1520 nop->isvolatile = op->isvolatile;
1521 nop->isGlobal = op->isGlobal;
1522 nop->isLiteral = op->isLiteral;
1523 nop->usesDefs = op->usesDefs;
1524 nop->isParm = op->isParm;
1528 /*-----------------------------------------------------------------*/
1529 /* operand from operand - creates an operand holder for the type */
1530 /*-----------------------------------------------------------------*/
1532 operandFromOperand (operand * op)
1538 nop = newOperand ();
1539 nop->type = op->type;
1540 nop->isaddr = op->isaddr;
1542 nop->isvolatile = op->isvolatile;
1543 nop->isGlobal = op->isGlobal;
1544 nop->isLiteral = op->isLiteral;
1545 nop->usesDefs = op->usesDefs;
1546 nop->isParm = op->isParm;
1551 nop->operand.symOperand = op->operand.symOperand;
1554 nop->operand.valOperand = op->operand.valOperand;
1557 nop->operand.typeOperand = op->operand.typeOperand;
1564 /*-----------------------------------------------------------------*/
1565 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1566 /*-----------------------------------------------------------------*/
1568 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1570 operand *nop = operandFromOperand (op);
1572 if (nop->type == SYMBOL)
1574 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1575 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1581 /*-----------------------------------------------------------------*/
1582 /* operandFromSymbol - creates an operand from a symbol */
1583 /*-----------------------------------------------------------------*/
1585 operandFromSymbol (symbol * sym)
1590 /* if the symbol's type is a literal */
1591 /* then it is an enumerator type */
1592 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1593 return operandFromValue (valFromType (sym->etype));
1596 sym->key = ++operandKey;
1598 /* if this an implicit variable, means struct/union */
1599 /* member so just return it */
1600 if (sym->implicit || IS_FUNC (sym->type))
1604 op->operand.symOperand = sym;
1606 op->isvolatile = isOperandVolatile (op, TRUE);
1607 op->isGlobal = isOperandGlobal (op);
1611 /* under the following conditions create a
1612 register equivalent for a local symbol */
1613 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1614 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1616 (!(options.model == MODEL_FLAT24)) ) &&
1617 options.stackAuto == 0)
1620 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1621 !IS_FUNC (sym->type) && /* not a function */
1622 !sym->_isparm && /* not a parameter */
1623 IS_AUTO (sym) && /* is a local auto variable */
1624 !sym->addrtaken && /* whose address has not been taken */
1625 !sym->reqv && /* does not already have a reg equivalence */
1626 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1627 !sym->islbl && /* not a label */
1628 ok /* farspace check */
1632 /* we will use it after all optimizations
1633 and before liveRange calculation */
1634 sym->reqv = newiTempOperand (sym->type, 0);
1635 sym->reqv->key = sym->key;
1636 OP_SYMBOL (sym->reqv)->prereqv = sym;
1637 OP_SYMBOL (sym->reqv)->key = sym->key;
1638 OP_SYMBOL (sym->reqv)->isreqv = 1;
1639 OP_SYMBOL (sym->reqv)->islocal = 1;
1640 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1641 SPIL_LOC (sym->reqv) = sym;
1644 if (!IS_AGGREGATE (sym->type))
1648 op->operand.symOperand = sym;
1651 op->isvolatile = isOperandVolatile (op, TRUE);
1652 op->isGlobal = isOperandGlobal (op);
1653 op->isPtr = IS_PTR (operandType (op));
1654 op->isParm = sym->_isparm;
1659 /* itemp = &[_symbol] */
1661 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1662 IC_LEFT (ic)->type = SYMBOL;
1663 IC_LEFT (ic)->operand.symOperand = sym;
1664 IC_LEFT (ic)->key = sym->key;
1665 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1666 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1667 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1670 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1671 if (IS_ARRAY (sym->type))
1673 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1674 IC_RESULT (ic)->isaddr = 0;
1677 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1681 return IC_RESULT (ic);
1684 /*-----------------------------------------------------------------*/
1685 /* operandFromValue - creates an operand from value */
1686 /*-----------------------------------------------------------------*/
1688 operandFromValue (value * val)
1692 /* if this is a symbol then do the symbol thing */
1694 return operandFromSymbol (val->sym);
1696 /* this is not a symbol */
1699 op->operand.valOperand = val;
1700 op->isLiteral = isOperandLiteral (op);
1704 /*-----------------------------------------------------------------*/
1705 /* operandFromLink - operand from typeChain */
1706 /*-----------------------------------------------------------------*/
1708 operandFromLink (sym_link * type)
1712 /* operand from sym_link */
1718 op->operand.typeOperand = copyLinkChain (type);
1722 /*-----------------------------------------------------------------*/
1723 /* operandFromLit - makes an operand from a literal value */
1724 /*-----------------------------------------------------------------*/
1726 operandFromLit (double i)
1728 return operandFromValue (valueFromLit (i));
1731 /*-----------------------------------------------------------------*/
1732 /* operandFromAst - creates an operand from an ast */
1733 /*-----------------------------------------------------------------*/
1735 operandFromAst (ast * tree,int lvl)
1741 /* depending on type do */
1745 return ast2iCode (tree,lvl+1);
1749 return operandFromValue (tree->opval.val);
1753 return operandFromLink (tree->opval.lnk);
1760 /* Just to keep the compiler happy */
1761 return (operand *) 0;
1764 /*-----------------------------------------------------------------*/
1765 /* setOperandType - sets the operand's type to the given type */
1766 /*-----------------------------------------------------------------*/
1768 setOperandType (operand * op, sym_link * type)
1770 /* depending on the type of operand */
1775 op->operand.valOperand->etype =
1776 getSpec (op->operand.valOperand->type =
1777 copyLinkChain (type));
1781 if (op->operand.symOperand->isitmp)
1782 op->operand.symOperand->etype =
1783 getSpec (op->operand.symOperand->type =
1784 copyLinkChain (type));
1786 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1787 "attempt to modify type of source");
1791 op->operand.typeOperand = copyLinkChain (type);
1797 /*-----------------------------------------------------------------*/
1798 /* Get size in byte of ptr need to access an array */
1799 /*-----------------------------------------------------------------*/
1801 getArraySizePtr (operand * op)
1803 sym_link *ltype = operandType(op);
1807 int size = getSize(ltype);
1808 return((IS_GENPTR(ltype) && GPTRSIZE > FPTRSIZE) ? (size-1) : size);
1813 sym_link *letype = getSpec(ltype);
1814 switch (PTR_TYPE (SPEC_OCLS (letype)))
1826 if (GPTRSIZE > FPTRSIZE)
1827 return (GPTRSIZE-1);
1838 /*-----------------------------------------------------------------*/
1839 /* perform "usual unary conversions" */
1840 /*-----------------------------------------------------------------*/
1843 usualUnaryConversions (operand * op)
1845 if (IS_INTEGRAL (operandType (op)))
1847 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1850 return geniCodeCast (INTTYPE, op, TRUE);
1857 /*-----------------------------------------------------------------*/
1858 /* perform "usual binary conversions" */
1859 /*-----------------------------------------------------------------*/
1862 usualBinaryConversions (operand ** op1, operand ** op2,
1863 RESULT_TYPE resultType, int op)
1866 sym_link *rtype = operandType (*op2);
1867 sym_link *ltype = operandType (*op1);
1869 ctype = computeType (ltype, rtype, resultType, op);
1876 if (IS_CHAR (getSpec (ltype)) && IS_CHAR (getSpec (rtype)))
1878 /* one byte operations: keep signedness for code generator */
1886 *op1 = geniCodeCast (ctype, *op1, TRUE);
1887 *op2 = geniCodeCast (ctype, *op2, TRUE);
1892 /*-----------------------------------------------------------------*/
1893 /* geniCodeValueAtAddress - generate intermeditate code for value */
1895 /*-----------------------------------------------------------------*/
1897 geniCodeRValue (operand * op, bool force)
1900 sym_link *type = operandType (op);
1901 sym_link *etype = getSpec (type);
1903 /* if this is an array & already */
1904 /* an address then return this */
1905 if (IS_AGGREGATE (type) ||
1906 (IS_PTR (type) && !force && !op->isaddr))
1907 return operandFromOperand (op);
1909 /* if this is not an address then must be */
1910 /* rvalue already so return this one */
1914 /* if this is not a temp symbol then */
1915 if (!IS_ITEMP (op) &&
1917 !(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08))
1919 op = operandFromOperand (op);
1924 if (IS_SPEC (type) &&
1925 IS_TRUE_SYMOP (op) &&
1926 (!(IN_FARSPACE (SPEC_OCLS (etype)) && !TARGET_IS_HC08) ||
1927 (options.model == MODEL_FLAT24) ))
1929 op = operandFromOperand (op);
1934 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1935 if (IS_PTR (type) && op->isaddr && force)
1938 type = copyLinkChain (type);
1940 IC_RESULT (ic) = newiTempOperand (type, 1);
1941 IC_RESULT (ic)->isaddr = 0;
1943 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1947 return IC_RESULT (ic);
1950 /*-----------------------------------------------------------------*/
1951 /* geniCodeCast - changes the value from one type to another */
1952 /*-----------------------------------------------------------------*/
1954 geniCodeCast (sym_link * type, operand * op, bool implicit)
1958 sym_link *opetype = getSpec (optype = operandType (op));
1962 /* one of them has size zero then error */
1963 if (IS_VOID (optype))
1965 werror (E_CAST_ZERO);
1969 if (IS_ITEMP (op) && IS_ARRAY (OP_SYMBOL (op)->type))
1971 geniCodeArray2Ptr (op);
1975 /* if the operand is already the desired type then do nothing */
1976 if (compareType (type, optype) == 1)
1979 /* if this is a literal then just change the type & return */
1980 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1982 return operandFromValue (valCastLiteral (type,
1983 operandLitValue (op)));
1986 /* if casting to/from pointers, do some checking */
1987 if (IS_PTR(type)) { // to a pointer
1988 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1989 if (IS_INTEGRAL(optype)) {
1990 // maybe this is NULL, than it's ok.
1991 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1992 if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) {
1993 // no way to set the storage
1994 if (IS_LITERAL(optype)) {
1995 werror(E_LITERAL_GENERIC);
1998 werror(E_NONPTR2_GENPTR);
2001 } else if (implicit) {
2002 werror(W_INTEGRAL2PTR_NOCAST);
2007 // shouldn't do that with float, array or structure unless to void
2008 if (!IS_VOID(getSpec(type)) &&
2009 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2010 werror(E_INCOMPAT_TYPES);
2014 } else { // from a pointer to a pointer
2015 if (IS_GENPTR(type) && IS_VOID(type->next))
2016 { // cast to void* is always allowed
2018 else if (IS_GENPTR(optype) && IS_VOID(optype->next))
2019 { // cast from void* is always allowed
2021 else if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) {
2022 // if not a pointer to a function
2023 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
2024 if (implicit) { // if not to generic, they have to match
2025 if (!IS_GENPTR(type) &&
2026 !((DCL_TYPE(optype) == DCL_TYPE(type)) ||
2027 ((DCL_TYPE(optype) == POINTER) && (DCL_TYPE(type) == IPOINTER))
2031 werror(E_INCOMPAT_PTYPES);
2038 } else { // to a non pointer
2039 if (IS_PTR(optype)) { // from a pointer
2040 if (implicit) { // sneaky
2041 if (IS_INTEGRAL(type)) {
2042 werror(W_PTR2INTEGRAL_NOCAST);
2044 } else { // shouldn't do that with float, array or structure
2045 werror(E_INCOMPAT_TYPES);
2052 printFromToType (optype, type);
2055 /* if they are the same size create an assignment */
2057 /* This seems very dangerous to me, since there are several */
2058 /* optimizations (for example, gcse) that don't notice the */
2059 /* cast hidden in this assignment and may simplify an */
2060 /* iCode to use the original (uncasted) operand. */
2061 /* Unfortunately, other things break when this cast is */
2062 /* made explicit. Need to fix this someday. */
2063 /* -- EEP, 2004/01/21 */
2064 if (getSize (type) == getSize (optype) &&
2065 !IS_BITFIELD (type) &&
2067 !IS_FLOAT (optype) &&
2069 !IS_FIXED (optype) &&
2070 ((IS_SPEC (type) && IS_SPEC (optype)) ||
2071 (!IS_SPEC (type) && !IS_SPEC (optype))))
2073 ic = newiCode ('=', NULL, op);
2074 IC_RESULT (ic) = newiTempOperand (type, 0);
2075 if (IS_TRUE_SYMOP (op) && !IS_VOLATILE (optype))
2076 SPIL_LOC (IC_RESULT (ic)) = OP_SYMBOL (op);
2077 IC_RESULT (ic)->isaddr = 0;
2081 ic = newiCode (CAST, operandFromLink (type),
2082 geniCodeRValue (op, FALSE));
2084 IC_RESULT (ic) = newiTempOperand (type, 0);
2087 /* preserve the storage class & output class */
2088 /* of the original variable */
2089 restype = getSpec (operandType (IC_RESULT (ic)));
2090 if (!IS_LITERAL(opetype) &&
2093 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
2094 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
2097 return IC_RESULT (ic);
2100 /*-----------------------------------------------------------------*/
2101 /* geniCodeLabel - will create a Label */
2102 /*-----------------------------------------------------------------*/
2104 geniCodeLabel (symbol * label)
2108 ic = newiCodeLabelGoto (LABEL, label);
2112 /*-----------------------------------------------------------------*/
2113 /* geniCodeGoto - will create a Goto */
2114 /*-----------------------------------------------------------------*/
2116 geniCodeGoto (symbol * label)
2120 ic = newiCodeLabelGoto (GOTO, label);
2124 /*-----------------------------------------------------------------*/
2125 /* geniCodeMultiply - gen intermediate code for multiplication */
2126 /*-----------------------------------------------------------------*/
2128 geniCodeMultiply (operand * left, operand * right, RESULT_TYPE resultType)
2135 /* if they are both literal then we know the result */
2136 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2137 return operandFromValue (valMult (left->operand.valOperand,
2138 right->operand.valOperand));
2140 if (IS_LITERAL(retype)) {
2141 p2 = powof2 ((TYPE_TARGET_ULONG) floatFromVal (right->operand.valOperand));
2144 resType = usualBinaryConversions (&left, &right, resultType, '*');
2146 rtype = operandType (right);
2147 retype = getSpec (rtype);
2148 ltype = operandType (left);
2149 letype = getSpec (ltype);
2152 /* if the right is a literal & power of 2 */
2153 /* then make it a left shift */
2154 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
2155 efficient in most cases than 2 bytes result = 2 bytes << literal
2156 if port has 1 byte muldiv */
2157 if ((p2 > 0) && !IS_FLOAT (letype) && !IS_FIXED (letype)
2158 && !((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype))
2159 && (port->support.muldiv == 1))
2160 && strcmp (port->target, "pic16") != 0 /* don't shift for pic */
2161 && strcmp (port->target, "pic14") != 0)
2163 if ((resultType == RESULT_TYPE_INT) && (getSize (resType) != getSize (ltype)))
2165 /* LEFT_OP need same size for left and result, */
2166 left = geniCodeCast (resType, left, TRUE);
2167 ltype = operandType (left);
2169 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
2173 /* if the size left or right > 1 then support routine */
2174 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2176 if (IS_LITERAL (retype))
2177 ic = newiCode ('*', right, left); /* multiplication by support routine with one literal */
2179 ic = newiCode ('*', left, right); /* multiplication by support routine */
2184 ic = newiCode ('*', left, right); /* normal multiplication */
2187 IC_RESULT (ic) = newiTempOperand (resType, 1);
2190 return IC_RESULT (ic);
2193 /*-----------------------------------------------------------------*/
2194 /* geniCodeDivision - gen intermediate code for division */
2195 /*-----------------------------------------------------------------*/
2197 geniCodeDivision (operand * left, operand * right, RESULT_TYPE resultType)
2202 sym_link *rtype = operandType (right);
2203 sym_link *retype = getSpec (rtype);
2204 sym_link *ltype = operandType (left);
2205 sym_link *letype = getSpec (ltype);
2207 resType = usualBinaryConversions (&left, &right, resultType, '/');
2209 /* if the right is a literal & power of 2
2210 and left is unsigned then make it a
2212 if (IS_LITERAL (retype) &&
2213 !IS_FLOAT (letype) &&
2214 !IS_FIXED (letype) &&
2215 IS_UNSIGNED(letype) &&
2216 ((p2 = powof2 ((TYPE_TARGET_ULONG)
2217 floatFromVal (right->operand.valOperand))) > 0)) {
2218 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2222 ic = newiCode ('/', left, right); /* normal division */
2223 /* if the size left or right > 1 then support routine */
2224 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2227 IC_RESULT (ic) = newiTempOperand (resType, 0);
2230 return IC_RESULT (ic);
2232 /*-----------------------------------------------------------------*/
2233 /* geniCodeModulus - gen intermediate code for modulus */
2234 /*-----------------------------------------------------------------*/
2236 geniCodeModulus (operand * left, operand * right, RESULT_TYPE resultType)
2242 /* if they are both literal then we know the result */
2243 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2244 return operandFromValue (valMod (left->operand.valOperand,
2245 right->operand.valOperand));
2247 resType = usualBinaryConversions (&left, &right, resultType, '%');
2249 /* now they are the same size */
2250 ic = newiCode ('%', left, right);
2252 /* if the size left or right > 1 then support routine */
2253 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2255 IC_RESULT (ic) = newiTempOperand (resType, 0);
2258 return IC_RESULT (ic);
2261 /*-----------------------------------------------------------------*/
2262 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2263 /*-----------------------------------------------------------------*/
2265 geniCodePtrPtrSubtract (operand * left, operand * right)
2271 /* if they are both literals then */
2272 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2274 result = operandFromValue (valMinus (left->operand.valOperand,
2275 right->operand.valOperand));
2279 ic = newiCode ('-', left, right);
2281 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2285 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2289 // should we really do this? is this ANSI?
2290 return geniCodeDivision (result,
2291 operandFromLit (getSize (ltype->next)),
2295 /*-----------------------------------------------------------------*/
2296 /* geniCodeSubtract - generates code for subtraction */
2297 /*-----------------------------------------------------------------*/
2299 geniCodeSubtract (operand * left, operand * right, RESULT_TYPE resultType)
2306 /* if they both pointers then */
2307 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2308 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2309 return geniCodePtrPtrSubtract (left, right);
2311 /* if they are both literal then we know the result */
2312 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2313 && left->isLiteral && right->isLiteral)
2314 return operandFromValue (valMinus (left->operand.valOperand,
2315 right->operand.valOperand));
2317 /* if left is an array or pointer */
2318 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2320 isarray = left->isaddr;
2321 right = geniCodeMultiply (right,
2322 operandFromLit (getSize (ltype->next)),
2323 (getArraySizePtr(left) >= INTSIZE) ?
2326 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2329 { /* make them the same size */
2330 resType = usualBinaryConversions (&left, &right, resultType, '-');
2333 ic = newiCode ('-', left, right);
2335 IC_RESULT (ic) = newiTempOperand (resType, 1);
2336 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2338 /* if left or right is a float */
2339 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2340 || IS_FIXED (ltype) || IS_FIXED (rtype))
2344 return IC_RESULT (ic);
2347 /*-----------------------------------------------------------------*/
2348 /* geniCodeAdd - generates iCode for addition */
2349 /*-----------------------------------------------------------------*/
2351 geniCodeAdd (operand * left, operand * right, RESULT_TYPE resultType, int lvl)
2360 /* if the right side is LITERAL zero */
2361 /* return the left side */
2362 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (rtype)))
2365 /* if left is literal zero return right */
2366 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (ltype)))
2369 /* if left is a pointer then size */
2370 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2372 isarray = left->isaddr;
2373 // there is no need to multiply with 1
2374 if (getSize (ltype->next) != 1)
2376 size = operandFromLit (getSize (ltype->next));
2377 SPEC_USIGN (getSpec (operandType (size))) = 1;
2378 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2379 right = geniCodeMultiply (right, size, resultType);
2380 /* Even if right is a 'unsigned char',
2381 the result will be a 'signed int' due to the promotion rules.
2382 It doesn't make sense when accessing arrays, so let's fix it here: */
2384 SPEC_USIGN (getSpec (operandType (right))) = 1;
2386 resType = copyLinkChain (ltype);
2389 { // make them the same size
2390 resType = usualBinaryConversions (&left, &right, resultType, '+');
2393 /* if they are both literals then we know */
2394 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2395 && left->isLiteral && right->isLiteral)
2396 return operandFromValue (valPlus (valFromType (ltype),
2397 valFromType (rtype)));
2399 ic = newiCode ('+', left, right);
2401 IC_RESULT (ic) = newiTempOperand (resType, 1);
2402 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2404 /* if left or right is a float then support
2406 if (IS_FLOAT (ltype) || IS_FLOAT (rtype)
2407 || IS_FIXED (ltype) || IS_FIXED (rtype))
2412 return IC_RESULT (ic);
2416 /*-----------------------------------------------------------------*/
2417 /* aggrToPtr - changes an "aggregate" to a "pointer to aggregate" */
2418 /*-----------------------------------------------------------------*/
2420 aggrToPtr (sym_link * type, bool force)
2425 if (IS_PTR (type) && !force)
2428 etype = getSpec (type);
2429 ptype = newLink (DECLARATOR);
2433 /* set the pointer depending on the storage class */
2434 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2438 /*------------------------------------------------------------------*/
2439 /* aggrToPtrDclType - like aggrToPtr, but returns only the DCL_TYPE */
2440 /*------------------------------------------------------------------*/
2442 aggrToPtrDclType (sym_link * type, bool force)
2444 if (IS_PTR (type) && !force)
2445 return DCL_TYPE (type);
2447 /* return the pointer depending on the storage class */
2448 return PTR_TYPE (SPEC_OCLS (getSpec (type)));
2451 /*-----------------------------------------------------------------*/
2452 /* geniCodeArray2Ptr - array to pointer */
2453 /*-----------------------------------------------------------------*/
2455 geniCodeArray2Ptr (operand * op)
2457 sym_link *optype = operandType (op);
2458 sym_link *opetype = getSpec (optype);
2460 /* set the pointer depending on the storage class */
2461 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2468 /*-----------------------------------------------------------------*/
2469 /* geniCodeArray - array access */
2470 /*-----------------------------------------------------------------*/
2472 geniCodeArray (operand * left, operand * right, int lvl)
2476 sym_link *ltype = operandType (left);
2478 RESULT_TYPE resultType;
2480 resultType = (getArraySizePtr(left) >= INTSIZE) ? RESULT_TYPE_INT : RESULT_TYPE_CHAR;
2481 if (DCL_ELEM (ltype))
2483 if (DCL_ELEM (ltype) * getSize (ltype->next) <= 255)
2484 resultType = RESULT_TYPE_CHAR;
2489 if (IS_PTR (ltype->next) && left->isaddr)
2491 left = geniCodeRValue (left, FALSE);
2494 return geniCodeDerefPtr (geniCodeAdd (left, right, resultType, lvl),
2497 size = operandFromLit (getSize (ltype->next));
2498 SPEC_USIGN (getSpec (operandType (size))) = 1;
2499 indexUnsigned = IS_UNSIGNED (getSpec (operandType (right)));
2500 right = geniCodeMultiply (right, size, resultType);
2501 /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules.
2502 It doesn't make sense when accessing arrays, so let's fix it here: */
2504 SPEC_USIGN (getSpec (operandType (right))) = 1;
2505 /* we can check for limits here */
2506 /* already done in SDCCast.c
2507 if (isOperandLiteral (right) &&
2510 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2512 werror (W_IDX_OUT_OF_BOUNDS,
2513 (int) operandLitValue (right) / getSize (ltype->next),
2518 ic = newiCode ('+', left, right);
2520 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2521 !IS_AGGREGATE (ltype->next) &&
2522 !IS_PTR (ltype->next))
2523 ? ltype : ltype->next), 0);
2525 if (!IS_AGGREGATE (ltype->next))
2527 IC_RESULT (ic)->isaddr = 1;
2528 IC_RESULT (ic)->aggr2ptr = 1;
2532 return IC_RESULT (ic);
2535 /*-----------------------------------------------------------------*/
2536 /* geniCodeStruct - generates intermediate code for structures */
2537 /*-----------------------------------------------------------------*/
2539 geniCodeStruct (operand * left, operand * right, bool islval)
2542 sym_link *type = operandType (left);
2543 sym_link *etype = getSpec (type);
2545 symbol *element = getStructElement (SPEC_STRUCT (etype),
2546 right->operand.symOperand);
2548 wassert(IS_SYMOP(right));
2550 /* add the offset */
2551 ic = newiCode ('+', left, operandFromLit (element->offset));
2553 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2555 /* preserve the storage & output class of the struct */
2556 /* as well as the volatile attribute */
2557 retype = getSpec (operandType (IC_RESULT (ic)));
2558 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2559 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2560 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2561 SPEC_CONST (retype) |= SPEC_CONST (etype);
2563 if (IS_PTR (element->type))
2564 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2566 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2569 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2572 /*-----------------------------------------------------------------*/
2573 /* geniCodePostInc - generate int code for Post increment */
2574 /*-----------------------------------------------------------------*/
2576 geniCodePostInc (operand * op)
2580 sym_link *optype = operandType (op);
2582 operand *rv = (IS_ITEMP (op) ?
2583 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2585 sym_link *rvtype = operandType (rv);
2588 /* if this is not an address we have trouble */
2591 werror (E_LVALUE_REQUIRED, "++");
2595 rOp = newiTempOperand (rvtype, 0);
2596 OP_SYMBOL(rOp)->noSpilLoc = 1;
2599 OP_SYMBOL(rv)->noSpilLoc = 1;
2601 geniCodeAssign (rOp, rv, 0, 0);
2603 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2605 werror(W_SIZEOF_VOID);
2606 if (IS_FLOAT (rvtype))
2607 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2608 else if (IS_FIXED16X16 (rvtype))
2609 ic = newiCode ('+', rv, operandFromValue (constFixed16x16Val ("1.0")));
2611 ic = newiCode ('+', rv, operandFromLit (size));
2613 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2616 geniCodeAssign (op, result, 0, 0);
2622 /*-----------------------------------------------------------------*/
2623 /* geniCodePreInc - generate code for preIncrement */
2624 /*-----------------------------------------------------------------*/
2626 geniCodePreInc (operand * op, bool lvalue)
2629 sym_link *optype = operandType (op);
2630 operand *rop = (IS_ITEMP (op) ?
2631 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2633 sym_link *roptype = operandType (rop);
2639 werror (E_LVALUE_REQUIRED, "++");
2643 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2645 werror(W_SIZEOF_VOID);
2646 if (IS_FLOAT (roptype))
2647 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2648 else if (IS_FIXED16X16 (roptype))
2649 ic = newiCode ('+', rop, operandFromValue (constFixed16x16Val ("1.0")));
2651 ic = newiCode ('+', rop, operandFromLit (size));
2652 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2655 (void) geniCodeAssign (op, result, 0, 0);
2656 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2662 /*-----------------------------------------------------------------*/
2663 /* geniCodePostDec - generates code for Post decrement */
2664 /*-----------------------------------------------------------------*/
2666 geniCodePostDec (operand * op)
2670 sym_link *optype = operandType (op);
2672 operand *rv = (IS_ITEMP (op) ?
2673 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2675 sym_link *rvtype = operandType (rv);
2678 /* if this is not an address we have trouble */
2681 werror (E_LVALUE_REQUIRED, "--");
2685 rOp = newiTempOperand (rvtype, 0);
2686 OP_SYMBOL(rOp)->noSpilLoc = 1;
2689 OP_SYMBOL(rv)->noSpilLoc = 1;
2691 geniCodeAssign (rOp, rv, 0, 0);
2693 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2695 werror(W_SIZEOF_VOID);
2696 if (IS_FLOAT (rvtype))
2697 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2698 else if (IS_FIXED16X16 (rvtype))
2699 ic = newiCode ('-', rv, operandFromValue (constFixed16x16Val ("1.0")));
2701 ic = newiCode ('-', rv, operandFromLit (size));
2703 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2706 geniCodeAssign (op, result, 0, 0);
2712 /*-----------------------------------------------------------------*/
2713 /* geniCodePreDec - generate code for pre decrement */
2714 /*-----------------------------------------------------------------*/
2716 geniCodePreDec (operand * op, bool lvalue)
2719 sym_link *optype = operandType (op);
2720 operand *rop = (IS_ITEMP (op) ?
2721 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2723 sym_link *roptype = operandType (rop);
2729 werror (E_LVALUE_REQUIRED, "--");
2733 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2735 werror(W_SIZEOF_VOID);
2736 if (IS_FLOAT (roptype))
2737 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2738 else if (IS_FIXED16X16 (roptype))
2739 ic = newiCode ('-', rop, operandFromValue (constFixed16x16Val ("1.0")));
2741 ic = newiCode ('-', rop, operandFromLit (size));
2742 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2745 (void) geniCodeAssign (op, result, 0, 0);
2746 if (lvalue || IS_TRUE_SYMOP (op) || IS_BITVAR (optype))
2753 /*-----------------------------------------------------------------*/
2754 /* geniCodeBitwise - gen int code for bitWise operators */
2755 /*-----------------------------------------------------------------*/
2757 geniCodeBitwise (operand * left, operand * right,
2758 int oper, sym_link * resType)
2762 left = geniCodeCast (resType, left, TRUE);
2763 right = geniCodeCast (resType, right, TRUE);
2765 ic = newiCode (oper, left, right);
2766 IC_RESULT (ic) = newiTempOperand (resType, 0);
2769 return IC_RESULT (ic);
2772 /*-----------------------------------------------------------------*/
2773 /* geniCodeAddressOf - gens icode for '&' address of operator */
2774 /*-----------------------------------------------------------------*/
2776 geniCodeAddressOf (operand * op)
2780 sym_link *optype = operandType (op);
2781 sym_link *opetype = getSpec (optype);
2783 if (IS_ITEMP (op) && op->isaddr && IS_PTR (optype))
2785 op = operandFromOperand (op);
2790 /* lvalue check already done in decorateType */
2791 /* this must be a lvalue */
2792 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2793 /* werror (E_LVALUE_REQUIRED,"&"); */
2797 p = newLink (DECLARATOR);
2799 /* set the pointer depending on the storage class */
2800 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2802 p->next = copyLinkChain (optype);
2804 /* if already a temp */
2807 setOperandType (op, p);
2812 /* otherwise make this of the type coming in */
2813 ic = newiCode (ADDRESS_OF, op, NULL);
2814 IC_RESULT (ic) = newiTempOperand (p, 1);
2815 IC_RESULT (ic)->isaddr = 0;
2817 return IC_RESULT (ic);
2820 /*-----------------------------------------------------------------*/
2821 /* setOClass - sets the output class depending on the pointer type */
2822 /*-----------------------------------------------------------------*/
2824 setOClass (sym_link * ptr, sym_link * spec)
2826 switch (DCL_TYPE (ptr))
2829 SPEC_OCLS (spec) = data;
2833 SPEC_OCLS (spec) = generic;
2837 SPEC_OCLS (spec) = xdata;
2841 SPEC_OCLS (spec) = code;
2845 SPEC_OCLS (spec) = idata;
2849 SPEC_OCLS (spec) = xstack;
2853 SPEC_OCLS (spec) = eeprom;
2862 /*-----------------------------------------------------------------*/
2863 /* geniCodeDerefPtr - dereference pointer with '*' */
2864 /*-----------------------------------------------------------------*/
2866 geniCodeDerefPtr (operand * op,int lvl)
2868 sym_link *rtype, *retype;
2869 sym_link *optype = operandType (op);
2871 // if this is an array then array access
2872 if (IS_ARRAY (optype)) {
2873 // don't worry, this will be optimized out later
2874 return geniCodeArray (op, operandFromLit (0), lvl);
2877 // just in case someone screws up
2878 wassert (IS_PTR (optype));
2880 if (IS_TRUE_SYMOP (op))
2883 op = geniCodeRValue (op, TRUE);
2886 /* now get rid of the pointer part */
2887 if (isLvaluereq(lvl) && IS_ITEMP (op))
2889 retype = getSpec (rtype = copyLinkChain (optype));
2893 retype = getSpec (rtype = copyLinkChain (optype->next));
2894 /* outputclass needs 2b updated */
2895 setOClass (optype, retype);
2898 op->isGptr = IS_GENPTR (optype);
2900 op->isaddr = (IS_PTR (rtype) ||
2901 IS_STRUCT (rtype) ||
2907 if (!isLvaluereq(lvl))
2908 op = geniCodeRValue (op, TRUE);
2910 setOperandType (op, rtype);
2915 /*-----------------------------------------------------------------*/
2916 /* geniCodeUnaryMinus - does a unary minus of the operand */
2917 /*-----------------------------------------------------------------*/
2919 geniCodeUnaryMinus (operand * op)
2922 sym_link *optype = operandType (op);
2924 if (IS_LITERAL (optype))
2925 return operandFromLit (-floatFromVal (op->operand.valOperand));
2927 ic = newiCode (UNARYMINUS, op, NULL);
2928 IC_RESULT (ic) = newiTempOperand (optype, 0);
2930 return IC_RESULT (ic);
2933 /*-----------------------------------------------------------------*/
2934 /* geniCodeLeftShift - gen i code for left shift */
2935 /*-----------------------------------------------------------------*/
2937 geniCodeLeftShift (operand * left, operand * right, RESULT_TYPE resultType)
2942 ic = newiCode (LEFT_OP, left, right);
2944 resType = usualBinaryConversions (&left, &right, resultType, LEFT_OP);
2945 IC_RESULT (ic) = newiTempOperand (resType, 0);
2947 return IC_RESULT (ic);
2950 /*-----------------------------------------------------------------*/
2951 /* geniCodeRightShift - gen i code for right shift */
2952 /*-----------------------------------------------------------------*/
2954 geniCodeRightShift (operand * left, operand * right)
2958 ic = newiCode (RIGHT_OP, left, right);
2959 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2961 return IC_RESULT (ic);
2964 /*-----------------------------------------------------------------*/
2965 /* geniCodeLogic- logic code */
2966 /*-----------------------------------------------------------------*/
2968 geniCodeLogic (operand * left, operand * right, int op, ast *tree)
2971 sym_link *ctype, *ttype;
2972 sym_link *rtype = operandType (right);
2973 sym_link *ltype = operandType (left);
2975 /* left is integral type and right is literal then
2976 check if the literal value is within bounds */
2977 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2979 CCR_RESULT ccr_result = checkConstantRange (ltype, rtype, op, FALSE);
2982 case CCR_ALWAYS_TRUE:
2983 case CCR_ALWAYS_FALSE:
2984 if (!options.lessPedantic)
2985 werror (W_COMP_RANGE, "true resp. false");
2986 return operandFromLit (ccr_result == CCR_ALWAYS_TRUE ? 1 : 0);
2992 /* if one operand is a pointer and the other is a literal generic void pointer,
2993 change the type of the literal generic void pointer to match the other pointer */
2994 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2995 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2997 /* find left's definition */
2998 ic = (iCode *) setFirstItem (iCodeChain);
3001 if (((ic->op == CAST) || (ic->op == '='))
3002 && isOperandEqual(left, IC_RESULT (ic)))
3005 ic = setNextItem (iCodeChain);
3007 /* if casting literal to generic pointer, then cast to rtype instead */
3008 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3010 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
3011 ltype = operandType(left);
3014 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
3015 && IS_PTR (ltype) && !IS_GENPTR(ltype))
3017 /* find right's definition */
3018 ic = (iCode *) setFirstItem (iCodeChain);
3021 if (((ic->op == CAST) || (ic->op == '='))
3022 && isOperandEqual(right, IC_RESULT (ic)))
3025 ic = setNextItem (iCodeChain);
3027 /* if casting literal to generic pointer, then cast to rtype instead */
3028 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
3030 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
3031 rtype = operandType(right);
3035 ctype = usualBinaryConversions (&left, &right, RESULT_TYPE_BIT, 0);
3037 ic = newiCode (op, left, right);
3038 /* store 0 or 1 in result */
3039 ttype = (tree && IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3040 IC_RESULT (ic) = newiTempOperand (ttype, 1);
3042 /* if comparing float
3043 and not a '==' || '!=' || '&&' || '||' (these
3045 if (IS_FLOAT(ctype) &&
3052 /* if comparing a fixed type use support functions */
3053 if (IS_FIXED(ctype))
3057 return IC_RESULT (ic);
3060 /*-----------------------------------------------------------------*/
3061 /* geniCodeLogicAndOr - && || operations */
3062 /*-----------------------------------------------------------------*/
3064 geniCodeLogicAndOr (ast *tree, int lvl)
3068 symbol *falseLabel = newiTempLabel (NULL);
3069 symbol *trueLabel = newiTempLabel (NULL);
3070 symbol *exitLabel = newiTempLabel (NULL);
3071 operand *op, *result, *condition;
3073 /* AND_OP and OR_OP are no longer generated because of bug-905492.
3074 They can be reenabled by executing the following block. If you find
3075 a decent optimization you could start right here:
3080 operand *leftOp, *rightOp;
3082 leftOp = geniCodeRValue (ast2iCode (tree->left , lvl + 1), FALSE);
3083 rightOp = geniCodeRValue (ast2iCode (tree->right, lvl + 1), FALSE);
3085 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3089 /* generate two IFX for the '&&' or '||' op */
3091 /* evaluate left operand */
3092 condition = ast2iCode (tree->left, lvl + 1);
3093 op = geniCodeRValue (condition, FALSE);
3095 /* test left operand */
3096 if (tree->opval.op == AND_OP)
3097 ic = newiCodeCondition (op, NULL, falseLabel);
3099 ic = newiCodeCondition (op, trueLabel, NULL);
3102 /* evaluate right operand */
3103 condition = ast2iCode (tree->right, lvl + 1);
3104 op = geniCodeRValue (condition, FALSE);
3106 /* test right operand */
3107 ic = newiCodeCondition (op, trueLabel, NULL);
3110 /* store 0 or 1 in result */
3111 type = (IS_BIT (tree->ftype)) ? newBoolLink() : newCharLink();
3112 result = newiTempOperand (type, 1);
3114 geniCodeLabel (falseLabel);
3115 geniCodeAssign (result, operandFromLit (0), 0, 0);
3116 /* generate an unconditional goto */
3117 geniCodeGoto (exitLabel);
3119 geniCodeLabel (trueLabel);
3120 geniCodeAssign (result, operandFromLit (1), 0, 0);
3122 geniCodeLabel (exitLabel);
3127 /*-----------------------------------------------------------------*/
3128 /* geniCodeUnary - for a generic unary operation */
3129 /*-----------------------------------------------------------------*/
3131 geniCodeUnary (operand * op, int oper)
3133 iCode *ic = newiCode (oper, op, NULL);
3135 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
3137 return IC_RESULT (ic);
3140 /*-----------------------------------------------------------------*/
3141 /* geniCodeBinary - for a generic binary operation */
3142 /*-----------------------------------------------------------------*/
3144 geniCodeBinary (operand * left, operand * right, int oper)
3146 iCode *ic = newiCode (oper, left, right);
3148 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
3150 return IC_RESULT (ic);
3153 /*-----------------------------------------------------------------*/
3154 /* geniCodeConditional - geniCode for '?' ':' operation */
3155 /*-----------------------------------------------------------------*/
3157 geniCodeConditional (ast * tree,int lvl)
3160 symbol *falseLabel = newiTempLabel (NULL);
3161 symbol *exitLabel = newiTempLabel (NULL);
3162 ast *astTrue = tree->right->left;
3163 ast *astFalse = tree->right->right;
3164 operand *cond = ast2iCode (tree->left, lvl+1);
3165 operand *result = newiTempOperand (tree->right->ftype, 0);
3166 operand *opTrue, *opFalse;
3168 ic = newiCodeCondition (geniCodeRValue (cond, FALSE), NULL, falseLabel);
3171 opTrue = ast2iCode (astTrue, lvl+1);
3173 /* move the value to the new operand */
3174 geniCodeAssign (result, geniCodeRValue (opTrue, FALSE), 0, 0);
3176 /* generate an unconditional goto */
3177 geniCodeGoto (exitLabel);
3179 /* now for the right side */
3180 geniCodeLabel (falseLabel);
3182 opFalse = ast2iCode (astFalse, lvl+1);
3183 geniCodeAssign (result, geniCodeRValue (opFalse, FALSE), 0, 0);
3185 /* create the exit label */
3186 geniCodeLabel (exitLabel);
3191 /*-----------------------------------------------------------------*/
3192 /* geniCodeAssign - generate code for assignment */
3193 /*-----------------------------------------------------------------*/
3195 geniCodeAssign (operand * left, operand * right, int nosupdate, int strictLval)
3198 sym_link *ltype = operandType (left);
3199 sym_link *rtype = operandType (right);
3201 if (!left->isaddr && (!IS_ITEMP (left) || strictLval))
3203 werror (E_LVALUE_REQUIRED, "assignment");
3207 /* left is integral type and right is literal then
3208 check if the literal value is within bounds */
3209 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype) &&
3210 checkConstantRange (ltype, rtype, '=', FALSE) == CCR_OVL &&
3211 !options.lessPedantic)
3213 werror (W_LIT_OVERFLOW);
3216 /* if the left & right type don't exactly match */
3217 /* if pointer set then make sure the check is
3218 done with the type & not the pointer */
3219 /* then cast rights type to left */
3221 /* first check the type for pointer assignement */
3222 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
3223 compareType (ltype, rtype) <= 0)
3226 right = geniCodeCast (ltype, right, TRUE);
3227 else if (compareType (ltype->next, rtype) < 0)
3228 right = geniCodeCast (ltype->next, right, TRUE);
3230 else if (compareType (ltype, rtype) < 0)
3231 right = geniCodeCast (ltype, right, TRUE);
3233 /* If left is a true symbol & ! volatile
3234 create an assignment to temporary for
3235 the right & then assign this temporary
3236 to the symbol. This is SSA (static single
3237 assignment). Isn't it simple and folks have
3238 published mountains of paper on it */
3239 if (IS_TRUE_SYMOP (left) &&
3240 !isOperandVolatile (left, FALSE) &&
3241 isOperandGlobal (left))
3246 if (IS_TRUE_SYMOP (right))
3247 sym = OP_SYMBOL (right);
3248 ic = newiCode ('=', NULL, right);
3249 IC_RESULT (ic) = newRight = newiTempOperand (ltype, 0);
3250 /* avoid double fetch from volatile right, see bug 1369874 */
3251 if (!isOperandVolatile (right, FALSE))
3252 SPIL_LOC (newRight) = sym;
3257 ic = newiCode ('=', NULL, right);
3258 IC_RESULT (ic) = left;
3261 /* if left isgptr flag is set then support
3262 routine will be required */
3266 ic->nosupdate = nosupdate;
3267 /* left could be a pointer assignment,
3268 return the properly casted right instead */
3272 /*-----------------------------------------------------------------*/
3273 /* geniCodeDummyRead - generate code for dummy read */
3274 /*-----------------------------------------------------------------*/
3276 geniCodeDummyRead (operand * op)
3279 sym_link *type = operandType (op);
3281 if (!IS_VOLATILE(type))
3284 ic = newiCode (DUMMY_READ_VOLATILE, NULL, op);
3290 /*-----------------------------------------------------------------*/
3291 /* geniCodeSEParms - generate code for side effecting fcalls */
3292 /*-----------------------------------------------------------------*/
3294 geniCodeSEParms (ast * parms,int lvl)
3299 if (parms->type == EX_OP && parms->opval.op == PARAM)
3301 geniCodeSEParms (parms->left,lvl);
3302 geniCodeSEParms (parms->right,lvl);
3306 /* hack don't like this but too lazy to think of
3308 if (IS_ADDRESS_OF_OP (parms))
3309 parms->left->lvalue = 1;
3311 if (IS_CAST_OP (parms) &&
3312 IS_PTR (parms->ftype) &&
3313 IS_ADDRESS_OF_OP (parms->right))
3314 parms->right->left->lvalue = 1;
3316 parms->opval.oprnd =
3317 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3319 parms->type = EX_OPERAND;
3320 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
3321 SPEC_ARGREG(parms->ftype);
3324 /*-----------------------------------------------------------------*/
3325 /* geniCodeParms - generates parameters */
3326 /*-----------------------------------------------------------------*/
3328 geniCodeParms (ast * parms, value *argVals, int *stack,
3329 sym_link * ftype, int lvl)
3337 if (argVals==NULL) {
3339 argVals = FUNC_ARGS (ftype);
3342 /* if this is a param node then do the left & right */
3343 if (parms->type == EX_OP && parms->opval.op == PARAM)
3345 argVals=geniCodeParms (parms->left, argVals, stack, ftype, lvl);
3346 argVals=geniCodeParms (parms->right, argVals, stack, ftype, lvl);
3350 /* get the parameter value */
3351 if (parms->type == EX_OPERAND)
3352 pval = parms->opval.oprnd;
3355 /* maybe this else should go away ?? */
3356 /* hack don't like this but too lazy to think of
3358 if (IS_ADDRESS_OF_OP (parms))
3359 parms->left->lvalue = 1;
3361 if (IS_CAST_OP (parms) &&
3362 IS_PTR (parms->ftype) &&
3363 IS_ADDRESS_OF_OP (parms->right))
3364 parms->right->left->lvalue = 1;
3366 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
3369 /* if register parm then make it a send */
3370 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(ftype)) ||
3371 IFFUNC_ISBUILTIN(ftype))
3373 ic = newiCode (SEND, pval, NULL);
3374 ic->argreg = SPEC_ARGREG(parms->etype);
3375 ic->builtinSEND = FUNC_ISBUILTIN(ftype);
3380 /* now decide whether to push or assign */
3381 if (!(options.stackAuto || IFFUNC_ISREENT (ftype)))
3385 operand *top = operandFromSymbol (argVals->sym);
3386 /* clear useDef and other bitVectors */
3387 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
3388 geniCodeAssign (top, pval, 1, 0);
3392 sym_link *p = operandType (pval);
3394 ic = newiCode (IPUSH, pval, NULL);
3396 /* update the stack adjustment */
3397 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
3402 argVals=argVals->next;
3406 /*-----------------------------------------------------------------*/
3407 /* geniCodeCall - generates temp code for calling */
3408 /*-----------------------------------------------------------------*/
3410 geniCodeCall (operand * left, ast * parms,int lvl)
3414 sym_link *type, *etype;
3418 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
3419 !IS_FUNCPTR(OP_SYMBOL(left)->type)) {
3420 werror (E_FUNCTION_EXPECTED);
3421 return operandFromValue(valueFromLit(0));
3424 /* take care of parameters with side-effecting
3425 function calls in them, this is required to take care
3426 of overlaying function parameters */
3427 geniCodeSEParms (parms,lvl);
3429 ftype = operandType (left);
3430 if (IS_FUNCPTR (ftype))
3431 ftype = ftype->next;
3433 /* first the parameters */
3434 geniCodeParms (parms, NULL, &stack, ftype, lvl);
3436 /* now call : if symbol then pcall */
3437 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3438 ic = newiCode (PCALL, left, NULL);
3440 ic = newiCode (CALL, left, NULL);
3443 type = copyLinkChain (ftype->next);
3444 etype = getSpec (type);
3445 SPEC_EXTR (etype) = 0;
3446 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3450 /* stack adjustment after call */
3451 ic->parmBytes = stack;
3456 /*-----------------------------------------------------------------*/
3457 /* geniCodeReceive - generate intermediate code for "receive" */
3458 /*-----------------------------------------------------------------*/
3460 geniCodeReceive (value * args, operand * func)
3462 unsigned char paramByteCounter = 0;
3464 /* for all arguments that are passed in registers */
3467 if (IS_REGPARM (args->etype))
3469 operand *opr = operandFromValue (args);
3471 symbol *sym = OP_SYMBOL (opr);
3474 /* we will use it after all optimizations
3475 and before liveRange calculation */
3476 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3479 if ((IN_FARSPACE (SPEC_OCLS (sym->etype)) && !TARGET_IS_HC08) &&
3480 options.stackAuto == 0 &&
3481 (!(options.model == MODEL_FLAT24)) )
3486 opl = newiTempOperand (args->type, 0);
3488 sym->reqv->key = sym->key;
3489 OP_SYMBOL (sym->reqv)->key = sym->key;
3490 OP_SYMBOL (sym->reqv)->isreqv = 1;
3491 OP_SYMBOL (sym->reqv)->islocal = 0;
3492 SPIL_LOC (sym->reqv) = sym;
3496 ic = newiCode (RECEIVE, func, NULL);
3497 ic->argreg = SPEC_ARGREG(args->etype);
3498 if (ic->argreg == 1) {
3499 currFunc->recvSize = getSize (sym->type);
3501 IC_RESULT (ic) = opr;
3503 /* misuse of parmBytes (normally used for functions)
3504 * to save estimated stack position of this argument.
3505 * Normally this should be zero for RECEIVE iCodes.
3506 * No idea if this causes side effects on other ports. - dw
3508 ic->parmBytes = paramByteCounter;
3510 /* what stack position do we have? */
3511 paramByteCounter += getSize (sym->type);
3520 /*-----------------------------------------------------------------*/
3521 /* geniCodeFunctionBody - create the function body */
3522 /*-----------------------------------------------------------------*/
3524 geniCodeFunctionBody (ast * tree,int lvl)
3531 /* reset the auto generation */
3537 func = ast2iCode (tree->left,lvl+1);
3538 fetype = getSpec (operandType (func));
3540 savelineno = lineno;
3541 lineno = OP_SYMBOL (func)->lineDef;
3542 /* create an entry label */
3543 geniCodeLabel (entryLabel);
3544 lineno = savelineno;
3546 /* create a proc icode */
3547 ic = newiCode (FUNCTION, func, NULL);
3548 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3553 /* for all parameters that are passed
3554 on registers add a "receive" */
3555 geniCodeReceive (tree->values.args, func);
3557 /* generate code for the body */
3558 ast2iCode (tree->right,lvl+1);
3560 /* create a label for return */
3561 geniCodeLabel (returnLabel);
3563 /* now generate the end proc */
3564 ic = newiCode (ENDFUNCTION, func, NULL);
3570 /*-----------------------------------------------------------------*/
3571 /* geniCodeReturn - gen icode for 'return' statement */
3572 /*-----------------------------------------------------------------*/
3574 geniCodeReturn (operand * op)
3578 /* if the operand is present force an rvalue */
3580 op = geniCodeRValue (op, FALSE);
3582 ic = newiCode (RETURN, op, NULL);
3586 /*-----------------------------------------------------------------*/
3587 /* geniCodeIfx - generates code for extended if statement */
3588 /*-----------------------------------------------------------------*/
3590 geniCodeIfx (ast * tree,int lvl)
3593 operand *condition = ast2iCode (tree->left,lvl+1);
3596 /* if condition is null then exit */
3600 condition = geniCodeRValue (condition, FALSE);
3602 cetype = getSpec (operandType (condition));
3603 /* if the condition is a literal */
3604 if (IS_LITERAL (cetype))
3606 if (floatFromVal (condition->operand.valOperand))
3608 if (tree->trueLabel)
3609 geniCodeGoto (tree->trueLabel);
3615 if (tree->falseLabel)
3616 geniCodeGoto (tree->falseLabel);
3621 if (tree->trueLabel)
3623 ic = newiCodeCondition (condition,
3628 if (tree->falseLabel)
3629 geniCodeGoto (tree->falseLabel);
3633 ic = newiCodeCondition (condition,
3640 ast2iCode (tree->right,lvl+1);
3643 /*-----------------------------------------------------------------*/
3644 /* geniCodeJumpTable - tries to create a jump table for switch */
3645 /*-----------------------------------------------------------------*/
3647 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3649 int min, max, cnt = 1;
3656 int needRangeCheck = !optimize.noJTabBoundary
3657 || tree->values.switchVals.swDefault;
3658 sym_link *cetype = getSpec (operandType (cond));
3659 int sizeofMinCost, sizeofZeroMinCost, sizeofMaxCost;
3660 int sizeofMatchJump, sizeofJumpTable;
3663 if (!tree || !caseVals)
3666 /* the criteria for creating a jump table is */
3667 /* all integer numbers between the maximum & minimum must */
3668 /* be present , the maximum value should not exceed 255 */
3669 /* If not all integer numbers are present the algorithm */
3670 /* inserts jumps to the default label for the missing numbers */
3671 /* and decides later whether it is worth it */
3672 min = (int) floatFromVal (vch = caseVals);
3679 max = (int) floatFromVal (vch);
3681 /* Exit if the range is too large to handle with a jump table. */
3682 if (1 + max - min > port->jumptableCost.maxCount)
3685 switch (getSize (operandType (cond)))
3687 case 1: sizeIndex = 0; break;
3688 case 2: sizeIndex = 1; break;
3689 case 4: sizeIndex = 2; break;
3693 /* Compute the size cost of the range check and subtraction. */
3695 sizeofZeroMinCost = 0;
3699 if (!(min==0 && IS_UNSIGNED (cetype)))
3700 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3701 if (!IS_UNSIGNED (cetype))
3702 sizeofZeroMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3703 sizeofMaxCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3706 sizeofMinCost += port->jumptableCost.sizeofSubtract;
3708 /* If the size cost of handling a non-zero minimum exceeds the */
3709 /* cost of extending the range down to zero, then it might be */
3710 /* better to extend the range to zero. */
3711 if (min > 0 && (sizeofMinCost-sizeofZeroMinCost)
3712 >= (min * port->jumptableCost.sizeofElement))
3714 /* Only extend the jump table if it would still be manageable. */
3715 if (1 + max <= port->jumptableCost.maxCount)
3718 if (IS_UNSIGNED (cetype))
3721 sizeofMinCost = port->jumptableCost.sizeofRangeCompare[sizeIndex];
3725 /* Compute the total size cost of a jump table. */
3726 sizeofJumpTable = (1 + max - min) * port->jumptableCost.sizeofElement
3727 + port->jumptableCost.sizeofDispatch
3728 + sizeofMinCost + sizeofMaxCost;
3730 /* Compute the total size cost of a match & jump sequence */
3731 sizeofMatchJump = cnt * port->jumptableCost.sizeofMatchJump[sizeIndex];
3733 /* If the size cost of the jump table is uneconomical then exit */
3734 if (sizeofMatchJump < sizeofJumpTable)
3737 /* The jump table is preferable. */
3739 /* First, a label for the default or missing cases. */
3740 if (tree->values.switchVals.swDefault)
3742 SNPRINTF (buffer, sizeof(buffer),
3744 tree->values.switchVals.swNum);
3748 SNPRINTF (buffer, sizeof(buffer),
3750 tree->values.switchVals.swNum);
3752 falseLabel = newiTempLabel (buffer);
3754 /* Build the list of labels for the jump table. */
3756 t = (int) floatFromVal (vch);
3757 for (i=min; i<=max; i++)
3761 /* Explicit case: make a new label for it. */
3762 SNPRINTF (buffer, sizeof(buffer),
3764 tree->values.switchVals.swNum,
3766 addSet (&labels, newiTempLabel (buffer));
3769 t = (int) floatFromVal (vch);
3773 /* Implicit case: use the default label. */
3774 addSet (&labels, falseLabel);
3778 /* first we rule out the boundary conditions */
3779 /* if only optimization says so */
3782 sym_link *cetype = getSpec (operandType (cond));
3783 /* no need to check the lower bound if
3784 the condition is unsigned & minimum value is zero */
3785 if (!(min == 0 && IS_UNSIGNED (cetype)))
3787 boundary = geniCodeLogic (cond, operandFromLit (min), '<', NULL);
3788 ic = newiCodeCondition (boundary, falseLabel, NULL);
3792 /* now for upper bounds */
3793 boundary = geniCodeLogic (cond, operandFromLit (max), '>', NULL);
3794 ic = newiCodeCondition (boundary, falseLabel, NULL);
3798 /* if the min is not zero then we no make it zero */
3801 cond = geniCodeSubtract (cond, operandFromLit (min), RESULT_TYPE_CHAR);
3802 if (!IS_LITERAL(getSpec(operandType(cond))))
3803 setOperandType (cond, UCHARTYPE);
3806 /* now create the jumptable */
3807 ic = newiCode (JUMPTABLE, NULL, NULL);
3808 IC_JTCOND (ic) = cond;
3809 IC_JTLABELS (ic) = labels;
3814 /*-----------------------------------------------------------------*/
3815 /* geniCodeSwitch - changes a switch to a if statement */
3816 /*-----------------------------------------------------------------*/
3818 geniCodeSwitch (ast * tree,int lvl)
3821 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3822 value *caseVals = tree->values.switchVals.swVals;
3823 symbol *trueLabel, *falseLabel;
3825 /* If the condition is a literal, then just jump to the */
3826 /* appropriate case label. */
3827 if (IS_LITERAL(getSpec(operandType(cond))))
3829 int switchVal, caseVal;
3831 switchVal = (int) floatFromVal (cond->operand.valOperand);
3834 caseVal = (int) floatFromVal (caseVals);
3835 if (caseVal == switchVal)
3837 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3838 tree->values.switchVals.swNum, caseVal);
3839 trueLabel = newiTempLabel (buffer);
3840 geniCodeGoto (trueLabel);
3843 caseVals = caseVals->next;
3845 goto defaultOrBreak;
3848 /* If cond is volatile, it might change while we are trying to */
3849 /* find the matching case. To avoid this possibility, make a */
3850 /* non-volatile copy to use instead. */
3851 if (IS_OP_VOLATILE (cond))
3856 newcond = newiTempOperand (operandType (cond), TRUE);
3857 newcond->isvolatile = 0;
3858 ic = newiCode ('=', NULL, cond);
3859 IC_RESULT (ic) = newcond;
3864 /* if we can make this a jump table */
3865 if (geniCodeJumpTable (cond, caseVals, tree))
3866 goto jumpTable; /* no need for the comparison */
3868 /* for the cases defined do */
3872 operand *compare = geniCodeLogic (cond,
3873 operandFromValue (caseVals),
3876 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3877 tree->values.switchVals.swNum,
3878 (int) floatFromVal (caseVals));
3879 trueLabel = newiTempLabel (buffer);
3881 ic = newiCodeCondition (compare, trueLabel, NULL);
3883 caseVals = caseVals->next;
3888 /* if default is present then goto break else break */
3889 if (tree->values.switchVals.swDefault)
3891 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3895 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3898 falseLabel = newiTempLabel (buffer);
3899 geniCodeGoto (falseLabel);
3902 ast2iCode (tree->right,lvl+1);
3905 /*-----------------------------------------------------------------*/
3906 /* geniCodeInline - intermediate code for inline assembler */
3907 /*-----------------------------------------------------------------*/
3909 geniCodeInline (ast * tree)
3913 ic = newiCode (INLINEASM, NULL, NULL);
3914 IC_INLINE (ic) = tree->values.inlineasm;
3918 /*-----------------------------------------------------------------*/
3919 /* geniCodeArrayInit - intermediate code for array initializer */
3920 /*-----------------------------------------------------------------*/
3922 geniCodeArrayInit (ast * tree, operand *array)
3926 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3927 ic = newiCode (ARRAYINIT, array, NULL);
3928 IC_ARRAYILIST (ic) = tree->values.constlist;
3930 operand *left=newOperand(), *right=newOperand();
3931 left->type=right->type=SYMBOL;
3932 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3933 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3934 ic = newiCode (ARRAYINIT, left, right);
3939 /*-----------------------------------------------------------------*/
3940 /* geniCodeCritical - intermediate code for a critical statement */
3941 /*-----------------------------------------------------------------*/
3943 geniCodeCritical (ast *tree, int lvl)
3949 if (!options.stackAuto)
3951 type = newLink(SPECIFIER);
3952 SPEC_VOLATILE(type) = 1;
3953 SPEC_NOUN(type) = V_BIT;
3954 SPEC_SCLS(type) = S_BIT;
3955 SPEC_BLEN(type) = 1;
3956 SPEC_BSTR(type) = 0;
3957 op = newiTempOperand(type, 1);
3960 /* If op is NULL, the original interrupt state will saved on */
3961 /* the stack. Otherwise, it will be saved in op. */
3963 /* Generate a save of the current interrupt state & disable */
3964 ic = newiCode (CRITICAL, NULL, NULL);
3965 IC_RESULT (ic) = op;
3968 /* Generate the critical code sequence */
3969 if (tree->left && tree->left->type == EX_VALUE)
3970 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
3972 ast2iCode (tree->left,lvl+1);
3974 /* Generate a restore of the original interrupt state */
3975 ic = newiCode (ENDCRITICAL, NULL, op);
3979 /*-----------------------------------------------------------------*/
3980 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3981 /* particular case. Ie : assigning or dereferencing array or ptr */
3982 /*-----------------------------------------------------------------*/
3983 set * lvaluereqSet = NULL;
3984 typedef struct lvalItem
3991 /*-----------------------------------------------------------------*/
3992 /* addLvaluereq - add a flag for lvalreq for current ast level */
3993 /*-----------------------------------------------------------------*/
3994 void addLvaluereq(int lvl)
3996 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3999 addSetHead(&lvaluereqSet,lpItem);
4002 /*-----------------------------------------------------------------*/
4003 /* delLvaluereq - del a flag for lvalreq for current ast level */
4004 /*-----------------------------------------------------------------*/
4008 lpItem = getSet(&lvaluereqSet);
4009 if(lpItem) Safe_free(lpItem);
4011 /*-----------------------------------------------------------------*/
4012 /* clearLvaluereq - clear lvalreq flag */
4013 /*-----------------------------------------------------------------*/
4014 void clearLvaluereq()
4017 lpItem = peekSet(lvaluereqSet);
4018 if(lpItem) lpItem->req = 0;
4020 /*-----------------------------------------------------------------*/
4021 /* getLvaluereq - get the last lvalreq level */
4022 /*-----------------------------------------------------------------*/
4023 int getLvaluereqLvl()
4026 lpItem = peekSet(lvaluereqSet);
4027 if(lpItem) return lpItem->lvl;
4030 /*-----------------------------------------------------------------*/
4031 /* isLvaluereq - is lvalreq valid for this level ? */
4032 /*-----------------------------------------------------------------*/
4033 int isLvaluereq(int lvl)
4036 lpItem = peekSet(lvaluereqSet);
4037 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
4041 /*-----------------------------------------------------------------*/
4042 /* ast2iCode - creates an icodeList from an ast */
4043 /*-----------------------------------------------------------------*/
4045 ast2iCode (ast * tree,int lvl)
4047 operand *left = NULL;
4048 operand *right = NULL;
4052 /* set the global variables for filename & line number */
4054 filename = tree->filename;
4056 lineno = tree->lineno;
4058 block = tree->block;
4060 scopeLevel = tree->level;
4062 seqPoint = tree->seqPoint;
4064 if (tree->type == EX_VALUE)
4065 return operandFromValue (tree->opval.val);
4067 if (tree->type == EX_LINK)
4068 return operandFromLink (tree->opval.lnk);
4070 /* if we find a nullop */
4071 if (tree->type == EX_OP &&
4072 (tree->opval.op == NULLOP ||
4073 tree->opval.op == BLOCK))
4075 if (tree->left && tree->left->type == EX_VALUE)
4076 geniCodeDummyRead (ast2iCode (tree->left,lvl+1));
4078 ast2iCode (tree->left,lvl+1);
4079 if (tree->right && tree->right->type == EX_VALUE)
4080 geniCodeDummyRead (ast2iCode (tree->right,lvl+1));
4082 ast2iCode (tree->right,lvl+1);
4086 /* special cases for not evaluating */
4087 if (tree->opval.op != ':' &&
4088 tree->opval.op != '?' &&
4089 tree->opval.op != CALL &&
4090 tree->opval.op != IFX &&
4091 tree->opval.op != AND_OP &&
4092 tree->opval.op != OR_OP &&
4093 tree->opval.op != LABEL &&
4094 tree->opval.op != GOTO &&
4095 tree->opval.op != SWITCH &&
4096 tree->opval.op != FUNCTION &&
4097 tree->opval.op != INLINEASM &&
4098 tree->opval.op != CRITICAL)
4101 if (IS_ASSIGN_OP (tree->opval.op) ||
4102 IS_DEREF_OP (tree) ||
4103 (tree->opval.op == '&' && !tree->right) ||
4104 tree->opval.op == PTR_OP)
4107 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
4108 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
4111 left = operandFromAst (tree->left,lvl);
4113 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
4114 left = geniCodeRValue (left, TRUE);
4118 left = operandFromAst (tree->left,lvl);
4120 if (tree->opval.op == INC_OP ||
4121 tree->opval.op == DEC_OP)
4124 right = operandFromAst (tree->right,lvl);
4129 right = operandFromAst (tree->right,lvl);
4133 /* now depending on the type of operand */
4134 /* this will be a biggy */
4135 switch (tree->opval.op)
4138 case '[': /* array operation */
4140 //sym_link *ltype = operandType (left);
4141 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
4142 left = geniCodeRValue (left, FALSE);
4143 right = geniCodeRValue (right, TRUE);
4146 return geniCodeArray (left, right,lvl);
4148 case '.': /* structure dereference */
4149 if (IS_PTR (operandType (left)))
4150 left = geniCodeRValue (left, TRUE);
4152 left = geniCodeRValue (left, FALSE);
4154 return geniCodeStruct (left, right, tree->lvalue);
4156 case PTR_OP: /* structure pointer dereference */
4159 pType = operandType (left);
4160 left = geniCodeRValue (left, TRUE);
4162 setOClass (pType, getSpec (operandType (left)));
4165 return geniCodeStruct (left, right, tree->lvalue);
4167 case INC_OP: /* increment operator */
4169 return geniCodePostInc (left);
4171 return geniCodePreInc (right, tree->lvalue);
4173 case DEC_OP: /* decrement operator */
4175 return geniCodePostDec (left);
4177 return geniCodePreDec (right, tree->lvalue);
4179 case '&': /* bitwise and or address of operator */
4181 { /* this is a bitwise operator */
4182 left = geniCodeRValue (left, FALSE);
4183 right = geniCodeRValue (right, FALSE);
4184 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
4187 return geniCodeAddressOf (left);
4189 case '|': /* bitwise or & xor */
4191 return geniCodeBitwise (geniCodeRValue (left, FALSE),
4192 geniCodeRValue (right, FALSE),
4197 return geniCodeDivision (geniCodeRValue (left, FALSE),
4198 geniCodeRValue (right, FALSE),
4199 getResultTypeFromType (tree->ftype));
4202 return geniCodeModulus (geniCodeRValue (left, FALSE),
4203 geniCodeRValue (right, FALSE),
4204 getResultTypeFromType (tree->ftype));
4207 return geniCodeMultiply (geniCodeRValue (left, FALSE),
4208 geniCodeRValue (right, FALSE),
4209 getResultTypeFromType (tree->ftype));
4211 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
4215 return geniCodeSubtract (geniCodeRValue (left, FALSE),
4216 geniCodeRValue (right, FALSE),
4217 getResultTypeFromType (tree->ftype));
4219 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
4223 return geniCodeAdd (geniCodeRValue (left, FALSE),
4224 geniCodeRValue (right, FALSE),
4225 getResultTypeFromType (tree->ftype),
4228 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
4231 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
4232 geniCodeRValue (right, FALSE),
4233 getResultTypeFromType (tree->ftype));
4236 return geniCodeRightShift (geniCodeRValue (left, FALSE),
4237 geniCodeRValue (right, FALSE));
4239 #if 0 // this indeed needs a second thought
4243 // let's keep this simple: get the rvalue we need
4244 op=geniCodeRValue (right, FALSE);
4245 // now cast it to whatever we want
4246 op=geniCodeCast (operandType(left), op, FALSE);
4247 // if this is going to be used as an lvalue, make it so
4253 #else // bug #604575, is it a bug ????
4254 return geniCodeCast (operandType (left),
4255 geniCodeRValue (right, FALSE), FALSE);
4262 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4267 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
4268 if (!IS_BIT (operandType (op)))
4269 setOperandType (op, UCHARTYPE);
4274 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4275 geniCodeRValue (right, FALSE),
4277 if (!IS_BIT (operandType (op)))
4278 setOperandType (op, UCHARTYPE);
4283 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4284 geniCodeRValue (right, FALSE),
4286 setOperandType (op, UCHARTYPE);
4291 operand *op = geniCodeBinary (geniCodeRValue (left, FALSE),
4292 geniCodeRValue (right, FALSE),
4294 setOperandType (op, UINTTYPE);
4299 return geniCodeLogicAndOr (tree, lvl);
4306 /* different compilers (even different gccs) evaluate
4307 the two calls in a different order. to get the same
4308 result on all machines we have to specify a clear sequence.
4309 return geniCodeLogic (geniCodeRValue (left, FALSE),
4310 geniCodeRValue (right, FALSE),
4314 operand *leftOp, *rightOp;
4316 leftOp = geniCodeRValue (left , FALSE);
4317 rightOp = geniCodeRValue (right, FALSE);
4319 return geniCodeLogic (leftOp, rightOp, tree->opval.op, tree);
4322 return geniCodeConditional (tree,lvl);
4325 return operandFromLit (getSize (tree->right->ftype));
4329 sym_link *rtype = operandType (right);
4330 sym_link *ltype = operandType (left);
4331 if (IS_PTR (rtype) && IS_ITEMP (right)
4332 && right->isaddr && compareType (rtype->next, ltype) == 1)
4333 right = geniCodeRValue (right, TRUE);
4335 right = geniCodeRValue (right, FALSE);
4337 return geniCodeAssign (left, right, 0, 1);
4341 geniCodeAssign (left,
4342 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
4344 geniCodeRValue (right, FALSE),
4345 getResultTypeFromType (tree->ftype)),
4350 geniCodeAssign (left,
4351 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
4353 geniCodeRValue (right, FALSE),
4354 getResultTypeFromType (tree->ftype)),
4358 geniCodeAssign (left,
4359 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
4361 geniCodeRValue (right, FALSE),
4362 getResultTypeFromType (tree->ftype)),
4366 sym_link *rtype = operandType (right);
4367 sym_link *ltype = operandType (left);
4368 if (IS_PTR (rtype) && IS_ITEMP (right)
4369 && right->isaddr && compareType (rtype->next, ltype) == 1)
4370 right = geniCodeRValue (right, TRUE);
4372 right = geniCodeRValue (right, FALSE);
4375 return geniCodeAssign (left,
4376 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
4379 getResultTypeFromType (tree->ftype),
4385 sym_link *rtype = operandType (right);
4386 sym_link *ltype = operandType (left);
4387 if (IS_PTR (rtype) && IS_ITEMP (right)
4388 && right->isaddr && compareType (rtype->next, ltype) == 1)
4390 right = geniCodeRValue (right, TRUE);
4394 right = geniCodeRValue (right, FALSE);
4397 geniCodeAssign (left,
4398 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
4401 getResultTypeFromType (tree->ftype)),
4406 geniCodeAssign (left,
4407 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
4409 geniCodeRValue (right, FALSE),
4410 getResultTypeFromType (tree->ftype)),
4414 geniCodeAssign (left,
4415 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
4417 geniCodeRValue (right, FALSE)), 0, 1);
4420 geniCodeAssign (left,
4421 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4423 geniCodeRValue (right, FALSE),
4425 operandType (left)), 0, 1);
4428 geniCodeAssign (left,
4429 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
4431 geniCodeRValue (right, FALSE),
4433 operandType (left)), 0, 1);
4436 geniCodeAssign (left,
4437 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
4439 geniCodeRValue (right, FALSE),
4441 operandType (left)), 0, 1);
4443 return geniCodeRValue (right, FALSE);
4446 return geniCodeCall (ast2iCode (tree->left,lvl+1),
4449 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4450 return ast2iCode (tree->right,lvl+1);
4453 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
4454 return ast2iCode (tree->right,lvl+1);
4457 geniCodeFunctionBody (tree,lvl);
4461 geniCodeReturn (right);
4465 geniCodeIfx (tree,lvl);
4469 geniCodeSwitch (tree,lvl);
4473 geniCodeInline (tree);
4477 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
4481 geniCodeCritical (tree, lvl);
4487 /*-----------------------------------------------------------------*/
4488 /* reverseICChain - gets from the list and creates a linkedlist */
4489 /*-----------------------------------------------------------------*/
4496 while ((loop = getSet (&iCodeChain)))
4508 /*-----------------------------------------------------------------*/
4509 /* iCodeFromAst - given an ast will convert it to iCode */
4510 /*-----------------------------------------------------------------*/
4512 iCodeFromAst (ast * tree)
4514 returnLabel = newiTempLabel ("_return");
4515 entryLabel = newiTempLabel ("_entry");
4517 return reverseiCChain ();
4520 static const char *opTypeToStr(OPTYPE op)
4524 case SYMBOL: return "symbol";
4525 case VALUE: return "value";
4526 case TYPE: return "type";
4528 return "undefined type";
4532 operand *validateOpType(operand *op,
4539 if (op && op->type == type)
4544 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
4545 " expected %s, got %s\n",
4546 macro, args, file, line,
4547 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
4549 return op; // never reached, makes compiler happy.