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 -------------------------------------------------------------------------*/
29 /*-----------------------------------------------------------------*/
30 /* global variables */
32 set *iCodeChain = NULL;
42 symbol *returnLabel; /* function return label */
43 symbol *entryLabel; /* function entry label */
45 /*-----------------------------------------------------------------*/
46 /* forward definition of some functions */
47 operand *geniCodeDivision (operand *, operand *);
48 operand *geniCodeAssign (operand *, operand *, int);
49 operand *geniCodeArray (operand *, operand *,int);
50 operand *geniCodeArray2Ptr (operand *);
51 operand *geniCodeRValue (operand *, bool);
52 operand *geniCodeDerefPtr (operand *,int);
53 int isLvaluereq(int lvl);
55 #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s)
56 /* forward definition of ic print functions */
57 PRINTFUNC (picGetValueAtAddr);
58 PRINTFUNC (picSetValueAtAddr);
59 PRINTFUNC (picAddrOf);
60 PRINTFUNC (picGeneric);
61 PRINTFUNC (picGenericOne);
63 PRINTFUNC (picAssign);
67 PRINTFUNC (picJumpTable);
68 PRINTFUNC (picInline);
69 PRINTFUNC (picReceive);
70 PRINTFUNC (picDummyRead);
72 iCodeTable codeTable[] =
74 {'!', "not", picGenericOne, NULL},
75 {'~', "~", picGenericOne, NULL},
76 {RRC, "rrc", picGenericOne, NULL},
77 {RLC, "rlc", picGenericOne, NULL},
78 {GETHBIT, "ghbit", picGenericOne, NULL},
79 {UNARYMINUS, "-", picGenericOne, NULL},
80 {IPUSH, "push", picGenericOne, NULL},
81 {IPOP, "pop", picGenericOne, NULL},
82 {CALL, "call", picGenericOne, NULL},
83 {PCALL, "pcall", picGenericOne, NULL},
84 {FUNCTION, "proc", picGenericOne, NULL},
85 {ENDFUNCTION, "eproc", picGenericOne, NULL},
86 {RETURN, "ret", picGenericOne, NULL},
87 {'+', "+", picGeneric, NULL},
88 {'-', "-", picGeneric, NULL},
89 {'*', "*", picGeneric, NULL},
90 {'/', "/", picGeneric, NULL},
91 {'%', "%", picGeneric, NULL},
92 {'>', ">", picGeneric, NULL},
93 {'<', "<", picGeneric, NULL},
94 {LE_OP, "<=", picGeneric, NULL},
95 {GE_OP, ">=", picGeneric, NULL},
96 {EQ_OP, "==", picGeneric, NULL},
97 {NE_OP, "!=", picGeneric, NULL},
98 {AND_OP, "&&", picGeneric, NULL},
99 {OR_OP, "||", picGeneric, NULL},
100 {'^', "^", picGeneric, NULL},
101 {'|', "|", picGeneric, NULL},
102 {BITWISEAND, "&", picGeneric, NULL},
103 {LEFT_OP, "<<", picGeneric, NULL},
104 {RIGHT_OP, ">>", picGeneric, NULL},
105 {GET_VALUE_AT_ADDRESS, "@", picGetValueAtAddr, NULL},
106 {ADDRESS_OF, "&", picAddrOf, NULL},
107 {CAST, "<>", picCast, NULL},
108 {'=', ":=", picAssign, NULL},
109 {LABEL, "", picLabel, NULL},
110 {GOTO, "", picGoto, NULL},
111 {JUMPTABLE, "jtab", picJumpTable, NULL},
112 {IFX, "if", picIfx, NULL},
113 {INLINEASM, "", picInline, NULL},
114 {RECEIVE, "recv", picReceive, NULL},
115 {SEND, "send", picGenericOne, NULL},
116 {ARRAYINIT, "arrayInit", picGenericOne, NULL},
117 {DUMMY_READ_VOLATILE, "dummy = (volatile)", picDummyRead, NULL}
120 /*-----------------------------------------------------------------*/
121 /* checkConstantRange: check a constant against the type */
122 /*-----------------------------------------------------------------*/
125 /* pedantic=0: allmost anything is allowed as long as the absolute
126 value is within the bit range of the type, and -1 is treated as
127 0xf..f for unsigned types (e.g. in assign)
128 pedantic=1: -1==-1, not allowed for unsigned types (e.g. in compare)
129 pedantic>1: "char c=200" is not allowed (evaluates to -56)
132 void checkConstantRange(sym_link *ltype, value *val, char *msg,
139 max = pow ((double)2.0, (double)bitsForType(ltype));
141 if (SPEC_LONG(val->type)) {
142 if (SPEC_USIGN(val->type)) {
143 v=SPEC_CVAL(val->type).v_ulong;
145 v=SPEC_CVAL(val->type).v_long;
148 if (SPEC_USIGN(val->type)) {
149 v=SPEC_CVAL(val->type).v_uint;
151 v=SPEC_CVAL(val->type).v_int;
157 // this could be a good idea
158 if (options.pedantic)
162 if (SPEC_NOUN(ltype)==FLOAT) {
167 if (!SPEC_USIGN(val->type) && v<0) {
169 if (SPEC_USIGN(ltype) && (pedantic>1)) {
175 // if very pedantic: "char c=200" is not allowed
176 if (pedantic>1 && !SPEC_USIGN(ltype)) {
177 max = max/2 + negative;
184 #if 0 // temporary disabled, leaving the warning as a reminder
186 SNPRINTF (message, sizeof(message), "for %s %s in %s",
187 SPEC_USIGN(ltype) ? "unsigned" : "signed",
188 nounName(ltype), msg);
189 werror (W_CONST_RANGE, message);
197 /*-----------------------------------------------------------------*/
198 /* operandName - returns the name of the operand */
199 /*-----------------------------------------------------------------*/
201 printOperand (operand * op, FILE * file)
218 opetype = getSpec (operandType (op));
219 if (SPEC_NOUN (opetype) == V_FLOAT)
220 fprintf (file, "%g {", SPEC_CVAL (opetype).v_float);
222 fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand));
223 printTypeChain (operandType (op), file);
230 fprintf (file, "%s [k%d lr%d:%d so:%d]{ ia%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}" , */
231 (OP_SYMBOL (op)->rname[0] ? OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name),
233 OP_LIVEFROM (op), OP_LIVETO (op),
234 OP_SYMBOL (op)->stack,
235 op->isaddr, OP_SYMBOL (op)->isreqv,
236 OP_SYMBOL (op)->remat,OP_SYMBOL(op)->noSpilLoc,
237 OP_SYMBOL(op)->ruonly,OP_SYMBOL(op)->dptr
241 printTypeChain (operandType (op), file);
242 if (SPIL_LOC (op) && IS_ITEMP (op))
243 fprintf (file, "}{ sir@ %s", SPIL_LOC (op)->rname);
248 /* if assigned to registers */
249 if (OP_SYMBOL (op)->nRegs)
251 if (OP_SYMBOL (op)->isspilt)
253 if (!OP_SYMBOL (op)->remat)
254 if (OP_SYMBOL (op)->usl.spillLoc)
255 fprintf (file, "[%s]", (OP_SYMBOL (op)->usl.spillLoc->rname[0] ?
256 OP_SYMBOL (op)->usl.spillLoc->rname :
257 OP_SYMBOL (op)->usl.spillLoc->name));
259 fprintf (file, "[err]");
261 fprintf (file, "[remat]");
267 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
268 fprintf (file, "%s ", port->getRegName (OP_SYMBOL (op)->regs[i]));
273 fprintf (file, "%s", (OP_SYMBOL (op)->rname[0] ?
274 OP_SYMBOL (op)->rname : OP_SYMBOL (op)->name));
275 /* if assigned to registers */
276 if (OP_SYMBOL (op)->nRegs && !OP_SYMBOL (op)->isspilt)
280 for (i = 0; i < OP_SYMBOL (op)->nRegs; i++)
281 fprintf (file, "%s ", (OP_SYMBOL (op)->regs[i] ?
282 OP_SYMBOL (op)->regs[i]->name :
291 printTypeChain (op->operand.typeOperand, file);
297 fprintf (file, "\n");
302 /*-----------------------------------------------------------------*/
303 /* print functions */
304 /*-----------------------------------------------------------------*/
305 PRINTFUNC (picGetValueAtAddr)
308 printOperand (IC_RESULT (ic), of);
311 printOperand (IC_LEFT (ic), of);
317 PRINTFUNC (picSetValueAtAddr)
321 printOperand (IC_LEFT (ic), of);
322 fprintf (of, "] = ");
323 printOperand (IC_RIGHT (ic), of);
327 PRINTFUNC (picAddrOf)
330 printOperand (IC_RESULT (ic), of);
331 if (IS_ITEMP (IC_LEFT (ic)))
334 fprintf (of, " = &[");
335 printOperand (IC_LEFT (ic), of);
338 if (IS_ITEMP (IC_LEFT (ic)))
339 fprintf (of, " offsetAdd ");
342 printOperand (IC_RIGHT (ic), of);
344 if (IS_ITEMP (IC_LEFT (ic)))
350 PRINTFUNC (picJumpTable)
355 fprintf (of, "%s\t", s);
356 printOperand (IC_JTCOND (ic), of);
358 for (sym = setFirstItem (IC_JTLABELS (ic)); sym;
359 sym = setNextItem (IC_JTLABELS (ic)))
360 fprintf (of, "\t\t\t%s\n", sym->name);
363 PRINTFUNC (picGeneric)
366 printOperand (IC_RESULT (ic), of);
368 printOperand (IC_LEFT (ic), of);
369 fprintf (of, " %s ", s);
370 printOperand (IC_RIGHT (ic), of);
374 PRINTFUNC (picGenericOne)
379 printOperand (IC_RESULT (ic), of);
385 fprintf (of, "%s ", s);
386 printOperand (IC_LEFT (ic), of);
389 if (!IC_RESULT (ic) && !IC_LEFT (ic))
392 if (ic->op == SEND || ic->op == RECEIVE) {
393 fprintf(of,"{argreg = %d}",ic->argreg);
401 printOperand (IC_RESULT (ic), of);
403 printOperand (IC_LEFT (ic), of);
404 printOperand (IC_RIGHT (ic), of);
409 PRINTFUNC (picAssign)
413 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
416 printOperand (IC_RESULT (ic), of);
418 if (IC_RESULT (ic)->isaddr && IS_ITEMP (IC_RESULT (ic)))
421 fprintf (of, " %s ", s);
422 printOperand (IC_RIGHT (ic), of);
429 fprintf (of, " %s($%d) :\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
435 fprintf (of, " goto %s($%d)\n", IC_LABEL (ic)->name, IC_LABEL (ic)->key);
442 printOperand (IC_COND (ic), of);
445 fprintf (of, " == 0 goto %s($%d)\n", IC_FALSE (ic)->name, IC_FALSE (ic)->key);
448 fprintf (of, " != 0 goto %s($%d)\n", IC_TRUE (ic)->name, IC_TRUE (ic)->key);
450 fprintf (of, "\tzzgoto %s\n", IC_FALSE (ic)->name);
454 PRINTFUNC (picInline)
456 fprintf (of, "%s", IC_INLINE (ic));
459 PRINTFUNC (picReceive)
461 printOperand (IC_RESULT (ic), of);
462 fprintf (of, " = %s ", s);
463 printOperand (IC_LEFT (ic), of);
467 PRINTFUNC (picDummyRead)
470 fprintf (of, "%s ", s);
471 printOperand (IC_RIGHT (ic), of);
475 /*-----------------------------------------------------------------*/
476 /* piCode - prints one iCode */
477 /*-----------------------------------------------------------------*/
479 piCode (void *item, FILE * of)
487 icTab = getTableEntry (ic->op);
488 fprintf (stdout, "%s(%d:%d:%d:%d:%d)\t",
489 ic->filename, ic->lineno,
490 ic->seq, ic->key, ic->depth, ic->supportRtn);
491 icTab->iCodePrint (of, ic, icTab->printName);
497 printiCChain(ic,stdout);
499 /*-----------------------------------------------------------------*/
500 /* printiCChain - prints intermediate code for humans */
501 /*-----------------------------------------------------------------*/
503 printiCChain (iCode * icChain, FILE * of)
510 for (loop = icChain; loop; loop = loop->next)
512 if ((icTab = getTableEntry (loop->op)))
514 fprintf (of, "%s(l%d:s%d:k%d:d%d:s%d)\t",
515 loop->filename, loop->lineno,
516 loop->seq, loop->key, loop->depth, loop->supportRtn);
518 icTab->iCodePrint (of, loop, icTab->printName);
524 /*-----------------------------------------------------------------*/
525 /* newOperand - allocate, init & return a new iCode */
526 /*-----------------------------------------------------------------*/
532 op = Safe_alloc ( sizeof (operand));
538 /*-----------------------------------------------------------------*/
539 /* newiCode - create and return a new iCode entry initialised */
540 /*-----------------------------------------------------------------*/
542 newiCode (int op, operand * left, operand * right)
546 ic = Safe_alloc ( sizeof (iCode));
549 ic->filename = filename;
551 ic->level = scopeLevel;
553 ic->key = iCodeKey++;
555 IC_RIGHT (ic) = right;
560 /*-----------------------------------------------------------------*/
561 /* newiCode for conditional statements */
562 /*-----------------------------------------------------------------*/
564 newiCodeCondition (operand * condition,
570 if (IS_VOID(operandType(condition))) {
571 werror(E_VOID_VALUE_USED);
574 ic = newiCode (IFX, NULL, NULL);
575 IC_COND (ic) = condition;
576 IC_TRUE (ic) = trueLabel;
577 IC_FALSE (ic) = falseLabel;
581 /*-----------------------------------------------------------------*/
582 /* newiCodeLabelGoto - unconditional goto statement| label stmnt */
583 /*-----------------------------------------------------------------*/
585 newiCodeLabelGoto (int op, symbol * label)
589 ic = newiCode (op, NULL, NULL);
593 IC_RIGHT (ic) = NULL;
594 IC_RESULT (ic) = NULL;
598 /*-----------------------------------------------------------------*/
599 /* newiTemp - allocate & return a newItemp Variable */
600 /*-----------------------------------------------------------------*/
608 SNPRINTF (buffer, sizeof(buffer), "%s", s);
612 SNPRINTF (buffer, sizeof(buffer), "iTemp%d", iTempNum++);
615 itmp = newSymbol (buffer, 1);
616 strncpyz (itmp->rname, itmp->name, SDCC_NAME_MAX);
622 /*-----------------------------------------------------------------*/
623 /* newiTempLabel - creates a temp variable label */
624 /*-----------------------------------------------------------------*/
626 newiTempLabel (char *s)
630 /* check if this alredy exists */
631 if (s && (itmplbl = findSym (LabelTab, NULL, s)))
636 itmplbl = newSymbol (s, 1);
640 SNPRINTF (buffer, sizeof(buffer), "iTempLbl%d", iTempLblNum++);
641 itmplbl = newSymbol (buffer, 1);
646 itmplbl->key = labelKey++;
647 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
651 /*-----------------------------------------------------------------*/
652 /* newiTempPreheaderLabel - creates a new preheader label */
653 /*-----------------------------------------------------------------*/
655 newiTempPreheaderLabel ()
659 SNPRINTF (buffer, sizeof(buffer), "preHeaderLbl%d", iTempLblNum++);
660 itmplbl = newSymbol (buffer, 1);
664 itmplbl->key = labelKey++;
665 addSym (LabelTab, itmplbl, itmplbl->name, 0, 0, 0);
670 /*-----------------------------------------------------------------*/
671 /* initiCode - initialises some iCode related stuff */
672 /*-----------------------------------------------------------------*/
679 /*-----------------------------------------------------------------*/
680 /* copyiCode - make a copy of the iCode given */
681 /*-----------------------------------------------------------------*/
683 copyiCode (iCode * ic)
685 iCode *nic = newiCode (ic->op, NULL, NULL);
687 nic->lineno = ic->lineno;
688 nic->filename = ic->filename;
689 nic->block = ic->block;
690 nic->level = ic->level;
691 nic->parmBytes = ic->parmBytes;
693 /* deal with the special cases first */
697 IC_COND (nic) = operandFromOperand (IC_COND (ic));
698 IC_TRUE (nic) = IC_TRUE (ic);
699 IC_FALSE (nic) = IC_FALSE (ic);
703 IC_JTCOND (nic) = operandFromOperand (IC_JTCOND (ic));
704 IC_JTLABELS (nic) = IC_JTLABELS (ic);
709 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
710 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
714 IC_INLINE (nic) = IC_INLINE (ic);
718 IC_ARRAYILIST(nic) = IC_ARRAYILIST(ic);
722 IC_RESULT (nic) = operandFromOperand (IC_RESULT (ic));
723 IC_LEFT (nic) = operandFromOperand (IC_LEFT (ic));
724 IC_RIGHT (nic) = operandFromOperand (IC_RIGHT (ic));
730 /*-----------------------------------------------------------------*/
731 /* getTableEntry - gets the table entry for the given operator */
732 /*-----------------------------------------------------------------*/
734 getTableEntry (int oper)
738 for (i = 0; i < (sizeof (codeTable) / sizeof (iCodeTable)); i++)
739 if (oper == codeTable[i].icode)
740 return &codeTable[i];
745 /*-----------------------------------------------------------------*/
746 /* newiTempOperand - new intermediate temp operand */
747 /*-----------------------------------------------------------------*/
749 newiTempOperand (sym_link * type, char throwType)
752 operand *op = newOperand ();
756 itmp = newiTemp (NULL);
758 etype = getSpec (type);
760 if (IS_LITERAL (etype))
763 /* copy the type information */
765 itmp->etype = getSpec (itmp->type = (throwType ? type :
766 copyLinkChain (type)));
767 if (IS_LITERAL (itmp->etype))
769 SPEC_SCLS (itmp->etype) = S_REGISTER;
770 SPEC_OCLS (itmp->etype) = reg;
773 op->operand.symOperand = itmp;
774 op->key = itmp->key = ++operandKey;
778 /*-----------------------------------------------------------------*/
779 /* operandType - returns the type chain for an operand */
780 /*-----------------------------------------------------------------*/
782 operandType (operand * op)
784 /* depending on type of operand */
789 return op->operand.valOperand->type;
792 return op->operand.symOperand->type;
795 return op->operand.typeOperand;
797 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
798 " operand type not known ");
799 assert (0); /* should never come here */
800 /* Just to keep the compiler happy */
801 return (sym_link *) 0;
805 /*-----------------------------------------------------------------*/
806 /* isParamterToCall - will return 1 if op is a parameter to args */
807 /*-----------------------------------------------------------------*/
809 isParameterToCall (value * args, operand * op)
813 wassert (IS_SYMOP(op));
818 isSymbolEqual (op->operand.symOperand, tval->sym))
825 /*-----------------------------------------------------------------*/
826 /* isOperandGlobal - return 1 if operand is a global variable */
827 /*-----------------------------------------------------------------*/
829 isOperandGlobal (operand * op)
838 (op->operand.symOperand->level == 0 ||
839 IS_STATIC (op->operand.symOperand->etype) ||
840 IS_EXTERN (op->operand.symOperand->etype))
847 /*-----------------------------------------------------------------*/
848 /* isOperandVolatile - return 1 if the operand is volatile */
849 /*-----------------------------------------------------------------*/
851 isOperandVolatile (operand * op, bool chkTemp)
856 if (IS_ITEMP (op) && !chkTemp)
859 opetype = getSpec (optype = operandType (op));
861 if (IS_PTR (optype) && DCL_PTR_VOLATILE (optype))
864 if (IS_VOLATILE (opetype))
869 /*-----------------------------------------------------------------*/
870 /* isOperandLiteral - returns 1 if an operand contains a literal */
871 /*-----------------------------------------------------------------*/
873 isOperandLiteral (operand * op)
880 opetype = getSpec (operandType (op));
882 if (IS_LITERAL (opetype))
888 /*-----------------------------------------------------------------*/
889 /* isOperandInFarSpace - will return true if operand is in farSpace */
890 /*-----------------------------------------------------------------*/
892 isOperandInFarSpace (operand * op)
902 if (!IS_TRUE_SYMOP (op))
905 etype = SPIL_LOC (op)->etype;
911 etype = getSpec (operandType (op));
913 return (IN_FARSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
916 /*------------------------------------------------------------------*/
917 /* isOperandInDirSpace - will return true if operand is in dirSpace */
918 /*------------------------------------------------------------------*/
920 isOperandInDirSpace (operand * op)
930 if (!IS_TRUE_SYMOP (op))
933 etype = SPIL_LOC (op)->etype;
939 etype = getSpec (operandType (op));
941 return (IN_DIRSPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
944 /*--------------------------------------------------------------------*/
945 /* isOperandInCodeSpace - will return true if operand is in codeSpace */
946 /*--------------------------------------------------------------------*/
948 isOperandInCodeSpace (operand * op)
958 etype = getSpec (operandType (op));
960 if (!IS_TRUE_SYMOP (op))
963 etype = SPIL_LOC (op)->etype;
969 etype = getSpec (operandType (op));
971 return (IN_CODESPACE (SPEC_OCLS (etype)) ? TRUE : FALSE);
974 /*-----------------------------------------------------------------*/
975 /* isOperandOnStack - will return true if operand is on stack */
976 /*-----------------------------------------------------------------*/
978 isOperandOnStack (operand * op)
988 etype = getSpec (operandType (op));
989 if (IN_STACK (etype) ||
990 OP_SYMBOL(op)->onStack ||
991 (SPIL_LOC(op) && SPIL_LOC(op)->onStack))
997 /*-----------------------------------------------------------------*/
998 /* operandLitValue - literal value of an operand */
999 /*-----------------------------------------------------------------*/
1001 operandLitValue (operand * op)
1003 assert (isOperandLiteral (op));
1005 return floatFromVal (op->operand.valOperand);
1008 /*-----------------------------------------------------------------*/
1009 /* getBuiltInParms - returns parameters to a builtin functions */
1010 /*-----------------------------------------------------------------*/
1011 iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms)
1016 /* builtin functions uses only SEND for parameters */
1017 while (ic->op != CALL) {
1018 assert(ic->op == SEND && ic->builtinSEND);
1019 ic->generated = 1; /* mark the icode as generated */
1020 parms[*pcount] = IC_LEFT(ic);
1026 /* make sure this is a builtin function call */
1027 assert(IS_SYMOP(IC_LEFT(ic)));
1028 ftype = operandType(IC_LEFT(ic));
1029 assert(IFFUNC_ISBUILTIN(ftype));
1033 /*-----------------------------------------------------------------*/
1034 /* operandOperation - performs operations on operands */
1035 /*-----------------------------------------------------------------*/
1037 operandOperation (operand * left, operand * right,
1038 int op, sym_link * type)
1040 sym_link *let , *ret=NULL;
1041 operand *retval = (operand *) 0;
1043 assert (isOperandLiteral (left));
1044 let = getSpec(operandType(left));
1046 assert (isOperandLiteral (right));
1047 ret = getSpec(operandType(right));
1053 retval = operandFromValue (valCastLiteral (type,
1054 operandLitValue (left) +
1055 operandLitValue (right)));
1058 retval = operandFromValue (valCastLiteral (type,
1059 operandLitValue (left) -
1060 operandLitValue (right)));
1064 retval = operandFromValue (valCastLiteral (type,
1065 operandLitValue (left) *
1066 operandLitValue (right)));
1067 This could be all we've to do, but with gcc we've to take care about
1068 overflows. Two examples:
1069 ULONG_MAX * ULONG_MAX doesn't fit into a double, some of the least
1070 significant bits are lost (52 in fraction, 63 bits would be
1071 necessary to keep full precision).
1072 If the resulting double value is greater than ULONG_MAX (resp.
1073 USHRT_MAX, ...), then 0 will be assigned to v_ulong (resp. u_uint, ...)!
1076 /* if it is not a specifier then we can assume that */
1077 /* it will be an unsigned long */
1078 if (IS_INT (type) ||
1081 /* long is handled here, because it can overflow with double */
1082 if (SPEC_LONG (type) ||
1084 /* signed and unsigned mul are the same, as long as the precision
1085 of the result isn't bigger than the precision of the operands. */
1086 retval = operandFromValue (valCastLiteral (type,
1087 (TYPE_UDWORD) operandLitValue (left) *
1088 (TYPE_UDWORD) operandLitValue (right)));
1089 else if (SPEC_USIGN (type)) /* unsigned int */
1091 /* unsigned int is handled here in order to detect overflow */
1092 TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) *
1093 (TYPE_UWORD) operandLitValue (right);
1095 retval = operandFromValue (valCastLiteral (type, (TYPE_UWORD) ul));
1096 if (!options.lessPedantic &&
1097 ul != (TYPE_UWORD) ul)
1100 else /* signed int */
1102 /* signed int is handled here in order to detect overflow */
1103 TYPE_DWORD l = (TYPE_WORD) operandLitValue (left) *
1104 (TYPE_WORD) operandLitValue (right);
1106 retval = operandFromValue (valCastLiteral (type, (TYPE_WORD) l));
1107 if (!options.lessPedantic &&
1113 /* all others go here: */
1114 retval = operandFromValue (valCastLiteral (type,
1115 operandLitValue (left) *
1116 operandLitValue (right)));
1119 if ((TYPE_UDWORD) operandLitValue (right) == 0)
1121 werror (E_DIVIDE_BY_ZERO);
1126 retval = operandFromValue (valCastLiteral (type,
1127 operandLitValue (left) /
1128 operandLitValue (right)));
1131 if ((TYPE_UDWORD) operandLitValue (right) == 0) {
1132 werror (E_DIVIDE_BY_ZERO);
1137 if (SPEC_USIGN(let) || SPEC_USIGN(ret))
1138 /* one of the operands is unsigned */
1139 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) %
1140 (TYPE_UDWORD) operandLitValue (right));
1142 /* both operands are signed */
1143 retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) %
1144 (TYPE_DWORD) operandLitValue (right));
1148 /* The number of left shifts is always unsigned. Signed doesn't make
1149 sense here. Shifting by a negative number is impossible. */
1150 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) <<
1151 (TYPE_UDWORD) operandLitValue (right));
1154 /* The number of right shifts is always unsigned. Signed doesn't make
1155 sense here. Shifting by a negative number is impossible. */
1156 if (SPEC_USIGN(let))
1157 /* unsigned: logic shift right */
1158 retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >>
1159 (TYPE_UDWORD) operandLitValue (right));
1161 /* signed: arithmetic shift right */
1162 retval = operandFromLit ((TYPE_DWORD ) operandLitValue (left) >>
1163 (TYPE_UDWORD) operandLitValue (right));
1166 /* this op doesn't care about signedness */
1170 l = (TYPE_UDWORD) operandLitValue (left);
1171 if (SPEC_NOUN(OP_VALUE(left)->type) == V_CHAR)
1173 else if (!SPEC_LONG (OP_VALUE(left)->type))
1175 r = (TYPE_UDWORD) operandLitValue (right);
1176 if (SPEC_NOUN(OP_VALUE(right)->type) == V_CHAR)
1178 else if (!SPEC_LONG (OP_VALUE(right)->type))
1180 retval = operandFromLit (l == r);
1184 retval = operandFromLit (operandLitValue (left) <
1185 operandLitValue (right));
1188 retval = operandFromLit (operandLitValue (left) <=
1189 operandLitValue (right));
1192 retval = operandFromLit (operandLitValue (left) !=
1193 operandLitValue (right));
1196 retval = operandFromLit (operandLitValue (left) >
1197 operandLitValue (right));
1200 retval = operandFromLit (operandLitValue (left) >=
1201 operandLitValue (right));
1204 retval = operandFromValue (valCastLiteral (type,
1205 (TYPE_UDWORD)operandLitValue(left) &
1206 (TYPE_UDWORD)operandLitValue(right)));
1209 retval = operandFromValue (valCastLiteral (type,
1210 (TYPE_UDWORD)operandLitValue(left) |
1211 (TYPE_UDWORD)operandLitValue(right)));
1214 retval = operandFromValue (valCastLiteral (type,
1215 (TYPE_UDWORD)operandLitValue(left) ^
1216 (TYPE_UDWORD)operandLitValue(right)));
1219 retval = operandFromLit (operandLitValue (left) &&
1220 operandLitValue (right));
1223 retval = operandFromLit (operandLitValue (left) ||
1224 operandLitValue (right));
1228 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1230 retval = operandFromLit ((i >> (getSize (operandType (left)) * 8 - 1)) |
1236 TYPE_UDWORD i = (TYPE_UDWORD) operandLitValue (left);
1238 retval = operandFromLit ((i << (getSize (operandType (left)) * 8 - 1)) |
1244 retval = operandFromValue (valCastLiteral (type,
1245 -1 * operandLitValue (left)));
1249 retval = operandFromLit (~((TYPE_UDWORD) operandLitValue (left)));
1253 retval = operandFromLit (!operandLitValue (left));
1257 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1258 " operandOperation invalid operator ");
1266 /*-----------------------------------------------------------------*/
1267 /* isOperandEqual - compares two operand & return 1 if they r = */
1268 /*-----------------------------------------------------------------*/
1270 isOperandEqual (operand * left, operand * right)
1272 /* if the pointers are equal then they are equal */
1276 /* if either of them null then false */
1277 if (!left || !right)
1280 if (left->type != right->type)
1283 if (IS_SYMOP (left) && IS_SYMOP (right))
1284 return left->key == right->key;
1286 /* if types are the same */
1290 return isSymbolEqual (left->operand.symOperand,
1291 right->operand.symOperand);
1293 return (floatFromVal (left->operand.valOperand) ==
1294 floatFromVal (right->operand.valOperand));
1296 if (compareType (left->operand.typeOperand,
1297 right->operand.typeOperand) == 1)
1304 /*-------------------------------------------------------------------*/
1305 /* isiCodeEqual - compares two iCodes are equal, returns true if yes */
1306 /*-------------------------------------------------------------------*/
1308 isiCodeEqual (iCode * left, iCode * right)
1310 /* if the same pointer */
1314 /* if either of them null */
1315 if (!left || !right)
1318 /* if operand are the same */
1319 if (left->op == right->op)
1322 /* compare all the elements depending on type */
1323 if (left->op != IFX)
1325 if (!isOperandEqual (IC_LEFT (left), IC_LEFT (right)))
1327 if (!isOperandEqual (IC_RIGHT (left), IC_RIGHT (right)))
1333 if (!isOperandEqual (IC_COND (left), IC_COND (right)))
1335 if (!isSymbolEqual (IC_TRUE (left), IC_TRUE (right)))
1337 if (!isSymbolEqual (IC_FALSE (left), IC_FALSE (right)))
1346 /*-----------------------------------------------------------------*/
1347 /* newiTempFromOp - create a temp Operand with same attributes */
1348 /*-----------------------------------------------------------------*/
1350 newiTempFromOp (operand * op)
1360 nop = newiTempOperand (operandType (op), TRUE);
1361 nop->isaddr = op->isaddr;
1362 nop->isvolatile = op->isvolatile;
1363 nop->isGlobal = op->isGlobal;
1364 nop->isLiteral = op->isLiteral;
1365 nop->usesDefs = op->usesDefs;
1366 nop->isParm = op->isParm;
1370 /*-----------------------------------------------------------------*/
1371 /* operand from operand - creates an operand holder for the type */
1372 /*-----------------------------------------------------------------*/
1374 operandFromOperand (operand * op)
1380 nop = newOperand ();
1381 nop->type = op->type;
1382 nop->isaddr = op->isaddr;
1384 nop->isvolatile = op->isvolatile;
1385 nop->isGlobal = op->isGlobal;
1386 nop->isLiteral = op->isLiteral;
1387 nop->usesDefs = op->usesDefs;
1388 nop->isParm = op->isParm;
1393 nop->operand.symOperand = op->operand.symOperand;
1396 nop->operand.valOperand = op->operand.valOperand;
1399 nop->operand.typeOperand = op->operand.typeOperand;
1406 /*-----------------------------------------------------------------*/
1407 /* opFromOpWithDU - makes a copy of the operand and DU chains */
1408 /*-----------------------------------------------------------------*/
1410 opFromOpWithDU (operand * op, bitVect * defs, bitVect * uses)
1412 operand *nop = operandFromOperand (op);
1414 if (nop->type == SYMBOL)
1416 OP_SYMBOL (nop)->defs = bitVectCopy (defs);
1417 OP_SYMBOL (nop)->uses = bitVectCopy (uses);
1423 /*-----------------------------------------------------------------*/
1424 /* operandFromSymbol - creates an operand from a symbol */
1425 /*-----------------------------------------------------------------*/
1427 operandFromSymbol (symbol * sym)
1432 /* if the symbol's type is a literal */
1433 /* then it is an enumerator type */
1434 if (IS_LITERAL (sym->etype) && SPEC_ENUM (sym->etype))
1435 return operandFromValue (valFromType (sym->etype));
1438 sym->key = ++operandKey;
1440 /* if this an implicit variable, means struct/union */
1441 /* member so just return it */
1442 if (sym->implicit || IS_FUNC (sym->type))
1446 op->operand.symOperand = sym;
1448 op->isvolatile = isOperandVolatile (op, TRUE);
1449 op->isGlobal = isOperandGlobal (op);
1453 /* under the following conditions create a
1454 register equivalent for a local symbol */
1455 if (sym->level && sym->etype && SPEC_OCLS (sym->etype) &&
1456 (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
1457 (!(options.model == MODEL_FLAT24)) ) &&
1458 options.stackAuto == 0)
1461 if (!IS_AGGREGATE (sym->type) && /* not an aggregate */
1462 !IS_FUNC (sym->type) && /* not a function */
1463 !sym->_isparm && /* not a parameter */
1464 sym->level && /* is a local variable */
1465 !sym->addrtaken && /* whose address has not been taken */
1466 !sym->reqv && /* does not already have a reg equivalence */
1467 !IS_VOLATILE (sym->etype) && /* not declared as volatile */
1468 !IS_STATIC (sym->etype) && /* and not declared static */
1469 !sym->islbl && /* not a label */
1470 ok && /* farspace check */
1471 !IS_BITVAR (sym->etype) /* not a bit variable */
1475 /* we will use it after all optimizations
1476 and before liveRange calculation */
1477 sym->reqv = newiTempOperand (sym->type, 0);
1478 sym->reqv->key = sym->key;
1479 OP_SYMBOL (sym->reqv)->key = sym->key;
1480 OP_SYMBOL (sym->reqv)->isreqv = 1;
1481 OP_SYMBOL (sym->reqv)->islocal = 1;
1482 OP_SYMBOL (sym->reqv)->onStack = sym->onStack;
1483 SPIL_LOC (sym->reqv) = sym;
1486 if (!IS_AGGREGATE (sym->type))
1490 op->operand.symOperand = sym;
1493 op->isvolatile = isOperandVolatile (op, TRUE);
1494 op->isGlobal = isOperandGlobal (op);
1495 op->isPtr = IS_PTR (operandType (op));
1496 op->isParm = sym->_isparm;
1501 /* itemp = &[_symbol] */
1503 ic = newiCode (ADDRESS_OF, newOperand (), NULL);
1504 IC_LEFT (ic)->type = SYMBOL;
1505 IC_LEFT (ic)->operand.symOperand = sym;
1506 IC_LEFT (ic)->key = sym->key;
1507 (IC_LEFT (ic))->isvolatile = isOperandVolatile (IC_LEFT (ic), TRUE);
1508 (IC_LEFT (ic))->isGlobal = isOperandGlobal (IC_LEFT (ic));
1509 IC_LEFT (ic)->isPtr = IS_PTR (operandType (IC_LEFT (ic)));
1512 IC_RESULT (ic) = newiTempOperand (sym->type, 0);
1513 if (IS_ARRAY (sym->type))
1515 IC_RESULT (ic) = geniCodeArray2Ptr (IC_RESULT (ic));
1516 IC_RESULT (ic)->isaddr = 0;
1519 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (sym->type));
1523 return IC_RESULT (ic);
1526 /*-----------------------------------------------------------------*/
1527 /* operandFromValue - creates an operand from value */
1528 /*-----------------------------------------------------------------*/
1530 operandFromValue (value * val)
1534 /* if this is a symbol then do the symbol thing */
1536 return operandFromSymbol (val->sym);
1538 /* this is not a symbol */
1541 op->operand.valOperand = val;
1542 op->isLiteral = isOperandLiteral (op);
1546 /*-----------------------------------------------------------------*/
1547 /* operandFromLink - operand from typeChain */
1548 /*-----------------------------------------------------------------*/
1550 operandFromLink (sym_link * type)
1554 /* operand from sym_link */
1560 op->operand.typeOperand = copyLinkChain (type);
1564 /*-----------------------------------------------------------------*/
1565 /* operandFromLit - makes an operand from a literal value */
1566 /*-----------------------------------------------------------------*/
1568 operandFromLit (double i)
1570 return operandFromValue (valueFromLit (i));
1573 /*-----------------------------------------------------------------*/
1574 /* operandFromAst - creates an operand from an ast */
1575 /*-----------------------------------------------------------------*/
1577 operandFromAst (ast * tree,int lvl)
1583 /* depending on type do */
1587 return ast2iCode (tree,lvl+1);
1591 return operandFromValue (tree->opval.val);
1595 return operandFromLink (tree->opval.lnk);
1602 /* Just to keep the compiler happy */
1603 return (operand *) 0;
1606 /*-----------------------------------------------------------------*/
1607 /* setOperandType - sets the operand's type to the given type */
1608 /*-----------------------------------------------------------------*/
1610 setOperandType (operand * op, sym_link * type)
1612 /* depending on the type of operand */
1617 op->operand.valOperand->etype =
1618 getSpec (op->operand.valOperand->type =
1619 copyLinkChain (type));
1623 if (op->operand.symOperand->isitmp)
1624 op->operand.symOperand->etype =
1625 getSpec (op->operand.symOperand->type =
1626 copyLinkChain (type));
1628 werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
1629 "attempt to modify type of source");
1633 op->operand.typeOperand = copyLinkChain (type);
1638 /*-----------------------------------------------------------------*/
1639 /* Get size in byte of ptr need to access an array */
1640 /*-----------------------------------------------------------------*/
1642 getArraySizePtr (operand * op)
1644 sym_link *ltype = operandType(op);
1648 int size = getSize(ltype);
1649 return(IS_GENPTR(ltype)?(size-1):size);
1654 sym_link *letype = getSpec(ltype);
1655 switch (PTR_TYPE (SPEC_OCLS (letype)))
1667 return (GPTRSIZE-1);
1676 /*-----------------------------------------------------------------*/
1677 /* perform "usual unary conversions" */
1678 /*-----------------------------------------------------------------*/
1680 usualUnaryConversions (operand * op)
1682 if (IS_INTEGRAL (operandType (op)))
1684 if (getSize (operandType (op)) < (unsigned int) INTSIZE)
1687 return geniCodeCast (INTTYPE, op, TRUE);
1693 /*-----------------------------------------------------------------*/
1694 /* perform "usual binary conversions" */
1695 /*-----------------------------------------------------------------*/
1697 usualBinaryConversions (operand ** op1, operand ** op2)
1700 sym_link *rtype = operandType (*op2);
1701 sym_link *ltype = operandType (*op1);
1703 ctype = computeType (ltype, rtype);
1705 *op1 = geniCodeCast (ctype, *op1, TRUE);
1706 *op2 = geniCodeCast (ctype, *op2, TRUE);
1711 /*-----------------------------------------------------------------*/
1712 /* geniCodeValueAtAddress - generate intermeditate code for value */
1714 /*-----------------------------------------------------------------*/
1716 geniCodeRValue (operand * op, bool force)
1719 sym_link *type = operandType (op);
1720 sym_link *etype = getSpec (type);
1722 /* if this is an array & already */
1723 /* an address then return this */
1724 if (IS_AGGREGATE (type) ||
1725 (IS_PTR (type) && !force && !op->isaddr))
1726 return operandFromOperand (op);
1728 /* if this is not an address then must be */
1729 /* rvalue already so return this one */
1733 /* if this is not a temp symbol then */
1734 if (!IS_ITEMP (op) &&
1736 !IN_FARSPACE (SPEC_OCLS (etype)))
1738 op = operandFromOperand (op);
1743 if (IS_SPEC (type) &&
1744 IS_TRUE_SYMOP (op) &&
1745 (!IN_FARSPACE (SPEC_OCLS (etype)) ||
1746 (options.model == MODEL_FLAT24) ))
1748 op = operandFromOperand (op);
1753 ic = newiCode (GET_VALUE_AT_ADDRESS, op, NULL);
1754 if (IS_PTR (type) && op->isaddr && force)
1757 type = copyLinkChain (type);
1759 IC_RESULT (ic) = newiTempOperand (type, 1);
1760 IC_RESULT (ic)->isaddr = 0;
1762 /* ic->supportRtn = ((IS_GENPTR(type) | op->isGptr) & op->isaddr); */
1766 return IC_RESULT (ic);
1769 /*-----------------------------------------------------------------*/
1770 /* geniCodeCast - changes the value from one type to another */
1771 /*-----------------------------------------------------------------*/
1773 geniCodeCast (sym_link * type, operand * op, bool implicit)
1777 sym_link *opetype = getSpec (optype = operandType (op));
1781 /* one of them has size zero then error */
1782 if (IS_VOID (optype))
1784 werror (E_CAST_ZERO);
1788 /* if the operand is already the desired type then do nothing */
1789 if (compareType (type, optype) == 1)
1792 /* if this is a literal then just change the type & return */
1793 if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype))
1794 return operandFromValue (valCastLiteral (type,
1795 operandLitValue (op)));
1797 /* if casting to/from pointers, do some checking */
1798 if (IS_PTR(type)) { // to a pointer
1799 if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer
1800 if (IS_INTEGRAL(optype)) {
1801 // maybe this is NULL, than it's ok.
1802 if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) {
1803 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80 && IS_GENPTR(type)) {
1804 // no way to set the storage
1805 if (IS_LITERAL(optype)) {
1806 werror(E_LITERAL_GENERIC);
1809 werror(E_NONPTR2_GENPTR);
1812 } else if (implicit) {
1813 werror(W_INTEGRAL2PTR_NOCAST);
1818 // shouldn't do that with float, array or structure unless to void
1819 if (!IS_VOID(getSpec(type)) &&
1820 !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1821 werror(E_INCOMPAT_TYPES);
1825 } else { // from a pointer to a pointer
1826 if (!TARGET_IS_Z80 && !TARGET_IS_GBZ80) {
1827 // if not a pointer to a function
1828 if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) {
1829 if (implicit) { // if not to generic, they have to match
1830 if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) {
1831 werror(E_INCOMPAT_PTYPES);
1838 } else { // to a non pointer
1839 if (IS_PTR(optype)) { // from a pointer
1840 if (implicit) { // sneaky
1841 if (IS_INTEGRAL(type)) {
1842 werror(W_PTR2INTEGRAL_NOCAST);
1844 } else { // shouldn't do that with float, array or structure
1845 werror(E_INCOMPAT_TYPES);
1852 printFromToType (optype, type);
1855 /* if they are the same size create an assignment */
1856 if (getSize (type) == getSize (optype) &&
1857 !IS_BITFIELD (type) &&
1859 !IS_FLOAT (optype) &&
1860 ((IS_SPEC (type) && IS_SPEC (optype)) ||
1861 (!IS_SPEC (type) && !IS_SPEC (optype))))
1864 ic = newiCode ('=', NULL, op);
1865 IC_RESULT (ic) = newiTempOperand (type, 0);
1866 SPIL_LOC (IC_RESULT (ic)) =
1867 (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL);
1868 IC_RESULT (ic)->isaddr = 0;
1872 ic = newiCode (CAST, operandFromLink (type),
1873 geniCodeRValue (op, FALSE));
1875 IC_RESULT (ic) = newiTempOperand (type, 0);
1878 /* preserve the storage class & output class */
1879 /* of the original variable */
1880 restype = getSpec (operandType (IC_RESULT (ic)));
1881 if (!IS_LITERAL(opetype))
1882 SPEC_SCLS (restype) = SPEC_SCLS (opetype);
1883 SPEC_OCLS (restype) = SPEC_OCLS (opetype);
1886 return IC_RESULT (ic);
1889 /*-----------------------------------------------------------------*/
1890 /* geniCodeLabel - will create a Label */
1891 /*-----------------------------------------------------------------*/
1893 geniCodeLabel (symbol * label)
1897 ic = newiCodeLabelGoto (LABEL, label);
1901 /*-----------------------------------------------------------------*/
1902 /* geniCodeGoto - will create a Goto */
1903 /*-----------------------------------------------------------------*/
1905 geniCodeGoto (symbol * label)
1909 ic = newiCodeLabelGoto (GOTO, label);
1913 /*-----------------------------------------------------------------*/
1914 /* geniCodeMultiply - gen intermediate code for multiplication */
1915 /*-----------------------------------------------------------------*/
1917 geniCodeMultiply (operand * left, operand * right,int resultIsInt)
1924 /* if they are both literal then we know the result */
1925 if (IS_LITERAL (letype) && IS_LITERAL (retype))
1926 return operandFromValue (valMult (left->operand.valOperand,
1927 right->operand.valOperand));
1929 if (IS_LITERAL(retype)) {
1930 p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand));
1933 resType = usualBinaryConversions (&left, &right);
1935 rtype = operandType (right);
1936 retype = getSpec (rtype);
1937 ltype = operandType (left);
1938 letype = getSpec (ltype);
1942 SPEC_NOUN(getSpec(resType))=V_INT;
1945 /* if the right is a literal & power of 2 */
1946 /* then make it a left shift */
1947 /* code generated for 1 byte * 1 byte literal = 2 bytes result is more
1948 efficient in most cases than 2 bytes result = 2 bytes << literal
1949 if port has 1 byte muldiv */
1950 if (p2 && !IS_FLOAT (letype) &&
1951 !((resultIsInt) && (getSize (resType) != getSize (ltype)) &&
1952 (port->support.muldiv == 1)))
1954 if ((resultIsInt) && (getSize (resType) != getSize (ltype)))
1956 /* LEFT_OP need same size for left and result, */
1957 left = geniCodeCast (resType, left, TRUE);
1958 ltype = operandType (left);
1960 ic = newiCode (LEFT_OP, left, operandFromLit (p2)); /* left shift */
1964 ic = newiCode ('*', left, right); /* normal multiplication */
1965 /* if the size left or right > 1 then support routine */
1966 if (getSize (ltype) > 1 || getSize (rtype) > 1)
1970 IC_RESULT (ic) = newiTempOperand (resType, 1);
1973 return IC_RESULT (ic);
1976 /*-----------------------------------------------------------------*/
1977 /* geniCodeDivision - gen intermediate code for division */
1978 /*-----------------------------------------------------------------*/
1980 geniCodeDivision (operand * left, operand * right)
1985 sym_link *rtype = operandType (right);
1986 sym_link *retype = getSpec (rtype);
1987 sym_link *ltype = operandType (left);
1988 sym_link *letype = getSpec (ltype);
1990 resType = usualBinaryConversions (&left, &right);
1992 /* if the right is a literal & power of 2
1993 and left is unsigned then make it a
1995 if (IS_LITERAL (retype) &&
1996 !IS_FLOAT (letype) &&
1997 SPEC_USIGN(letype) &&
1998 (p2 = powof2 ((unsigned long)
1999 floatFromVal (right->operand.valOperand)))) {
2000 ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */
2004 ic = newiCode ('/', left, right); /* normal division */
2005 /* if the size left or right > 1 then support routine */
2006 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2009 IC_RESULT (ic) = newiTempOperand (resType, 0);
2012 return IC_RESULT (ic);
2014 /*-----------------------------------------------------------------*/
2015 /* geniCodeModulus - gen intermediate code for modulus */
2016 /*-----------------------------------------------------------------*/
2018 geniCodeModulus (operand * left, operand * right)
2024 /* if they are both literal then we know the result */
2025 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2026 return operandFromValue (valMod (left->operand.valOperand,
2027 right->operand.valOperand));
2029 resType = usualBinaryConversions (&left, &right);
2031 /* now they are the same size */
2032 ic = newiCode ('%', left, right);
2034 /* if the size left or right > 1 then support routine */
2035 if (getSize (ltype) > 1 || getSize (rtype) > 1)
2037 IC_RESULT (ic) = newiTempOperand (resType, 0);
2040 return IC_RESULT (ic);
2043 /*-----------------------------------------------------------------*/
2044 /* geniCodePtrPtrSubtract - subtracts pointer from pointer */
2045 /*-----------------------------------------------------------------*/
2047 geniCodePtrPtrSubtract (operand * left, operand * right)
2053 /* if they are both literals then */
2054 if (IS_LITERAL (letype) && IS_LITERAL (retype))
2056 result = operandFromValue (valMinus (left->operand.valOperand,
2057 right->operand.valOperand));
2061 ic = newiCode ('-', left, right);
2063 IC_RESULT (ic) = result = newiTempOperand (newIntLink (), 1);
2067 if (IS_VOID(ltype->next) || IS_VOID(rtype->next)) {
2071 // should we really do this? is this ANSI?
2072 return geniCodeDivision (result,
2073 operandFromLit (getSize (ltype->next)));
2076 /*-----------------------------------------------------------------*/
2077 /* geniCodeSubtract - generates code for subtraction */
2078 /*-----------------------------------------------------------------*/
2080 geniCodeSubtract (operand * left, operand * right)
2087 /* if they both pointers then */
2088 if ((IS_PTR (ltype) || IS_ARRAY (ltype)) &&
2089 (IS_PTR (rtype) || IS_ARRAY (rtype)))
2090 return geniCodePtrPtrSubtract (left, right);
2092 /* if they are both literal then we know the result */
2093 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2094 && left->isLiteral && right->isLiteral)
2095 return operandFromValue (valMinus (left->operand.valOperand,
2096 right->operand.valOperand));
2098 /* if left is an array or pointer */
2099 if (IS_PTR (ltype) || IS_ARRAY (ltype))
2101 isarray = left->isaddr;
2102 right = geniCodeMultiply (right,
2103 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2104 resType = copyLinkChain (IS_ARRAY (ltype) ? ltype->next : ltype);
2107 { /* make them the same size */
2108 resType = usualBinaryConversions (&left, &right);
2111 ic = newiCode ('-', left, right);
2113 IC_RESULT (ic) = newiTempOperand (resType, 1);
2114 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2116 /* if left or right is a float */
2117 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2121 return IC_RESULT (ic);
2124 /*-----------------------------------------------------------------*/
2125 /* geniCodeAdd - generates iCode for addition */
2126 /*-----------------------------------------------------------------*/
2128 geniCodeAdd (operand * left, operand * right, int lvl)
2136 /* if the right side is LITERAL zero */
2137 /* return the left side */
2138 if (IS_LITERAL (retype) && right->isLiteral && !floatFromVal (valFromType (retype)))
2141 /* if left is literal zero return right */
2142 if (IS_LITERAL (letype) && left->isLiteral && !floatFromVal (valFromType (letype)))
2145 /* if left is a pointer then size */
2146 if (IS_PTR (ltype) || IS_ARRAY(ltype))
2148 isarray = left->isaddr;
2149 // there is no need to multiply with 1
2150 if (getSize(ltype->next)!=1) {
2151 size = operandFromLit (getSize (ltype->next));
2152 right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE));
2154 resType = copyLinkChain (ltype);
2157 { // make them the same size
2158 resType = usualBinaryConversions (&left, &right);
2161 /* if they are both literals then we know */
2162 if (IS_LITERAL (letype) && IS_LITERAL (retype)
2163 && left->isLiteral && right->isLiteral)
2164 return operandFromValue (valPlus (valFromType (letype),
2165 valFromType (retype)));
2167 ic = newiCode ('+', left, right);
2169 IC_RESULT (ic) = newiTempOperand (resType, 1);
2170 IC_RESULT (ic)->isaddr = (isarray ? 1 : 0);
2172 /* if left or right is a float then support
2174 if (IS_FLOAT (ltype) || IS_FLOAT (rtype))
2179 return IC_RESULT (ic);
2183 /*-----------------------------------------------------------------*/
2184 /* aggrToPtr - changes an aggregate to pointer to an aggregate */
2185 /*-----------------------------------------------------------------*/
2187 aggrToPtr (sym_link * type, bool force)
2193 if (IS_PTR (type) && !force)
2196 etype = getSpec (type);
2197 ptype = newLink (DECLARATOR);
2201 /* set the pointer depending on the storage class */
2202 DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype));
2206 /*-----------------------------------------------------------------*/
2207 /* geniCodeArray2Ptr - array to pointer */
2208 /*-----------------------------------------------------------------*/
2210 geniCodeArray2Ptr (operand * op)
2212 sym_link *optype = operandType (op);
2213 sym_link *opetype = getSpec (optype);
2215 /* set the pointer depending on the storage class */
2216 DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype));
2223 /*-----------------------------------------------------------------*/
2224 /* geniCodeArray - array access */
2225 /*-----------------------------------------------------------------*/
2227 geniCodeArray (operand * left, operand * right,int lvl)
2230 sym_link *ltype = operandType (left);
2234 if (IS_PTR (ltype->next) && left->isaddr)
2236 left = geniCodeRValue (left, FALSE);
2238 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2241 right = geniCodeMultiply (right,
2242 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2244 /* we can check for limits here */
2245 if (isOperandLiteral (right) &&
2248 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2250 werror (E_ARRAY_BOUND);
2251 right = operandFromLit (0);
2254 ic = newiCode ('+', left, right);
2256 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2257 !IS_AGGREGATE (ltype->next) &&
2258 !IS_PTR (ltype->next))
2259 ? ltype : ltype->next), 0);
2261 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2263 return IC_RESULT (ic);
2266 /*-----------------------------------------------------------------*/
2267 /* geniCodeStruct - generates intermediate code for structres */
2268 /*-----------------------------------------------------------------*/
2270 geniCodeStruct (operand * left, operand * right, bool islval)
2273 sym_link *type = operandType (left);
2274 sym_link *etype = getSpec (type);
2276 symbol *element = getStructElement (SPEC_STRUCT (etype),
2277 right->operand.symOperand);
2279 wassert(IS_SYMOP(right));
2281 /* add the offset */
2282 ic = newiCode ('+', left, operandFromLit (element->offset));
2284 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2286 /* preserve the storage & output class of the struct */
2287 /* as well as the volatile attribute */
2288 retype = getSpec (operandType (IC_RESULT (ic)));
2289 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2290 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2291 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype); /* EEP - I'm doubtful about this */
2293 if (IS_PTR (element->type))
2294 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2296 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2300 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2303 /*-----------------------------------------------------------------*/
2304 /* geniCodePostInc - generate int code for Post increment */
2305 /*-----------------------------------------------------------------*/
2307 geniCodePostInc (operand * op)
2311 sym_link *optype = operandType (op);
2313 operand *rv = (IS_ITEMP (op) ?
2314 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2316 sym_link *rvtype = operandType (rv);
2319 /* if this is not an address we have trouble */
2322 werror (E_LVALUE_REQUIRED, "++");
2326 rOp = newiTempOperand (rvtype, 0);
2327 OP_SYMBOL(rOp)->noSpilLoc = 1;
2330 OP_SYMBOL(rv)->noSpilLoc = 1;
2332 geniCodeAssign (rOp, rv, 0);
2334 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2335 if (IS_FLOAT (rvtype))
2336 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2338 ic = newiCode ('+', rv, operandFromLit (size));
2340 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2343 geniCodeAssign (op, result, 0);
2349 /*-----------------------------------------------------------------*/
2350 /* geniCodePreInc - generate code for preIncrement */
2351 /*-----------------------------------------------------------------*/
2353 geniCodePreInc (operand * op)
2356 sym_link *optype = operandType (op);
2357 operand *rop = (IS_ITEMP (op) ?
2358 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2360 sym_link *roptype = operandType (rop);
2366 werror (E_LVALUE_REQUIRED, "++");
2371 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2372 if (IS_FLOAT (roptype))
2373 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2375 ic = newiCode ('+', rop, operandFromLit (size));
2376 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2380 return geniCodeAssign (op, result, 0);
2383 /*-----------------------------------------------------------------*/
2384 /* geniCodePostDec - generates code for Post decrement */
2385 /*-----------------------------------------------------------------*/
2387 geniCodePostDec (operand * op)
2391 sym_link *optype = operandType (op);
2393 operand *rv = (IS_ITEMP (op) ?
2394 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2396 sym_link *rvtype = operandType (rv);
2399 /* if this is not an address we have trouble */
2402 werror (E_LVALUE_REQUIRED, "--");
2406 rOp = newiTempOperand (rvtype, 0);
2407 OP_SYMBOL(rOp)->noSpilLoc = 1;
2410 OP_SYMBOL(rv)->noSpilLoc = 1;
2412 geniCodeAssign (rOp, rv, 0);
2414 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2415 if (IS_FLOAT (rvtype))
2416 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2418 ic = newiCode ('-', rv, operandFromLit (size));
2420 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2423 geniCodeAssign (op, result, 0);
2429 /*-----------------------------------------------------------------*/
2430 /* geniCodePreDec - generate code for pre decrement */
2431 /*-----------------------------------------------------------------*/
2433 geniCodePreDec (operand * op)
2436 sym_link *optype = operandType (op);
2437 operand *rop = (IS_ITEMP (op) ?
2438 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2440 sym_link *roptype = operandType (rop);
2446 werror (E_LVALUE_REQUIRED, "--");
2451 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2452 if (IS_FLOAT (roptype))
2453 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2455 ic = newiCode ('-', rop, operandFromLit (size));
2456 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2460 return geniCodeAssign (op, result, 0);
2464 /*-----------------------------------------------------------------*/
2465 /* geniCodeBitwise - gen int code for bitWise operators */
2466 /*-----------------------------------------------------------------*/
2468 geniCodeBitwise (operand * left, operand * right,
2469 int oper, sym_link * resType)
2473 left = geniCodeCast (resType, left, TRUE);
2474 right = geniCodeCast (resType, right, TRUE);
2476 ic = newiCode (oper, left, right);
2477 IC_RESULT (ic) = newiTempOperand (resType, 0);
2480 return IC_RESULT (ic);
2483 /*-----------------------------------------------------------------*/
2484 /* geniCodeAddressOf - gens icode for '&' address of operator */
2485 /*-----------------------------------------------------------------*/
2487 geniCodeAddressOf (operand * op)
2491 sym_link *optype = operandType (op);
2492 sym_link *opetype = getSpec (optype);
2494 /* lvalue check already done in decorateType */
2495 /* this must be a lvalue */
2496 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2497 /* werror (E_LVALUE_REQUIRED,"&"); */
2501 p = newLink (DECLARATOR);
2503 /* set the pointer depending on the storage class */
2504 DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype));
2506 p->next = copyLinkChain (optype);
2508 /* if already a temp */
2511 setOperandType (op, p);
2516 /* other wise make this of the type coming in */
2517 ic = newiCode (ADDRESS_OF, op, NULL);
2518 IC_RESULT (ic) = newiTempOperand (p, 1);
2519 IC_RESULT (ic)->isaddr = 0;
2521 return IC_RESULT (ic);
2523 /*-----------------------------------------------------------------*/
2524 /* setOClass - sets the output class depending on the pointer type */
2525 /*-----------------------------------------------------------------*/
2527 setOClass (sym_link * ptr, sym_link * spec)
2529 switch (DCL_TYPE (ptr))
2532 SPEC_OCLS (spec) = data;
2536 SPEC_OCLS (spec) = generic;
2540 SPEC_OCLS (spec) = xdata;
2544 SPEC_OCLS (spec) = code;
2548 SPEC_OCLS (spec) = idata;
2552 SPEC_OCLS (spec) = xstack;
2556 SPEC_OCLS (spec) = eeprom;
2565 /*-----------------------------------------------------------------*/
2566 /* geniCodeDerefPtr - dereference pointer with '*' */
2567 /*-----------------------------------------------------------------*/
2569 geniCodeDerefPtr (operand * op,int lvl)
2571 sym_link *rtype, *retype;
2572 sym_link *optype = operandType (op);
2574 // if this is an array then array access
2575 if (IS_ARRAY (optype)) {
2576 // don't worry, this will be optimized out later
2577 return geniCodeArray (op, operandFromLit (0), lvl);
2580 // just in case someone screws up
2581 wassert (IS_PTR (optype));
2583 if (IS_TRUE_SYMOP (op))
2586 op = geniCodeRValue (op, TRUE);
2589 /* now get rid of the pointer part */
2590 if (isLvaluereq(lvl) && IS_ITEMP (op))
2592 retype = getSpec (rtype = copyLinkChain (optype));
2596 retype = getSpec (rtype = copyLinkChain (optype->next));
2599 /* outputclass needs 2b updated */
2600 setOClass (optype, retype);
2602 op->isGptr = IS_GENPTR (optype);
2604 op->isaddr = (IS_PTR (rtype) ||
2605 IS_STRUCT (rtype) ||
2610 if (!isLvaluereq(lvl))
2611 op = geniCodeRValue (op, TRUE);
2613 setOperandType (op, rtype);
2618 /*-----------------------------------------------------------------*/
2619 /* geniCodeUnaryMinus - does a unary minus of the operand */
2620 /*-----------------------------------------------------------------*/
2622 geniCodeUnaryMinus (operand * op)
2625 sym_link *optype = operandType (op);
2627 if (IS_LITERAL (optype))
2628 return operandFromLit (-floatFromVal (op->operand.valOperand));
2630 ic = newiCode (UNARYMINUS, op, NULL);
2631 IC_RESULT (ic) = newiTempOperand (optype, 0);
2633 return IC_RESULT (ic);
2636 /*-----------------------------------------------------------------*/
2637 /* geniCodeLeftShift - gen i code for left shift */
2638 /*-----------------------------------------------------------------*/
2640 geniCodeLeftShift (operand * left, operand * right)
2644 ic = newiCode (LEFT_OP, left, right);
2645 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2647 return IC_RESULT (ic);
2650 /*-----------------------------------------------------------------*/
2651 /* geniCodeRightShift - gen i code for right shift */
2652 /*-----------------------------------------------------------------*/
2654 geniCodeRightShift (operand * left, operand * right)
2658 ic = newiCode (RIGHT_OP, left, right);
2659 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2661 return IC_RESULT (ic);
2664 /*-----------------------------------------------------------------*/
2665 /* geniCodeLogic- logic code */
2666 /*-----------------------------------------------------------------*/
2668 geniCodeLogic (operand * left, operand * right, int op)
2672 sym_link *rtype = operandType (right);
2673 sym_link *ltype = operandType (left);
2675 /* left is integral type and right is literal then
2676 check if the literal value is within bounds */
2677 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2679 checkConstantRange(ltype,
2680 OP_VALUE(right), "compare operation", 1);
2683 /* if one operand is a pointer and the other is a literal generic void pointer,
2684 change the type of the literal generic void pointer to match the other pointer */
2685 if (IS_GENPTR (ltype) && IS_VOID (ltype->next) && IS_ITEMP (left)
2686 && IS_PTR (rtype) && !IS_GENPTR(rtype))
2688 /* find left's definition */
2689 ic = (iCode *) setFirstItem (iCodeChain);
2692 if (((ic->op == CAST) || (ic->op == '='))
2693 && isOperandEqual(left, IC_RESULT (ic)))
2696 ic = setNextItem (iCodeChain);
2698 /* if casting literal to generic pointer, then cast to rtype instead */
2699 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2701 left = operandFromValue (valCastLiteral (rtype, operandLitValue (IC_RIGHT (ic))));
2702 ltype = operandType(left);
2705 if (IS_GENPTR (rtype) && IS_VOID (rtype->next) && IS_ITEMP (right)
2706 && IS_PTR (ltype) && !IS_GENPTR(ltype))
2708 /* find right's definition */
2709 ic = (iCode *) setFirstItem (iCodeChain);
2712 if (((ic->op == CAST) || (ic->op == '='))
2713 && isOperandEqual(right, IC_RESULT (ic)))
2716 ic = setNextItem (iCodeChain);
2718 /* if casting literal to generic pointer, then cast to rtype instead */
2719 if (ic && (ic->op == CAST) && isOperandLiteral(IC_RIGHT (ic)))
2721 right = operandFromValue (valCastLiteral (ltype, operandLitValue (IC_RIGHT (ic))));
2722 rtype = operandType(right);
2726 ctype = usualBinaryConversions (&left, &right);
2728 ic = newiCode (op, left, right);
2729 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2731 /* if comparing float
2732 and not a '==' || '!=' || '&&' || '||' (these
2734 if (IS_FLOAT(ctype) &&
2742 return IC_RESULT (ic);
2745 /*-----------------------------------------------------------------*/
2746 /* geniCodeUnary - for a a generic unary operation */
2747 /*-----------------------------------------------------------------*/
2749 geniCodeUnary (operand * op, int oper)
2751 iCode *ic = newiCode (oper, op, NULL);
2753 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2755 return IC_RESULT (ic);
2758 /*-----------------------------------------------------------------*/
2759 /* geniCodeConditional - geniCode for '?' ':' operation */
2760 /*-----------------------------------------------------------------*/
2762 geniCodeConditional (ast * tree,int lvl)
2765 symbol *falseLabel = newiTempLabel (NULL);
2766 symbol *exitLabel = newiTempLabel (NULL);
2767 operand *cond = ast2iCode (tree->left,lvl+1);
2768 operand *true, *false, *result;
2770 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2774 true = ast2iCode (tree->right->left,lvl+1);
2776 /* move the value to a new Operand */
2777 result = newiTempOperand (tree->right->ftype, 0);
2778 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2780 /* generate an unconditional goto */
2781 geniCodeGoto (exitLabel);
2783 /* now for the right side */
2784 geniCodeLabel (falseLabel);
2786 false = ast2iCode (tree->right->right,lvl+1);
2787 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2789 /* create the exit label */
2790 geniCodeLabel (exitLabel);
2795 /*-----------------------------------------------------------------*/
2796 /* geniCodeAssign - generate code for assignment */
2797 /*-----------------------------------------------------------------*/
2799 geniCodeAssign (operand * left, operand * right, int nosupdate)
2802 sym_link *ltype = operandType (left);
2803 sym_link *rtype = operandType (right);
2805 if (!left->isaddr && !IS_ITEMP (left))
2807 werror (E_LVALUE_REQUIRED, "assignment");
2811 /* left is integral type and right is literal then
2812 check if the literal value is within bounds */
2813 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2815 checkConstantRange(ltype,
2816 OP_VALUE(right), "= operation", 0);
2819 /* if the left & right type don't exactly match */
2820 /* if pointer set then make sure the check is
2821 done with the type & not the pointer */
2822 /* then cast rights type to left */
2824 /* first check the type for pointer assignement */
2825 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2826 compareType (ltype, rtype) <= 0)
2828 if (compareType (ltype->next, rtype) < 0)
2829 right = geniCodeCast (ltype->next, right, TRUE);
2831 else if (compareType (ltype, rtype) < 0)
2832 right = geniCodeCast (ltype, right, TRUE);
2834 /* if left is a true symbol & ! volatile
2835 create an assignment to temporary for
2836 the right & then assign this temporary
2837 to the symbol this is SSA . isn't it simple
2838 and folks have published mountains of paper on it */
2839 if (IS_TRUE_SYMOP (left) &&
2840 !isOperandVolatile (left, FALSE) &&
2841 isOperandGlobal (left))
2845 if (IS_TRUE_SYMOP (right))
2846 sym = OP_SYMBOL (right);
2847 ic = newiCode ('=', NULL, right);
2848 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2849 SPIL_LOC (right) = sym;
2853 ic = newiCode ('=', NULL, right);
2854 IC_RESULT (ic) = left;
2857 /* if left isgptr flag is set then support
2858 routine will be required */
2862 ic->nosupdate = nosupdate;
2866 /*-----------------------------------------------------------------*/
2867 /* geniCodeSEParms - generate code for side effecting fcalls */
2868 /*-----------------------------------------------------------------*/
2870 geniCodeSEParms (ast * parms,int lvl)
2875 if (parms->type == EX_OP && parms->opval.op == PARAM)
2877 geniCodeSEParms (parms->left,lvl);
2878 geniCodeSEParms (parms->right,lvl);
2882 /* hack don't like this but too lazy to think of
2884 if (IS_ADDRESS_OF_OP (parms))
2885 parms->left->lvalue = 1;
2887 if (IS_CAST_OP (parms) &&
2888 IS_PTR (parms->ftype) &&
2889 IS_ADDRESS_OF_OP (parms->right))
2890 parms->right->left->lvalue = 1;
2892 parms->opval.oprnd =
2893 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2895 parms->type = EX_OPERAND;
2896 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2897 SPEC_ARGREG(parms->ftype);
2900 /*-----------------------------------------------------------------*/
2901 /* geniCodeParms - generates parameters */
2902 /*-----------------------------------------------------------------*/
2904 geniCodeParms (ast * parms, value *argVals, int *stack,
2905 sym_link * fetype, symbol * func,int lvl)
2913 if (argVals==NULL) {
2915 argVals=FUNC_ARGS(func->type);
2918 /* if this is a param node then do the left & right */
2919 if (parms->type == EX_OP && parms->opval.op == PARAM)
2921 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2922 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2926 /* get the parameter value */
2927 if (parms->type == EX_OPERAND)
2928 pval = parms->opval.oprnd;
2931 /* maybe this else should go away ?? */
2932 /* hack don't like this but too lazy to think of
2934 if (IS_ADDRESS_OF_OP (parms))
2935 parms->left->lvalue = 1;
2937 if (IS_CAST_OP (parms) &&
2938 IS_PTR (parms->ftype) &&
2939 IS_ADDRESS_OF_OP (parms->right))
2940 parms->right->left->lvalue = 1;
2942 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2945 /* if register parm then make it a send */
2946 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2947 IFFUNC_ISBUILTIN(func->type))
2949 ic = newiCode (SEND, pval, NULL);
2950 ic->argreg = SPEC_ARGREG(parms->etype);
2951 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2956 /* now decide whether to push or assign */
2957 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2961 operand *top = operandFromSymbol (argVals->sym);
2962 /* clear useDef and other bitVectors */
2963 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
2964 geniCodeAssign (top, pval, 1);
2968 sym_link *p = operandType (pval);
2970 ic = newiCode (IPUSH, pval, NULL);
2972 /* update the stack adjustment */
2973 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2978 argVals=argVals->next;
2982 /*-----------------------------------------------------------------*/
2983 /* geniCodeCall - generates temp code for calling */
2984 /*-----------------------------------------------------------------*/
2986 geniCodeCall (operand * left, ast * parms,int lvl)
2990 sym_link *type, *etype;
2993 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2994 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2995 werror (E_FUNCTION_EXPECTED);
2999 /* take care of parameters with side-effecting
3000 function calls in them, this is required to take care
3001 of overlaying function parameters */
3002 geniCodeSEParms (parms,lvl);
3004 /* first the parameters */
3005 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
3007 /* now call : if symbol then pcall */
3008 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3009 ic = newiCode (PCALL, left, NULL);
3011 ic = newiCode (CALL, left, NULL);
3014 type = copyLinkChain (operandType (left)->next);
3015 etype = getSpec (type);
3016 SPEC_EXTR (etype) = 0;
3017 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3021 /* stack adjustment after call */
3022 ic->parmBytes = stack;
3027 /*-----------------------------------------------------------------*/
3028 /* geniCodeReceive - generate intermediate code for "receive" */
3029 /*-----------------------------------------------------------------*/
3031 geniCodeReceive (value * args)
3033 /* for all arguments that are passed in registers */
3037 if (IS_REGPARM (args->etype))
3039 operand *opr = operandFromValue (args);
3041 symbol *sym = OP_SYMBOL (opr);
3044 /* we will use it after all optimizations
3045 and before liveRange calculation */
3046 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3049 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
3050 options.stackAuto == 0 &&
3051 (!(options.model == MODEL_FLAT24)) )
3056 opl = newiTempOperand (args->type, 0);
3058 sym->reqv->key = sym->key;
3059 OP_SYMBOL (sym->reqv)->key = sym->key;
3060 OP_SYMBOL (sym->reqv)->isreqv = 1;
3061 OP_SYMBOL (sym->reqv)->islocal = 0;
3062 SPIL_LOC (sym->reqv) = sym;
3066 ic = newiCode (RECEIVE, NULL, NULL);
3067 ic->argreg = SPEC_ARGREG(args->etype);
3069 currFunc->recvSize = getSize (sym->type);
3072 IC_RESULT (ic) = opr;
3080 /*-----------------------------------------------------------------*/
3081 /* geniCodeFunctionBody - create the function body */
3082 /*-----------------------------------------------------------------*/
3084 geniCodeFunctionBody (ast * tree,int lvl)
3091 /* reset the auto generation */
3097 func = ast2iCode (tree->left,lvl+1);
3098 fetype = getSpec (operandType (func));
3100 savelineno = lineno;
3101 lineno = OP_SYMBOL (func)->lineDef;
3102 /* create an entry label */
3103 geniCodeLabel (entryLabel);
3104 lineno = savelineno;
3106 /* create a proc icode */
3107 ic = newiCode (FUNCTION, func, NULL);
3108 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3112 /* for all parameters that are passed
3113 on registers add a "receive" */
3114 geniCodeReceive (tree->values.args);
3116 /* generate code for the body */
3117 ast2iCode (tree->right,lvl+1);
3119 /* create a label for return */
3120 geniCodeLabel (returnLabel);
3122 /* now generate the end proc */
3123 ic = newiCode (ENDFUNCTION, func, NULL);
3128 /*-----------------------------------------------------------------*/
3129 /* geniCodeReturn - gen icode for 'return' statement */
3130 /*-----------------------------------------------------------------*/
3132 geniCodeReturn (operand * op)
3136 /* if the operand is present force an rvalue */
3138 op = geniCodeRValue (op, FALSE);
3140 ic = newiCode (RETURN, op, NULL);
3144 /*-----------------------------------------------------------------*/
3145 /* geniCodeIfx - generates code for extended if statement */
3146 /*-----------------------------------------------------------------*/
3148 geniCodeIfx (ast * tree,int lvl)
3151 operand *condition = ast2iCode (tree->left,lvl+1);
3154 /* if condition is null then exit */
3158 condition = geniCodeRValue (condition, FALSE);
3160 cetype = getSpec (operandType (condition));
3161 /* if the condition is a literal */
3162 if (IS_LITERAL (cetype))
3164 if (floatFromVal (condition->operand.valOperand))
3166 if (tree->trueLabel)
3167 geniCodeGoto (tree->trueLabel);
3173 if (tree->falseLabel)
3174 geniCodeGoto (tree->falseLabel);
3181 if (tree->trueLabel)
3183 ic = newiCodeCondition (condition,
3188 if (tree->falseLabel)
3189 geniCodeGoto (tree->falseLabel);
3193 ic = newiCodeCondition (condition,
3200 ast2iCode (tree->right,lvl+1);
3203 /*-----------------------------------------------------------------*/
3204 /* geniCodeJumpTable - tries to create a jump table for switch */
3205 /*-----------------------------------------------------------------*/
3207 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3209 int min = 0, max = 0, t, cnt = 0;
3216 if (!tree || !caseVals)
3219 /* the criteria for creating a jump table is */
3220 /* all integer numbers between the maximum & minimum must */
3221 /* be present , the maximum value should not exceed 255 */
3222 min = max = (int) floatFromVal (vch = caseVals);
3223 SNPRINTF (buffer, sizeof(buffer),
3225 tree->values.switchVals.swNum,
3227 addSet (&labels, newiTempLabel (buffer));
3229 /* if there is only one case value then no need */
3230 if (!(vch = vch->next))
3235 if (((t = (int) floatFromVal (vch)) - max) != 1)
3237 SNPRINTF (buffer, sizeof(buffer),
3239 tree->values.switchVals.swNum,
3241 addSet (&labels, newiTempLabel (buffer));
3247 /* if the number of case statements <= 2 then */
3248 /* it is not economical to create the jump table */
3249 /* since two compares are needed for boundary conditions */
3250 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3253 if (tree->values.switchVals.swDefault)
3255 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3259 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3263 falseLabel = newiTempLabel (buffer);
3265 /* so we can create a jumptable */
3266 /* first we rule out the boundary conditions */
3267 /* if only optimization says so */
3268 if (!optimize.noJTabBoundary)
3270 sym_link *cetype = getSpec (operandType (cond));
3271 /* no need to check the lower bound if
3272 the condition is unsigned & minimum value is zero */
3273 if (!(min == 0 && SPEC_USIGN (cetype)))
3275 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3276 ic = newiCodeCondition (boundary, falseLabel, NULL);
3280 /* now for upper bounds */
3281 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3282 ic = newiCodeCondition (boundary, falseLabel, NULL);
3286 /* if the min is not zero then we no make it zero */
3289 cond = geniCodeSubtract (cond, operandFromLit (min));
3290 setOperandType (cond, UCHARTYPE);
3293 /* now create the jumptable */
3294 ic = newiCode (JUMPTABLE, NULL, NULL);
3295 IC_JTCOND (ic) = cond;
3296 IC_JTLABELS (ic) = labels;
3301 /*-----------------------------------------------------------------*/
3302 /* geniCodeSwitch - changes a switch to a if statement */
3303 /*-----------------------------------------------------------------*/
3305 geniCodeSwitch (ast * tree,int lvl)
3308 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3309 value *caseVals = tree->values.switchVals.swVals;
3310 symbol *trueLabel, *falseLabel;
3312 /* if we can make this a jump table */
3313 if (geniCodeJumpTable (cond, caseVals, tree))
3314 goto jumpTable; /* no need for the comparison */
3316 /* for the cases defined do */
3320 operand *compare = geniCodeLogic (cond,
3321 operandFromValue (caseVals),
3324 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3325 tree->values.switchVals.swNum,
3326 (int) floatFromVal (caseVals));
3327 trueLabel = newiTempLabel (buffer);
3329 ic = newiCodeCondition (compare, trueLabel, NULL);
3331 caseVals = caseVals->next;
3336 /* if default is present then goto break else break */
3337 if (tree->values.switchVals.swDefault)
3339 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3343 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3346 falseLabel = newiTempLabel (buffer);
3347 geniCodeGoto (falseLabel);
3350 ast2iCode (tree->right,lvl+1);
3353 /*-----------------------------------------------------------------*/
3354 /* geniCodeInline - intermediate code for inline assembler */
3355 /*-----------------------------------------------------------------*/
3357 geniCodeInline (ast * tree)
3361 ic = newiCode (INLINEASM, NULL, NULL);
3362 IC_INLINE (ic) = tree->values.inlineasm;
3366 /*-----------------------------------------------------------------*/
3367 /* geniCodeArrayInit - intermediate code for array initializer */
3368 /*-----------------------------------------------------------------*/
3370 geniCodeArrayInit (ast * tree, operand *array)
3374 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3375 ic = newiCode (ARRAYINIT, array, NULL);
3376 IC_ARRAYILIST (ic) = tree->values.constlist;
3378 operand *left=newOperand(), *right=newOperand();
3379 left->type=right->type=SYMBOL;
3380 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3381 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3382 ic = newiCode (ARRAYINIT, left, right);
3387 /*-----------------------------------------------------------------*/
3388 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3389 /* particular case. Ie : assigning or dereferencing array or ptr */
3390 /*-----------------------------------------------------------------*/
3391 set * lvaluereqSet = NULL;
3392 typedef struct lvalItem
3399 /*-----------------------------------------------------------------*/
3400 /* addLvaluereq - add a flag for lvalreq for current ast level */
3401 /*-----------------------------------------------------------------*/
3402 void addLvaluereq(int lvl)
3404 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3407 addSetHead(&lvaluereqSet,lpItem);
3410 /*-----------------------------------------------------------------*/
3411 /* delLvaluereq - del a flag for lvalreq for current ast level */
3412 /*-----------------------------------------------------------------*/
3416 lpItem = getSet(&lvaluereqSet);
3417 if(lpItem) Safe_free(lpItem);
3419 /*-----------------------------------------------------------------*/
3420 /* clearLvaluereq - clear lvalreq flag */
3421 /*-----------------------------------------------------------------*/
3422 void clearLvaluereq()
3425 lpItem = peekSet(lvaluereqSet);
3426 if(lpItem) lpItem->req = 0;
3428 /*-----------------------------------------------------------------*/
3429 /* getLvaluereq - get the last lvalreq level */
3430 /*-----------------------------------------------------------------*/
3431 int getLvaluereqLvl()
3434 lpItem = peekSet(lvaluereqSet);
3435 if(lpItem) return lpItem->lvl;
3438 /*-----------------------------------------------------------------*/
3439 /* isLvaluereq - is lvalreq valid for this level ? */
3440 /*-----------------------------------------------------------------*/
3441 int isLvaluereq(int lvl)
3444 lpItem = peekSet(lvaluereqSet);
3445 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3449 /*-----------------------------------------------------------------*/
3450 /* ast2iCode - creates an icodeList from an ast */
3451 /*-----------------------------------------------------------------*/
3453 ast2iCode (ast * tree,int lvl)
3455 operand *left = NULL;
3456 operand *right = NULL;
3460 /* set the global variables for filename & line number */
3462 filename = tree->filename;
3464 lineno = tree->lineno;
3466 block = tree->block;
3468 scopeLevel = tree->level;
3470 if (tree->type == EX_VALUE)
3471 return operandFromValue (tree->opval.val);
3473 if (tree->type == EX_LINK)
3474 return operandFromLink (tree->opval.lnk);
3476 /* if we find a nullop */
3477 if (tree->type == EX_OP &&
3478 (tree->opval.op == NULLOP ||
3479 tree->opval.op == BLOCK))
3481 ast2iCode (tree->left,lvl+1);
3482 ast2iCode (tree->right,lvl+1);
3486 /* special cases for not evaluating */
3487 if (tree->opval.op != ':' &&
3488 tree->opval.op != '?' &&
3489 tree->opval.op != CALL &&
3490 tree->opval.op != IFX &&
3491 tree->opval.op != LABEL &&
3492 tree->opval.op != GOTO &&
3493 tree->opval.op != SWITCH &&
3494 tree->opval.op != FUNCTION &&
3495 tree->opval.op != INLINEASM)
3498 if (IS_ASSIGN_OP (tree->opval.op) ||
3499 IS_DEREF_OP (tree) ||
3500 (tree->opval.op == '&' && !tree->right) ||
3501 tree->opval.op == PTR_OP)
3504 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3505 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3508 left = operandFromAst (tree->left,lvl);
3510 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3511 left = geniCodeRValue (left, TRUE);
3515 left = operandFromAst (tree->left,lvl);
3517 if (tree->opval.op == INC_OP ||
3518 tree->opval.op == DEC_OP)
3521 right = operandFromAst (tree->right,lvl);
3526 right = operandFromAst (tree->right,lvl);
3530 /* now depending on the type of operand */
3531 /* this will be a biggy */
3532 switch (tree->opval.op)
3535 case '[': /* array operation */
3537 //sym_link *ltype = operandType (left);
3538 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3539 left = geniCodeRValue (left, FALSE);
3540 right = geniCodeRValue (right, TRUE);
3543 return geniCodeArray (left, right,lvl);
3545 case '.': /* structure dereference */
3546 if (IS_PTR (operandType (left)))
3547 left = geniCodeRValue (left, TRUE);
3549 left = geniCodeRValue (left, FALSE);
3551 return geniCodeStruct (left, right, tree->lvalue);
3553 case PTR_OP: /* structure pointer dereference */
3556 pType = operandType (left);
3557 left = geniCodeRValue (left, TRUE);
3559 setOClass (pType, getSpec (operandType (left)));
3562 return geniCodeStruct (left, right, tree->lvalue);
3564 case INC_OP: /* increment operator */
3566 return geniCodePostInc (left);
3568 return geniCodePreInc (right);
3570 case DEC_OP: /* decrement operator */
3572 return geniCodePostDec (left);
3574 return geniCodePreDec (right);
3576 case '&': /* bitwise and or address of operator */
3578 { /* this is a bitwise operator */
3579 left = geniCodeRValue (left, FALSE);
3580 right = geniCodeRValue (right, FALSE);
3581 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3584 return geniCodeAddressOf (left);
3586 case '|': /* bitwise or & xor */
3588 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3589 geniCodeRValue (right, FALSE),
3594 return geniCodeDivision (geniCodeRValue (left, FALSE),
3595 geniCodeRValue (right, FALSE));
3598 return geniCodeModulus (geniCodeRValue (left, FALSE),
3599 geniCodeRValue (right, FALSE));
3602 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3603 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3605 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3609 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3610 geniCodeRValue (right, FALSE));
3612 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3616 return geniCodeAdd (geniCodeRValue (left, FALSE),
3617 geniCodeRValue (right, FALSE),lvl);
3619 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3622 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3623 geniCodeRValue (right, FALSE));
3626 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3627 geniCodeRValue (right, FALSE));
3629 #if 0 // this indeed needs a second thought
3633 // let's keep this simple: get the rvalue we need
3634 op=geniCodeRValue (right, FALSE);
3635 // now cast it to whatever we want
3636 op=geniCodeCast (operandType(left), op, FALSE);
3637 // if this is going to be used as an lvalue, make it so
3643 #else // bug #604575, is it a bug ????
3644 return geniCodeCast (operandType (left),
3645 geniCodeRValue (right, FALSE), FALSE);
3651 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3656 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3657 setOperandType (op, UCHARTYPE);
3668 /* different compilers (even different gccs) evaluate
3669 the two calls in a different order. to get the same
3670 result on all machines we've to specify a clear sequence.
3671 return geniCodeLogic (geniCodeRValue (left, FALSE),
3672 geniCodeRValue (right, FALSE),
3676 operand *leftOp, *rightOp;
3678 rightOp = geniCodeRValue (right, FALSE);
3679 leftOp = geniCodeRValue (left , FALSE);
3681 return geniCodeLogic (leftOp, rightOp, tree->opval.op);
3684 return geniCodeConditional (tree,lvl);
3687 return operandFromLit (getSize (tree->right->ftype));
3691 sym_link *rtype = operandType (right);
3692 sym_link *ltype = operandType (left);
3693 if (IS_PTR (rtype) && IS_ITEMP (right)
3694 && right->isaddr && compareType (rtype->next, ltype) == 1)
3695 right = geniCodeRValue (right, TRUE);
3697 right = geniCodeRValue (right, FALSE);
3699 geniCodeAssign (left, right, 0);
3704 geniCodeAssign (left,
3705 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3707 geniCodeRValue (right, FALSE),FALSE), 0);
3711 geniCodeAssign (left,
3712 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3714 geniCodeRValue (right, FALSE)), 0);
3717 geniCodeAssign (left,
3718 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3720 geniCodeRValue (right, FALSE)), 0);
3723 sym_link *rtype = operandType (right);
3724 sym_link *ltype = operandType (left);
3725 if (IS_PTR (rtype) && IS_ITEMP (right)
3726 && right->isaddr && compareType (rtype->next, ltype) == 1)
3727 right = geniCodeRValue (right, TRUE);
3729 right = geniCodeRValue (right, FALSE);
3732 return geniCodeAssign (left,
3733 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3739 sym_link *rtype = operandType (right);
3740 sym_link *ltype = operandType (left);
3741 if (IS_PTR (rtype) && IS_ITEMP (right)
3742 && right->isaddr && compareType (rtype->next, ltype) == 1)
3744 right = geniCodeRValue (right, TRUE);
3748 right = geniCodeRValue (right, FALSE);
3751 geniCodeAssign (left,
3752 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3758 geniCodeAssign (left,
3759 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3761 geniCodeRValue (right, FALSE)), 0);
3764 geniCodeAssign (left,
3765 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3767 geniCodeRValue (right, FALSE)), 0);
3770 geniCodeAssign (left,
3771 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3773 geniCodeRValue (right, FALSE),
3775 operandType (left)), 0);
3778 geniCodeAssign (left,
3779 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3781 geniCodeRValue (right, FALSE),
3783 operandType (left)), 0);
3786 geniCodeAssign (left,
3787 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3789 geniCodeRValue (right, FALSE),
3791 operandType (left)), 0);
3793 return geniCodeRValue (right, FALSE);
3796 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3799 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3800 return ast2iCode (tree->right,lvl+1);
3803 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3804 return ast2iCode (tree->right,lvl+1);
3807 geniCodeFunctionBody (tree,lvl);
3811 geniCodeReturn (right);
3815 geniCodeIfx (tree,lvl);
3819 geniCodeSwitch (tree,lvl);
3823 geniCodeInline (tree);
3827 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3834 /*-----------------------------------------------------------------*/
3835 /* reverseICChain - gets from the list and creates a linkedlist */
3836 /*-----------------------------------------------------------------*/
3843 while ((loop = getSet (&iCodeChain)))
3855 /*-----------------------------------------------------------------*/
3856 /* iCodeFromAst - given an ast will convert it to iCode */
3857 /*-----------------------------------------------------------------*/
3859 iCodeFromAst (ast * tree)
3861 returnLabel = newiTempLabel ("_return");
3862 entryLabel = newiTempLabel ("_entry");
3864 return reverseiCChain ();
3867 static const char *opTypeToStr(OPTYPE op)
3871 case SYMBOL: return "symbol";
3872 case VALUE: return "value";
3873 case TYPE: return "type";
3875 return "undefined type";
3879 operand *validateOpType(operand *op,
3886 if (op && op->type == type)
3891 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
3892 " expected %s, got %s\n",
3893 macro, args, file, line,
3894 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
3896 return op; // never reached, makes compiler happy.