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)
1102 /* 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 /* if the output class is code */
2202 if ((DCL_TYPE (ptype) = PTR_TYPE (SPEC_OCLS (etype))) == CPOINTER)
2203 DCL_PTR_CONST (ptype) = port->mem.code_ro;
2205 /* if the variable was declared a constant */
2206 /* then the pointer points to a constant */
2207 if (IS_CONSTANT (etype))
2208 DCL_PTR_CONST (ptype) = 1;
2210 /* the variable was volatile then pointer to volatile */
2211 if (IS_VOLATILE (etype))
2212 DCL_PTR_VOLATILE (ptype) = 1;
2217 /*-----------------------------------------------------------------*/
2218 /* geniCodeArray2Ptr - array to pointer */
2219 /*-----------------------------------------------------------------*/
2221 geniCodeArray2Ptr (operand * op)
2223 sym_link *optype = operandType (op);
2224 sym_link *opetype = getSpec (optype);
2226 /* set the pointer depending on the storage class */
2227 if ((DCL_TYPE (optype) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2228 DCL_PTR_CONST (optype) = port->mem.code_ro;
2230 /* if the variable was declared a constant */
2231 /* then the pointer points to a constant */
2232 if (IS_CONSTANT (opetype))
2233 DCL_PTR_CONST (optype) = 1;
2235 /* the variable was volatile then pointer to volatile */
2236 if (IS_VOLATILE (opetype))
2237 DCL_PTR_VOLATILE (optype) = 1;
2244 /*-----------------------------------------------------------------*/
2245 /* geniCodeArray - array access */
2246 /*-----------------------------------------------------------------*/
2248 geniCodeArray (operand * left, operand * right,int lvl)
2251 sym_link *ltype = operandType (left);
2255 if (IS_PTR (ltype->next) && left->isaddr)
2257 left = geniCodeRValue (left, FALSE);
2259 return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl);
2262 right = geniCodeMultiply (right,
2263 operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE));
2265 /* we can check for limits here */
2266 if (isOperandLiteral (right) &&
2269 (operandLitValue (right) / getSize (ltype->next)) >= DCL_ELEM (ltype))
2271 werror (E_ARRAY_BOUND);
2272 right = operandFromLit (0);
2275 ic = newiCode ('+', left, right);
2277 IC_RESULT (ic) = newiTempOperand (((IS_PTR (ltype) &&
2278 !IS_AGGREGATE (ltype->next) &&
2279 !IS_PTR (ltype->next))
2280 ? ltype : ltype->next), 0);
2282 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (ltype->next));
2284 return IC_RESULT (ic);
2287 /*-----------------------------------------------------------------*/
2288 /* geniCodeStruct - generates intermediate code for structres */
2289 /*-----------------------------------------------------------------*/
2291 geniCodeStruct (operand * left, operand * right, bool islval)
2294 sym_link *type = operandType (left);
2295 sym_link *etype = getSpec (type);
2297 symbol *element = getStructElement (SPEC_STRUCT (etype),
2298 right->operand.symOperand);
2300 wassert(IS_SYMOP(right));
2302 /* add the offset */
2303 ic = newiCode ('+', left, operandFromLit (element->offset));
2305 IC_RESULT (ic) = newiTempOperand (element->type, 0);
2307 /* preserve the storage & output class of the struct */
2308 /* as well as the volatile attribute */
2309 retype = getSpec (operandType (IC_RESULT (ic)));
2310 SPEC_SCLS (retype) = SPEC_SCLS (etype);
2311 SPEC_OCLS (retype) = SPEC_OCLS (etype);
2312 SPEC_VOLATILE (retype) |= SPEC_VOLATILE (etype);
2314 if (IS_PTR (element->type))
2315 setOperandType (IC_RESULT (ic), aggrToPtr (operandType (IC_RESULT (ic)), TRUE));
2317 IC_RESULT (ic)->isaddr = (!IS_AGGREGATE (element->type));
2321 return (islval ? IC_RESULT (ic) : geniCodeRValue (IC_RESULT (ic), TRUE));
2324 /*-----------------------------------------------------------------*/
2325 /* geniCodePostInc - generate int code for Post increment */
2326 /*-----------------------------------------------------------------*/
2328 geniCodePostInc (operand * op)
2332 sym_link *optype = operandType (op);
2334 operand *rv = (IS_ITEMP (op) ?
2335 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2337 sym_link *rvtype = operandType (rv);
2340 /* if this is not an address we have trouble */
2343 werror (E_LVALUE_REQUIRED, "++");
2347 rOp = newiTempOperand (rvtype, 0);
2348 OP_SYMBOL(rOp)->noSpilLoc = 1;
2351 OP_SYMBOL(rv)->noSpilLoc = 1;
2353 geniCodeAssign (rOp, rv, 0);
2355 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2356 if (IS_FLOAT (rvtype))
2357 ic = newiCode ('+', rv, operandFromValue (constFloatVal ("1.0")));
2359 ic = newiCode ('+', rv, operandFromLit (size));
2361 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2364 geniCodeAssign (op, result, 0);
2370 /*-----------------------------------------------------------------*/
2371 /* geniCodePreInc - generate code for preIncrement */
2372 /*-----------------------------------------------------------------*/
2374 geniCodePreInc (operand * op)
2377 sym_link *optype = operandType (op);
2378 operand *rop = (IS_ITEMP (op) ?
2379 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2381 sym_link *roptype = operandType (rop);
2387 werror (E_LVALUE_REQUIRED, "++");
2392 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2393 if (IS_FLOAT (roptype))
2394 ic = newiCode ('+', rop, operandFromValue (constFloatVal ("1.0")));
2396 ic = newiCode ('+', rop, operandFromLit (size));
2397 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2401 return geniCodeAssign (op, result, 0);
2404 /*-----------------------------------------------------------------*/
2405 /* geniCodePostDec - generates code for Post decrement */
2406 /*-----------------------------------------------------------------*/
2408 geniCodePostDec (operand * op)
2412 sym_link *optype = operandType (op);
2414 operand *rv = (IS_ITEMP (op) ?
2415 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2417 sym_link *rvtype = operandType (rv);
2420 /* if this is not an address we have trouble */
2423 werror (E_LVALUE_REQUIRED, "--");
2427 rOp = newiTempOperand (rvtype, 0);
2428 OP_SYMBOL(rOp)->noSpilLoc = 1;
2431 OP_SYMBOL(rv)->noSpilLoc = 1;
2433 geniCodeAssign (rOp, rv, 0);
2435 size = (IS_PTR (rvtype) ? getSize (rvtype->next) : 1);
2436 if (IS_FLOAT (rvtype))
2437 ic = newiCode ('-', rv, operandFromValue (constFloatVal ("1.0")));
2439 ic = newiCode ('-', rv, operandFromLit (size));
2441 IC_RESULT (ic) = result = newiTempOperand (rvtype, 0);
2444 geniCodeAssign (op, result, 0);
2450 /*-----------------------------------------------------------------*/
2451 /* geniCodePreDec - generate code for pre decrement */
2452 /*-----------------------------------------------------------------*/
2454 geniCodePreDec (operand * op)
2457 sym_link *optype = operandType (op);
2458 operand *rop = (IS_ITEMP (op) ?
2459 geniCodeRValue (op, (IS_PTR (optype) ? TRUE : FALSE)) :
2461 sym_link *roptype = operandType (rop);
2467 werror (E_LVALUE_REQUIRED, "--");
2472 size = (IS_PTR (roptype) ? getSize (roptype->next) : 1);
2473 if (IS_FLOAT (roptype))
2474 ic = newiCode ('-', rop, operandFromValue (constFloatVal ("1.0")));
2476 ic = newiCode ('-', rop, operandFromLit (size));
2477 IC_RESULT (ic) = result = newiTempOperand (roptype, 0);
2481 return geniCodeAssign (op, result, 0);
2485 /*-----------------------------------------------------------------*/
2486 /* geniCodeBitwise - gen int code for bitWise operators */
2487 /*-----------------------------------------------------------------*/
2489 geniCodeBitwise (operand * left, operand * right,
2490 int oper, sym_link * resType)
2494 left = geniCodeCast (resType, left, TRUE);
2495 right = geniCodeCast (resType, right, TRUE);
2497 ic = newiCode (oper, left, right);
2498 IC_RESULT (ic) = newiTempOperand (resType, 0);
2501 return IC_RESULT (ic);
2504 /*-----------------------------------------------------------------*/
2505 /* geniCodeAddressOf - gens icode for '&' address of operator */
2506 /*-----------------------------------------------------------------*/
2508 geniCodeAddressOf (operand * op)
2512 sym_link *optype = operandType (op);
2513 sym_link *opetype = getSpec (optype);
2515 /* lvalue check already done in decorateType */
2516 /* this must be a lvalue */
2517 /* if (!op->isaddr && !IS_AGGREGATE(optype)) { */
2518 /* werror (E_LVALUE_REQUIRED,"&"); */
2522 p = newLink (DECLARATOR);
2524 /* set the pointer depending on the storage class */
2525 if ((DCL_TYPE (p) = PTR_TYPE (SPEC_OCLS (opetype))) == CPOINTER)
2526 DCL_PTR_CONST (p) = port->mem.code_ro;
2528 /* make sure we preserve the const & volatile */
2529 if (IS_CONSTANT (opetype))
2530 DCL_PTR_CONST (p) = 1;
2532 if (IS_VOLATILE (opetype))
2533 DCL_PTR_VOLATILE (p) = 1;
2535 p->next = copyLinkChain (optype);
2537 /* if already a temp */
2540 setOperandType (op, p);
2545 /* other wise make this of the type coming in */
2546 ic = newiCode (ADDRESS_OF, op, NULL);
2547 IC_RESULT (ic) = newiTempOperand (p, 1);
2548 IC_RESULT (ic)->isaddr = 0;
2550 return IC_RESULT (ic);
2552 /*-----------------------------------------------------------------*/
2553 /* setOClass - sets the output class depending on the pointer type */
2554 /*-----------------------------------------------------------------*/
2556 setOClass (sym_link * ptr, sym_link * spec)
2558 switch (DCL_TYPE (ptr))
2561 SPEC_OCLS (spec) = data;
2565 SPEC_OCLS (spec) = generic;
2569 SPEC_OCLS (spec) = xdata;
2573 SPEC_OCLS (spec) = code;
2577 SPEC_OCLS (spec) = idata;
2581 SPEC_OCLS (spec) = xstack;
2585 SPEC_OCLS (spec) = eeprom;
2594 /*-----------------------------------------------------------------*/
2595 /* geniCodeDerefPtr - dereference pointer with '*' */
2596 /*-----------------------------------------------------------------*/
2598 geniCodeDerefPtr (operand * op,int lvl)
2600 sym_link *rtype, *retype;
2601 sym_link *optype = operandType (op);
2603 // if this is an array then array access
2604 if (IS_ARRAY (optype)) {
2605 // don't worry, this will be optimized out later
2606 return geniCodeArray (op, operandFromLit (0), lvl);
2609 // just in case someone screws up
2610 wassert (IS_PTR (optype));
2612 if (IS_TRUE_SYMOP (op))
2615 op = geniCodeRValue (op, TRUE);
2618 /* now get rid of the pointer part */
2619 if (isLvaluereq(lvl) && IS_ITEMP (op))
2621 retype = getSpec (rtype = copyLinkChain (optype));
2625 retype = getSpec (rtype = copyLinkChain (optype->next));
2628 /* outputclass needs 2b updated */
2629 setOClass (optype, retype);
2631 op->isGptr = IS_GENPTR (optype);
2633 /* if the pointer was declared as a constant */
2634 /* then we cannot allow assignment to the derefed */
2635 if (IS_PTR_CONST (optype))
2636 SPEC_CONST (retype) = 1;
2638 op->isaddr = (IS_PTR (rtype) ||
2639 IS_STRUCT (rtype) ||
2644 if (!isLvaluereq(lvl))
2645 op = geniCodeRValue (op, TRUE);
2647 setOperandType (op, rtype);
2652 /*-----------------------------------------------------------------*/
2653 /* geniCodeUnaryMinus - does a unary minus of the operand */
2654 /*-----------------------------------------------------------------*/
2656 geniCodeUnaryMinus (operand * op)
2659 sym_link *optype = operandType (op);
2661 if (IS_LITERAL (optype))
2662 return operandFromLit (-floatFromVal (op->operand.valOperand));
2664 ic = newiCode (UNARYMINUS, op, NULL);
2665 IC_RESULT (ic) = newiTempOperand (optype, 0);
2667 return IC_RESULT (ic);
2670 /*-----------------------------------------------------------------*/
2671 /* geniCodeLeftShift - gen i code for left shift */
2672 /*-----------------------------------------------------------------*/
2674 geniCodeLeftShift (operand * left, operand * right)
2678 ic = newiCode (LEFT_OP, left, right);
2679 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2681 return IC_RESULT (ic);
2684 /*-----------------------------------------------------------------*/
2685 /* geniCodeRightShift - gen i code for right shift */
2686 /*-----------------------------------------------------------------*/
2688 geniCodeRightShift (operand * left, operand * right)
2692 ic = newiCode (RIGHT_OP, left, right);
2693 IC_RESULT (ic) = newiTempOperand (operandType (left), 0);
2695 return IC_RESULT (ic);
2698 /*-----------------------------------------------------------------*/
2699 /* geniCodeLogic- logic code */
2700 /*-----------------------------------------------------------------*/
2702 geniCodeLogic (operand * left, operand * right, int op)
2706 sym_link *rtype = operandType (right);
2707 sym_link *ltype = operandType (left);
2709 /* left is integral type and right is literal then
2710 check if the literal value is within bounds */
2711 if (IS_INTEGRAL (ltype) && IS_VALOP (right) && IS_LITERAL (rtype))
2713 checkConstantRange(ltype,
2714 OP_VALUE(right), "compare operation", 1);
2717 ctype = usualBinaryConversions (&left, &right);
2719 ic = newiCode (op, left, right);
2720 IC_RESULT (ic) = newiTempOperand (newCharLink (), 1);
2722 /* if comparing float
2723 and not a '==' || '!=' || '&&' || '||' (these
2725 if (IS_FLOAT(ctype) &&
2733 return IC_RESULT (ic);
2736 /*-----------------------------------------------------------------*/
2737 /* geniCodeUnary - for a a generic unary operation */
2738 /*-----------------------------------------------------------------*/
2740 geniCodeUnary (operand * op, int oper)
2742 iCode *ic = newiCode (oper, op, NULL);
2744 IC_RESULT (ic) = newiTempOperand (operandType (op), 0);
2746 return IC_RESULT (ic);
2749 /*-----------------------------------------------------------------*/
2750 /* geniCodeConditional - geniCode for '?' ':' operation */
2751 /*-----------------------------------------------------------------*/
2753 geniCodeConditional (ast * tree,int lvl)
2756 symbol *falseLabel = newiTempLabel (NULL);
2757 symbol *exitLabel = newiTempLabel (NULL);
2758 operand *cond = ast2iCode (tree->left,lvl+1);
2759 operand *true, *false, *result;
2761 ic = newiCodeCondition (geniCodeRValue (cond, FALSE),
2765 true = ast2iCode (tree->right->left,lvl+1);
2767 /* move the value to a new Operand */
2768 result = newiTempOperand (tree->right->ftype, 0);
2769 geniCodeAssign (result, geniCodeRValue (true, FALSE), 0);
2771 /* generate an unconditional goto */
2772 geniCodeGoto (exitLabel);
2774 /* now for the right side */
2775 geniCodeLabel (falseLabel);
2777 false = ast2iCode (tree->right->right,lvl+1);
2778 geniCodeAssign (result, geniCodeRValue (false, FALSE), 0);
2780 /* create the exit label */
2781 geniCodeLabel (exitLabel);
2786 /*-----------------------------------------------------------------*/
2787 /* geniCodeAssign - generate code for assignment */
2788 /*-----------------------------------------------------------------*/
2790 geniCodeAssign (operand * left, operand * right, int nosupdate)
2793 sym_link *ltype = operandType (left);
2794 sym_link *rtype = operandType (right);
2796 if (!left->isaddr && !IS_ITEMP (left))
2798 werror (E_LVALUE_REQUIRED, "assignment");
2802 /* left is integral type and right is literal then
2803 check if the literal value is within bounds */
2804 if (IS_INTEGRAL (ltype) && right->type == VALUE && IS_LITERAL (rtype))
2806 checkConstantRange(ltype,
2807 OP_VALUE(right), "= operation", 0);
2810 /* if the left & right type don't exactly match */
2811 /* if pointer set then make sure the check is
2812 done with the type & not the pointer */
2813 /* then cast rights type to left */
2815 /* first check the type for pointer assignement */
2816 if (left->isaddr && IS_PTR (ltype) && IS_ITEMP (left) &&
2817 compareType (ltype, rtype) <= 0)
2819 if (compareType (ltype->next, rtype) < 0)
2820 right = geniCodeCast (ltype->next, right, TRUE);
2822 else if (compareType (ltype, rtype) < 0)
2823 right = geniCodeCast (ltype, right, TRUE);
2825 /* if left is a true symbol & ! volatile
2826 create an assignment to temporary for
2827 the right & then assign this temporary
2828 to the symbol this is SSA . isn't it simple
2829 and folks have published mountains of paper on it */
2830 if (IS_TRUE_SYMOP (left) &&
2831 !isOperandVolatile (left, FALSE) &&
2832 isOperandGlobal (left))
2836 if (IS_TRUE_SYMOP (right))
2837 sym = OP_SYMBOL (right);
2838 ic = newiCode ('=', NULL, right);
2839 IC_RESULT (ic) = right = newiTempOperand (ltype, 0);
2840 SPIL_LOC (right) = sym;
2844 ic = newiCode ('=', NULL, right);
2845 IC_RESULT (ic) = left;
2848 /* if left isgptr flag is set then support
2849 routine will be required */
2853 ic->nosupdate = nosupdate;
2857 /*-----------------------------------------------------------------*/
2858 /* geniCodeSEParms - generate code for side effecting fcalls */
2859 /*-----------------------------------------------------------------*/
2861 geniCodeSEParms (ast * parms,int lvl)
2866 if (parms->type == EX_OP && parms->opval.op == PARAM)
2868 geniCodeSEParms (parms->left,lvl);
2869 geniCodeSEParms (parms->right,lvl);
2873 /* hack don't like this but too lazy to think of
2875 if (IS_ADDRESS_OF_OP (parms))
2876 parms->left->lvalue = 1;
2878 if (IS_CAST_OP (parms) &&
2879 IS_PTR (parms->ftype) &&
2880 IS_ADDRESS_OF_OP (parms->right))
2881 parms->right->left->lvalue = 1;
2883 parms->opval.oprnd =
2884 geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2886 parms->type = EX_OPERAND;
2887 AST_ARGREG(parms) = parms->etype ? SPEC_ARGREG(parms->etype) :
2888 SPEC_ARGREG(parms->ftype);
2891 /*-----------------------------------------------------------------*/
2892 /* geniCodeParms - generates parameters */
2893 /*-----------------------------------------------------------------*/
2895 geniCodeParms (ast * parms, value *argVals, int *stack,
2896 sym_link * fetype, symbol * func,int lvl)
2904 if (argVals==NULL) {
2906 argVals=FUNC_ARGS(func->type);
2909 /* if this is a param node then do the left & right */
2910 if (parms->type == EX_OP && parms->opval.op == PARAM)
2912 argVals=geniCodeParms (parms->left, argVals, stack, fetype, func,lvl);
2913 argVals=geniCodeParms (parms->right, argVals, stack, fetype, func,lvl);
2917 /* get the parameter value */
2918 if (parms->type == EX_OPERAND)
2919 pval = parms->opval.oprnd;
2922 /* maybe this else should go away ?? */
2923 /* hack don't like this but too lazy to think of
2925 if (IS_ADDRESS_OF_OP (parms))
2926 parms->left->lvalue = 1;
2928 if (IS_CAST_OP (parms) &&
2929 IS_PTR (parms->ftype) &&
2930 IS_ADDRESS_OF_OP (parms->right))
2931 parms->right->left->lvalue = 1;
2933 pval = geniCodeRValue (ast2iCode (parms,lvl+1), FALSE);
2936 /* if register parm then make it a send */
2937 if ((IS_REGPARM (parms->etype) && !IFFUNC_HASVARARGS(func->type)) ||
2938 IFFUNC_ISBUILTIN(func->type))
2940 ic = newiCode (SEND, pval, NULL);
2941 ic->argreg = SPEC_ARGREG(parms->etype);
2942 ic->builtinSEND = FUNC_ISBUILTIN(func->type);
2947 /* now decide whether to push or assign */
2948 if (!(options.stackAuto || IFFUNC_ISREENT (func->type)))
2952 operand *top = operandFromSymbol (argVals->sym);
2953 /* clear useDef and other bitVectors */
2954 OP_USES(top)=OP_DEFS(top)=OP_SYMBOL(top)->clashes = NULL;
2955 geniCodeAssign (top, pval, 1);
2959 sym_link *p = operandType (pval);
2961 ic = newiCode (IPUSH, pval, NULL);
2963 /* update the stack adjustment */
2964 *stack += getSize (IS_AGGREGATE (p) ? aggrToPtr (p, FALSE) : p);
2969 argVals=argVals->next;
2973 /*-----------------------------------------------------------------*/
2974 /* geniCodeCall - generates temp code for calling */
2975 /*-----------------------------------------------------------------*/
2977 geniCodeCall (operand * left, ast * parms,int lvl)
2981 sym_link *type, *etype;
2984 if (!IS_FUNC(OP_SYMBOL(left)->type) &&
2985 !IS_CODEPTR(OP_SYMBOL(left)->type)) {
2986 werror (E_FUNCTION_EXPECTED);
2990 /* take care of parameters with side-effecting
2991 function calls in them, this is required to take care
2992 of overlaying function parameters */
2993 geniCodeSEParms (parms,lvl);
2995 /* first the parameters */
2996 geniCodeParms (parms, NULL, &stack, getSpec (operandType (left)), OP_SYMBOL (left),lvl);
2998 /* now call : if symbol then pcall */
2999 if (IS_OP_POINTER (left) || IS_ITEMP(left)) {
3000 ic = newiCode (PCALL, left, NULL);
3002 ic = newiCode (CALL, left, NULL);
3005 type = copyLinkChain (operandType (left)->next);
3006 etype = getSpec (type);
3007 SPEC_EXTR (etype) = 0;
3008 IC_RESULT (ic) = result = newiTempOperand (type, 1);
3012 /* stack adjustment after call */
3013 ic->parmBytes = stack;
3018 /*-----------------------------------------------------------------*/
3019 /* geniCodeReceive - generate intermediate code for "receive" */
3020 /*-----------------------------------------------------------------*/
3022 geniCodeReceive (value * args)
3024 /* for all arguments that are passed in registers */
3028 if (IS_REGPARM (args->etype))
3030 operand *opr = operandFromValue (args);
3032 symbol *sym = OP_SYMBOL (opr);
3035 /* we will use it after all optimizations
3036 and before liveRange calculation */
3037 if (!sym->addrtaken && !IS_VOLATILE (sym->etype))
3040 if (IN_FARSPACE (SPEC_OCLS (sym->etype)) &&
3041 options.stackAuto == 0 &&
3042 (!(options.model == MODEL_FLAT24)) )
3047 opl = newiTempOperand (args->type, 0);
3049 sym->reqv->key = sym->key;
3050 OP_SYMBOL (sym->reqv)->key = sym->key;
3051 OP_SYMBOL (sym->reqv)->isreqv = 1;
3052 OP_SYMBOL (sym->reqv)->islocal = 0;
3053 SPIL_LOC (sym->reqv) = sym;
3057 ic = newiCode (RECEIVE, NULL, NULL);
3058 ic->argreg = SPEC_ARGREG(args->etype);
3060 currFunc->recvSize = getSize (sym->type);
3063 IC_RESULT (ic) = opr;
3071 /*-----------------------------------------------------------------*/
3072 /* geniCodeFunctionBody - create the function body */
3073 /*-----------------------------------------------------------------*/
3075 geniCodeFunctionBody (ast * tree,int lvl)
3082 /* reset the auto generation */
3088 func = ast2iCode (tree->left,lvl+1);
3089 fetype = getSpec (operandType (func));
3091 savelineno = lineno;
3092 lineno = OP_SYMBOL (func)->lineDef;
3093 /* create an entry label */
3094 geniCodeLabel (entryLabel);
3095 lineno = savelineno;
3097 /* create a proc icode */
3098 ic = newiCode (FUNCTION, func, NULL);
3099 lineno=ic->lineno = OP_SYMBOL (func)->lineDef;
3103 /* for all parameters that are passed
3104 on registers add a "receive" */
3105 geniCodeReceive (tree->values.args);
3107 /* generate code for the body */
3108 ast2iCode (tree->right,lvl+1);
3110 /* create a label for return */
3111 geniCodeLabel (returnLabel);
3113 /* now generate the end proc */
3114 ic = newiCode (ENDFUNCTION, func, NULL);
3119 /*-----------------------------------------------------------------*/
3120 /* geniCodeReturn - gen icode for 'return' statement */
3121 /*-----------------------------------------------------------------*/
3123 geniCodeReturn (operand * op)
3127 /* if the operand is present force an rvalue */
3129 op = geniCodeRValue (op, FALSE);
3131 ic = newiCode (RETURN, op, NULL);
3135 /*-----------------------------------------------------------------*/
3136 /* geniCodeIfx - generates code for extended if statement */
3137 /*-----------------------------------------------------------------*/
3139 geniCodeIfx (ast * tree,int lvl)
3142 operand *condition = ast2iCode (tree->left,lvl+1);
3145 /* if condition is null then exit */
3149 condition = geniCodeRValue (condition, FALSE);
3151 cetype = getSpec (operandType (condition));
3152 /* if the condition is a literal */
3153 if (IS_LITERAL (cetype))
3155 if (floatFromVal (condition->operand.valOperand))
3157 if (tree->trueLabel)
3158 geniCodeGoto (tree->trueLabel);
3164 if (tree->falseLabel)
3165 geniCodeGoto (tree->falseLabel);
3172 if (tree->trueLabel)
3174 ic = newiCodeCondition (condition,
3179 if (tree->falseLabel)
3180 geniCodeGoto (tree->falseLabel);
3184 ic = newiCodeCondition (condition,
3191 ast2iCode (tree->right,lvl+1);
3194 /*-----------------------------------------------------------------*/
3195 /* geniCodeJumpTable - tries to create a jump table for switch */
3196 /*-----------------------------------------------------------------*/
3198 geniCodeJumpTable (operand * cond, value * caseVals, ast * tree)
3200 int min = 0, max = 0, t, cnt = 0;
3207 if (!tree || !caseVals)
3210 /* the criteria for creating a jump table is */
3211 /* all integer numbers between the maximum & minimum must */
3212 /* be present , the maximum value should not exceed 255 */
3213 min = max = (int) floatFromVal (vch = caseVals);
3214 SNPRINTF (buffer, sizeof(buffer),
3216 tree->values.switchVals.swNum,
3218 addSet (&labels, newiTempLabel (buffer));
3220 /* if there is only one case value then no need */
3221 if (!(vch = vch->next))
3226 if (((t = (int) floatFromVal (vch)) - max) != 1)
3228 SNPRINTF (buffer, sizeof(buffer),
3230 tree->values.switchVals.swNum,
3232 addSet (&labels, newiTempLabel (buffer));
3238 /* if the number of case statements <= 2 then */
3239 /* it is not economical to create the jump table */
3240 /* since two compares are needed for boundary conditions */
3241 if ((!optimize.noJTabBoundary && cnt <= 2) || max > (255 / 3))
3244 if (tree->values.switchVals.swDefault)
3246 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3250 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3254 falseLabel = newiTempLabel (buffer);
3256 /* so we can create a jumptable */
3257 /* first we rule out the boundary conditions */
3258 /* if only optimization says so */
3259 if (!optimize.noJTabBoundary)
3261 sym_link *cetype = getSpec (operandType (cond));
3262 /* no need to check the lower bound if
3263 the condition is unsigned & minimum value is zero */
3264 if (!(min == 0 && SPEC_USIGN (cetype)))
3266 boundary = geniCodeLogic (cond, operandFromLit (min), '<');
3267 ic = newiCodeCondition (boundary, falseLabel, NULL);
3271 /* now for upper bounds */
3272 boundary = geniCodeLogic (cond, operandFromLit (max), '>');
3273 ic = newiCodeCondition (boundary, falseLabel, NULL);
3277 /* if the min is not zero then we no make it zero */
3280 cond = geniCodeSubtract (cond, operandFromLit (min));
3281 setOperandType (cond, UCHARTYPE);
3284 /* now create the jumptable */
3285 ic = newiCode (JUMPTABLE, NULL, NULL);
3286 IC_JTCOND (ic) = cond;
3287 IC_JTLABELS (ic) = labels;
3292 /*-----------------------------------------------------------------*/
3293 /* geniCodeSwitch - changes a switch to a if statement */
3294 /*-----------------------------------------------------------------*/
3296 geniCodeSwitch (ast * tree,int lvl)
3299 operand *cond = geniCodeRValue (ast2iCode (tree->left,lvl+1), FALSE);
3300 value *caseVals = tree->values.switchVals.swVals;
3301 symbol *trueLabel, *falseLabel;
3303 /* if we can make this a jump table */
3304 if (geniCodeJumpTable (cond, caseVals, tree))
3305 goto jumpTable; /* no need for the comparison */
3307 /* for the cases defined do */
3311 operand *compare = geniCodeLogic (cond,
3312 operandFromValue (caseVals),
3315 SNPRINTF (buffer, sizeof(buffer), "_case_%d_%d",
3316 tree->values.switchVals.swNum,
3317 (int) floatFromVal (caseVals));
3318 trueLabel = newiTempLabel (buffer);
3320 ic = newiCodeCondition (compare, trueLabel, NULL);
3322 caseVals = caseVals->next;
3327 /* if default is present then goto break else break */
3328 if (tree->values.switchVals.swDefault)
3330 SNPRINTF (buffer, sizeof(buffer), "_default_%d", tree->values.switchVals.swNum);
3334 SNPRINTF (buffer, sizeof(buffer), "_swBrk_%d", tree->values.switchVals.swNum);
3337 falseLabel = newiTempLabel (buffer);
3338 geniCodeGoto (falseLabel);
3341 ast2iCode (tree->right,lvl+1);
3344 /*-----------------------------------------------------------------*/
3345 /* geniCodeInline - intermediate code for inline assembler */
3346 /*-----------------------------------------------------------------*/
3348 geniCodeInline (ast * tree)
3352 ic = newiCode (INLINEASM, NULL, NULL);
3353 IC_INLINE (ic) = tree->values.inlineasm;
3357 /*-----------------------------------------------------------------*/
3358 /* geniCodeArrayInit - intermediate code for array initializer */
3359 /*-----------------------------------------------------------------*/
3361 geniCodeArrayInit (ast * tree, operand *array)
3365 if (!getenv("TRY_THE_NEW_INITIALIZER")) {
3366 ic = newiCode (ARRAYINIT, array, NULL);
3367 IC_ARRAYILIST (ic) = tree->values.constlist;
3369 operand *left=newOperand(), *right=newOperand();
3370 left->type=right->type=SYMBOL;
3371 OP_SYMBOL(left)=AST_SYMBOL(tree->left);
3372 OP_SYMBOL(right)=AST_SYMBOL(tree->right);
3373 ic = newiCode (ARRAYINIT, left, right);
3378 /*-----------------------------------------------------------------*/
3379 /* Stuff used in ast2iCode to modify geniCodeDerefPtr in some */
3380 /* particular case. Ie : assigning or dereferencing array or ptr */
3381 /*-----------------------------------------------------------------*/
3382 set * lvaluereqSet = NULL;
3383 typedef struct lvalItem
3390 /*-----------------------------------------------------------------*/
3391 /* addLvaluereq - add a flag for lvalreq for current ast level */
3392 /*-----------------------------------------------------------------*/
3393 void addLvaluereq(int lvl)
3395 lvalItem * lpItem = (lvalItem *)Safe_alloc ( sizeof (lvalItem));
3398 addSetHead(&lvaluereqSet,lpItem);
3401 /*-----------------------------------------------------------------*/
3402 /* delLvaluereq - del a flag for lvalreq for current ast level */
3403 /*-----------------------------------------------------------------*/
3407 lpItem = getSet(&lvaluereqSet);
3408 if(lpItem) Safe_free(lpItem);
3410 /*-----------------------------------------------------------------*/
3411 /* clearLvaluereq - clear lvalreq flag */
3412 /*-----------------------------------------------------------------*/
3413 void clearLvaluereq()
3416 lpItem = peekSet(lvaluereqSet);
3417 if(lpItem) lpItem->req = 0;
3419 /*-----------------------------------------------------------------*/
3420 /* getLvaluereq - get the last lvalreq level */
3421 /*-----------------------------------------------------------------*/
3422 int getLvaluereqLvl()
3425 lpItem = peekSet(lvaluereqSet);
3426 if(lpItem) return lpItem->lvl;
3429 /*-----------------------------------------------------------------*/
3430 /* isLvaluereq - is lvalreq valid for this level ? */
3431 /*-----------------------------------------------------------------*/
3432 int isLvaluereq(int lvl)
3435 lpItem = peekSet(lvaluereqSet);
3436 if(lpItem) return ((lpItem->req)&&(lvl <= (lpItem->lvl+1)));
3440 /*-----------------------------------------------------------------*/
3441 /* ast2iCode - creates an icodeList from an ast */
3442 /*-----------------------------------------------------------------*/
3444 ast2iCode (ast * tree,int lvl)
3446 operand *left = NULL;
3447 operand *right = NULL;
3451 /* set the global variables for filename & line number */
3453 filename = tree->filename;
3455 lineno = tree->lineno;
3457 block = tree->block;
3459 scopeLevel = tree->level;
3461 if (tree->type == EX_VALUE)
3462 return operandFromValue (tree->opval.val);
3464 if (tree->type == EX_LINK)
3465 return operandFromLink (tree->opval.lnk);
3467 /* if we find a nullop */
3468 if (tree->type == EX_OP &&
3469 (tree->opval.op == NULLOP ||
3470 tree->opval.op == BLOCK))
3472 ast2iCode (tree->left,lvl+1);
3473 ast2iCode (tree->right,lvl+1);
3477 /* special cases for not evaluating */
3478 if (tree->opval.op != ':' &&
3479 tree->opval.op != '?' &&
3480 tree->opval.op != CALL &&
3481 tree->opval.op != IFX &&
3482 tree->opval.op != LABEL &&
3483 tree->opval.op != GOTO &&
3484 tree->opval.op != SWITCH &&
3485 tree->opval.op != FUNCTION &&
3486 tree->opval.op != INLINEASM)
3489 if (IS_ASSIGN_OP (tree->opval.op) ||
3490 IS_DEREF_OP (tree) ||
3491 (tree->opval.op == '&' && !tree->right) ||
3492 tree->opval.op == PTR_OP)
3495 if ((IS_ARRAY_OP (tree->left) && IS_ARRAY_OP (tree->left->left)) ||
3496 (IS_DEREF_OP (tree) && IS_ARRAY_OP (tree->left)))
3499 left = operandFromAst (tree->left,lvl);
3501 if (IS_DEREF_OP (tree) && IS_DEREF_OP (tree->left))
3502 left = geniCodeRValue (left, TRUE);
3506 left = operandFromAst (tree->left,lvl);
3508 if (tree->opval.op == INC_OP ||
3509 tree->opval.op == DEC_OP)
3512 right = operandFromAst (tree->right,lvl);
3517 right = operandFromAst (tree->right,lvl);
3521 /* now depending on the type of operand */
3522 /* this will be a biggy */
3523 switch (tree->opval.op)
3526 case '[': /* array operation */
3528 //sym_link *ltype = operandType (left);
3529 //left = geniCodeRValue (left, IS_PTR (ltype->next) ? TRUE : FALSE);
3530 left = geniCodeRValue (left, FALSE);
3531 right = geniCodeRValue (right, TRUE);
3534 return geniCodeArray (left, right,lvl);
3536 case '.': /* structure dereference */
3537 if (IS_PTR (operandType (left)))
3538 left = geniCodeRValue (left, TRUE);
3540 left = geniCodeRValue (left, FALSE);
3542 return geniCodeStruct (left, right, tree->lvalue);
3544 case PTR_OP: /* structure pointer dereference */
3547 pType = operandType (left);
3548 left = geniCodeRValue (left, TRUE);
3550 setOClass (pType, getSpec (operandType (left)));
3553 return geniCodeStruct (left, right, tree->lvalue);
3555 case INC_OP: /* increment operator */
3557 return geniCodePostInc (left);
3559 return geniCodePreInc (right);
3561 case DEC_OP: /* decrement operator */
3563 return geniCodePostDec (left);
3565 return geniCodePreDec (right);
3567 case '&': /* bitwise and or address of operator */
3569 { /* this is a bitwise operator */
3570 left = geniCodeRValue (left, FALSE);
3571 right = geniCodeRValue (right, FALSE);
3572 return geniCodeBitwise (left, right, BITWISEAND, tree->ftype);
3575 return geniCodeAddressOf (left);
3577 case '|': /* bitwise or & xor */
3579 return geniCodeBitwise (geniCodeRValue (left, FALSE),
3580 geniCodeRValue (right, FALSE),
3585 return geniCodeDivision (geniCodeRValue (left, FALSE),
3586 geniCodeRValue (right, FALSE));
3589 return geniCodeModulus (geniCodeRValue (left, FALSE),
3590 geniCodeRValue (right, FALSE));
3593 return geniCodeMultiply (geniCodeRValue (left, FALSE),
3594 geniCodeRValue (right, FALSE),IS_INT(tree->ftype));
3596 return geniCodeDerefPtr (geniCodeRValue (left, FALSE),lvl);
3600 return geniCodeSubtract (geniCodeRValue (left, FALSE),
3601 geniCodeRValue (right, FALSE));
3603 return geniCodeUnaryMinus (geniCodeRValue (left, FALSE));
3607 return geniCodeAdd (geniCodeRValue (left, FALSE),
3608 geniCodeRValue (right, FALSE),lvl);
3610 return geniCodeRValue (left, FALSE); /* unary '+' has no meaning */
3613 return geniCodeLeftShift (geniCodeRValue (left, FALSE),
3614 geniCodeRValue (right, FALSE));
3617 return geniCodeRightShift (geniCodeRValue (left, FALSE),
3618 geniCodeRValue (right, FALSE));
3620 #if 0 // this indeed needs a second thought
3624 // let's keep this simple: get the rvalue we need
3625 op=geniCodeRValue (right, FALSE);
3626 // now cast it to whatever we want
3627 op=geniCodeCast (operandType(left), op, FALSE);
3628 // if this is going to be used as an lvalue, make it so
3634 #else // bug #604575, is it a bug ????
3635 return geniCodeCast (operandType (left),
3636 geniCodeRValue (right, FALSE), FALSE);
3642 return geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3647 operand *op = geniCodeUnary (geniCodeRValue (left, FALSE), tree->opval.op);
3648 setOperandType (op, UCHARTYPE);
3659 return geniCodeLogic (geniCodeRValue (left, FALSE),
3660 geniCodeRValue (right, FALSE),
3663 return geniCodeConditional (tree,lvl);
3666 return operandFromLit (getSize (tree->right->ftype));
3670 sym_link *rtype = operandType (right);
3671 sym_link *ltype = operandType (left);
3672 if (IS_PTR (rtype) && IS_ITEMP (right)
3673 && right->isaddr && compareType (rtype->next, ltype) == 1)
3674 right = geniCodeRValue (right, TRUE);
3676 right = geniCodeRValue (right, FALSE);
3678 geniCodeAssign (left, right, 0);
3683 geniCodeAssign (left,
3684 geniCodeMultiply (geniCodeRValue (operandFromOperand (left),
3686 geniCodeRValue (right, FALSE),FALSE), 0);
3690 geniCodeAssign (left,
3691 geniCodeDivision (geniCodeRValue (operandFromOperand (left),
3693 geniCodeRValue (right, FALSE)), 0);
3696 geniCodeAssign (left,
3697 geniCodeModulus (geniCodeRValue (operandFromOperand (left),
3699 geniCodeRValue (right, FALSE)), 0);
3702 sym_link *rtype = operandType (right);
3703 sym_link *ltype = operandType (left);
3704 if (IS_PTR (rtype) && IS_ITEMP (right)
3705 && right->isaddr && compareType (rtype->next, ltype) == 1)
3706 right = geniCodeRValue (right, TRUE);
3708 right = geniCodeRValue (right, FALSE);
3711 return geniCodeAssign (left,
3712 geniCodeAdd (geniCodeRValue (operandFromOperand (left),
3718 sym_link *rtype = operandType (right);
3719 sym_link *ltype = operandType (left);
3720 if (IS_PTR (rtype) && IS_ITEMP (right)
3721 && right->isaddr && compareType (rtype->next, ltype) == 1)
3723 right = geniCodeRValue (right, TRUE);
3727 right = geniCodeRValue (right, FALSE);
3730 geniCodeAssign (left,
3731 geniCodeSubtract (geniCodeRValue (operandFromOperand (left),
3737 geniCodeAssign (left,
3738 geniCodeLeftShift (geniCodeRValue (operandFromOperand (left)
3740 geniCodeRValue (right, FALSE)), 0);
3743 geniCodeAssign (left,
3744 geniCodeRightShift (geniCodeRValue (operandFromOperand (left)
3746 geniCodeRValue (right, FALSE)), 0);
3749 geniCodeAssign (left,
3750 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3752 geniCodeRValue (right, FALSE),
3754 operandType (left)), 0);
3757 geniCodeAssign (left,
3758 geniCodeBitwise (geniCodeRValue (operandFromOperand (left),
3760 geniCodeRValue (right, FALSE),
3762 operandType (left)), 0);
3765 geniCodeAssign (left,
3766 geniCodeBitwise (geniCodeRValue (operandFromOperand (left)
3768 geniCodeRValue (right, FALSE),
3770 operandType (left)), 0);
3772 return geniCodeRValue (right, FALSE);
3775 return geniCodeCall (ast2iCode (tree->left,lvl+1),
3778 geniCodeLabel (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3779 return ast2iCode (tree->right,lvl+1);
3782 geniCodeGoto (ast2iCode (tree->left,lvl+1)->operand.symOperand);
3783 return ast2iCode (tree->right,lvl+1);
3786 geniCodeFunctionBody (tree,lvl);
3790 geniCodeReturn (right);
3794 geniCodeIfx (tree,lvl);
3798 geniCodeSwitch (tree,lvl);
3802 geniCodeInline (tree);
3806 geniCodeArrayInit(tree, ast2iCode (tree->left,lvl+1));
3813 /*-----------------------------------------------------------------*/
3814 /* reverseICChain - gets from the list and creates a linkedlist */
3815 /*-----------------------------------------------------------------*/
3822 while ((loop = getSet (&iCodeChain)))
3834 /*-----------------------------------------------------------------*/
3835 /* iCodeFromAst - given an ast will convert it to iCode */
3836 /*-----------------------------------------------------------------*/
3838 iCodeFromAst (ast * tree)
3840 returnLabel = newiTempLabel ("_return");
3841 entryLabel = newiTempLabel ("_entry");
3843 return reverseiCChain ();
3846 static const char *opTypeToStr(OPTYPE op)
3850 case SYMBOL: return "symbol";
3851 case VALUE: return "value";
3852 case TYPE: return "type";
3854 return "undefined type";
3858 operand *validateOpType(operand *op,
3865 if (op && op->type == type)
3870 "Internal error: validateOpType failed in %s(%s) @ %s:%u:"
3871 " expected %s, got %s\n",
3872 macro, args, file, line,
3873 opTypeToStr(type), op ? opTypeToStr(op->type) : "null op");
3875 return op; // never reached, makes compiler happy.